|
|
1.1 root 1: /*
2: * UAE - The Un*x Amiga Emulator
3: *
4: * Win32 interface
5: *
6: * Copyright 1997 Mathias Ortmann
7: */
8:
1.1.1.2 root 9: #include "sysconfig.h"
10: #include "sysdeps.h"
11:
1.1 root 12: #include <windows.h>
13: #include <stdlib.h>
14: #include <stdarg.h>
1.1.1.3 root 15: #include <ddraw.h>
1.1 root 16: #include <commctrl.h>
17: #include <commdlg.h>
18: #include <stdio.h>
19: #include <fcntl.h>
20: #include <sys/stat.h>
21: #include <io.h>
1.1.1.3 root 22: #include <sys/types.h>
23: #include <sys/timeb.h>
24: #include <process.h>
1.1 root 25: #include "options.h"
1.1.1.3 root 26: #include "posixemu.h"
27: #include "filesys.h"
28:
29: /* Our Win32 implementation of this function */
30: void gettimeofday( struct timeval *tv, void *blah )
31: {
32: struct timeb time;
33: ftime( &time );
34:
35: tv->tv_sec = time.time;
36: tv->tv_usec = time.millitm * 1000;
37: }
38:
39: /* convert time_t to/from AmigaDOS time */
40: #define secs_per_day ( 24 * 60 * 60 )
41: #define diff ( (8 * 365 + 2) * secs_per_day )
42:
43: void get_time(time_t t, long* days, long* mins, long* ticks)
44: {
45: /* time_t is secs since 1-1-1970 */
46: /* days since 1-1-1978 */
47: /* mins since midnight */
48: /* ticks past minute @ 50Hz */
49:
50: t -= diff;
51: *days = t / secs_per_day;
52: t -= *days * secs_per_day;
53: *mins = t / 60;
54: t -= *mins * 60;
55: *ticks = t * 50;
56: }
1.1 root 57:
58: /* stdioemu, posixemu, mallocemu, and various file system helper routines */
59: static DWORD lasterror;
60:
61: static int isillegal (unsigned char *str)
62: {
1.1.1.3 root 63: int result = 0;
1.1 root 64: unsigned char a = *str, b = str[1], c = str[2];
65:
66: if (a >= 'a' && a <= 'z')
67: a &= ~' ';
68: if (b >= 'a' && b <= 'z')
69: b &= ~' ';
70: if (c >= 'a' && c <= 'z')
71: c &= ~' ';
72:
1.1.1.3 root 73: result = ( (a == 'A' && b == 'U' && c == 'X') ||
1.1.1.4 ! root 74: (a == 'C' && b == 'O' && c == 'N') ||
! 75: (a == 'P' && b == 'R' && c == 'N') ||
! 76: (a == 'N' && b == 'U' && c == 'L') );
1.1.1.3 root 77:
78: return result;
1.1 root 79: }
80:
81: static int checkspace (char *str, char s, char d)
82: {
83: char *ptr = str;
84:
85: while (*ptr && *ptr == s)
86: ptr++;
87:
88: if (!*ptr || *ptr == '/' || *ptr == '\\') {
89: while (str < ptr)
90: *(str++) = d;
91: return 0;
92: }
93: return 1;
94: }
95:
96: /* This is sick and incomplete... in the meantime, I have discovered six new illegal file name formats
97: * M$ sucks! */
1.1.1.2 root 98: void fname_atow (const char *src, char *dst, int size)
1.1 root 99: {
1.1.1.2 root 100: char *lastslash = dst, *strt = dst, *posn = NULL, *temp = NULL;
1.1 root 101: int i, j;
102:
1.1.1.2 root 103: temp = xmalloc( size );
104:
1.1 root 105: while (size-- > 0) {
106: if (!(*dst = *src++))
107: break;
108:
109: if (*dst == '~' || *dst == '|' || *dst == '*' || *dst == '?') {
110: if (size > 2) {
111: sprintf (dst, "~%02x", *dst);
112: size -= 2;
113: dst += 2;
114: }
115: } else if (*dst == '/') {
1.1.1.3 root 116: if (checkspace (lastslash, ' ', (char)0xa0) && (dst - lastslash == 3 || (dst - lastslash > 3 && lastslash[3] == '.')) && isillegal (lastslash)) {
1.1 root 117: i = dst - lastslash - 3;
118: dst++;
119: for (j = i + 1; j--; dst--)
120: *dst = dst[-1];
1.1.1.3 root 121: *(dst++) = (char)0xa0;
1.1 root 122: dst += i;
123: size--;
1.1.1.3 root 124: } else if (*lastslash == '.' && (dst - lastslash == 1 || (lastslash[1] == '.' && dst - lastslash == 2)) && size) {
125: *(dst++) = (char)0xa0;
1.1 root 126: size--;
127: }
128: *dst = '\\';
129: lastslash = dst + 1;
130: }
131: dst++;
132: }
133:
1.1.1.3 root 134: if (checkspace (lastslash, ' ', (char)0xa0) && (dst - lastslash == 3 || (dst - lastslash > 3 && lastslash[3] == '.')) && isillegal (lastslash) && size > 1) {
1.1 root 135: i = dst - lastslash - 3;
136: dst++;
137: for (j = i + 1; j--; dst--)
138: *dst = dst[-1];
1.1.1.3 root 139: *(dst++) = (char)0xa0;
1.1 root 140: } else if (!strcmp (lastslash, ".") || !strcmp (lastslash, ".."))
141: strcat (lastslash, "\xa0");
142:
1.1.1.2 root 143: /* Major kludge, because I can't find the problem... */
144: if( ( posn = strstr( strt, "..\xA0\\" ) ) == strt && temp)
1.1 root 145: {
1.1.1.4 ! root 146: strcpy( temp, "..\\" );
! 147: strcat( temp, strt + 4 );
! 148: strcpy( strt, temp );
1.1 root 149: }
1.1.1.3 root 150:
151: /* Another major kludge, for the MUI installation... */
152: if( *strt == ' ' ) /* first char as a space is illegal in Windoze */
153: {
1.1.1.4 ! root 154: sprintf( temp, "~%02x%s", ' ', strt+1 );
! 155: strcpy( strt, temp );
1.1.1.3 root 156: }
1.1 root 157: }
158:
159: static int hextol (char a)
160: {
161: if (a >= '0' && a <= '9')
162: return a - '0';
163: if (a >= 'a' && a <= 'f')
164: return a - 'a' + 10;
165: if (a >= 'A' && a <= 'F')
166: return a - 'A' + 10;
167: return 2;
168: }
169:
170: /* Win32 file name restrictions suck... */
171: void fname_wtoa (unsigned char *ptr)
172: {
173: unsigned char *lastslash = ptr;
174:
175: while (*ptr) {
176: if (*ptr == '~') {
177: *ptr = hextol (ptr[1]) * 16 + hextol (ptr[2]);
178: strcpy (ptr + 1, ptr + 3);
179: } else if (*ptr == '\\') {
1.1.1.3 root 180: if (checkspace (lastslash, ' ', (char)0xa0) && ptr - lastslash > 3 && lastslash[3] == 0xa0 && isillegal (lastslash)) {
1.1 root 181: ptr--;
182: strcpy (lastslash + 3, lastslash + 4);
183: }
184: *ptr = '/';
185: lastslash = ptr + 1;
186: }
187: ptr++;
188: }
189:
1.1.1.3 root 190: if (checkspace (lastslash, ' ', (char)0xa0) && ptr - lastslash > 3 && lastslash[3] == 0xa0 && isillegal (lastslash))
1.1 root 191: strcpy (lastslash + 3, lastslash + 4);
192: }
193:
1.1.1.3 root 194: #ifndef HAVE_TRUNCATE
195: int truncate (const char *name, long int len)
1.1 root 196: {
1.1.1.3 root 197: HANDLE hFile;
198: BOOL bResult = FALSE;
199: int result = -1;
200:
201: #if 0
202: char buf[1024];
203:
204: fname_atow(name,buf,sizeof buf);
205:
206: if( ( hFile = CreateFile( buf, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
1.1.1.4 ! root 207: OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ) ) != INVALID_HANDLE_VALUE )
1.1.1.3 root 208: {
1.1.1.4 ! root 209: if( SetFilePointer( hFile, len, NULL, FILE_BEGIN ) == (DWORD)len )
! 210: {
! 211: if( SetEndOfFile( hFile ) == TRUE )
! 212: result = 0;
! 213: }
! 214: else
! 215: {
! 216: write_log( "SetFilePointer() failure for %s to posn %d\n", buf, len );
! 217: }
! 218: CloseHandle( hFile );
1.1.1.3 root 219: }
220: else
221: {
1.1.1.4 ! root 222: write_log( "CreateFile() failed to open %s\n", buf );
1.1.1.3 root 223: }
224: #else
225: if( ( hFile = CreateFile( name, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
1.1.1.4 ! root 226: OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ) ) != INVALID_HANDLE_VALUE )
1.1.1.3 root 227: {
1.1.1.4 ! root 228: if( SetFilePointer( hFile, len, NULL, FILE_BEGIN ) == (DWORD)len )
! 229: {
! 230: if( SetEndOfFile( hFile ) == TRUE )
! 231: result = 0;
! 232: }
! 233: else
! 234: {
! 235: write_log( "SetFilePointer() failure for %s to posn %d\n", name, len );
! 236: }
! 237: CloseHandle( hFile );
1.1.1.3 root 238: }
239: else
240: {
1.1.1.4 ! root 241: write_log( "CreateFile() failed to open %s\n", name );
1.1.1.3 root 242: }
243: #endif
244: if( result == -1 )
1.1.1.4 ! root 245: lasterror = GetLastError();
1.1.1.3 root 246: return result;
1.1 root 247: }
1.1.1.3 root 248: #endif
1.1 root 249:
1.1.1.3 root 250: #if 0
251:
252: DIR {
253: WIN32_FIND_DATA finddata;
254: HANDLE hDir;
255: int getnext;
256: };
257:
258: DIR *posixemu_opendir(const char *path)
1.1 root 259: {
1.1.1.3 root 260: char buf[1024];
261: DIR *dir;
262:
263: if (!(dir = (DIR *)GlobalAlloc(GPTR,sizeof(DIR))))
264: {
265: lasterror = GetLastError();
266: return 0;
267: }
268: #if 0
269: fname_atow(path,buf,sizeof buf-4);
270: #else
271: strcpy( buf, path );
272: #endif
273: strcat(buf,"\\*");
274:
275: if ((dir->hDir = FindFirstFile(buf,&dir->finddata)) == INVALID_HANDLE_VALUE)
276: {
277: lasterror = GetLastError();
278: GlobalFree(dir);
279: return 0;
280: }
281:
282: return dir;
1.1 root 283: }
284:
1.1.1.3 root 285: struct dirent *posixemu_readdir(DIR *dir)
1.1 root 286: {
1.1.1.3 root 287: if (dir->getnext)
288: {
289: if (!FindNextFile(dir->hDir,&dir->finddata))
290: {
291: lasterror = GetLastError();
292: return 0;
293: }
294: }
295: dir->getnext = TRUE;
296:
297: fname_wtoa(dir->finddata.cFileName);
298: return (struct dirent *)dir->finddata.cFileName;
1.1 root 299: }
300:
1.1.1.3 root 301: void posixemu_closedir(DIR *dir)
1.1 root 302: {
1.1.1.3 root 303: FindClose(dir->hDir);
304: GlobalFree(dir);
1.1 root 305: }
306: #endif
1.1.1.3 root 307:
308: int w32fopendel(char *name, char *mode, int delflag)
1.1 root 309: {
1.1.1.3 root 310: HANDLE hFile;
311:
312: if ((hFile = CreateFile(name,
313: mode[1] == '+' ? GENERIC_READ | GENERIC_WRITE : GENERIC_READ, // ouch :)
314: FILE_SHARE_READ | FILE_SHARE_WRITE,
315: NULL,
316: OPEN_EXISTING,
317: delflag ? FILE_ATTRIBUTE_NORMAL|FILE_FLAG_DELETE_ON_CLOSE : FILE_ATTRIBUTE_NORMAL,
318: NULL)) == INVALID_HANDLE_VALUE)
319: {
320: lasterror = GetLastError();
321: hFile = 0;
322: }
323:
324: return (int)hFile; /* return handle */
1.1 root 325: }
1.1.1.3 root 326:
327: DWORD getattr(const char *name, LPFILETIME lpft, size_t *size)
328: {
329: HANDLE hFind;
330: WIN32_FIND_DATA fd;
1.1 root 331:
1.1.1.3 root 332: if ((hFind = FindFirstFile(name,&fd)) == INVALID_HANDLE_VALUE)
333: {
334: lasterror = GetLastError();
335:
336: fd.dwFileAttributes = GetFileAttributes(name);
337:
338: return fd.dwFileAttributes;
339: }
340:
341: FindClose(hFind);
342:
343: if (lpft) *lpft = fd.ftLastWriteTime;
344: if (size) *size = fd.nFileSizeLow;
345:
346: return fd.dwFileAttributes;
347: }
348:
349: #if 0
350: int posixemu_stat(const char *name, struct stat *statbuf)
1.1.1.2 root 351: {
1.1.1.3 root 352: DWORD attr;
353: FILETIME ft, lft;
354:
355: if ((attr = getattr(name,&ft,(size_t*)&statbuf->st_size)) == (DWORD)~0)
356: {
357: lasterror = GetLastError();
358: return -1;
359: }
360: else
361: {
362: statbuf->st_mode = (attr & FILE_ATTRIBUTE_READONLY) ? FILEFLAG_READ: FILEFLAG_READ | FILEFLAG_WRITE;
363: if (attr & FILE_ATTRIBUTE_ARCHIVE) statbuf->st_mode |= FILEFLAG_ARCHIVE;
364: if (attr & FILE_ATTRIBUTE_DIRECTORY) statbuf->st_mode |= FILEFLAG_DIR;
365: FileTimeToLocalFileTime(&ft,&lft);
366: statbuf->st_mtime = (*(__int64 *)&lft-((__int64)(369*365+89)*(__int64)(24*60*60)*(__int64)10000000))/(__int64)10000000;
367: }
1.1.1.2 root 368: return 0;
369: }
1.1.1.3 root 370:
371: int posixemu_chmod(const char *name, int mode)
372: {
373: DWORD attr = FILE_ATTRIBUTE_NORMAL;
374: if (mode & 0x05) attr |= FILE_ATTRIBUTE_READONLY; /* Delete (0x01) or Write (0x04) bits */
375: if (mode & 0x10) attr |= FILE_ATTRIBUTE_ARCHIVE;
376:
377: if (SetFileAttributes(name,attr)) return 1;
378: lasterror = GetLastError();
379:
380: return -1;
381: }
1.1.1.2 root 382: #endif
1.1.1.3 root 383:
384: void tmToSystemTime( struct tm *tmtime, LPSYSTEMTIME systime )
385: {
386: if( tmtime == NULL )
387: {
1.1.1.4 ! root 388: GetSystemTime( systime );
1.1.1.3 root 389: }
390: else
391: {
1.1.1.4 ! root 392: systime->wDay = tmtime->tm_mday;
! 393: systime->wDayOfWeek = tmtime->tm_wday;
! 394: systime->wMonth = tmtime->tm_mon + 1;
! 395: systime->wYear = tmtime->tm_year + 1900;
! 396: systime->wHour = tmtime->tm_hour;
! 397: systime->wMinute = tmtime->tm_min;
! 398: systime->wSecond = tmtime->tm_sec;
! 399: systime->wMilliseconds = 0;
1.1.1.3 root 400: }
401: }
402:
403: static int setfiletime(const char *name, unsigned int days, int minute, int tick)
404: {
405: FILETIME LocalFileTime, FileTime;
406: HANDLE hFile;
407: int success;
408: if ((hFile = CreateFile(name, GENERIC_WRITE,FILE_SHARE_READ | FILE_SHARE_WRITE,NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_BACKUP_SEMANTICS, NULL)) == INVALID_HANDLE_VALUE)
409: {
410: lasterror = GetLastError();
411: return 0;
412: }
413:
414: *(__int64 *)&LocalFileTime = (((__int64)(377*365+91+days)*(__int64)1440+(__int64)minute)*(__int64)(60*50)+(__int64)tick)*(__int64)200000;
415:
416: if (!LocalFileTimeToFileTime(&LocalFileTime,&FileTime)) FileTime = LocalFileTime;
417:
418: if (!(success = SetFileTime(hFile,&FileTime,&FileTime,&FileTime))) lasterror = GetLastError();
419: CloseHandle(hFile);
420:
421: return success;
422: }
423:
424: int posixemu_utime( const char *name, struct utimbuf *time )
425: {
426: int result = -1;
427: long days, mins, ticks;
428:
429: get_time( time->actime, &days, &mins, &ticks );
430:
431: if( setfiletime( name, days, mins, ticks ) )
1.1.1.4 ! root 432: result = 0;
1.1.1.3 root 433:
434: return result;
435: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.