/[pearpc]/src/system/osapi/win32/sysfile.cc
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Contents of /src/system/osapi/win32/sysfile.cc

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1 - (show annotations)
Wed Sep 5 17:11:21 2007 UTC (16 years, 7 months ago) by dpavlin
File size: 9572 byte(s)
import upstream CVS
1 /*
2 * PearPC
3 * sysfile.cc - file system functions for Win32
4 *
5 * Copyright (C) 1999-2004 Sebastian Biallas (sb@biallas.net)
6 * Copyright (C) 1999-2002 Stefan Weyergraf
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22 #include <cctype>
23 #include <cerrno>
24 #include <cstdlib>
25 #include <cstdio>
26 #include <sys/stat.h>
27
28 #include "system/file.h"
29 #include "system/sys.h"
30
31 #ifndef WIN32_LEAN_AND_MEAN
32 #define WIN32_LEAN_AND_MEAN
33 #endif
34 #include <windows.h>
35
36 #ifndef S_IFMT
37 #define S_IFMT 0xf000
38 #endif
39
40 #ifndef S_ISREG
41 # ifndef S_IFREG
42 # define S_ISREG(m) (0)
43 # else
44 # define S_ISREG(m) (((m) & S_IFMT)==S_IFREG)
45 # endif
46 #endif
47
48 #ifndef S_ISBLK
49 # ifndef S_IFBLK
50 # define S_ISBLK(m) (0)
51 # else
52 # define S_ISBLK(m) (((m) & S_IFMT)==S_IFBLK)
53 # endif
54 #endif
55
56
57 #ifndef S_ISCHR
58 # ifndef S_IFCHR
59 # define S_ISCHR(m) (0)
60 # else
61 # define S_ISCHR(m) (((m) & S_IFMT)==S_IFCHR)
62 # endif
63 #endif
64
65 #ifndef S_ISDIR
66 # ifndef S_IFDIR
67 # define S_ISDIR(m) (0)
68 # else
69 # define S_ISDIR(m) (((m) & S_IFMT)==S_IFDIR)
70 # endif
71 #endif
72
73 #ifndef S_ISFIFO
74 # ifndef S_IFFIFO
75 # define S_ISFIFO(m) (0)
76 # else
77 # define S_ISFIFO(m) (((m) & S_IFMT)==S_IFFIFO)
78 # endif
79 #endif
80
81 #ifndef S_ISLNK
82 # ifndef S_IFLNK
83 # define S_ISLNK(m) (0)
84 # else
85 # define S_ISLNK(m) (((m) & S_IFMT)==S_IFLNK)
86 # endif
87 #endif
88
89 #ifndef S_ISSOCK
90 # ifndef S_IFSOCK
91 # define S_ISSOCK(m) (0)
92 # else
93 # define S_ISSOCK(m) (((m) & S_IFMT)==S_IFSOCK)
94 # endif
95 #endif
96
97 #ifndef S_IRUSR
98 #define S_IRUSR 0
99 #endif
100 #ifndef S_IRGRP
101 #define S_IRGRP 0
102 #endif
103 #ifndef S_IROTH
104 #define S_IROTH 0
105 #endif
106
107 #ifndef S_IWUSR
108 #define S_IWUSR 0
109 #endif
110 #ifndef S_IWGRP
111 #define S_IWGRP 0
112 #endif
113 #ifndef S_IWOTH
114 #define S_IWOTH 0
115 #endif
116
117 #ifndef S_IXUSR
118 #define S_IXUSR 0
119 #endif
120 #ifndef S_IXGRP
121 #define S_IXGRP 0
122 #endif
123 #ifndef S_IXOTH
124 #define S_IXOTH 0
125 #endif
126
127
128 struct winfindstate {
129 HANDLE fhandle;
130 WIN32_FIND_DATA find_data;
131 };
132
133 int sys_file_mode(int mode)
134 {
135 int m = 0;
136 if (S_ISREG(mode)) {
137 m |= HT_S_IFREG;
138 } else if (S_ISBLK(mode)) {
139 m |= HT_S_IFBLK;
140 } else if (S_ISCHR(mode)) {
141 m |= HT_S_IFCHR;
142 } else if (S_ISDIR(mode)) {
143 m |= HT_S_IFDIR;
144 } else if (S_ISFIFO(mode)) {
145 m |= HT_S_IFFIFO;
146 } else if (S_ISLNK(mode)) {
147 m |= HT_S_IFLNK;
148 } else if (S_ISSOCK(mode)) {
149 m |= HT_S_IFSOCK;
150 }
151 if (mode & S_IRUSR) m |= HT_S_IRUSR;
152 if (mode & S_IRGRP) m |= HT_S_IRGRP;
153 if (mode & S_IROTH) m |= HT_S_IROTH;
154
155 if (mode & S_IWUSR) m |= HT_S_IWUSR;
156 if (mode & S_IWGRP) m |= HT_S_IWGRP;
157 if (mode & S_IWOTH) m |= HT_S_IWOTH;
158
159 if (mode & S_IXUSR) m |= HT_S_IXUSR;
160 if (mode & S_IXGRP) m |= HT_S_IXGRP;
161 if (mode & S_IXOTH) m |= HT_S_IXOTH;
162 return m;
163 }
164
165 bool sys_filename_is_absolute(const char *filename)
166 {
167 if (strlen(filename) < 3) return false;
168 return (isalpha(filename[0]) && (filename[1] == ':') &&
169 sys_is_path_delim(filename[2]));
170 }
171
172 int sys_canonicalize(char *result, const char *filename)
173 {
174 if (!sys_filename_is_absolute(filename)) return ENOENT;
175 char *dunno;
176 return (GetFullPathName(filename, HT_NAME_MAX, result, &dunno) > 0) ? 0 : ENOENT;
177 }
178
179 uint filetime_to_ctime(FILETIME f)
180 {
181 uint64 q;
182 q = ((uint64)f.dwHighDateTime<<32)|((uint64)f.dwLowDateTime);
183 q = q / 10000000ULL; // 100 nano-sec to full sec
184 return q + 1240431886; // MAGIC: this is 1.1.1970 minus 1.1.1601 in seconds
185 }
186
187 void sys_findfill(pfind_t &pfind)
188 {
189 /*DWORD dwFileAttributes;
190 FILETIME ftCreationTime;
191 FILETIME ftLastAccessTime;
192 FILETIME ftLastWriteTime;
193 DWORD nFileSizeHigh;
194 DWORD nFileSizeLow;
195 DWORD dwReserved0;
196 DWORD dwReserved1;
197 TCHAR cFileName[ MAX_PATH ];
198 TCHAR cAlternateFileName[ 14 ];*/
199 winfindstate *wfs=(winfindstate*)pfind.findstate;
200 pfind.name = (char *)&wfs->find_data.cFileName;
201 pfind.stat.caps = pstat_ctime|pstat_mtime|pstat_atime|pstat_size|pstat_mode_type;
202
203 pfind.stat.size = wfs->find_data.nFileSizeLow | (((uint64)wfs->find_data.nFileSizeHigh) << 32);
204
205 pfind.stat.mode = (wfs->find_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ? HT_S_IFDIR : HT_S_IFREG;
206 pfind.stat.ctime = filetime_to_ctime(wfs->find_data.ftCreationTime);
207 pfind.stat.mtime = filetime_to_ctime(wfs->find_data.ftLastWriteTime);
208 pfind.stat.atime = filetime_to_ctime(wfs->find_data.ftLastAccessTime);
209 }
210
211 int sys_findfirst(pfind_t &pfind, const char *dirname)
212 {
213 if (!sys_filename_is_absolute(dirname)) return ENOENT;
214 char *Dirname = (char *)malloc(strlen(dirname)+5);
215 strcpy(Dirname, dirname);
216 int dnl=strlen(dirname);
217 if ((dirname[dnl-1]!='\\') && (dirname[dnl-1]!='/')) {
218 Dirname[dnl]='\\';
219 Dirname[dnl+1]=0;
220 }
221 char *s=Dirname;
222 while ((s=strchr(s, '/'))) *s='\\';
223 strcat(Dirname, "*.*");
224
225 pfind.findstate=malloc(sizeof (winfindstate));
226 winfindstate *wfs=(winfindstate*)pfind.findstate;
227
228 wfs->fhandle = FindFirstFile(Dirname, &wfs->find_data);
229 free(Dirname);
230 if (wfs->fhandle == INVALID_HANDLE_VALUE) {
231 free(pfind.findstate);
232 return ENOENT;
233 }
234 sys_findfill(pfind);
235 return 0;
236 }
237
238 int sys_findnext(pfind_t &pfind)
239 {
240 winfindstate *wfs=(winfindstate*)pfind.findstate;
241
242 if (!FindNextFile(wfs->fhandle, &wfs->find_data)) {
243 return ENOENT;
244 }
245 sys_findfill(pfind);
246 return 0;
247 }
248
249 int sys_findclose(pfind_t &pfind)
250 {
251 int r=FindClose(((winfindstate*)pfind.findstate)->fhandle);
252 free(pfind.findstate);
253 return r ? ENOENT : 0;
254 }
255
256 static void stat_to_pstat_t(const struct stat &st, pstat_t &s)
257 {
258 s.caps = pstat_ctime|pstat_mtime|pstat_atime|pstat_uid|pstat_gid|pstat_mode_all|pstat_size|pstat_inode;
259 s.ctime = st.st_ctime;
260 s.mtime = st.st_mtime;
261 s.atime = st.st_atime;
262 s.gid = st.st_uid;
263 s.uid = st.st_gid;
264 s.mode = sys_file_mode(st.st_mode);
265 s.size = st.st_size;
266 s.fsid = st.st_ino;
267 }
268
269 int sys_pstat(pstat_t &s, const char *filename)
270 {
271 if (!sys_filename_is_absolute(filename)) return ENOENT;
272 struct stat st;
273 int e = stat(filename, &st);
274 if (e) return errno ? errno : ENOENT;
275 stat_to_pstat_t(st, s);
276 return 0;
277 }
278
279 int sys_pstat_fd(pstat_t &s, int fd)
280 {
281 struct stat st;
282 int e = fstat(fd, &st);
283 if (e) return errno ? errno : ENOENT;
284 stat_to_pstat_t(st, s);
285 return 0;
286 }
287
288 void sys_suspend()
289 {
290 Sleep(0);
291 }
292
293 /*int sys_get_free_mem()
294 {
295 return 0;
296 }*/
297
298 int sys_truncate(const char *filename, FileOfs ofs)
299 {
300 if (!sys_filename_is_absolute(filename)) return ENOENT;
301 HANDLE hfile = CreateFile(filename, GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
302 if (hfile == INVALID_HANDLE_VALUE) {
303 return EIO;
304 }
305 // FIXME: uint64
306 if (SetFilePointer(hfile, ofs, NULL, FILE_BEGIN)==0xffffffff) {
307 CloseHandle(hfile);
308 return EIO;
309 }
310 if (!SetEndOfFile(hfile)) {
311 CloseHandle(hfile);
312 return EIO;
313 }
314 CloseHandle(hfile);
315 return 0;
316 }
317
318 int sys_truncate_fd(int fd, FileOfs ofs)
319 {
320 return ENOSYS;
321 }
322
323 int sys_deletefile(const char *filename)
324 {
325 if (!sys_filename_is_absolute(filename)) return ENOENT;
326 if (DeleteFile(filename)) {
327 return 0;
328 }
329 return EIO;
330 }
331
332 bool sys_is_path_delim(char c)
333 {
334 return (c == '\\');
335 }
336
337 int sys_filename_cmp(const char *a, const char *b)
338 {
339 while (*a && *b) {
340 if (sys_is_path_delim(*a) && sys_is_path_delim(*b)) {
341 } else if (tolower(*a) != tolower(*b)) {
342 break;
343 } else if (*a != *b) {
344 break;
345 }
346 a++;
347 b++;
348 }
349 return tolower(*a) - tolower(*b);
350 }
351
352 SYS_FILE *sys_fopen(const char *filename, int openmode)
353 {
354 HANDLE *f = (HANDLE *)malloc(sizeof (HANDLE));
355 if (openmode & SYS_OPEN_CREATE) {
356 *f = CreateFile(filename, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS, NULL);
357 } else {
358 if (openmode & SYS_OPEN_WRITE) {
359 *f = CreateFile(filename, GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS, NULL);
360 } else {
361 *f = CreateFile(filename, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS, NULL);
362 }
363 }
364 if (*f == INVALID_HANDLE_VALUE) {
365 free(f);
366 return NULL;
367 }
368 return (SYS_FILE *)f;
369 }
370
371 void sys_fclose(SYS_FILE *file)
372 {
373 CloseHandle(*(HANDLE *)file);
374 free(file);
375 }
376
377 int sys_fread(SYS_FILE *file, byte *buf, int size)
378 {
379 DWORD read;
380 ReadFile(*(HANDLE *)file, buf, size, &read, NULL);
381 return read;
382 }
383
384 int sys_fwrite(SYS_FILE *file, byte *buf, int size)
385 {
386 DWORD written;
387 WriteFile(*(HANDLE *)file, buf, size, &written, NULL);
388 return written;
389 }
390
391 int sys_fseek(SYS_FILE *file, FileOfs newofs, int seekmode)
392 {
393 DWORD m;
394 switch (seekmode) {
395 case SYS_SEEK_SET: m = FILE_BEGIN; break;
396 case SYS_SEEK_REL: m = FILE_CURRENT; break;
397 case SYS_SEEK_END: m = FILE_END; break;
398 default: return EINVAL;
399 }
400 LONG newofs_h = newofs >> 32;
401 if (SetFilePointer(*(HANDLE *)file, newofs, &newofs_h, m) == 0xffffffff) {
402 return EINVAL;
403 } else {
404 return 0;
405 }
406 }
407
408 void sys_flush(SYS_FILE *file)
409 {
410 FlushFileBuffers(*(HANDLE *)file);
411 }
412
413 FileOfs sys_ftell(SYS_FILE *file)
414 {
415 LONG a, b=0;
416 a = SetFilePointer(*(HANDLE *)file, 0, &b, FILE_CURRENT);
417 return (((FileOfs)b)<<32)+((uint32)a);
418 }
419
420 void *sys_alloc_read_write_execute(int size)
421 {
422 return VirtualAlloc(NULL, size, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
423 }
424
425 void sys_free_read_write_execute(void *p)
426 {
427 VirtualFree(p, 0, MEM_DECOMMIT | MEM_RELEASE);
428 }

  ViewVC Help
Powered by ViewVC 1.1.26