1 /* 2 ** 2015 November 30 3 ** 4 ** The author disclaims copyright to this source code. In place of 5 ** a legal notice, here is a blessing: 6 ** 7 ** May you do good and not evil. 8 ** May you find forgiveness for yourself and forgive others. 9 ** May you share freely, never taking more than you give. 10 ** 11 ************************************************************************* 12 ** This file contains code to implement most of the opendir() family of 13 ** POSIX functions on Win32 using the MSVCRT. 14 */ 15 16 #if defined(_WIN32) && defined(_MSC_VER) 17 18 #include "test_windirent.h" 19 20 /* 21 ** Implementation of the POSIX opendir() function using the MSVCRT. 22 */ 23 LPDIR opendir( 24 const char *dirname 25 ){ 26 struct _finddata_t data; 27 LPDIR dirp = (LPDIR)sqlite3_malloc(sizeof(DIR)); 28 SIZE_T namesize = sizeof(data.name) / sizeof(data.name[0]); 29 30 if( dirp==NULL ) return NULL; 31 memset(dirp, 0, sizeof(DIR)); 32 33 /* TODO: Remove this if Unix-style root paths are not used. */ 34 if( sqlite3_stricmp(dirname, "/")==0 ){ 35 dirname = getenv("SystemDrive"); 36 } 37 38 _snprintf(data.name, namesize, "%s\\*", dirname); 39 dirp->d_handle = _findfirst(data.name, &data); 40 41 if( dirp->d_handle==BAD_INTPTR_T ){ 42 closedir(dirp); 43 return NULL; 44 } 45 46 /* TODO: Remove this block to allow hidden and system files. */ 47 if( data.attrib&_A_HIDDEN || data.attrib&_A_SYSTEM ){ 48 if( _findnext(dirp->d_handle, &data)==-1 ){ 49 closedir(dirp); 50 return NULL; 51 } 52 } 53 54 dirp->d_first.d_attributes = data.attrib; 55 strncpy(dirp->d_first.d_name, data.name, NAME_MAX); 56 dirp->d_first.d_name[NAME_MAX] = '\0'; 57 58 return dirp; 59 } 60 61 /* 62 ** Implementation of the POSIX readdir() function using the MSVCRT. 63 */ 64 LPDIRENT readdir( 65 LPDIR dirp 66 ){ 67 struct _finddata_t data; 68 69 if( dirp==NULL ) return NULL; 70 71 if( dirp->d_first.d_ino==0 ){ 72 dirp->d_first.d_ino++; 73 dirp->d_next.d_ino++; 74 75 return &dirp->d_first; 76 } 77 78 next: 79 80 if( _findnext(dirp->d_handle, &data)==-1 ) return NULL; 81 82 /* TODO: Remove this block to allow hidden and system files. */ 83 if( data.attrib&_A_HIDDEN ) goto next; 84 if( data.attrib&_A_SYSTEM ) goto next; 85 86 dirp->d_next.d_ino++; 87 dirp->d_next.d_attributes = data.attrib; 88 strncpy(dirp->d_next.d_name, data.name, NAME_MAX); 89 dirp->d_next.d_name[NAME_MAX] = '\0'; 90 91 return &dirp->d_next; 92 } 93 94 /* 95 ** Implementation of the POSIX readdir_r() function using the MSVCRT. 96 */ 97 INT readdir_r( 98 LPDIR dirp, 99 LPDIRENT entry, 100 LPDIRENT *result 101 ){ 102 struct _finddata_t data; 103 104 if( dirp==NULL ) return EBADF; 105 106 if( dirp->d_first.d_ino==0 ){ 107 dirp->d_first.d_ino++; 108 dirp->d_next.d_ino++; 109 110 entry->d_ino = dirp->d_first.d_ino; 111 entry->d_attributes = dirp->d_first.d_attributes; 112 strncpy(entry->d_name, dirp->d_first.d_name, NAME_MAX); 113 entry->d_name[NAME_MAX] = '\0'; 114 115 *result = entry; 116 return 0; 117 } 118 119 next: 120 121 if( _findnext(dirp->d_handle, &data)==-1 ){ 122 *result = NULL; 123 return ENOENT; 124 } 125 126 /* TODO: Remove this block to allow hidden and system files. */ 127 if( data.attrib&_A_HIDDEN ) goto next; 128 if( data.attrib&_A_SYSTEM ) goto next; 129 130 entry->d_ino = (ino_t)-1; /* not available */ 131 entry->d_attributes = data.attrib; 132 strncpy(entry->d_name, data.name, NAME_MAX); 133 entry->d_name[NAME_MAX] = '\0'; 134 135 *result = entry; 136 return 0; 137 } 138 139 /* 140 ** Implementation of the POSIX closedir() function using the MSVCRT. 141 */ 142 INT closedir( 143 LPDIR dirp 144 ){ 145 INT result = 0; 146 147 if( dirp==NULL ) return EINVAL; 148 149 if( dirp->d_handle!=NULL_INTPTR_T && dirp->d_handle!=BAD_INTPTR_T ){ 150 result = _findclose(dirp->d_handle); 151 } 152 153 sqlite3_free(dirp); 154 return result; 155 } 156 157 #endif /* defined(WIN32) && defined(_MSC_VER) */ 158