Fix one more instance of incorrect OPENSSL_API_COMPAT value
[openssl.git] / crypto / LPdir_win.c
1 /*
2  * Copyright 2004-2016 The OpenSSL Project Authors. All Rights Reserved.
3  *
4  * Licensed under the OpenSSL license (the "License").  You may not use
5  * this file except in compliance with the License.  You can obtain a copy
6  * in the file LICENSE in the source distribution or at
7  * https://www.openssl.org/source/license.html
8  */
9
10 #include <windows.h>
11 #include <tchar.h>
12 #ifndef LPDIR_H
13 # include "LPdir.h"
14 #endif
15
16 /*
17  * We're most likely overcautious here, but let's reserve for broken WinCE
18  * headers and explicitly opt for UNICODE call. Keep in mind that our WinCE
19  * builds are compiled with -DUNICODE [as well as -D_UNICODE].
20  */
21 #if defined(LP_SYS_WINCE) && !defined(FindFirstFile)
22 # define FindFirstFile FindFirstFileW
23 #endif
24 #if defined(LP_SYS_WINCE) && !defined(FindNextFile)
25 # define FindNextFile FindNextFileW
26 #endif
27
28 #ifndef NAME_MAX
29 # define NAME_MAX 255
30 #endif
31
32 struct LP_dir_context_st {
33     WIN32_FIND_DATA ctx;
34     HANDLE handle;
35     char entry_name[NAME_MAX + 1];
36 };
37
38 const char *LP_find_file(LP_DIR_CTX **ctx, const char *directory)
39 {
40     if (ctx == NULL || directory == NULL) {
41         errno = EINVAL;
42         return 0;
43     }
44
45     errno = 0;
46     if (*ctx == NULL) {
47         const char *extdir = directory;
48         char *extdirbuf = NULL;
49         size_t dirlen = strlen(directory);
50
51         if (dirlen == 0) {
52             errno = ENOENT;
53             return 0;
54         }
55
56         *ctx = malloc(sizeof(**ctx));
57         if (*ctx == NULL) {
58             errno = ENOMEM;
59             return 0;
60         }
61         memset(*ctx, 0, sizeof(**ctx));
62
63         if (directory[dirlen - 1] != '*') {
64             extdirbuf = (char *)malloc(dirlen + 3);
65             if (extdirbuf == NULL) {
66                 free(*ctx);
67                 *ctx = NULL;
68                 errno = ENOMEM;
69                 return 0;
70             }
71             if (directory[dirlen - 1] != '/' && directory[dirlen - 1] != '\\')
72                 extdir = strcat(strcpy(extdirbuf, directory), "/*");
73             else
74                 extdir = strcat(strcpy(extdirbuf, directory), "*");
75         }
76
77         if (sizeof(TCHAR) != sizeof(char)) {
78             TCHAR *wdir = NULL;
79             /* len_0 denotes string length *with* trailing 0 */
80             size_t index = 0, len_0 = strlen(extdir) + 1;
81
82             wdir = (TCHAR *)calloc(len_0, sizeof(TCHAR));
83             if (wdir == NULL) {
84                 if (extdirbuf != NULL) {
85                     free(extdirbuf);
86                 }
87                 free(*ctx);
88                 *ctx = NULL;
89                 errno = ENOMEM;
90                 return 0;
91             }
92 #ifdef LP_MULTIBYTE_AVAILABLE
93             if (!MultiByteToWideChar
94                 (CP_ACP, 0, extdir, len_0, (WCHAR *)wdir, len_0))
95 #endif
96                 for (index = 0; index < len_0; index++)
97                     wdir[index] = (TCHAR)extdir[index];
98
99             (*ctx)->handle = FindFirstFile(wdir, &(*ctx)->ctx);
100
101             free(wdir);
102         } else {
103             (*ctx)->handle = FindFirstFile((TCHAR *)extdir, &(*ctx)->ctx);
104         }
105         if (extdirbuf != NULL) {
106             free(extdirbuf);
107         }
108
109         if ((*ctx)->handle == INVALID_HANDLE_VALUE) {
110             free(*ctx);
111             *ctx = NULL;
112             errno = EINVAL;
113             return 0;
114         }
115     } else {
116         if (FindNextFile((*ctx)->handle, &(*ctx)->ctx) == FALSE) {
117             return 0;
118         }
119     }
120     if (sizeof(TCHAR) != sizeof(char)) {
121         TCHAR *wdir = (*ctx)->ctx.cFileName;
122         size_t index, len_0 = 0;
123
124         while (wdir[len_0] && len_0 < (sizeof((*ctx)->entry_name) - 1))
125             len_0++;
126         len_0++;
127
128 #ifdef LP_MULTIBYTE_AVAILABLE
129         if (!WideCharToMultiByte
130             (CP_ACP, 0, (WCHAR *)wdir, len_0, (*ctx)->entry_name,
131              sizeof((*ctx)->entry_name), NULL, 0))
132 #endif
133             for (index = 0; index < len_0; index++)
134                 (*ctx)->entry_name[index] = (char)wdir[index];
135     } else
136         strncpy((*ctx)->entry_name, (const char *)(*ctx)->ctx.cFileName,
137                 sizeof((*ctx)->entry_name) - 1);
138
139     (*ctx)->entry_name[sizeof((*ctx)->entry_name) - 1] = '\0';
140
141     return (*ctx)->entry_name;
142 }
143
144 int LP_find_file_end(LP_DIR_CTX **ctx)
145 {
146     if (ctx != NULL && *ctx != NULL) {
147         FindClose((*ctx)->handle);
148         free(*ctx);
149         *ctx = NULL;
150         return 1;
151     }
152     errno = EINVAL;
153     return 0;
154 }