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