LPdir_win.c revision 296465
1/* 2 * Copyright (c) 2004, Richard Levitte <richard@levitte.org> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 15 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 16 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 17 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 18 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 19 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 20 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 */ 26#include <windows.h> 27#include <tchar.h> 28#ifndef LPDIR_H 29# include "LPdir.h" 30#endif 31 32/* 33 * We're most likely overcautious here, but let's reserve for broken WinCE 34 * headers and explicitly opt for UNICODE call. Keep in mind that our WinCE 35 * builds are compiled with -DUNICODE [as well as -D_UNICODE]. 36 */ 37#if defined(LP_SYS_WINCE) && !defined(FindFirstFile) 38# define FindFirstFile FindFirstFileW 39#endif 40#if defined(LP_SYS_WINCE) && !defined(FindFirstFile) 41# define FindNextFile FindNextFileW 42#endif 43 44#ifndef NAME_MAX 45# define NAME_MAX 255 46#endif 47 48struct LP_dir_context_st { 49 WIN32_FIND_DATA ctx; 50 HANDLE handle; 51 char entry_name[NAME_MAX + 1]; 52}; 53 54const char *LP_find_file(LP_DIR_CTX **ctx, const char *directory) 55{ 56 struct dirent *direntry = NULL; 57 58 if (ctx == NULL || directory == NULL) { 59 errno = EINVAL; 60 return 0; 61 } 62 63 errno = 0; 64 if (*ctx == NULL) { 65 const char *extdir = directory; 66 char *extdirbuf = NULL; 67 size_t dirlen = strlen(directory); 68 69 if (dirlen == 0) { 70 errno = ENOENT; 71 return 0; 72 } 73 74 *ctx = (LP_DIR_CTX *)malloc(sizeof(LP_DIR_CTX)); 75 if (*ctx == NULL) { 76 errno = ENOMEM; 77 return 0; 78 } 79 memset(*ctx, '\0', sizeof(LP_DIR_CTX)); 80 81 if (directory[dirlen - 1] != '*') { 82 extdirbuf = (char *)malloc(dirlen + 3); 83 if (extdirbuf == NULL) { 84 free(*ctx); 85 *ctx = NULL; 86 errno = ENOMEM; 87 return 0; 88 } 89 if (directory[dirlen - 1] != '/' && directory[dirlen - 1] != '\\') 90 extdir = strcat(strcpy(extdirbuf, directory), "/*"); 91 else 92 extdir = strcat(strcpy(extdirbuf, directory), "*"); 93 } 94 95 if (sizeof(TCHAR) != sizeof(char)) { 96 TCHAR *wdir = NULL; 97 /* len_0 denotes string length *with* trailing 0 */ 98 size_t index = 0, len_0 = strlen(extdir) + 1; 99 100 wdir = (TCHAR *)calloc(len_0, sizeof(TCHAR)); 101 if (wdir == NULL) { 102 if (extdirbuf != NULL) { 103 free(extdirbuf); 104 } 105 free(*ctx); 106 *ctx = NULL; 107 errno = ENOMEM; 108 return 0; 109 } 110#ifdef LP_MULTIBYTE_AVAILABLE 111 if (!MultiByteToWideChar 112 (CP_ACP, 0, extdir, len_0, (WCHAR *)wdir, len_0)) 113#endif 114 for (index = 0; index < len_0; index++) 115 wdir[index] = (TCHAR)extdir[index]; 116 117 (*ctx)->handle = FindFirstFile(wdir, &(*ctx)->ctx); 118 119 free(wdir); 120 } else { 121 (*ctx)->handle = FindFirstFile((TCHAR *)extdir, &(*ctx)->ctx); 122 } 123 if (extdirbuf != NULL) { 124 free(extdirbuf); 125 } 126 127 if ((*ctx)->handle == INVALID_HANDLE_VALUE) { 128 free(*ctx); 129 *ctx = NULL; 130 errno = EINVAL; 131 return 0; 132 } 133 } else { 134 if (FindNextFile((*ctx)->handle, &(*ctx)->ctx) == FALSE) { 135 return 0; 136 } 137 } 138 if (sizeof(TCHAR) != sizeof(char)) { 139 TCHAR *wdir = (*ctx)->ctx.cFileName; 140 size_t index, len_0 = 0; 141 142 while (wdir[len_0] && len_0 < (sizeof((*ctx)->entry_name) - 1)) 143 len_0++; 144 len_0++; 145 146#ifdef LP_MULTIBYTE_AVAILABLE 147 if (!WideCharToMultiByte 148 (CP_ACP, 0, (WCHAR *)wdir, len_0, (*ctx)->entry_name, 149 sizeof((*ctx)->entry_name), NULL, 0)) 150#endif 151 for (index = 0; index < len_0; index++) 152 (*ctx)->entry_name[index] = (char)wdir[index]; 153 } else 154 strncpy((*ctx)->entry_name, (const char *)(*ctx)->ctx.cFileName, 155 sizeof((*ctx)->entry_name) - 1); 156 157 (*ctx)->entry_name[sizeof((*ctx)->entry_name) - 1] = '\0'; 158 159 return (*ctx)->entry_name; 160} 161 162int LP_find_file_end(LP_DIR_CTX **ctx) 163{ 164 if (ctx != NULL && *ctx != NULL) { 165 FindClose((*ctx)->handle); 166 free(*ctx); 167 *ctx = NULL; 168 return 1; 169 } 170 errno = EINVAL; 171 return 0; 172} 173