Home | History | Annotate | Download | only in crypto
      1 /*
      2  * Copyright (c) 2004, Richard Levitte <richard (at) 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 
     47 struct LP_dir_context_st
     48 {
     49   WIN32_FIND_DATA ctx;
     50   HANDLE handle;
     51   char entry_name[NAME_MAX+1];
     52 };
     53 
     54 const char *LP_find_file(LP_DIR_CTX **ctx, const char *directory)
     55 {
     56   if (ctx == NULL || directory == NULL)
     57     {
     58       errno = EINVAL;
     59       return 0;
     60     }
     61 
     62   errno = 0;
     63   if (*ctx == NULL)
     64     {
     65       const char *extdir = directory;
     66       char *extdirbuf = NULL;
     67       size_t dirlen = strlen (directory);
     68 
     69       if (dirlen == 0)
     70 	{
     71 	  errno = ENOENT;
     72 	  return 0;
     73 	}
     74 
     75       *ctx = (LP_DIR_CTX *)malloc(sizeof(LP_DIR_CTX));
     76       if (*ctx == NULL)
     77 	{
     78 	  errno = ENOMEM;
     79 	  return 0;
     80 	}
     81       memset(*ctx, '\0', sizeof(LP_DIR_CTX));
     82 
     83       if (directory[dirlen-1] != '*')
     84 	{
     85 	  extdirbuf = (char *)malloc(dirlen + 3);
     86 	  if (extdirbuf == NULL)
     87 	    {
     88 	      free(*ctx);
     89 	      *ctx = NULL;
     90 	      errno = ENOMEM;
     91 	      return 0;
     92 	    }
     93 	  if (directory[dirlen-1] != '/' && directory[dirlen-1] != '\\')
     94 	    extdir = strcat(strcpy (extdirbuf,directory),"/*");
     95 	  else
     96 	    extdir = strcat(strcpy (extdirbuf,directory),"*");
     97 	}
     98 
     99       if (sizeof(TCHAR) != sizeof(char))
    100 	{
    101 	  TCHAR *wdir = NULL;
    102 	  /* len_0 denotes string length *with* trailing 0 */
    103 	  size_t index = 0,len_0 = strlen(extdir) + 1;
    104 
    105 	  wdir = (TCHAR *)calloc(len_0, sizeof(TCHAR));
    106 	  if (wdir == NULL)
    107 	    {
    108 	      if (extdirbuf != NULL)
    109 		{
    110 		  free (extdirbuf);
    111 		}
    112 	      free(*ctx);
    113 	      *ctx = NULL;
    114 	      errno = ENOMEM;
    115 	      return 0;
    116 	    }
    117 
    118 #ifdef LP_MULTIBYTE_AVAILABLE
    119 	  if (!MultiByteToWideChar(CP_ACP, 0, extdir, len_0, (WCHAR *)wdir, len_0))
    120 #endif
    121 	    for (index = 0; index < len_0; index++)
    122 	      wdir[index] = (TCHAR)extdir[index];
    123 
    124 	  (*ctx)->handle = FindFirstFile(wdir, &(*ctx)->ctx);
    125 
    126 	  free(wdir);
    127 	}
    128       else
    129 	{
    130 	  (*ctx)->handle = FindFirstFile((TCHAR *)extdir, &(*ctx)->ctx);
    131 	}
    132       if (extdirbuf != NULL)
    133 	{
    134 	  free (extdirbuf);
    135 	}
    136 
    137       if ((*ctx)->handle == INVALID_HANDLE_VALUE)
    138 	{
    139 	  free(*ctx);
    140 	  *ctx = NULL;
    141 	  errno = EINVAL;
    142 	  return 0;
    143 	}
    144     }
    145   else
    146     {
    147       if (FindNextFile((*ctx)->handle, &(*ctx)->ctx) == FALSE)
    148 	{
    149 	  return 0;
    150 	}
    151     }
    152   if (sizeof(TCHAR) != sizeof(char))
    153     {
    154       TCHAR *wdir = (*ctx)->ctx.cFileName;
    155       size_t index, len_0 = 0;
    156 
    157       while (wdir[len_0] && len_0 < (sizeof((*ctx)->entry_name) - 1)) len_0++;
    158       len_0++;
    159 
    160 #ifdef LP_MULTIBYTE_AVAILABLE
    161       if (!WideCharToMultiByte(CP_ACP, 0, (WCHAR *)wdir, len_0, (*ctx)->entry_name,
    162 			       sizeof((*ctx)->entry_name), NULL, 0))
    163 #endif
    164 	for (index = 0; index < len_0; index++)
    165 	  (*ctx)->entry_name[index] = (char)wdir[index];
    166     }
    167   else
    168     strncpy((*ctx)->entry_name, (const char *)(*ctx)->ctx.cFileName,
    169 	    sizeof((*ctx)->entry_name)-1);
    170 
    171   (*ctx)->entry_name[sizeof((*ctx)->entry_name)-1] = '\0';
    172 
    173   return (*ctx)->entry_name;
    174 }
    175 
    176 int LP_find_file_end(LP_DIR_CTX **ctx)
    177 {
    178   if (ctx != NULL && *ctx != NULL)
    179     {
    180       FindClose((*ctx)->handle);
    181       free(*ctx);
    182       *ctx = NULL;
    183       return 1;
    184     }
    185   errno = EINVAL;
    186   return 0;
    187 }
    188