LPdir_win.c revision 279265
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/* We're most likely overcautious here, but let's reserve for 33 broken WinCE headers and explicitly opt for UNICODE call. 34 Keep in mind that our WinCE builds are compiled with -DUNICODE 35 [as well as -D_UNICODE]. */ 36#if defined(LP_SYS_WINCE) && !defined(FindFirstFile) 37# define FindFirstFile FindFirstFileW 38#endif 39#if defined(LP_SYS_WINCE) && !defined(FindFirstFile) 40# define FindNextFile FindNextFileW 41#endif 42 43#ifndef NAME_MAX 44#define NAME_MAX 255 45#endif 46 47struct LP_dir_context_st 48{ 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 { 60 errno = EINVAL; 61 return 0; 62 } 63 64 errno = 0; 65 if (*ctx == NULL) 66 { 67 const char *extdir = directory; 68 char *extdirbuf = NULL; 69 size_t dirlen = strlen (directory); 70 71 if (dirlen == 0) 72 { 73 errno = ENOENT; 74 return 0; 75 } 76 77 *ctx = (LP_DIR_CTX *)malloc(sizeof(LP_DIR_CTX)); 78 if (*ctx == NULL) 79 { 80 errno = ENOMEM; 81 return 0; 82 } 83 memset(*ctx, '\0', sizeof(LP_DIR_CTX)); 84 85 if (directory[dirlen-1] != '*') 86 { 87 extdirbuf = (char *)malloc(dirlen + 3); 88 if (extdirbuf == NULL) 89 { 90 free(*ctx); 91 *ctx = NULL; 92 errno = ENOMEM; 93 return 0; 94 } 95 if (directory[dirlen-1] != '/' && directory[dirlen-1] != '\\') 96 extdir = strcat(strcpy (extdirbuf,directory),"/*"); 97 else 98 extdir = strcat(strcpy (extdirbuf,directory),"*"); 99 } 100 101 if (sizeof(TCHAR) != sizeof(char)) 102 { 103 TCHAR *wdir = NULL; 104 /* len_0 denotes string length *with* trailing 0 */ 105 size_t index = 0,len_0 = strlen(extdir) + 1; 106 107 wdir = (TCHAR *)calloc(len_0, sizeof(TCHAR)); 108 if (wdir == NULL) 109 { 110 if (extdirbuf != NULL) 111 { 112 free (extdirbuf); 113 } 114 free(*ctx); 115 *ctx = NULL; 116 errno = ENOMEM; 117 return 0; 118 } 119 120#ifdef LP_MULTIBYTE_AVAILABLE 121 if (!MultiByteToWideChar(CP_ACP, 0, extdir, len_0, (WCHAR *)wdir, len_0)) 122#endif 123 for (index = 0; index < len_0; index++) 124 wdir[index] = (TCHAR)extdir[index]; 125 126 (*ctx)->handle = FindFirstFile(wdir, &(*ctx)->ctx); 127 128 free(wdir); 129 } 130 else 131 { 132 (*ctx)->handle = FindFirstFile((TCHAR *)extdir, &(*ctx)->ctx); 133 } 134 if (extdirbuf != NULL) 135 { 136 free (extdirbuf); 137 } 138 139 if ((*ctx)->handle == INVALID_HANDLE_VALUE) 140 { 141 free(*ctx); 142 *ctx = NULL; 143 errno = EINVAL; 144 return 0; 145 } 146 } 147 else 148 { 149 if (FindNextFile((*ctx)->handle, &(*ctx)->ctx) == FALSE) 150 { 151 return 0; 152 } 153 } 154 if (sizeof(TCHAR) != sizeof(char)) 155 { 156 TCHAR *wdir = (*ctx)->ctx.cFileName; 157 size_t index, len_0 = 0; 158 159 while (wdir[len_0] && len_0 < (sizeof((*ctx)->entry_name) - 1)) len_0++; 160 len_0++; 161 162#ifdef LP_MULTIBYTE_AVAILABLE 163 if (!WideCharToMultiByte(CP_ACP, 0, (WCHAR *)wdir, len_0, (*ctx)->entry_name, 164 sizeof((*ctx)->entry_name), NULL, 0)) 165#endif 166 for (index = 0; index < len_0; index++) 167 (*ctx)->entry_name[index] = (char)wdir[index]; 168 } 169 else 170 strncpy((*ctx)->entry_name, (const char *)(*ctx)->ctx.cFileName, 171 sizeof((*ctx)->entry_name)-1); 172 173 (*ctx)->entry_name[sizeof((*ctx)->entry_name)-1] = '\0'; 174 175 return (*ctx)->entry_name; 176} 177 178int LP_find_file_end(LP_DIR_CTX **ctx) 179{ 180 if (ctx != NULL && *ctx != NULL) 181 { 182 FindClose((*ctx)->handle); 183 free(*ctx); 184 *ctx = NULL; 185 return 1; 186 } 187 errno = EINVAL; 188 return 0; 189} 190