coan 4.2.4
fs_win.c
Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (C) 2004, 2006 Symbian Software Ltd.                        *
00003  *   All rights reserved.                                                  *
00004  *   Copyright (C) 2007-2011 Mike Kinghan, imk@strudl.org                  *
00005  *   All rights reserved.                                                  *
00006  *                                                                         *
00007  *   Redistribution and use in source and binary forms, with or without    *
00008  *   modification, are permitted provided that the following conditions    *
00009  *   are met:                                                              *
00010  *                                                                         *
00011  *   Redistributions of source code must retain the above copyright        *
00012  *   notice, this list of conditions and the following disclaimer.         *
00013  *                                                                         *
00014  *   Redistributions in binary form must reproduce the above copyright     *
00015  *   notice, this list of conditions and the following disclaimer in the   *
00016  *   documentation and/or other materials provided with the distribution.  *
00017  *                                                                         *
00018  *   Neither the name of Symbian Software Ltd. nor the names of its        *
00019  *   contributors may be used to endorse or promote products derived from  *
00020  *   this software without specific prior written permission.              *
00021  *                                                                         *
00022  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS   *
00023  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT     *
00024  *   LIMITED TO, THE IMPLIED WARRANTIES OF  MERCHANTABILITY AND FITNESS    *
00025  *   FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE        *
00026  *   COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,   *
00027  *   INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,  *
00028  *   BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS *
00029  *   OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED    *
00030  *   AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,*
00031  *   OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF *
00032  *   THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH  *
00033  *   DAMAGE.                                                               *
00034  *                                                                         *
00035  **************************************************************************/
00036 
00042 #include "platform.h"
00043 
00044 #ifdef WINDOWS
00045 
00046 #include "filesys.h"
00047 #include "memory.h"
00048 #include "report.h"
00049 #include <ctype.h>
00050 #include <stdlib.h>
00051 #include <windows.h>
00052 
00055 
00057 typedef struct fs_dir_win {
00059     struct fs_dir_win * parent;
00061     heap_str dirname;
00063     char *dirname_end;
00065     HANDLE handle;
00067     WIN32_FIND_DATA obj_info;
00068 } fs_dir_win_t;
00069 
00070 
00073 heap_str
00074 fs_real_path(char const *relname, size_t *namelen)
00075 {
00076     heap_str fullpath = _fullpath(NULL,relname,MAX_PATH);
00077     if (namelen) {
00078         *namelen = strlen(fullpath);
00079     }
00080     return fullpath;
00081 }
00082 
00083 fs_obj_type_t
00084 fs_obj_type(char const *name)
00085 {
00086     WIN32_FILE_ATTRIBUTE_DATA obj_info;
00087     int res = GetFileAttributesEx(name,GetFileExInfoStandard,&obj_info);
00088     if (res) {
00089         if (obj_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
00090             return FS_OBJ_DIR;
00091         } else {
00092             return FS_OBJ_FILE;
00093         }
00094     }
00095     return FS_OBJ_NONE;
00096 }
00097 
00098 fs_dir_t
00099 fs_open_dir(char const *dirname, fs_dir_t const parent)
00100 {
00101     fs_dir_win_t * dir = NULL;
00102     size_t namelen;
00103     heap_str fullname = fs_real_path(dirname,&namelen);
00104     if (fullname) {
00105         HANDLE find_handle;
00106         WIN32_FIND_DATA obj_info;
00107         if (fullname[namelen - 1] == PATH_DELIM) {
00108             --namelen;
00109         }
00110         fullname = reallocate(fullname,namelen + 3);
00111         strcpy(fullname + namelen,"\\*");
00112         find_handle = FindFirstFile(fullname,&obj_info);
00113         if (find_handle != INVALID_HANDLE_VALUE) {
00114             size_t needed;
00115             dir = zallocate(sizeof(fs_dir_win_t));
00116             dir->parent = (fs_dir_win_t *)parent;
00117             dir->dirname = fullname;
00118             dir->handle = find_handle;
00119             dir->obj_info = obj_info;
00120             dir->dirname[namelen] = '\0';
00121             dir->dirname_end = dir->dirname + namelen;
00122             needed = strlen(dir->obj_info.cFileName) + 1;
00123             dir->dirname = reallocate(dir->dirname,namelen + needed + 1);
00124             dir->dirname_end = dir->dirname + namelen;
00125             *dir->dirname_end = '\0';
00126         }
00127     }
00128     return dir;
00129 }
00130 
00131 void
00132 fs_close_dir(fs_dir_t dir)
00133 {
00134     fs_dir_win_t * win_dir = dir;
00135     assert(dir);
00136     if (win_dir->handle != INVALID_HANDLE_VALUE) {
00137         FindClose(win_dir->handle);
00138     }
00139     free(win_dir->dirname);
00140     free(win_dir);
00141 }
00142 
00143 char const *
00144 fs_read_dir(fs_dir_t dir, char const ** fullname)
00145 {
00146     fs_dir_win_t * win_dir = dir;
00147     char * filename = NULL;
00148     BOOL res;
00149     assert(dir);
00150     if (win_dir->handle != INVALID_HANDLE_VALUE) {
00151         size_t len = win_dir->dirname_end - win_dir->dirname;
00152         size_t available = strlen(win_dir->dirname_end) ;
00153         size_t needed = strlen(win_dir->obj_info.cFileName) + 1;
00154         if (available < needed) {
00155             win_dir->dirname = reallocate(win_dir->dirname,len + needed + 1);
00156             win_dir->dirname_end = win_dir->dirname + len;
00157         }
00158         *win_dir->dirname_end = PATH_DELIM;
00159         filename = win_dir->dirname_end + 1;
00160         strcpy(filename,win_dir->obj_info.cFileName);
00161         if (fullname) {
00162             *fullname = win_dir->dirname;
00163         }
00164     }
00165     if (filename) {
00166         res = FindNextFile(win_dir->handle,&win_dir->obj_info);
00167         if (!res) {
00168             FindClose(win_dir->handle);
00169             win_dir->handle = INVALID_HANDLE_VALUE;
00170             if (GetLastError() != ERROR_NO_MORE_FILES) {
00171                 bail(GRIPE_CANT_READ_DIR,"Read error on directory \"%s\"",
00172                      win_dir->dirname);
00173             }
00174         }
00175         if (filename[0] == '.' &&
00176                 ((filename[1] == '.' && filename[2] == '\0') || filename[1] == '\0')) {
00177             return  fs_read_dir(dir,fullname);
00178         }
00179     } else {
00180         *win_dir->dirname_end = '\0';
00181     }
00182     return filename;
00183 }
00184 
00185 char const *
00186 fs_cur_dir_entry(fs_dir_t dir, char const **entry)
00187 {
00188     fs_dir_win_t * win_dir = dir;
00189     assert(dir);
00190     if (entry) {
00191         *entry = win_dir->dirname_end;
00192     }
00193     return win_dir->dirname;
00194 }
00195 
00196 fs_dir_t
00197 fs_get_parent(fs_dir_t dir)
00198 {
00199     fs_dir_win_t * win_dir;
00200     assert(dir);
00201     win_dir = dir;
00202     return win_dir->parent;
00203 }
00204 
00205 #endif
00206 
00207 /* EOF*/
00208 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines