filesystem_win32.ii

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

Generated by doxygen 1.7.1 on Thu May 24 2012 01:02:36 for The Battle for Wesnoth
Gna! | Forum | Wiki | CIA | devdocs