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@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#include <windows.h> 28#include <tchar.h> 29#ifndef LPDIR_H 30#include "LPdir.h" 31#endif 32 33/* We're most likely overcautious here, but let's reserve for 34 broken WinCE headers and explicitly opt for UNICODE call. 35 Keep in mind that our WinCE builds are compiled with -DUNICODE 36 [as well as -D_UNICODE]. */ 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{ 50 WIN32_FIND_DATA ctx; 51 HANDLE handle; 52 char entry_name[NAME_MAX+1]; 53}; 54 55const char *LP_find_file(LP_DIR_CTX **ctx, const char *directory) 56{ 57 struct dirent *direntry = NULL; 58 59 if (ctx == NULL || directory == NULL) 60 { 61 errno = EINVAL; 62 return 0; 63 } 64 65 errno = 0; 66 if (*ctx == NULL) 67 { 68 *ctx = (LP_DIR_CTX *)malloc(sizeof(LP_DIR_CTX)); 69 if (*ctx == NULL) 70 { 71 errno = ENOMEM; 72 return 0; 73 } 74 memset(*ctx, '\0', sizeof(LP_DIR_CTX)); 75 76 if (sizeof(TCHAR) != sizeof(char)) 77 { 78 TCHAR *wdir = NULL; 79 /* len_0 denotes string length *with* trailing 0 */ 80 size_t index = 0,len_0 = strlen(directory) + 1; 81 82 wdir = (TCHAR *)malloc(len_0 * sizeof(TCHAR)); 83 if (wdir == NULL) 84 { 85 free(*ctx); 86 *ctx = NULL; 87 errno = ENOMEM; 88 return 0; 89 } 90 91#ifdef LP_MULTIBYTE_AVAILABLE 92 if (!MultiByteToWideChar(CP_ACP, 0, directory, len_0, (WCHAR *)wdir, len_0)) 93#endif 94 for (index = 0; index < len_0; index++) 95 wdir[index] = (TCHAR)directory[index]; 96 97 (*ctx)->handle = FindFirstFile(wdir, &(*ctx)->ctx); 98 99 free(wdir); 100 } 101 else 102 (*ctx)->handle = FindFirstFile((TCHAR *)directory, &(*ctx)->ctx); 103 104 if ((*ctx)->handle == INVALID_HANDLE_VALUE) 105 { 106 free(*ctx); 107 *ctx = NULL; 108 errno = EINVAL; 109 return 0; 110 } 111 } 112 else 113 { 114 if (FindNextFile((*ctx)->handle, &(*ctx)->ctx) == FALSE) 115 { 116 return 0; 117 } 118 } 119 120 if (sizeof(TCHAR) != sizeof(char)) 121 { 122 TCHAR *wdir = (*ctx)->ctx.cFileName; 123 size_t index, len_0 = 0; 124 125 while (wdir[len_0] && len_0 < (sizeof((*ctx)->entry_name) - 1)) len_0++; 126 len_0++; 127 128#ifdef LP_MULTIBYTE_AVAILABLE 129 if (!WideCharToMultiByte(CP_ACP, 0, (WCHAR *)wdir, len_0, (*ctx)->entry_name, 130 sizeof((*ctx)->entry_name), NULL, 0)) 131#endif 132 for (index = 0; index < len_0; index++) 133 (*ctx)->entry_name[index] = (char)wdir[index]; 134 } 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 144int LP_find_file_end(LP_DIR_CTX **ctx) 145{ 146 if (ctx != NULL && *ctx != NULL) 147 { 148 FindClose((*ctx)->handle); 149 free(*ctx); 150 *ctx = NULL; 151 return 1; 152 } 153 errno = EINVAL; 154 return 0; 155} 156