CASToR  1.1
Tomographic Reconstruction (PET/SPECT)
 All Classes Files Functions Variables Typedefs Macros Groups Pages
oDirentWin32.hh
Go to the documentation of this file.
1 
2 /*
3  * Dirent interface for Microsoft Visual Studio
4  * Version 1.21
5  *
6  * Copyright (C) 2006-2012 Toni Ronkko
7  * This file is part of dirent. Dirent may be freely distributed
8  * under the MIT license. For all details and documentation, see
9  * https://github.com/tronkko/dirent
10  */
11 
12 #ifndef DIRENT_H
13 #define DIRENT_H
14 
15 /*
16  * Define architecture flags so we don't need to include windows.h.
17  * Avoiding windows.h makes it simpler to use windows sockets in conjunction
18  * with dirent.h.
19  */
20 #if !defined(_68K_) && !defined(_MPPC_) && !defined(_X86_) && !defined(_IA64_) && !defined(_AMD64_) && defined(_M_IX86)
21 # define _X86_
22 #endif
23 #if !defined(_68K_) && !defined(_MPPC_) && !defined(_X86_) && !defined(_IA64_) && !defined(_AMD64_) && defined(_M_AMD64)
24 #define _AMD64_
25 #endif
26 
27 #include <stdio.h>
28 #include <stdarg.h>
29 #include <windef.h>
30 #include <winbase.h>
31 #include <wchar.h>
32 #include <string.h>
33 #include <stdlib.h>
34 #include <malloc.h>
35 #include <sys/types.h>
36 #include <sys/stat.h>
37 #include <errno.h>
38 
39 /* Indicates that d_type field is available in dirent structure */
40 #define _DIRENT_HAVE_D_TYPE
41 
42 /* Indicates that d_namlen field is available in dirent structure */
43 #define _DIRENT_HAVE_D_NAMLEN
44 
45 /* Entries missing from MSVC 6.0 */
46 #if !defined(FILE_ATTRIBUTE_DEVICE)
47 # define FILE_ATTRIBUTE_DEVICE 0x40
48 #endif
49 
50 /* File type and permission flags for stat(), general mask */
51 #if !defined(S_IFMT)
52 # define S_IFMT _S_IFMT
53 #endif
54 
55 /* Directory bit */
56 #if !defined(S_IFDIR)
57 # define S_IFDIR _S_IFDIR
58 #endif
59 
60 /* Character device bit */
61 #if !defined(S_IFCHR)
62 # define S_IFCHR _S_IFCHR
63 #endif
64 
65 /* Pipe bit */
66 #if !defined(S_IFFIFO)
67 # define S_IFFIFO _S_IFFIFO
68 #endif
69 
70 /* Regular file bit */
71 #if !defined(S_IFREG)
72 # define S_IFREG _S_IFREG
73 #endif
74 
75 /* Read permission */
76 #if !defined(S_IREAD)
77 # define S_IREAD _S_IREAD
78 #endif
79 
80 /* Write permission */
81 #if !defined(S_IWRITE)
82 # define S_IWRITE _S_IWRITE
83 #endif
84 
85 /* Execute permission */
86 #if !defined(S_IEXEC)
87 # define S_IEXEC _S_IEXEC
88 #endif
89 
90 /* Pipe */
91 #if !defined(S_IFIFO)
92 # define S_IFIFO _S_IFIFO
93 #endif
94 
95 /* Block device */
96 #if !defined(S_IFBLK)
97 # define S_IFBLK 0
98 #endif
99 
100 /* Link */
101 #if !defined(S_IFLNK)
102 # define S_IFLNK 0
103 #endif
104 
105 /* Socket */
106 #if !defined(S_IFSOCK)
107 # define S_IFSOCK 0
108 #endif
109 
110 /* Read user permission */
111 #if !defined(S_IRUSR)
112 # define S_IRUSR S_IREAD
113 #endif
114 
115 /* Write user permission */
116 #if !defined(S_IWUSR)
117 # define S_IWUSR S_IWRITE
118 #endif
119 
120 /* Execute user permission */
121 #if !defined(S_IXUSR)
122 # define S_IXUSR 0
123 #endif
124 
125 /* Read group permission */
126 #if !defined(S_IRGRP)
127 # define S_IRGRP 0
128 #endif
129 
130 /* Write group permission */
131 #if !defined(S_IWGRP)
132 # define S_IWGRP 0
133 #endif
134 
135 /* Execute group permission */
136 #if !defined(S_IXGRP)
137 # define S_IXGRP 0
138 #endif
139 
140 /* Read others permission */
141 #if !defined(S_IROTH)
142 # define S_IROTH 0
143 #endif
144 
145 /* Write others permission */
146 #if !defined(S_IWOTH)
147 # define S_IWOTH 0
148 #endif
149 
150 /* Execute others permission */
151 #if !defined(S_IXOTH)
152 # define S_IXOTH 0
153 #endif
154 
155 /* Maximum length of file name */
156 #if !defined(PATH_MAX)
157 # define PATH_MAX MAX_PATH
158 #endif
159 #if !defined(FILENAME_MAX)
160 # define FILENAME_MAX MAX_PATH
161 #endif
162 #if !defined(NAME_MAX)
163 # define NAME_MAX FILENAME_MAX
164 #endif
165 
166 /* File type flags for d_type */
167 #define DT_UNKNOWN 0
168 #define DT_REG S_IFREG
169 #define DT_DIR S_IFDIR
170 #define DT_FIFO S_IFIFO
171 #define DT_SOCK S_IFSOCK
172 #define DT_CHR S_IFCHR
173 #define DT_BLK S_IFBLK
174 #define DT_LNK S_IFLNK
175 
176 /* Macros for converting between st_mode and d_type */
177 #define IFTODT(mode) ((mode) & S_IFMT)
178 #define DTTOIF(type) (type)
179 
180 /*
181  * File type macros. Note that block devices, sockets and links cannot be
182  * distinguished on Windows and the macros S_ISBLK, S_ISSOCK and S_ISLNK are
183  * only defined for compatibility. These macros should always return false
184  * on Windows.
185  */
186 #if !defined(S_ISFIFO)
187 # define S_ISFIFO(mode) (((mode) & S_IFMT) == S_IFIFO)
188 #endif
189 #if !defined(S_ISDIR)
190 # define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR)
191 #endif
192 #if !defined(S_ISREG)
193 # define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG)
194 #endif
195 #if !defined(S_ISLNK)
196 # define S_ISLNK(mode) (((mode) & S_IFMT) == S_IFLNK)
197 #endif
198 #if !defined(S_ISSOCK)
199 # define S_ISSOCK(mode) (((mode) & S_IFMT) == S_IFSOCK)
200 #endif
201 #if !defined(S_ISCHR)
202 # define S_ISCHR(mode) (((mode) & S_IFMT) == S_IFCHR)
203 #endif
204 #if !defined(S_ISBLK)
205 # define S_ISBLK(mode) (((mode) & S_IFMT) == S_IFBLK)
206 #endif
207 
208 /* Return the exact length of d_namlen without zero terminator */
209 #define _D_EXACT_NAMLEN(p) ((p)->d_namlen)
210 
211 /* Return number of bytes needed to store d_namlen */
212 #define _D_ALLOC_NAMLEN(p) (PATH_MAX)
213 
214 
215 #ifdef __cplusplus
216 extern "C" {
217 #endif
218 
219 
220 /* Wide-character version */
221 struct _wdirent {
222  /* Always zero */
223  long d_ino;
224 
225  /* Structure size */
226  unsigned short d_reclen;
227 
228  /* Length of name without \0 */
229  size_t d_namlen;
230 
231  /* File type */
232  int d_type;
233 
234  /* File name */
235  wchar_t d_name[PATH_MAX];
236 };
237 typedef struct _wdirent _wdirent;
238 
239 struct _WDIR {
240  /* Current directory entry */
241  struct _wdirent ent;
242 
243  /* Private file data */
244  WIN32_FIND_DATAW data;
245 
246  /* True if data is valid */
247  int cached;
248 
249  /* Win32 search handle */
250  HANDLE handle;
251 
252  /* Initial directory name */
253  wchar_t *patt;
254 };
255 typedef struct _WDIR _WDIR;
256 
257 static _WDIR *_wopendir (const wchar_t *dirname);
258 static struct _wdirent *_wreaddir (_WDIR *dirp);
259 static int _wclosedir (_WDIR *dirp);
260 static void _wrewinddir (_WDIR* dirp);
261 
262 
263 /* For compatibility with Symbian */
264 #define wdirent _wdirent
265 #define WDIR _WDIR
266 #define wopendir _wopendir
267 #define wreaddir _wreaddir
268 #define wclosedir _wclosedir
269 #define wrewinddir _wrewinddir
270 
271 
272 /* Multi-byte character versions */
273 struct dirent {
274  /* Always zero */
275  long d_ino;
276 
277  /* Structure size */
278  unsigned short d_reclen;
279 
280  /* Length of name without \0 */
281  size_t d_namlen;
282 
283  /* File type */
284  int d_type;
285 
286  /* File name */
288 };
289 typedef struct dirent dirent;
290 
291 struct DIR {
292  struct dirent ent;
293  struct _WDIR *wdirp;
294 };
295 typedef struct DIR DIR;
296 
297 static DIR *opendir (const char *dirname);
298 static struct dirent *readdir (DIR *dirp);
299 static int closedir (DIR *dirp);
300 static void rewinddir (DIR* dirp);
301 
302 
303 /* Internal utility functions */
304 static WIN32_FIND_DATAW *dirent_first (_WDIR *dirp);
305 static WIN32_FIND_DATAW *dirent_next (_WDIR *dirp);
306 
307 static int dirent_mbstowcs_s(
308  size_t *pReturnValue,
309  wchar_t *wcstr,
310  size_t sizeInWords,
311  const char *mbstr,
312  size_t count);
313 
314 static int dirent_wcstombs_s(
315  size_t *pReturnValue,
316  char *mbstr,
317  size_t sizeInBytes,
318  const wchar_t *wcstr,
319  size_t count);
320 
321 static void dirent_set_errno (int error);
322 
323 /*
324  * Open directory stream DIRNAME for read and return a pointer to the
325  * internal working area that is used to retrieve individual directory
326  * entries.
327  */
328 static _WDIR*
330  const wchar_t *dirname)
331 {
332  _WDIR *dirp = NULL;
333  int error;
334 
335  /* Must have directory name */
336  if (dirname == NULL || dirname[0] == '\0') {
337  dirent_set_errno (ENOENT);
338  return NULL;
339  }
340 
341  /* Allocate new _WDIR structure */
342  dirp = (_WDIR*) malloc (sizeof (struct _WDIR));
343  if (dirp != NULL) {
344  DWORD n;
345 
346  /* Reset _WDIR structure */
347  dirp->handle = INVALID_HANDLE_VALUE;
348  dirp->patt = NULL;
349  dirp->cached = 0;
350 
351  /* Compute the length of full path plus zero terminator */
352  n = GetFullPathNameW (dirname, 0, NULL, NULL);
353 
354  /* Allocate room for absolute directory name and search pattern */
355  dirp->patt = (wchar_t*) malloc (sizeof (wchar_t) * n + 16);
356  if (dirp->patt) {
357 
358  /*
359  * Convert relative directory name to an absolute one. This
360  * allows rewinddir() to function correctly even when current
361  * working directory is changed between opendir() and rewinddir().
362  */
363  n = GetFullPathNameW (dirname, n, dirp->patt, NULL);
364  if (n > 0) {
365  wchar_t *p;
366 
367  /* Append search pattern \* to the directory name */
368  p = dirp->patt + n;
369  if (dirp->patt < p) {
370  switch (p[-1]) {
371  case '\\':
372  case '/':
373  case ':':
374  /* Directory ends in path separator, e.g. c:\temp\ */
375  /*NOP*/;
376  break;
377 
378  default:
379  /* Directory name doesn't end in path separator */
380  *p++ = '\\';
381  }
382  }
383  *p++ = '*';
384  *p = '\0';
385 
386  /* Open directory stream and retrieve the first entry */
387  if (dirent_first (dirp)) {
388  /* Directory stream opened successfully */
389  error = 0;
390  } else {
391  /* Cannot retrieve first entry */
392  error = 1;
393  dirent_set_errno (ENOENT);
394  }
395 
396  } else {
397  /* Cannot retrieve full path name */
398  dirent_set_errno (ENOENT);
399  error = 1;
400  }
401 
402  } else {
403  /* Cannot allocate memory for search pattern */
404  error = 1;
405  }
406 
407  } else {
408  /* Cannot allocate _WDIR structure */
409  error = 1;
410  }
411 
412  /* Clean up in case of error */
413  if (error && dirp) {
414  _wclosedir (dirp);
415  dirp = NULL;
416  }
417 
418  return dirp;
419 }
420 
421 /*
422  * Read next directory entry. The directory entry is returned in dirent
423  * structure in the d_name field. Individual directory entries returned by
424  * this function include regular files, sub-directories, pseudo-directories
425  * "." and ".." as well as volume labels, hidden files and system files.
426  */
427 static struct _wdirent*
429  _WDIR *dirp)
430 {
431  WIN32_FIND_DATAW *datap;
432  struct _wdirent *entp;
433 
434  /* Read next directory entry */
435  datap = dirent_next (dirp);
436  if (datap) {
437  size_t n;
438  DWORD attr;
439 
440  /* Pointer to directory entry to return */
441  entp = &dirp->ent;
442 
443  /*
444  * Copy file name as wide-character string. If the file name is too
445  * long to fit in to the destination buffer, then truncate file name
446  * to PATH_MAX characters and zero-terminate the buffer.
447  */
448  n = 0;
449  while (n + 1 < PATH_MAX && datap->cFileName[n] != 0) {
450  entp->d_name[n] = datap->cFileName[n];
451  n++;
452  }
453  dirp->ent.d_name[n] = 0;
454 
455  /* Length of file name excluding zero terminator */
456  entp->d_namlen = n;
457 
458  /* File type */
459  attr = datap->dwFileAttributes;
460  if ((attr & FILE_ATTRIBUTE_DEVICE) != 0) {
461  entp->d_type = DT_CHR;
462  } else if ((attr & FILE_ATTRIBUTE_DIRECTORY) != 0) {
463  entp->d_type = DT_DIR;
464  } else {
465  entp->d_type = DT_REG;
466  }
467 
468  /* Reset dummy fields */
469  entp->d_ino = 0;
470  entp->d_reclen = sizeof (struct _wdirent);
471 
472  } else {
473 
474  /* Last directory entry read */
475  entp = NULL;
476 
477  }
478 
479  return entp;
480 }
481 
482 /*
483  * Close directory stream opened by opendir() function. This invalidates the
484  * DIR structure as well as any directory entry read previously by
485  * _wreaddir().
486  */
487 static int
489  _WDIR *dirp)
490 {
491  int ok;
492  if (dirp) {
493 
494  /* Release search handle */
495  if (dirp->handle != INVALID_HANDLE_VALUE) {
496  FindClose (dirp->handle);
497  dirp->handle = INVALID_HANDLE_VALUE;
498  }
499 
500  /* Release search pattern */
501  if (dirp->patt) {
502  free (dirp->patt);
503  dirp->patt = NULL;
504  }
505 
506  /* Release directory structure */
507  free (dirp);
508  ok = /*success*/0;
509 
510  } else {
511  /* Invalid directory stream */
512  dirent_set_errno (EBADF);
513  ok = /*failure*/-1;
514  }
515  return ok;
516 }
517 
518 /*
519  * Rewind directory stream such that _wreaddir() returns the very first
520  * file name again.
521  */
522 static void
524  _WDIR* dirp)
525 {
526  if (dirp) {
527  /* Release existing search handle */
528  if (dirp->handle != INVALID_HANDLE_VALUE) {
529  FindClose (dirp->handle);
530  }
531 
532  /* Open new search handle */
533  dirent_first (dirp);
534  }
535 }
536 
537 /* Get first directory entry (internal) */
538 static WIN32_FIND_DATAW*
540  _WDIR *dirp)
541 {
542  WIN32_FIND_DATAW *datap;
543 
544  /* Open directory and retrieve the first entry */
545  dirp->handle = FindFirstFileW (dirp->patt, &dirp->data);
546  if (dirp->handle != INVALID_HANDLE_VALUE) {
547 
548  /* a directory entry is now waiting in memory */
549  datap = &dirp->data;
550  dirp->cached = 1;
551 
552  } else {
553 
554  /* Failed to re-open directory: no directory entry in memory */
555  dirp->cached = 0;
556  datap = NULL;
557 
558  }
559  return datap;
560 }
561 
562 /* Get next directory entry (internal) */
563 static WIN32_FIND_DATAW*
565  _WDIR *dirp)
566 {
567  WIN32_FIND_DATAW *p;
568 
569  /* Get next directory entry */
570  if (dirp->cached != 0) {
571 
572  /* A valid directory entry already in memory */
573  p = &dirp->data;
574  dirp->cached = 0;
575 
576  } else if (dirp->handle != INVALID_HANDLE_VALUE) {
577 
578  /* Get the next directory entry from stream */
579  if (FindNextFileW (dirp->handle, &dirp->data) != FALSE) {
580  /* Got a file */
581  p = &dirp->data;
582  } else {
583  /* The very last entry has been processed or an error occured */
584  FindClose (dirp->handle);
585  dirp->handle = INVALID_HANDLE_VALUE;
586  p = NULL;
587  }
588 
589  } else {
590 
591  /* End of directory stream reached */
592  p = NULL;
593 
594  }
595 
596  return p;
597 }
598 
599 /*
600  * Open directory stream using plain old C-string.
601  */
602 static DIR*
604  const char *dirname)
605 {
606  struct DIR *dirp;
607  int error;
608 
609  /* Must have directory name */
610  if (dirname == NULL || dirname[0] == '\0') {
611  dirent_set_errno (ENOENT);
612  return NULL;
613  }
614 
615  /* Allocate memory for DIR structure */
616  dirp = (DIR*) malloc (sizeof (struct DIR));
617  if (dirp) {
618  wchar_t wname[PATH_MAX];
619  size_t n;
620 
621  /* Convert directory name to wide-character string */
622  error = dirent_mbstowcs_s (&n, wname, PATH_MAX, dirname, PATH_MAX);
623  if (!error) {
624 
625  /* Open directory stream using wide-character name */
626  dirp->wdirp = _wopendir (wname);
627  if (dirp->wdirp) {
628  /* Directory stream opened */
629  error = 0;
630  } else {
631  /* Failed to open directory stream */
632  error = 1;
633  }
634 
635  } else {
636  /*
637  * Cannot convert file name to wide-character string. This
638  * occurs if the string contains invalid multi-byte sequences or
639  * the output buffer is too small to contain the resulting
640  * string.
641  */
642  error = 1;
643  }
644 
645  } else {
646  /* Cannot allocate DIR structure */
647  error = 1;
648  }
649 
650  /* Clean up in case of error */
651  if (error && dirp) {
652  free (dirp);
653  dirp = NULL;
654  }
655 
656  return dirp;
657 }
658 
659 /*
660  * Read next directory entry.
661  *
662  * When working with text consoles, please note that file names returned by
663  * readdir() are represented in the default ANSI code page while any output to
664  * console is typically formatted on another code page. Thus, non-ASCII
665  * characters in file names will not usually display correctly on console. The
666  * problem can be fixed in two ways: (1) change the character set of console
667  * to 1252 using chcp utility and use Lucida Console font, or (2) use
668  * _cprintf function when writing to console. The _cprinf() will re-encode
669  * ANSI strings to the console code page so many non-ASCII characters will
670  * display correcly.
671  */
672 static struct dirent*
674  DIR *dirp)
675 {
676  WIN32_FIND_DATAW *datap;
677  struct dirent *entp;
678 
679  /* Read next directory entry */
680  datap = dirent_next (dirp->wdirp);
681  if (datap) {
682  size_t n;
683  int error;
684 
685  /* Attempt to convert file name to multi-byte string */
686  error = dirent_wcstombs_s(
687  &n, dirp->ent.d_name, PATH_MAX, datap->cFileName, PATH_MAX);
688 
689  /*
690  * If the file name cannot be represented by a multi-byte string,
691  * then attempt to use old 8+3 file name. This allows traditional
692  * Unix-code to access some file names despite of unicode
693  * characters, although file names may seem unfamiliar to the user.
694  *
695  * Be ware that the code below cannot come up with a short file
696  * name unless the file system provides one. At least
697  * VirtualBox shared folders fail to do this.
698  */
699  if (error && datap->cAlternateFileName[0] != '\0') {
700  error = dirent_wcstombs_s(
701  &n, dirp->ent.d_name, PATH_MAX,
702  datap->cAlternateFileName, PATH_MAX);
703  }
704 
705  if (!error) {
706  DWORD attr;
707 
708  /* Initialize directory entry for return */
709  entp = &dirp->ent;
710 
711  /* Length of file name excluding zero terminator */
712  entp->d_namlen = n - 1;
713 
714  /* File attributes */
715  attr = datap->dwFileAttributes;
716  if ((attr & FILE_ATTRIBUTE_DEVICE) != 0) {
717  entp->d_type = DT_CHR;
718  } else if ((attr & FILE_ATTRIBUTE_DIRECTORY) != 0) {
719  entp->d_type = DT_DIR;
720  } else {
721  entp->d_type = DT_REG;
722  }
723 
724  /* Reset dummy fields */
725  entp->d_ino = 0;
726  entp->d_reclen = sizeof (struct dirent);
727 
728  } else {
729  /*
730  * Cannot convert file name to multi-byte string so construct
731  * an errornous directory entry and return that. Note that
732  * we cannot return NULL as that would stop the processing
733  * of directory entries completely.
734  */
735  entp = &dirp->ent;
736  entp->d_name[0] = '?';
737  entp->d_name[1] = '\0';
738  entp->d_namlen = 1;
739  entp->d_type = DT_UNKNOWN;
740  entp->d_ino = 0;
741  entp->d_reclen = 0;
742  }
743 
744  } else {
745  /* No more directory entries */
746  entp = NULL;
747  }
748 
749  return entp;
750 }
751 
752 /*
753  * Close directory stream.
754  */
755 static int
757  DIR *dirp)
758 {
759  int ok;
760  if (dirp) {
761 
762  /* Close wide-character directory stream */
763  ok = _wclosedir (dirp->wdirp);
764  dirp->wdirp = NULL;
765 
766  /* Release multi-byte character version */
767  free (dirp);
768 
769  } else {
770 
771  /* Invalid directory stream */
772  dirent_set_errno (EBADF);
773  ok = /*failure*/-1;
774 
775  }
776  return ok;
777 }
778 
779 /*
780  * Rewind directory stream to beginning.
781  */
782 static void
784  DIR* dirp)
785 {
786  /* Rewind wide-character string directory stream */
787  _wrewinddir (dirp->wdirp);
788 }
789 
790 /* Convert multi-byte string to wide character string */
791 static int
793  size_t *pReturnValue,
794  wchar_t *wcstr,
795  size_t sizeInWords,
796  const char *mbstr,
797  size_t count)
798 {
799  int error;
800 
801 #if defined(_MSC_VER) && _MSC_VER >= 1400
802 
803  /* Microsoft Visual Studio 2005 or later */
804  error = mbstowcs_s (pReturnValue, wcstr, sizeInWords, mbstr, count);
805 
806 #else
807 
808  /* Older Visual Studio or non-Microsoft compiler */
809  size_t n;
810 
811  /* Convert to wide-character string (or count characters) */
812  n = mbstowcs (wcstr, mbstr, sizeInWords);
813  if (!wcstr || n < count) {
814 
815  /* Zero-terminate output buffer */
816  if (wcstr && sizeInWords) {
817  if (n >= sizeInWords) {
818  n = sizeInWords - 1;
819  }
820  wcstr[n] = 0;
821  }
822 
823  /* Length of resuting multi-byte string WITH zero terminator */
824  if (pReturnValue) {
825  *pReturnValue = n + 1;
826  }
827 
828  /* Success */
829  error = 0;
830 
831  } else {
832 
833  /* Could not convert string */
834  error = 1;
835 
836  }
837 
838 #endif
839 
840  return error;
841 }
842 
843 /* Convert wide-character string to multi-byte string */
844 static int
846  size_t *pReturnValue,
847  char *mbstr,
848  size_t sizeInBytes, /* max size of mbstr */
849  const wchar_t *wcstr,
850  size_t count)
851 {
852  int error;
853 
854 #if defined(_MSC_VER) && _MSC_VER >= 1400
855 
856  /* Microsoft Visual Studio 2005 or later */
857  error = wcstombs_s (pReturnValue, mbstr, sizeInBytes, wcstr, count);
858 
859 #else
860 
861  /* Older Visual Studio or non-Microsoft compiler */
862  size_t n;
863 
864  /* Convert to multi-byte string (or count the number of bytes needed) */
865  n = wcstombs (mbstr, wcstr, sizeInBytes);
866  if (!mbstr || n < count) {
867 
868  /* Zero-terminate output buffer */
869  if (mbstr && sizeInBytes) {
870  if (n >= sizeInBytes) {
871  n = sizeInBytes - 1;
872  }
873  mbstr[n] = '\0';
874  }
875 
876  /* Lenght of resulting multi-bytes string WITH zero-terminator */
877  if (pReturnValue) {
878  *pReturnValue = n + 1;
879  }
880 
881  /* Success */
882  error = 0;
883 
884  } else {
885 
886  /* Cannot convert string */
887  error = 1;
888 
889  }
890 
891 #endif
892 
893  return error;
894 }
895 
896 /* Set errno variable */
897 static void
899  int error)
900 {
901 #if defined(_MSC_VER) && _MSC_VER >= 1400
902 
903  /* Microsoft Visual Studio 2005 and later */
904  _set_errno (error);
905 
906 #else
907 
908  /* Non-Microsoft compiler or older Microsoft compiler */
909  errno = error;
910 
911 #endif
912 }
913 
914 
915 #ifdef __cplusplus
916 }
917 #endif
918 #endif /*DIRENT_H*/
919 
#define DT_REG
WIN32_FIND_DATAW data
#define DT_CHR
HANDLE handle
static void dirent_set_errno(int error)
unsigned short d_reclen
static int dirent_mbstowcs_s(size_t *pReturnValue, wchar_t *wcstr, size_t sizeInWords, const char *mbstr, size_t count)
char d_name[PATH_MAX]
int cached
int d_type
#define DT_DIR
size_t d_namlen
static WIN32_FIND_DATAW * dirent_first(_WDIR *dirp)
static struct _wdirent * _wreaddir(_WDIR *dirp)
#define PATH_MAX
unsigned short d_reclen
#define DT_UNKNOWN
long d_ino
static int closedir(DIR *dirp)
static void rewinddir(DIR *dirp)
static void _wrewinddir(_WDIR *dirp)
static DIR * opendir(const char *dirname)
wchar_t * patt
static int dirent_wcstombs_s(size_t *pReturnValue, char *mbstr, size_t sizeInBytes, const wchar_t *wcstr, size_t count)
static _WDIR * _wopendir(const wchar_t *dirname)
struct dirent ent
static struct dirent * readdir(DIR *dirp)
size_t d_namlen
static int _wclosedir(_WDIR *dirp)
struct _WDIR * wdirp
static WIN32_FIND_DATAW * dirent_next(_WDIR *dirp)
#define FILE_ATTRIBUTE_DEVICE
Definition: oDirentWin32.hh:47
struct _wdirent ent
wchar_t d_name[PATH_MAX]