06948f7adc1833763fb724617a7061ad5b4c9bc8
[openssl.git] / crypto / LPdir_win.c
1 /* $LP: LPlib/source/LPdir_win.c,v 1.5 2004/07/20 22:39:13 _cvs_levitte Exp $ */
2 /*
3  * Copyright (c) 2004, Richard Levitte <richard@levitte.org>
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25  * SUCH DAMAGE.
26  */
27 #include <windows.h>
28 #include <tchar.h>
29 #ifndef LPDIR_H
30 #include "LPdir.h"
31 #endif
32
33 /* It seems like WinCE doesn't always have the "normal" mapping
34    macros.  We're opting for the UNICODE ones. */
35 #if defined(LP_SYS_WINCE) && !defined(FindFirstFile)
36 # define FindFirstFile FindFirstFileW
37 #endif
38
39 struct LP_dir_context_st
40 {
41   WIN32_FIND_DATA ctx;
42   HANDLE handle;
43   char entry_name[NAME_MAX+1];
44 };
45
46 const char *LP_find_file(LP_DIR_CTX **ctx, const char *directory)
47 {
48   struct dirent *direntry = NULL;
49
50   if (ctx == NULL || directory == NULL)
51     {
52       errno = EINVAL;
53       return 0;
54     }
55
56   errno = 0;
57   if (*ctx == NULL)
58     {
59       *ctx = (LP_DIR_CTX *)malloc(sizeof(LP_DIR_CTX));
60       if (*ctx == NULL)
61         {
62           errno = ENOMEM;
63           return 0;
64         }
65       memset(*ctx, '\0', sizeof(LP_DIR_CTX));
66
67       if (sizeof(TCHAR) != sizeof(char))
68         {
69           TCHAR *wdir = NULL;
70           size_t index = 0,len = strlen(direcory);
71
72           wdir = (TCHAR *)malloc((len + 1) * sizeof(TCHAR));
73           if (wdir == NULL)
74             {
75               free(*ctx);
76               *ctx = NULL;
77               errno = ENOMEM;
78               return 0;
79             }
80
81 #ifdef LP_MULTIBYTE_AVAILABLE
82           if (!MultiByteToWideChar(CP_ACP, 0, directory, len, wdir, len + 1))
83 #endif
84             for (index = 0; index < strlen(directory) + 1; index++)
85               wdir[index] = (TCHAR)directory[index];
86
87           (*ctx)->handle = FindFirstFile(wdir, &(*ctx)->ctx);
88
89           free(wdir);
90         }
91       else
92         (*ctx)->handle = FindFirstFile(directory, &(*ctx)->ctx);
93
94       if ((*ctx)->handle == INVALID_HANDLE_VALUE)
95         {
96           free(*ctx);
97           *ctx = NULL;
98           errno = EINVAL;
99           return 0;
100         }
101     }
102   else
103     {
104       if (FindNextFile((*ctx)->handle, (*ctx)->ctx) == FALSE)
105         {
106           return 0;
107         }
108     }
109
110   if (sizeof(TCHAR) != sizeof(char))
111     {
112       TCHAR *wdir = (*ctx)->ctx.cFileName;
113       size_t index, len;
114
115       for (len = 0; wdir[len] && len < (sizeof((*ctx)->entry_name) - 1);)
116         len++;
117
118 #ifdef LP_MULTIBYTE_AVAILABLE
119       if (!WideCharToMultiByte(CP_ACP, 0, wdir, len, (*ctx)->entry_name,
120                                sizeof((*ctx)->entry_name) - 1, NULL, 0))
121 #endif
122         for (index = 0; index < len; index++)
123           (*ctx)->entry_name[index] = (char)wdir[index];
124     }
125   else
126     strncpy((*ctx)->entry_name, (*ctx)->ctx.cFileName,
127             sizeof((*ctx)->entry_name)-1);
128
129   (*ctx)->entry_name[sizeof((*ctx)->entry_name)-1] = '\0';
130
131   return (*ctx)->entry_name;
132 }
133
134 int LP_find_file_end(LP_DIR_CTX **ctx)
135 {
136   if (ctx != NULL && *ctx != NULL)
137     {
138       FindClose((*ctx)->handle);
139       free(*ctx);
140       *ctx = NULL;
141       return 1;
142     }
143   errno = EINVAL;
144   return 0;
145 }