1 /* $LP: LPlib/source/LPdir_win.c,v 1.10 2004/08/26 13:36:05 _cvs_levitte Exp $ */ 2 /* 3 * Copyright (c) 2004, Richard Levitte <richard (at) 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 COPYRIGHT HOLDERS AND CONTRIBUTORS 16 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 18 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 19 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 21 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 */ 27 28 #include "directory.h" 29 30 31 #if defined(OPENSSL_WINDOWS) 32 33 #pragma warning(push, 3) 34 #include <windows.h> 35 #pragma warning(pop) 36 #include <errno.h> 37 #include <string.h> 38 #include <tchar.h> 39 40 #ifndef NAME_MAX 41 #define NAME_MAX 255 42 #endif 43 44 #include <openssl/mem.h> 45 46 47 struct OPENSSL_dir_context_st { 48 WIN32_FIND_DATA ctx; 49 HANDLE handle; 50 char entry_name[NAME_MAX + 1]; 51 }; 52 53 const char *OPENSSL_DIR_read(OPENSSL_DIR_CTX **ctx, const char *directory) { 54 if (ctx == NULL || directory == NULL) { 55 errno = EINVAL; 56 return 0; 57 } 58 59 errno = 0; 60 if (*ctx == NULL) { 61 *ctx = malloc(sizeof(OPENSSL_DIR_CTX)); 62 if (*ctx == NULL) { 63 errno = ENOMEM; 64 return 0; 65 } 66 memset(*ctx, 0, sizeof(OPENSSL_DIR_CTX)); 67 68 if (sizeof(TCHAR) != sizeof(char)) { 69 TCHAR *wdir = NULL; 70 /* len_0 denotes string length *with* trailing 0 */ 71 size_t index = 0, len_0 = strlen(directory) + 1; 72 73 wdir = (TCHAR *)malloc(len_0 * sizeof(TCHAR)); 74 if (wdir == NULL) { 75 free(*ctx); 76 *ctx = NULL; 77 errno = ENOMEM; 78 return 0; 79 } 80 81 if (!MultiByteToWideChar(CP_ACP, 0, directory, len_0, (WCHAR *)wdir, 82 len_0)) { 83 for (index = 0; index < len_0; index++) { 84 wdir[index] = (TCHAR)directory[index]; 85 } 86 } 87 88 (*ctx)->handle = FindFirstFile(wdir, &(*ctx)->ctx); 89 90 free(wdir); 91 } else { 92 (*ctx)->handle = FindFirstFile((TCHAR *)directory, &(*ctx)->ctx); 93 } 94 95 if ((*ctx)->handle == INVALID_HANDLE_VALUE) { 96 free(*ctx); 97 *ctx = NULL; 98 errno = EINVAL; 99 return 0; 100 } 101 } else { 102 if (FindNextFile((*ctx)->handle, &(*ctx)->ctx) == FALSE) { 103 return 0; 104 } 105 } 106 107 if (sizeof(TCHAR) != sizeof(char)) { 108 TCHAR *wdir = (*ctx)->ctx.cFileName; 109 size_t index, len_0 = 0; 110 111 while (wdir[len_0] && len_0 < (sizeof((*ctx)->entry_name) - 1)) { 112 len_0++; 113 } 114 len_0++; 115 116 if (!WideCharToMultiByte(CP_ACP, 0, (WCHAR *)wdir, len_0, 117 (*ctx)->entry_name, sizeof((*ctx)->entry_name), 118 NULL, 0)) { 119 for (index = 0; index < len_0; index++) { 120 (*ctx)->entry_name[index] = (char)wdir[index]; 121 } 122 } 123 } else { 124 strncpy((*ctx)->entry_name, (const char *)(*ctx)->ctx.cFileName, 125 sizeof((*ctx)->entry_name) - 1); 126 } 127 128 (*ctx)->entry_name[sizeof((*ctx)->entry_name) - 1] = '\0'; 129 130 return (*ctx)->entry_name; 131 } 132 133 int OPENSSL_DIR_end(OPENSSL_DIR_CTX **ctx) { 134 if (ctx != NULL && *ctx != NULL) { 135 FindClose((*ctx)->handle); 136 free(*ctx); 137 *ctx = NULL; 138 return 1; 139 } 140 errno = EINVAL; 141 return 0; 142 } 143 144 #endif /* OPENSSL_WINDOWS */ 145