coan 4.2.4
|
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