filesystem_win32.ii

Go to the documentation of this file.
00001 /* $Id: filesystem_win32.ii 24973 2008-03-22 10:47:27Z noyga $ */
00002 /*
00003    Copyright (C) 2003 - 2008 by David White <dave@whitevine.net>
00004    Part of the Battle for Wesnoth Project http://www.wesnoth.org/
00005 
00006    This program is free software; you can redistribute it and/or modify
00007    it under the terms of the GNU General Public License version 2
00008    or at your option any later version.
00009    This program is distributed in the hope that it will be useful,
00010    but WITHOUT ANY WARRANTY.
00011 
00012    See the COPYING file for more details.
00013 */
00014 
00015 //! @file filesystem_win32.ii
00016 //! Win32 platform-specific filesystem code.
00017 
00018 /* /////////////////////////////////////////////////////////////////////////
00019  * This code swiped from dirent.c in the unixem library, version 1.7.3.
00020  * See http://synesis.com.au/software/unixem.html for full sources.
00021  * It's under BSD license.
00022  */
00023 
00024 #include <direct.h>
00025 #include <io.h>
00026 #include <errno.h>
00027 #include <stdlib.h>
00028 #include <windows.h>
00029 
00030 
00031 /* /////////////////////////////////////////////////////////////////////////
00032  * Compiler differences
00033  */
00034 
00035 #if defined(__BORLANDC__)
00036 # define DIRENT_PROVIDED_BY_COMPILER
00037 #elif defined(__DMC__)
00038 # define DIRENT_PROVIDED_BY_COMPILER
00039 #elif defined(__GNUC__)
00040 # define DIRENT_PROVIDED_BY_COMPILER
00041 #elif defined(__INTEL_COMPILER)
00042 #elif defined(_MSC_VER)
00043 #elif defined(__MWERKS__)
00044 #elif defined(__WATCOMC__)
00045 #else
00046 # error Compiler not discriminated
00047 #endif /* compiler */
00048 
00049 #if defined(DIRENT_PROVIDED_BY_COMPILER)
00050 #include <dirent.h>
00051 #else
00052 
00053 /* ////////////////////////////////////////////////////////////////////// */
00054 
00055 #include <stddef.h>
00056 
00057 #ifndef NAME_MAX
00058 # define NAME_MAX   (260)
00059 #endif /* !NAME_MAX */
00060 
00061 struct dirent
00062 {
00063     char    d_name[NAME_MAX + 1];      /*!< file name (null-terminated) */
00064     int     d_mode;
00065 };
00066 
00067 struct DIR
00068 {
00069     char              directory[_MAX_DIR+1];   /* . */
00070     WIN32_FIND_DATAA  find_data;               /* The Win32 FindFile data. */
00071     HANDLE            hFind;                   /* The Win32 FindFile handle. */
00072     struct dirent     dirent;                  /* The handle's entry. */
00073 };
00074 
00075 #ifndef FILE_ATTRIBUTE_ERROR
00076 # define FILE_ATTRIBUTE_ERROR           (0xFFFFFFFF)
00077 #endif /* FILE_ATTRIBUTE_ERROR */
00078 
00079 /* /////////////////////////////////////////////////////////////////////////
00080  * Helper functions
00081  */
00082 
00083 static HANDLE dirent__findfile_directory(char const *name, LPWIN32_FIND_DATAA data)
00084 {
00085     char    search_spec[_MAX_PATH +1];
00086 
00087     // Simply add the *.*, ensuring the path separator is included.
00088     (void)lstrcpyA(search_spec, name);
00089     if( '\\' != search_spec[lstrlenA(search_spec) - 1] &&
00090         '/' != search_spec[lstrlenA(search_spec) - 1])
00091     {
00092         (void)lstrcatA(search_spec, "\\*.*");
00093     }
00094     else
00095     {
00096         (void)lstrcatA(search_spec, "*.*");
00097     }
00098 
00099     return FindFirstFileA(search_spec, data);
00100 }
00101 
00102 /* /////////////////////////////////////////////////////////////////////////
00103  * API functions
00104  */
00105 
00106 DIR *opendir(char const *name)
00107 {
00108     DIR     *result =   NULL;
00109     DWORD   dwAttr;
00110 
00111     // Must be a valid name 
00112     if( !name ||
00113         !*name ||
00114         (dwAttr = GetFileAttributes(name)) == 0xFFFFFFFF)
00115     {
00116         errno = ENOENT;
00117     }
00118     // Must be a directory 
00119     else if(!(dwAttr & FILE_ATTRIBUTE_DIRECTORY))
00120     {
00121         errno = ENOTDIR;
00122     }
00123     else
00124     {
00125         result = (DIR*)malloc(sizeof(DIR));
00126 
00127         if(result == NULL)
00128         {
00129             errno = ENOMEM;
00130         }
00131         else
00132         {
00133             result->hFind=dirent__findfile_directory(name, &result->find_data);
00134 
00135             if(result->hFind == INVALID_HANDLE_VALUE)
00136             {
00137                 free(result);
00138 
00139                 result = NULL;
00140             }
00141             else
00142             {
00143                 // Save the directory, in case of rewind. 
00144                 (void)lstrcpyA(result->directory, name);
00145                 (void)lstrcpyA(result->dirent.d_name, result->find_data.cFileName);
00146                 result->dirent.d_mode   =   (int)result->find_data.dwFileAttributes;
00147             }
00148         }
00149     }
00150 
00151     return result;
00152 }
00153 
00154 int closedir(DIR *dir)
00155 {
00156     int ret;
00157 
00158     if(dir == NULL)
00159     {
00160         errno = EBADF;
00161 
00162         ret = -1;
00163     }
00164     else
00165     {
00166         // Close the search handle, if not already done.
00167         if(dir->hFind != INVALID_HANDLE_VALUE)
00168         {
00169             (void)FindClose(dir->hFind);
00170         }
00171 
00172         free(dir);
00173 
00174         ret = 0;
00175     }
00176 
00177     return ret;
00178 }
00179 
00180 struct dirent *readdir(DIR *dir)
00181 {
00182     // The last find exhausted the matches, so return NULL.
00183     if(dir->hFind == INVALID_HANDLE_VALUE)
00184     {
00185         if(FILE_ATTRIBUTE_ERROR == dir->find_data.dwFileAttributes)
00186         {
00187             errno = EBADF;
00188         }
00189         else
00190         {
00191             dir->find_data.dwFileAttributes = FILE_ATTRIBUTE_ERROR;
00192         }
00193 
00194         return NULL;
00195     }
00196     else
00197     {
00198         // Copy the result of the last successful match to dirent.
00199         (void)lstrcpyA(dir->dirent.d_name, dir->find_data.cFileName);
00200 
00201         // Attempt the next match.
00202         if(!FindNextFileA(dir->hFind, &dir->find_data))
00203         {
00204             // Exhausted all matches, so close and null the handle.
00205             (void)FindClose(dir->hFind);
00206             dir->hFind = INVALID_HANDLE_VALUE;
00207         }
00208 
00209         return &dir->dirent;
00210     }
00211 }
00212 
00213 /*
00214  * Microsoft C uses _stat instead of stat,
00215  * for both the function name and the structure name.
00216  * See <http://svn.ghostscript.com:8080/ghostscript/trunk/gs/src/stat_.h>
00217  */
00218 #ifdef _MSC_VER
00219 #  define stat _stat
00220 namespace {
00221     typedef int mode_t;
00222 }
00223 #endif
00224 
00225 #ifndef S_IFMT
00226 #define S_IFMT  (S_IFDIR|S_IFREG)
00227 #endif
00228 #ifndef S_ISREG
00229 #define S_ISREG(x) (((x) & S_IFMT) == S_IFREG)
00230 #endif
00231 #ifndef S_ISDIR
00232 #define S_ISDIR(x) (((x) & S_IFMT) == S_IFDIR)
00233 #endif
00234 
00235 #endif /* !DIRENT_PROVIDED_BY_COMPILER */
00236 
00237 #define mkdir(a,b) (_mkdir(a))

Generated by doxygen 1.5.5 on 23 May 2008 for The Battle for Wesnoth
Gna! | Forum | Wiki | CIA | devdocs