xref: /sqlite-3.40.0/src/test_windirent.c (revision 03491a1a)
192af1ebcSmistachkin /*
292af1ebcSmistachkin ** 2015 November 30
392af1ebcSmistachkin **
492af1ebcSmistachkin ** The author disclaims copyright to this source code.  In place of
592af1ebcSmistachkin ** a legal notice, here is a blessing:
692af1ebcSmistachkin **
792af1ebcSmistachkin **    May you do good and not evil.
892af1ebcSmistachkin **    May you find forgiveness for yourself and forgive others.
992af1ebcSmistachkin **    May you share freely, never taking more than you give.
1092af1ebcSmistachkin **
1192af1ebcSmistachkin *************************************************************************
1292af1ebcSmistachkin ** This file contains code to implement most of the opendir() family of
1392af1ebcSmistachkin ** POSIX functions on Win32 using the MSVCRT.
1492af1ebcSmistachkin */
1592af1ebcSmistachkin 
1692af1ebcSmistachkin #if defined(_WIN32) && defined(_MSC_VER)
1792af1ebcSmistachkin #include "test_windirent.h"
1892af1ebcSmistachkin 
1992af1ebcSmistachkin /*
207dd7d98bSmistachkin ** Implementation of the POSIX getenv() function using the Win32 API.
217dd7d98bSmistachkin ** This function is not thread-safe.
227dd7d98bSmistachkin */
windirent_getenv(const char * name)237dd7d98bSmistachkin const char *windirent_getenv(
247dd7d98bSmistachkin   const char *name
257dd7d98bSmistachkin ){
267dd7d98bSmistachkin   static char value[32768]; /* Maximum length, per MSDN */
277dd7d98bSmistachkin   DWORD dwSize = sizeof(value) / sizeof(char); /* Size in chars */
287dd7d98bSmistachkin   DWORD dwRet; /* Value returned by GetEnvironmentVariableA() */
297dd7d98bSmistachkin 
307dd7d98bSmistachkin   memset(value, 0, sizeof(value));
317dd7d98bSmistachkin   dwRet = GetEnvironmentVariableA(name, value, dwSize);
327dd7d98bSmistachkin   if( dwRet==0 || dwRet>dwSize ){
337dd7d98bSmistachkin     /*
347dd7d98bSmistachkin     ** The function call to GetEnvironmentVariableA() failed -OR-
357dd7d98bSmistachkin     ** the buffer is not large enough.  Either way, return NULL.
367dd7d98bSmistachkin     */
377dd7d98bSmistachkin     return 0;
387dd7d98bSmistachkin   }else{
397dd7d98bSmistachkin     /*
407dd7d98bSmistachkin     ** The function call to GetEnvironmentVariableA() succeeded
417dd7d98bSmistachkin     ** -AND- the buffer contains the entire value.
427dd7d98bSmistachkin     */
437dd7d98bSmistachkin     return value;
447dd7d98bSmistachkin   }
457dd7d98bSmistachkin }
467dd7d98bSmistachkin 
477dd7d98bSmistachkin /*
4892af1ebcSmistachkin ** Implementation of the POSIX opendir() function using the MSVCRT.
4992af1ebcSmistachkin */
opendir(const char * dirname)5092af1ebcSmistachkin LPDIR opendir(
5192af1ebcSmistachkin   const char *dirname
5292af1ebcSmistachkin ){
5392af1ebcSmistachkin   struct _finddata_t data;
5492af1ebcSmistachkin   LPDIR dirp = (LPDIR)sqlite3_malloc(sizeof(DIR));
5592af1ebcSmistachkin   SIZE_T namesize = sizeof(data.name) / sizeof(data.name[0]);
5692af1ebcSmistachkin 
5792af1ebcSmistachkin   if( dirp==NULL ) return NULL;
5892af1ebcSmistachkin   memset(dirp, 0, sizeof(DIR));
5992af1ebcSmistachkin 
6092af1ebcSmistachkin   /* TODO: Remove this if Unix-style root paths are not used. */
6192af1ebcSmistachkin   if( sqlite3_stricmp(dirname, "/")==0 ){
627dd7d98bSmistachkin     dirname = windirent_getenv("SystemDrive");
6392af1ebcSmistachkin   }
6492af1ebcSmistachkin 
658a9e8358Smistachkin   memset(&data, 0, sizeof(struct _finddata_t));
6692af1ebcSmistachkin   _snprintf(data.name, namesize, "%s\\*", dirname);
6792af1ebcSmistachkin   dirp->d_handle = _findfirst(data.name, &data);
6892af1ebcSmistachkin 
6992af1ebcSmistachkin   if( dirp->d_handle==BAD_INTPTR_T ){
7092af1ebcSmistachkin     closedir(dirp);
7192af1ebcSmistachkin     return NULL;
7292af1ebcSmistachkin   }
7392af1ebcSmistachkin 
748a9e8358Smistachkin   /* TODO: Remove this block to allow hidden and/or system files. */
75*aac853baSmistachkin   if( is_filtered(data) ){
768a9e8358Smistachkin next:
778a9e8358Smistachkin 
788a9e8358Smistachkin     memset(&data, 0, sizeof(struct _finddata_t));
7992af1ebcSmistachkin     if( _findnext(dirp->d_handle, &data)==-1 ){
8092af1ebcSmistachkin       closedir(dirp);
8192af1ebcSmistachkin       return NULL;
8292af1ebcSmistachkin     }
838a9e8358Smistachkin 
848a9e8358Smistachkin     /* TODO: Remove this block to allow hidden and/or system files. */
85*aac853baSmistachkin     if( is_filtered(data) ) goto next;
8692af1ebcSmistachkin   }
8792af1ebcSmistachkin 
8892af1ebcSmistachkin   dirp->d_first.d_attributes = data.attrib;
8992af1ebcSmistachkin   strncpy(dirp->d_first.d_name, data.name, NAME_MAX);
9092af1ebcSmistachkin   dirp->d_first.d_name[NAME_MAX] = '\0';
9192af1ebcSmistachkin 
9292af1ebcSmistachkin   return dirp;
9392af1ebcSmistachkin }
9492af1ebcSmistachkin 
9592af1ebcSmistachkin /*
9692af1ebcSmistachkin ** Implementation of the POSIX readdir() function using the MSVCRT.
9792af1ebcSmistachkin */
readdir(LPDIR dirp)9892af1ebcSmistachkin LPDIRENT readdir(
9992af1ebcSmistachkin   LPDIR dirp
10092af1ebcSmistachkin ){
10192af1ebcSmistachkin   struct _finddata_t data;
10292af1ebcSmistachkin 
10392af1ebcSmistachkin   if( dirp==NULL ) return NULL;
10492af1ebcSmistachkin 
10592af1ebcSmistachkin   if( dirp->d_first.d_ino==0 ){
10692af1ebcSmistachkin     dirp->d_first.d_ino++;
10792af1ebcSmistachkin     dirp->d_next.d_ino++;
10892af1ebcSmistachkin 
10992af1ebcSmistachkin     return &dirp->d_first;
11092af1ebcSmistachkin   }
11192af1ebcSmistachkin 
11292af1ebcSmistachkin next:
11392af1ebcSmistachkin 
1148a9e8358Smistachkin   memset(&data, 0, sizeof(struct _finddata_t));
11592af1ebcSmistachkin   if( _findnext(dirp->d_handle, &data)==-1 ) return NULL;
11692af1ebcSmistachkin 
1178a9e8358Smistachkin   /* TODO: Remove this block to allow hidden and/or system files. */
118*aac853baSmistachkin   if( is_filtered(data) ) goto next;
11992af1ebcSmistachkin 
12092af1ebcSmistachkin   dirp->d_next.d_ino++;
12192af1ebcSmistachkin   dirp->d_next.d_attributes = data.attrib;
12292af1ebcSmistachkin   strncpy(dirp->d_next.d_name, data.name, NAME_MAX);
12392af1ebcSmistachkin   dirp->d_next.d_name[NAME_MAX] = '\0';
12492af1ebcSmistachkin 
12592af1ebcSmistachkin   return &dirp->d_next;
12692af1ebcSmistachkin }
12792af1ebcSmistachkin 
12892af1ebcSmistachkin /*
12992af1ebcSmistachkin ** Implementation of the POSIX readdir_r() function using the MSVCRT.
13092af1ebcSmistachkin */
readdir_r(LPDIR dirp,LPDIRENT entry,LPDIRENT * result)13192af1ebcSmistachkin INT readdir_r(
13292af1ebcSmistachkin   LPDIR dirp,
13392af1ebcSmistachkin   LPDIRENT entry,
13492af1ebcSmistachkin   LPDIRENT *result
13592af1ebcSmistachkin ){
13692af1ebcSmistachkin   struct _finddata_t data;
13792af1ebcSmistachkin 
13892af1ebcSmistachkin   if( dirp==NULL ) return EBADF;
13992af1ebcSmistachkin 
14092af1ebcSmistachkin   if( dirp->d_first.d_ino==0 ){
14192af1ebcSmistachkin     dirp->d_first.d_ino++;
14292af1ebcSmistachkin     dirp->d_next.d_ino++;
14392af1ebcSmistachkin 
14492af1ebcSmistachkin     entry->d_ino = dirp->d_first.d_ino;
14592af1ebcSmistachkin     entry->d_attributes = dirp->d_first.d_attributes;
14692af1ebcSmistachkin     strncpy(entry->d_name, dirp->d_first.d_name, NAME_MAX);
14792af1ebcSmistachkin     entry->d_name[NAME_MAX] = '\0';
14892af1ebcSmistachkin 
14992af1ebcSmistachkin     *result = entry;
15092af1ebcSmistachkin     return 0;
15192af1ebcSmistachkin   }
15292af1ebcSmistachkin 
15392af1ebcSmistachkin next:
15492af1ebcSmistachkin 
1558a9e8358Smistachkin   memset(&data, 0, sizeof(struct _finddata_t));
15692af1ebcSmistachkin   if( _findnext(dirp->d_handle, &data)==-1 ){
15792af1ebcSmistachkin     *result = NULL;
15892af1ebcSmistachkin     return ENOENT;
15992af1ebcSmistachkin   }
16092af1ebcSmistachkin 
1618a9e8358Smistachkin   /* TODO: Remove this block to allow hidden and/or system files. */
162*aac853baSmistachkin   if( is_filtered(data) ) goto next;
16392af1ebcSmistachkin 
16492af1ebcSmistachkin   entry->d_ino = (ino_t)-1; /* not available */
16592af1ebcSmistachkin   entry->d_attributes = data.attrib;
16692af1ebcSmistachkin   strncpy(entry->d_name, data.name, NAME_MAX);
16792af1ebcSmistachkin   entry->d_name[NAME_MAX] = '\0';
16892af1ebcSmistachkin 
16992af1ebcSmistachkin   *result = entry;
17092af1ebcSmistachkin   return 0;
17192af1ebcSmistachkin }
17292af1ebcSmistachkin 
17392af1ebcSmistachkin /*
17492af1ebcSmistachkin ** Implementation of the POSIX closedir() function using the MSVCRT.
17592af1ebcSmistachkin */
closedir(LPDIR dirp)17692af1ebcSmistachkin INT closedir(
17792af1ebcSmistachkin   LPDIR dirp
17892af1ebcSmistachkin ){
17992af1ebcSmistachkin   INT result = 0;
18092af1ebcSmistachkin 
18192af1ebcSmistachkin   if( dirp==NULL ) return EINVAL;
18292af1ebcSmistachkin 
18392af1ebcSmistachkin   if( dirp->d_handle!=NULL_INTPTR_T && dirp->d_handle!=BAD_INTPTR_T ){
18492af1ebcSmistachkin     result = _findclose(dirp->d_handle);
18592af1ebcSmistachkin   }
18692af1ebcSmistachkin 
18792af1ebcSmistachkin   sqlite3_free(dirp);
18892af1ebcSmistachkin   return result;
18992af1ebcSmistachkin }
19092af1ebcSmistachkin 
19192af1ebcSmistachkin #endif /* defined(WIN32) && defined(_MSC_VER) */
192