win_dirent.h
Go to the documentation of this file.
1 /*
2  * dirent.h - dirent API for Microsoft Visual Studio
3  *
4  * Copyright (C) 2006-2012 Toni Ronkko
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining
7  * a copy of this software and associated documentation files (the
8  * ``Software''), to deal in the Software without restriction, including
9  * without limitation the rights to use, copy, modify, merge, publish,
10  * distribute, sublicense, and/or sell copies of the Software, and to
11  * permit persons to whom the Software is furnished to do so, subject to
12  * the following conditions:
13  *
14  * The above copyright notice and this permission notice shall be included
15  * in all copies or substantial portions of the Software.
16  *
17  * THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
18  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20  * IN NO EVENT SHALL TONI RONKKO BE LIABLE FOR ANY CLAIM, DAMAGES OR
21  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
22  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23  * OTHER DEALINGS IN THE SOFTWARE.
24  *
25  */
26 #ifndef _GAZEBO_WIN_DIRENT_H_
27 #define _GAZEBO_WIN_DIRENT_H_
28 
29 // Define architecture flags so we don't need to include windows.h.
30 // Avoiding windows.h makes it simpler to use windows sockets in conjunction
31 // with dirent.h.
32 #if !defined(_68K_) && !defined(_MPPC_) && !defined(_X86_) && \
33  !defined(_IA64_) && !defined(_AMD64_) && defined(_M_IX86)
34 # define _X86_
35 #endif
36 #if !defined(_68K_) && !defined(_MPPC_) && !defined(_X86_) && \
37  !defined(_IA64_) && !defined(_AMD64_) && defined(_M_AMD64)
38 #define _AMD64_
39 #endif
40 
41 #include <cstdint>
42 #include <stdio.h>
43 #include <stdarg.h>
44 #include <windef.h>
45 #include <winbase.h>
46 #include <wchar.h>
47 #include <string.h>
48 #include <stdlib.h>
49 #include <malloc.h>
50 #include <sys/types.h>
51 #include <sys/stat.h>
52 #include <errno.h>
53 
54 // Indicates that d_type field is available in dirent structure
55 #define _DIRENT_HAVE_D_TYPE
56 
57 // Indicates that d_namlen field is available in dirent structure
58 #define _DIRENT_HAVE_D_NAMLEN
59 
60 // Entries missing from MSVC 6.0
61 #if !defined(FILE_ATTRIBUTE_DEVICE)
62 # define FILE_ATTRIBUTE_DEVICE 0x40
63 #endif
64 
65 // File type and permission flags for stat()
66 #if !defined(S_IFMT)
67  // File type mask
68 # define S_IFMT _S_IFMT
69 #endif
70 #if !defined(S_IFDIR)
71  // Directory
72 # define S_IFDIR _S_IFDIR
73 #endif
74 #if !defined(S_IFCHR)
75  // Character device
76 # define S_IFCHR _S_IFCHR
77 #endif
78 #if !defined(S_IFFIFO)
79  // Pipe
80 # define S_IFFIFO _S_IFFIFO
81 #endif
82 #if !defined(S_IFREG)
83  // Regular file
84 # define S_IFREG _S_IFREG
85 #endif
86 #if !defined(S_IREAD)
87  // Read permission
88 # define S_IREAD _S_IREAD
89 #endif
90 #if !defined(S_IWRITE)
91  // Write permission
92 # define S_IWRITE _S_IWRITE
93 #endif
94 #if !defined(S_IEXEC)
95  // Execute permission
96 # define S_IEXEC _S_IEXEC
97 #endif
98 #if !defined(S_IFIFO)
99  // Pipe
100 # define S_IFIFO _S_IFIFO
101 #endif
102 #if !defined(S_IFBLK)
103  // Block device
104 # define S_IFBLK 0
105 #endif
106 #if !defined(S_IFLNK)
107  // Link
108 # define S_IFLNK 0
109 #endif
110 #if !defined(S_IFSOCK)
111  // Socket
112 # define S_IFSOCK 0
113 #endif
114 
115 #if defined(_MSC_VER)
116  // Read user
117 # define S_IRUSR S_IREAD
118  // Write user
119 # define S_IWUSR S_IWRITE
120  // Execute user
121 # define S_IXUSR 0
122  // Read group
123 # define S_IRGRP 0
124  // Write group
125 # define S_IWGRP 0
126  // Execute group
127 # define S_IXGRP 0
128  // Read others
129 # define S_IROTH 0
130  // Write others
131 # define S_IWOTH 0
132  // Execute others
133 # define S_IXOTH 0
134 #endif
135 
136 // Maximum length of file name
137 #if !defined(PATH_MAX)
138 # define PATH_MAX MAX_PATH
139 #endif
140 #if !defined(FILENAME_MAX)
141 # define FILENAME_MAX MAX_PATH
142 #endif
143 #if !defined(NAME_MAX)
144 # define NAME_MAX FILENAME_MAX
145 #endif
146 
147 // File type flags for d_type
148 #define DT_UNKNOWN 0
149 #define DT_REG S_IFREG
150 #define DT_DIR S_IFDIR
151 #define DT_FIFO S_IFIFO
152 #define DT_SOCK S_IFSOCK
153 #define DT_CHR S_IFCHR
154 #define DT_BLK S_IFBLK
155 #define DT_LNK S_IFLNK
156 
157 // Macros for converting between st_mode and d_type
158 #define IFTODT(mode) ((mode) & S_IFMT)
159 #define DTTOIF(type) (type)
160 
161 // File type macros. Note that block devices, sockets and links cannot be
162 // distinguished on Windows and the macros S_ISBLK, S_ISSOCK and S_ISLNK are
163 // only defined for compatibility. These macros should always return false
164 // on Windows.
165 #define S_ISFIFO(mode) (((mode) & S_IFMT) == S_IFIFO)
166 #define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR)
167 #define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG)
168 #define S_ISLNK(mode) (((mode) & S_IFMT) == S_IFLNK)
169 #define S_ISSOCK(mode) (((mode) & S_IFMT) == S_IFSOCK)
170 #define S_ISCHR(mode) (((mode) & S_IFMT) == S_IFCHR)
171 #define S_ISBLK(mode) (((mode) & S_IFMT) == S_IFBLK)
172 
173 // Return the exact length of d_namlen without zero terminator
174 #define _D_EXACT_NAMLEN(p) ((p)->d_namlen)
175 
176 // Return number of bytes needed to store d_namlen
177 #define _D_ALLOC_NAMLEN(p) (PATH_MAX)
178 
179 #ifdef __cplusplus
180 extern "C"
181 {
182 #endif
183  // Wide-character version
184  struct _wdirent
185  {
186  // Always zero
187  int64_t d_ino;
188 
189  // Structure size
190  uint16_t d_reclen;
191 
192  // Length of name without \0
193  size_t d_namlen;
194 
195  // File type
196  int d_type;
197 
198  // File name
199  wchar_t d_name[PATH_MAX];
200  };
201  typedef struct _wdirent _wdirent;
202 
203  struct _WDIR
204  {
205  // Current directory entry
206  struct _wdirent ent;
207 
208  // Private file data
209  WIN32_FIND_DATAW data;
210 
211  // True if data is valid
212  int cached;
213 
214  // Win32 search handle
215  HANDLE handle;
216 
217  // Initial directory name
218  wchar_t *patt;
219  };
220  typedef struct _WDIR _WDIR;
221 
222  static _WDIR *_wopendir(const wchar_t *dirname);
223  static struct _wdirent *_wreaddir(_WDIR *dirp);
224  static int _wclosedir(_WDIR *dirp);
225  static void _wrewinddir(_WDIR* dirp);
226 
227  // For compatibility with Symbian
228 # define wdirent _wdirent
229 # define WDIR _WDIR
230 # define wopendir _wopendir
231 # define wreaddir _wreaddir
232 # define wclosedir _wclosedir
233 # define wrewinddir _wrewinddir
234 
235 
236  // Multi-byte character versions
237  struct dirent
238  {
239  // Always zero
240  int64_t d_ino;
241 
242  // Structure size
243  uint16_t d_reclen;
244 
245  // Length of name without \0
246  size_t d_namlen;
247 
248  // File type
249  int d_type;
250 
251  // File name
253  };
254  typedef struct dirent dirent;
255 
256  struct DIR
257  {
258  struct dirent ent;
259  struct _WDIR *wdirp;
260  };
261  typedef struct DIR DIR;
262 
263  static DIR *opendir(const char *dirname);
264  static int closedir(DIR *dirp);
265  static void rewinddir(DIR* dirp);
266 
267 
268  // Internal utility functions
269  static WIN32_FIND_DATAW *dirent_first(_WDIR *dirp);
270  static WIN32_FIND_DATAW *dirent_next(_WDIR *dirp);
271 
272  static int dirent_mbstowcs_s(
273  size_t *pReturnValue,
274  wchar_t *wcstr,
275  size_t sizeInWords,
276  const char *mbstr,
277  size_t count);
278 
279  static int dirent_wcstombs_s(
280  size_t *pReturnValue,
281  char *mbstr,
282  size_t sizeInBytes,
283  const wchar_t *wcstr,
284  size_t count);
285 
286  static void dirent_set_errno(int error);
287 
288  // Open directory stream DIRNAME for read and return a pointer to the
289  // internal working area that is used to retrieve individual directory
290  // entries.
291  static _WDIR* _wopendir(const wchar_t *dirname)
292  {
293  _WDIR *dirp = NULL;
294  int error;
295 
296  // Must have directory name
297  if (dirname == NULL || dirname[0] == '\0')
298  {
299  dirent_set_errno(ENOENT);
300  return NULL;
301  }
302 
303  // Allocate new _WDIR structure
304  dirp = static_cast<_WDIR*>(malloc(sizeof(struct _WDIR)));
305  if (dirp != NULL)
306  {
307  DWORD n;
308 
309  // Reset _WDIR structure
310  dirp->handle = INVALID_HANDLE_VALUE;
311  dirp->patt = NULL;
312  dirp->cached = 0;
313 
314  // Compute the length of full path plus zero terminator
315  n = GetFullPathNameW(dirname, 0, NULL, NULL);
316 
317  // Allocate room for absolute directory name and search pattern
318  dirp->patt = static_cast<wchar_t*>(malloc(sizeof(wchar_t) * n + 16));
319  if (dirp->patt)
320  {
321  // Convert relative directory name to an absolute one. This
322  // allows rewinddir() to function correctly even when current
323  // working directory is changed between opendir() and rewinddir().
324  n = GetFullPathNameW(dirname, n, dirp->patt, NULL);
325 
326  if (n > 0)
327  {
328  wchar_t *p;
329 
330  // Append search pattern \* to the directory name
331  p = dirp->patt + n;
332  if (dirp->patt < p)
333  {
334  switch (p[-1])
335  {
336  case '\\':
337  case '/':
338  case ':':
339  // Directory ends in path separator, e.g. c:\temp\
340  // NOP
341  break;
342 
343  default:
344  // Directory name doesn't end in path separator
345  *p++ = '\\';
346  }
347  }
348 
349  *p++ = '*';
350  *p = '\0';
351 
352  // Open directory stream and retrieve the first entry
353  if (dirent_first(dirp))
354  {
355  // Directory stream opened successfully
356  error = 0;
357  }
358  else
359  {
360  // Cannot retrieve first entry
361  error = 1;
362  dirent_set_errno(ENOENT);
363  }
364  }
365  else
366  {
367  // Cannot retrieve full path name
368  dirent_set_errno(ENOENT);
369  error = 1;
370  }
371  }
372  else
373  {
374  // Cannot allocate memory for search pattern
375  error = 1;
376  }
377  }
378  else
379  {
380  // Cannot allocate _WDIR structure
381  error = 1;
382  }
383 
384  // Clean up in case of error
385  if (error && dirp)
386  {
387  _wclosedir(dirp);
388  dirp = NULL;
389  }
390 
391  return dirp;
392  }
393 
394  // Read next directory entry. The directory entry is returned in dirent
395  // structure in the d_name field. Individual directory entries returned by
396  // this function include regular files, sub-directories, pseudo-directories
397  // "." and ".." as well as volume labels, hidden files and system files.
398  static struct _wdirent* _wreaddir(_WDIR *dirp)
399  {
400  WIN32_FIND_DATAW *datap;
401  struct _wdirent *entp;
402 
403  // Read next directory entry
404  datap = dirent_next(dirp);
405  if (datap)
406  {
407  size_t n;
408  DWORD attr;
409 
410  // Pointer to directory entry to return
411  entp = &dirp->ent;
412 
413  // Copy file name as wide-character string. If the file name is too
414  // long to fit in to the destination buffer, then truncate file name
415  // to PATH_MAX characters and zero-terminate the buffer.
416  n = 0;
417  while (n + 1 < PATH_MAX && datap->cFileName[n] != 0)
418  {
419  entp->d_name[n] = datap->cFileName[n];
420  n++;
421  }
422  dirp->ent.d_name[n] = 0;
423 
424  // Length of file name excluding zero terminator
425  entp->d_namlen = n;
426 
427  // File type
428  attr = datap->dwFileAttributes;
429  if ((attr & FILE_ATTRIBUTE_DEVICE) != 0)
430  {
431  entp->d_type = DT_CHR;
432  }
433  else if ((attr & FILE_ATTRIBUTE_DIRECTORY) != 0)
434  {
435  entp->d_type = DT_DIR;
436  }
437  else
438  {
439  entp->d_type = DT_REG;
440  }
441 
442  // Reset dummy fields
443  entp->d_ino = 0;
444  entp->d_reclen = sizeof(struct _wdirent);
445  }
446  else
447  {
448  // Last directory entry read
449  entp = NULL;
450  }
451 
452  return entp;
453  }
454 
455  // Close directory stream opened by opendir() function. This invalidates the
456  // DIR structure as well as any directory entry read previously by
457  // _wreaddir().
458  static int _wclosedir(_WDIR *dirp)
459  {
460  int ok;
461  if (dirp)
462  {
463  // Release search handle
464  if (dirp->handle != INVALID_HANDLE_VALUE)
465  {
466  FindClose(dirp->handle);
467  dirp->handle = INVALID_HANDLE_VALUE;
468  }
469 
470  // Release search pattern
471  if (dirp->patt)
472  {
473  free(dirp->patt);
474  dirp->patt = NULL;
475  }
476 
477  // Release directory structure
478  free(dirp);
479 
480  // success
481  ok = 0;
482  }
483  else
484  {
485  // Invalid directory stream
486  dirent_set_errno(EBADF);
487 
488  // failure
489  ok = -1;
490  }
491  return ok;
492  }
493 
494  // Rewind directory stream such that _wreaddir() returns the very first
495  // file name again.
496  static void _wrewinddir(_WDIR* dirp)
497  {
498  if (dirp)
499  {
500  // Release existing search handle
501  if (dirp->handle != INVALID_HANDLE_VALUE)
502  {
503  FindClose(dirp->handle);
504  }
505 
506  // Open new search handle
507  dirent_first(dirp);
508  }
509  }
510 
511  // Get first directory entry (internal)
512  static WIN32_FIND_DATAW* dirent_first(_WDIR *dirp)
513  {
514  WIN32_FIND_DATAW *datap;
515 
516  // Open directory and retrieve the first entry
517  dirp->handle = FindFirstFileW(dirp->patt, &dirp->data);
518  if (dirp->handle != INVALID_HANDLE_VALUE)
519  {
520  // a directory entry is now waiting in memory
521  datap = &dirp->data;
522  dirp->cached = 1;
523  }
524  else
525  {
526  // Failed to re-open directory: no directory entry in memory
527  dirp->cached = 0;
528  datap = NULL;
529  }
530  return datap;
531  }
532 
533  // Get next directory entry (internal)
534  static WIN32_FIND_DATAW* dirent_next(_WDIR *dirp)
535  {
536  WIN32_FIND_DATAW *p;
537 
538  // Get next directory entry
539  if (dirp->cached != 0)
540  {
541  // A valid directory entry already in memory
542  p = &dirp->data;
543  dirp->cached = 0;
544  }
545  else if (dirp->handle != INVALID_HANDLE_VALUE)
546  {
547  // Get the next directory entry from stream
548  if (FindNextFileW (dirp->handle, &dirp->data) != FALSE)
549  {
550  // Got a file
551  p = &dirp->data;
552  }
553  else
554  {
555  // The very last entry has been processed or an error occured
556  FindClose(dirp->handle);
557  dirp->handle = INVALID_HANDLE_VALUE;
558  p = NULL;
559  }
560  }
561  else
562  {
563  // End of directory stream reached
564  p = NULL;
565  }
566  return p;
567  }
568 
569  // Open directory stream using plain old C-string.
570  static DIR* opendir(const char *dirname)
571  {
572  struct DIR *dirp;
573  int error;
574 
575  // Must have directory name
576  if (dirname == NULL || dirname[0] == '\0')
577  {
578  dirent_set_errno(ENOENT);
579  return NULL;
580  }
581 
582  // Allocate memory for DIR structure
583  dirp = static_cast<DIR*>(malloc(sizeof(struct DIR)));
584  if (dirp)
585  {
586  wchar_t wname[PATH_MAX];
587  size_t n;
588 
589  // Convert directory name to wide-character string
590  error = dirent_mbstowcs_s(&n, wname, PATH_MAX, dirname, PATH_MAX);
591  if (!error)
592  {
593  // Open directory stream using wide-character name
594  dirp->wdirp = _wopendir(wname);
595  if (dirp->wdirp)
596  {
597  // Directory stream opened
598  error = 0;
599  }
600  else
601  {
602  // Failed to open directory stream
603  error = 1;
604  }
605  }
606  else
607  {
608  // Cannot convert file name to wide-character string. This
609  // occurs if the string contains invalid multi-byte sequences or
610  // the output buffer is too small to contain the resulting
611  // string.
612  error = 1;
613  }
614  }
615  else
616  {
617  // Cannot allocate DIR structure
618  error = 1;
619  }
620 
621  // Clean up in case of error
622  if (error && dirp)
623  {
624  free(dirp);
625  dirp = NULL;
626  }
627  return dirp;
628  }
629 
630  // Close directory stream.
631  static int closedir(DIR *dirp)
632  {
633  int ok;
634  if (dirp)
635  {
636  // Close wide-character directory stream
637  ok = _wclosedir(dirp->wdirp);
638  dirp->wdirp = NULL;
639 
640  // Release multi-byte character version
641  free(dirp);
642  }
643  else
644  {
645  // Invalid directory stream
646  dirent_set_errno(EBADF);
647 
648  // failure
649  ok = -1;
650  }
651  return ok;
652  }
653 
654  // Rewind directory stream to beginning.
655  static void rewinddir(DIR* dirp)
656  {
657  // Rewind wide-character string directory stream
658  _wrewinddir(dirp->wdirp);
659  }
660 
661  // Convert multi-byte string to wide character string
662  static int dirent_mbstowcs_s(
663  size_t *pReturnValue,
664  wchar_t *wcstr,
665  size_t sizeInWords,
666  const char *mbstr,
667  size_t count)
668  {
669  int error;
670 
671 # if defined(_MSC_VER) && _MSC_VER >= 1400
672  // Microsoft Visual Studio 2005 or later
673  error = mbstowcs_s(pReturnValue, wcstr, sizeInWords, mbstr, count);
674 
675 # else
676 
677  // Older Visual Studio or non-Microsoft compiler
678  size_t n;
679 
680  // Convert to wide-character string (or count characters)
681  n = mbstowcs(wcstr, mbstr, sizeInWords);
682  if (!wcstr || n < count)
683  {
684  // Zero-terminate output buffer
685  if (wcstr && sizeInWords)
686  {
687  if (n >= sizeInWords)
688  {
689  n = sizeInWords - 1;
690  }
691  wcstr[n] = 0;
692  }
693 
694  // Length of resuting multi-byte string WITH zero terminator
695  if (pReturnValue)
696  {
697  *pReturnValue = n + 1;
698  }
699 
700  // Success
701  error = 0;
702  }
703  else
704  {
705  // Could not convert string
706  error = 1;
707  }
708 #endif
709  return error;
710  }
711 
712  // Convert wide-character string to multi-byte string
713  static int dirent_wcstombs_s(
714  size_t *pReturnValue,
715  char *mbstr,
716  // max size of mbstr
717  size_t sizeInBytes,
718  const wchar_t *wcstr,
719  size_t count)
720  {
721  int error;
722 
723 # if defined(_MSC_VER) && _MSC_VER >= 1400
724 
725  // Microsoft Visual Studio 2005 or later
726  error = wcstombs_s(pReturnValue, mbstr, sizeInBytes, wcstr, count);
727 
728 #else
729 
730  // Older Visual Studio or non-Microsoft compiler
731  size_t n;
732 
733  // Convert to multi-byte string (or count the number of bytes needed)
734  n = wcstombs(mbstr, wcstr, sizeInBytes);
735  if (!mbstr || n < count)
736  {
737  // Zero-terminate output buffer
738  if (mbstr && sizeInBytes)
739  {
740  if (n >= sizeInBytes)
741  {
742  n = sizeInBytes - 1;
743  }
744  mbstr[n] = '\0';
745  }
746 
747  // Lenght of resulting multi-bytes string WITH zero-terminator
748  if (pReturnValue)
749  {
750  *pReturnValue = n + 1;
751  }
752 
753  // Success
754  error = 0;
755  }
756  else
757  {
758  // Cannot convert string
759  error = 1;
760  }
761 #endif
762 
763  return error;
764  }
765 
766  // Set errno variable
767  static void dirent_set_errno(int error)
768  {
769 # if defined(_MSC_VER) && _MSC_VER >= 1400
770  // Microsoft Visual Studio 2005 and later
771  _set_errno(error);
772 #else
773  // Non-Microsoft compiler or older Microsoft compiler
774  errno = error;
775 #endif
776  }
777 
778 #ifdef __cplusplus
779 }
780 #endif
781 
782 // _GAZEBO_WIN_DIRENT_H_
783 #endif
static struct _wdirent * _wreaddir(_WDIR *dirp)
Definition: win_dirent.h:398
static int dirent_wcstombs_s(size_t *pReturnValue, char *mbstr, size_t sizeInBytes, const wchar_t *wcstr, size_t count)
Definition: win_dirent.h:713
static void rewinddir(DIR *dirp)
Definition: win_dirent.h:655
uint16_t d_reclen
Definition: win_dirent.h:243
int cached
Definition: win_dirent.h:212
int64_t d_ino
Definition: win_dirent.h:240
int d_type
Definition: win_dirent.h:249
#define DT_CHR
Definition: win_dirent.h:153
Definition: win_dirent.h:237
size_t d_namlen
Definition: win_dirent.h:246
static DIR * opendir(const char *dirname)
Definition: win_dirent.h:570
Definition: win_dirent.h:256
struct dirent ent
Definition: win_dirent.h:258
static int closedir(DIR *dirp)
Definition: win_dirent.h:631
wchar_t * patt
Definition: win_dirent.h:218
static WIN32_FIND_DATAW * dirent_first(_WDIR *dirp)
Definition: win_dirent.h:512
int64_t d_ino
Definition: win_dirent.h:187
#define FILE_ATTRIBUTE_DEVICE
Definition: win_dirent.h:62
static void dirent_set_errno(int error)
Definition: win_dirent.h:767
static WIN32_FIND_DATAW * dirent_next(_WDIR *dirp)
Definition: win_dirent.h:534
Definition: win_dirent.h:184
static int _wclosedir(_WDIR *dirp)
Definition: win_dirent.h:458
int d_type
Definition: win_dirent.h:196
#define NULL
Definition: CommonTypes.hh:30
HANDLE handle
Definition: win_dirent.h:215
static void _wrewinddir(_WDIR *dirp)
Definition: win_dirent.h:496
static int dirent_mbstowcs_s(size_t *pReturnValue, wchar_t *wcstr, size_t sizeInWords, const char *mbstr, size_t count)
Definition: win_dirent.h:662
uint16_t d_reclen
Definition: win_dirent.h:190
#define PATH_MAX
Definition: win_dirent.h:138
static _WDIR * _wopendir(const wchar_t *dirname)
Definition: win_dirent.h:291
#define DT_DIR
Definition: win_dirent.h:150
#define DT_REG
Definition: win_dirent.h:149
struct _WDIR * wdirp
Definition: win_dirent.h:259
size_t d_namlen
Definition: win_dirent.h:193
char d_name[MAX_PATH]
Definition: win_dirent.h:252
struct _wdirent ent
Definition: win_dirent.h:206
WIN32_FIND_DATAW data
Definition: win_dirent.h:209
Definition: win_dirent.h:203
wchar_t d_name[MAX_PATH]
Definition: win_dirent.h:199