ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/Windows/posix_emu.cpp
Revision: 1.1
Committed: 2004-12-03T22:03:12Z (19 years, 11 months ago) by gbeauche
Branch: MAIN
CVS Tags: nigel-build-19, nigel-build-17
Log Message:
Merge and upgrade native filesystem support from B2/Win. The nice
"My Computer" icon is now back. Adapt from recent extfs_unix.cpp.

File Contents

# Content
1 /*
2 * posix_emu.cpp -- posix and virtual desktop
3 *
4 * Basilisk II (C) 1997-1999 Christian Bauer
5 *
6 * Windows platform specific code copyright (C) Lauri Pesonen
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 as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
22
23 // TODO: UNC names. Customizable "Virtual Desktop" location.
24
25 #include "sysdeps.h"
26 #define NO_POSIX_API_HOOK
27 #include "posix_emu.h"
28 #include "user_strings.h"
29 #include "util_windows.h"
30 #include "main.h"
31 #include "extfs_defs.h"
32 #include "prefs.h"
33 #include <ctype.h>
34
35
36 #define DEBUG_EXTFS 0
37
38 #if DEBUG_EXTFS
39
40 // This must be always on.
41 #define DEBUG 1
42 #undef OutputDebugString
43 #define OutputDebugString extfs_log_write
44 extern void extfs_log_write( char *s );
45 #define EXTFS_LOG_FILE_NAME "extfs.log"
46 #include "debug.h"
47
48 enum {
49 DB_EXTFS_NONE=0,
50 DB_EXTFS_NORMAL,
51 DB_EXTFS_LOUD
52 };
53 static int16 debug_extfs = DB_EXTFS_NONE;
54 static HANDLE extfs_log_file = INVALID_HANDLE_VALUE;
55
56 static void extfs_log_open( char *path )
57 {
58 if(debug_extfs == DB_EXTFS_NONE) return;
59
60 DeleteFile( path );
61 extfs_log_file = CreateFile(
62 path,
63 GENERIC_READ|GENERIC_WRITE,
64 FILE_SHARE_READ,
65 NULL,
66 CREATE_ALWAYS,
67 // FILE_FLAG_WRITE_THROUGH|FILE_FLAG_NO_BUFFERING,
68 FILE_FLAG_WRITE_THROUGH,
69 NULL
70 );
71 if( extfs_log_file == INVALID_HANDLE_VALUE ) {
72 ErrorAlert( "Could not create the EXTFS log file." );
73 }
74 }
75
76 static void extfs_log_close( void )
77 {
78 if(debug_extfs == DB_EXTFS_NONE) return;
79
80 if( extfs_log_file != INVALID_HANDLE_VALUE ) {
81 CloseHandle( extfs_log_file );
82 extfs_log_file = INVALID_HANDLE_VALUE;
83 }
84 }
85
86 static void extfs_log_write( char *s )
87 {
88 DWORD bytes_written;
89
90 // should have been checked already.
91 if(debug_extfs == DB_EXTFS_NONE) return;
92
93 if( extfs_log_file != INVALID_HANDLE_VALUE ) {
94
95 DWORD count = strlen(s);
96 if (0 == WriteFile(extfs_log_file, s, count, &bytes_written, NULL) ||
97 (int)bytes_written != count)
98 {
99 extfs_log_close();
100 ErrorAlert( "extfs log file write error (out of disk space?). Log closed." );
101 } else {
102 FlushFileBuffers( extfs_log_file );
103 }
104 }
105 }
106 #else
107
108 #define DEBUG 0
109 #include "debug.h"
110
111 #endif // DEBUG_EXTFS
112
113 int my_errno = 0;
114
115 #define VIRTUAL_ROOT_ID ((HANDLE)0xFFFFFFFE)
116
117 static const char *desktop_name = "Virtual Desktop";
118 static const char *custom_icon_name = "Icon\r";
119 #define my_computer GetString(STR_EXTFS_VOLUME_NAME)
120
121 static char lb1[MAX_PATH_LENGTH];
122 static char lb2[MAX_PATH_LENGTH];
123
124 #define MRP(path) translate(path,lb1)
125 #define MRP2(path) translate(path,lb2)
126
127 #define DISABLE_ERRORS UINT prevmode = SetErrorMode(SEM_NOOPENFILEERRORBOX|SEM_FAILCRITICALERRORS)
128 #define RESTORE_ERRORS SetErrorMode(prevmode);
129
130 static char host_drive_list[512];
131 static char virtual_root[248]; // Not _MAX_PATH
132
133 const uint8 my_comp_icon[2670] = {
134 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x09, 0xD8, 0x00, 0x00, 0x08, 0xD8, 0x00, 0x00, 0x00, 0x96,
135 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
136 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
137 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
138 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
139 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
140 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
141 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
142 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
143 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
144 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
145 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
146 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
147 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
148 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
149 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
150 0x00, 0x00, 0x02, 0x00, 0x79, 0x79, 0x79, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0xC0, 0xCC, 0xCC, 0xCC,
151 0xCC, 0xD7, 0x97, 0x97, 0x97, 0x97, 0x97, 0xC0, 0xC0, 0xC0, 0xC0, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
152 0xCD, 0xDB, 0xD9, 0x79, 0x79, 0x7E, 0x79, 0x0C, 0xDD, 0xCD, 0xDD, 0xCD, 0xCD, 0xDC, 0xDD, 0xCD,
153 0xCC, 0xED, 0xED, 0x97, 0x97, 0x97, 0x97, 0x0C, 0xE7, 0x78, 0x77, 0x97, 0x97, 0x97, 0x97, 0x97,
154 0xDC, 0xED, 0xDE, 0x79, 0x79, 0x79, 0x99, 0x0C, 0xD9, 0x7E, 0x5E, 0x65, 0x5E, 0x65, 0xD9, 0x79,
155 0xCD, 0xDE, 0xDD, 0x97, 0xE7, 0x9E, 0x77, 0xC0, 0x97, 0x9D, 0xCD, 0xCC, 0xC7, 0xCC, 0xE7, 0x97,
156 0xCC, 0xED, 0xEE, 0x79, 0x79, 0x79, 0x7E, 0xCC, 0x57, 0xD5, 0xD7, 0xD5, 0xDD, 0x5D, 0xD9, 0x7E,
157 0xCD, 0xDE, 0xDE, 0x79, 0x97, 0x97, 0x99, 0x0C, 0x87, 0xCD, 0x75, 0xC7, 0x5C, 0x7D, 0xD9, 0x79,
158 0xCD, 0xDD, 0xED, 0xE7, 0x7E, 0x79, 0x77, 0xCC, 0xE7, 0xB0, 0x00, 0xC0, 0x0C, 0xCD, 0xE7, 0x97,
159 0xDC, 0xED, 0xEE, 0x79, 0x97, 0x86, 0x79, 0xC0, 0xE7, 0xD0, 0x2C, 0xC1, 0xC2, 0xCD, 0xD9, 0x79,
160 0xCD, 0xDE, 0xDD, 0x97, 0x99, 0x79, 0x97, 0x0C, 0xE7, 0xB0, 0xD0, 0xDC, 0xCC, 0xCD, 0xD6, 0x87,
161 0xDD, 0xDE, 0xED, 0x79, 0x77, 0xE7, 0x79, 0x0C, 0x58, 0xDC, 0x0C, 0x0C, 0xCC, 0xCD, 0xE9, 0x79,
162 0xCD, 0xDD, 0xD5, 0x99, 0x97, 0x99, 0x79, 0xC0, 0x87, 0xD0, 0xC0, 0xC0, 0xC0, 0xCD, 0xD7, 0xE7,
163 0xDD, 0xDE, 0xD7, 0x97, 0x79, 0x77, 0xE7, 0x0C, 0xE7, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0x79, 0x79,
164 0xCD, 0xDE, 0xD9, 0x79, 0x97, 0xE9, 0x79, 0x0C, 0x97, 0x79, 0x79, 0x79, 0x79, 0x79, 0x97, 0x97,
165 0xDC, 0xED, 0xE7, 0x97, 0x79, 0x97, 0x97, 0x0C, 0xCD, 0xD7, 0xD7, 0xD7, 0xE7, 0xE7, 0x7E, 0x79,
166 0xCD, 0xDE, 0x79, 0x79, 0x97, 0x7E, 0x79, 0xC0, 0xCC, 0xCC, 0x0C, 0xCC, 0x0D, 0xCC, 0xDC, 0xDC,
167 0xDC, 0xED, 0x97, 0x97, 0x77, 0x99, 0x79, 0xCC, 0xCC, 0xCC, 0xDC, 0xCC, 0xDC, 0xCC, 0xCC, 0x8D,
168 0xCD, 0xDE, 0x79, 0x79, 0x96, 0x77, 0x97, 0x97, 0x97, 0x90, 0xCC, 0xCD, 0xCD, 0xDD, 0xDD, 0xCC,
169 0xDD, 0xD9, 0x76, 0x87, 0x97, 0x99, 0x7E, 0x7C, 0x0C, 0xCC, 0xDD, 0xDD, 0xED, 0xDE, 0xDD, 0xEE,
170 0xDE, 0xD5, 0xBD, 0xDE, 0x79, 0x79, 0x9C, 0xC0, 0xCC, 0xDD, 0xDD, 0xDD, 0xDE, 0xDD, 0xED, 0xDE,
171 0xDE, 0xDD, 0xDE, 0xDE, 0x79, 0x79, 0x70, 0xCD, 0xCC, 0xCC, 0xCC, 0xCC, 0xDC, 0xDD, 0xDD, 0xDD,
172 0xDD, 0xDD, 0xED, 0xED, 0x97, 0x97, 0x90, 0xCC, 0x8D, 0xCC, 0xDC, 0xCD, 0xCC, 0xCC, 0xCC, 0xCC,
173 0xCC, 0xEE, 0xDE, 0xDE, 0x79, 0x7E, 0x70, 0xCC, 0x88, 0xDC, 0xCC, 0xCC, 0xCD, 0xDD, 0xDD, 0xDC,
174 0xCD, 0xDD, 0xED, 0xED, 0x97, 0x97, 0xEC, 0xCC, 0xCC, 0xCC, 0xDC, 0xCC, 0xCD, 0xDD, 0xED, 0xDD,
175 0xDC, 0xED, 0xED, 0xEE, 0x79, 0x79, 0xDC, 0x0D, 0xCC, 0xDC, 0xCC, 0xCD, 0xCC, 0xCC, 0xCC, 0x0C,
176 0xDC, 0xDE, 0xDE, 0xED, 0x97, 0xDC, 0xCC, 0xDC, 0xCD, 0xCC, 0xDC, 0xCD, 0xCC, 0xCC, 0xCD, 0xCC,
177 0xCC, 0xED, 0xED, 0x79, 0xDD, 0xC0, 0xCD, 0xCC, 0xDC, 0xCD, 0xCC, 0xDC, 0xCC, 0xDC, 0xDD, 0xCD,
178 0xCD, 0xED, 0x97, 0x97, 0xDD, 0xCC, 0xCC, 0x00, 0xC0, 0xDD, 0xCD, 0xCC, 0xCC, 0xCD, 0xD0, 0xDC,
179 0xDD, 0xF7, 0x99, 0x79, 0x97, 0x9D, 0xDD, 0xDD, 0xCC, 0xC0, 0xCC, 0x0C, 0xDC, 0xDC, 0xCD, 0xCD,
180 0xDF, 0x79, 0x77, 0x97, 0x79, 0x79, 0x79, 0x79, 0xDD, 0xDE, 0xDC, 0xCC, 0xCC, 0xC0, 0xC0, 0xDD,
181 0xE9, 0x79, 0x97, 0x99, 0x97, 0xE7, 0xE7, 0x97, 0x97, 0x9D, 0x79, 0xDD, 0xDD, 0xDD, 0xCD, 0xDE,
182 0x79, 0x79, 0x7E, 0x77, 0x00, 0x00, 0x04, 0x00, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xF5, 0xF5,
183 0xF5, 0xF5, 0xF5, 0xF5, 0xF6, 0xF6, 0xF6, 0xF6, 0xF6, 0xF6, 0xF6, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B,
184 0x2B, 0x2B, 0xF9, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xF5, 0xF6,
185 0xF6, 0xF6, 0xF6, 0xF6, 0xF6, 0xF6, 0xF6, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0xF7, 0xF7, 0xF7,
186 0xF7, 0xF8, 0x81, 0xFA, 0xFA, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xF5, 0x2B,
187 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56,
188 0xF7, 0xF8, 0x81, 0x81, 0x81, 0xFA, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xF5, 0x2B,
189 0xA5, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2,
190 0xF8, 0xF8, 0x81, 0xFA, 0xFB, 0xFB, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xF5, 0x2B,
191 0xA5, 0xC2, 0xC2, 0xFB, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xFB, 0xC2, 0xC2, 0xC2,
192 0xF7, 0xF8, 0x81, 0x81, 0xFB, 0x81, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xF6, 0x2B,
193 0xA5, 0xC2, 0xC2, 0xFB, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x81, 0xC2, 0xC2, 0xC2,
194 0xF7, 0xF8, 0x81, 0x81, 0xFB, 0xFB, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xF6, 0x2B,
195 0xA5, 0xC2, 0xF9, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xF9, 0xFB, 0xC2, 0xC2, 0xC2,
196 0xF7, 0xF8, 0x81, 0x81, 0xFB, 0x81, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xF5, 0x2B,
197 0xA5, 0xC2, 0xF9, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0xF9, 0x81, 0xC2, 0xC2, 0xC2,
198 0xF8, 0x56, 0xFA, 0x81, 0x81, 0xFB, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xF5, 0x2B,
199 0xA5, 0xC2, 0xF9, 0xF5, 0xF5, 0xF5, 0xF6, 0xF6, 0xF6, 0xF6, 0x2B, 0xF9, 0xFB, 0xC2, 0xC2, 0xC2,
200 0xF8, 0x56, 0x81, 0x81, 0xFB, 0xFB, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xF5, 0x2B,
201 0xA5, 0xC2, 0xF9, 0xF5, 0x0A, 0xF6, 0x2B, 0x0A, 0xF6, 0x0A, 0x2B, 0xF9, 0x81, 0xC2, 0xC2, 0xC2,
202 0xF8, 0x56, 0x81, 0x81, 0x81, 0xFB, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xF5, 0x2B,
203 0xA5, 0xC2, 0xF9, 0xF5, 0xF8, 0xF6, 0x56, 0xF7, 0xF7, 0xF8, 0x2B, 0xF9, 0x81, 0xC2, 0xC2, 0xC2,
204 0xF8, 0x56, 0x81, 0x81, 0xFB, 0x81, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xF5, 0x2B,
205 0xA5, 0xC2, 0xF9, 0xF5, 0xF6, 0xF6, 0xF6, 0xF6, 0xF6, 0x2B, 0x2B, 0xF9, 0xFB, 0xC2, 0xC2, 0xC2,
206 0xF8, 0x56, 0xFA, 0x81, 0x81, 0xFB, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xF5, 0x2B,
207 0xA5, 0xC2, 0xF9, 0xF6, 0xF6, 0xF5, 0xF6, 0xF6, 0xF6, 0xF6, 0x2B, 0xF9, 0x81, 0xC2, 0xC2, 0xC2,
208 0xF8, 0x56, 0x81, 0x81, 0xFB, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xF5, 0x2B,
209 0xA5, 0xC2, 0xF9, 0xF9, 0xF9, 0xF9, 0xF9, 0xF9, 0xF9, 0xF9, 0xF9, 0xF9, 0xC2, 0xC2, 0xC2, 0xC2,
210 0xF8, 0x56, 0x81, 0x81, 0x81, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xF5, 0x2B,
211 0xA5, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2,
212 0xF8, 0x56, 0x81, 0x81, 0xFB, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xF5, 0x2B,
213 0xF7, 0x56, 0xF8, 0x7A, 0x7A, 0x9E, 0x9E, 0x9E, 0x9E, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2,
214 0xF8, 0x56, 0x81, 0xFA, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xF5, 0x2B,
215 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0xF7, 0xF7, 0xF8, 0xF8,
216 0xF8, 0x56, 0x81, 0x81, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xF7, 0xF7,
217 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0x56, 0xB9, 0xF8,
218 0xF8, 0x56, 0x81, 0x81, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2,
219 0xC2, 0xC2, 0xC2, 0xF6, 0x2B, 0x2B, 0xF7, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0xF8,
220 0xF8, 0x56, 0x81, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xF6,
221 0xF6, 0xF6, 0x2B, 0xF8, 0x56, 0xFA, 0xF9, 0x81, 0x81, 0x81, 0xFA, 0x81, 0x81, 0x81, 0xFB, 0x81,
222 0xFB, 0xFB, 0xFB, 0x81, 0xFA, 0xFA, 0xFA, 0x81, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xF6, 0xF6, 0xF6,
223 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0xFB,
224 0x81, 0xFB, 0xF9, 0xFA, 0xFA, 0xFB, 0x81, 0xFB, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xF5, 0x2B, 0xF7,
225 0xF8, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0xF8, 0xF8, 0x56, 0x56, 0xF9, 0xF9, 0xF9, 0xFA,
226 0xFA, 0xFA, 0xFA, 0x81, 0x81, 0xFB, 0x81, 0xFB, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xF5, 0x2B, 0xF7,
227 0x93, 0xA0, 0xF7, 0xF7, 0xF8, 0xF7, 0xF7, 0xF8, 0xF7, 0xF7, 0xF7, 0xF7, 0x2B, 0x2B, 0x2B, 0x2B,
228 0x2B, 0x2B, 0x81, 0xFB, 0x81, 0xFB, 0xFB, 0x81, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xF5, 0x2B, 0xF7,
229 0xA0, 0xA0, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0x56, 0x56, 0xF9, 0xF9, 0xF9, 0xF8, 0xF7,
230 0xF7, 0xF7, 0xFB, 0xFB, 0x81, 0xFB, 0x81, 0xFB, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xF5, 0x2B, 0xF7,
231 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF9, 0xF9, 0xFB, 0xFB, 0xFB, 0xF8, 0xF9,
232 0xF9, 0xF7, 0x81, 0xFB, 0xFB, 0x81, 0xFB, 0xFB, 0xC2, 0xC2, 0xC2, 0xC2, 0xF8, 0x2B, 0x2B, 0x56,
233 0x2B, 0x2B, 0xF9, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0xF8,
234 0xF8, 0xF7, 0xFB, 0xFB, 0x81, 0xFB, 0x81, 0xFB, 0xC2, 0xC2, 0xF8, 0xF8, 0xF6, 0xF6, 0xF9, 0xF8,
235 0x2B, 0xF9, 0xF8, 0x2B, 0xF9, 0x2B, 0x2B, 0xF9, 0x2B, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7,
236 0xF7, 0xF7, 0x81, 0xFB, 0x81, 0xFB, 0xC2, 0xC2, 0xF9, 0xF8, 0xF6, 0xF6, 0xF7, 0xF9, 0xF8, 0x2B,
237 0xF9, 0xF8, 0xF6, 0xF9, 0xF8, 0xF6, 0xF9, 0xF8, 0xF6, 0x2B, 0xF9, 0x2B, 0xF9, 0x56, 0x2B, 0xF9,
238 0x2B, 0xF9, 0xAC, 0xFB, 0xC2, 0xC2, 0xC2, 0xC2, 0xFA, 0xF9, 0xF8, 0x2B, 0x2B, 0x2B, 0xF5, 0xF5,
239 0xF5, 0xF5, 0xF9, 0xF8, 0xF6, 0xF9, 0xF8, 0xF6, 0x2B, 0xF8, 0x2B, 0xF9, 0x56, 0x2B, 0x56, 0x2B,
240 0x56, 0x81, 0xAC, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xFA, 0xFA, 0xFA, 0xF9, 0xF8,
241 0xF8, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0xF5, 0x2B, 0xF9, 0xF6, 0xF9, 0xF8, 0xF7, 0xF9, 0x2B, 0xF9,
242 0x81, 0xAC, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2,
243 0xFA, 0xFA, 0xFA, 0xFA, 0xF9, 0xF8, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0xF5, 0xF5, 0xF5, 0x56, 0x81,
244 0xAC, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2,
245 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xFA, 0xF9, 0xFA, 0xFA, 0xF9, 0xF9, 0xF8, 0xF8, 0x81, 0x81,
246 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0x00, 0x00, 0x01, 0x00, 0x03, 0xFF, 0xFF, 0xE0,
247 0x02, 0x00, 0x00, 0x38, 0x02, 0xFF, 0xFF, 0x3C, 0x02, 0xFF, 0xFF, 0x3C, 0x02, 0xFF, 0xFF, 0x3C,
248 0x02, 0xF0, 0x0F, 0x3C, 0x02, 0xFF, 0xFF, 0x3C, 0x02, 0xFF, 0xFF, 0x7C, 0x02, 0xE0, 0x1F, 0x7C,
249 0x02, 0xE0, 0x1F, 0x7C, 0x02, 0xE0, 0x1F, 0x7C, 0x02, 0xE0, 0x1F, 0x7C, 0x02, 0xE0, 0x1F, 0x78,
250 0x02, 0xFF, 0xFF, 0x78, 0x02, 0xFF, 0xFF, 0x78, 0x02, 0x1F, 0xFF, 0x70, 0x02, 0x00, 0x00, 0x70,
251 0x03, 0xFF, 0xFF, 0xF0, 0x00, 0x0F, 0xFF, 0xE0, 0x00, 0xFF, 0xFF, 0xFF, 0x01, 0x1F, 0xFF, 0xFF,
252 0x02, 0x00, 0x3F, 0xFF, 0x02, 0x40, 0x00, 0x3F, 0x02, 0xC0, 0x7C, 0x3F, 0x02, 0x00, 0x7D, 0xBF,
253 0x0F, 0x20, 0x00, 0x3F, 0x32, 0x49, 0x00, 0x3C, 0xC4, 0x92, 0x2D, 0x70, 0xE0, 0x24, 0x1A, 0xE0,
254 0x1F, 0x00, 0xA5, 0xC0, 0x00, 0xFC, 0x03, 0x80, 0x00, 0x03, 0xFF, 0x00, 0x03, 0xFF, 0xFF, 0xE0,
255 0x03, 0xFF, 0xFF, 0xF8, 0x03, 0xFF, 0xFF, 0xFC, 0x03, 0xFF, 0xFF, 0xFC, 0x03, 0xFF, 0xFF, 0xFC,
256 0x03, 0xFF, 0xFF, 0xFC, 0x03, 0xFF, 0xFF, 0xFC, 0x03, 0xFF, 0xFF, 0xFC, 0x03, 0xFF, 0xFF, 0xFC,
257 0x03, 0xFF, 0xFF, 0xFC, 0x03, 0xFF, 0xFF, 0xFC, 0x03, 0xFF, 0xFF, 0xFC, 0x03, 0xFF, 0xFF, 0xF8,
258 0x03, 0xFF, 0xFF, 0xF8, 0x03, 0xFF, 0xFF, 0xF8, 0x03, 0xFF, 0xFF, 0xF0, 0x03, 0xFF, 0xFF, 0xF0,
259 0x03, 0xFF, 0xFF, 0xF0, 0x00, 0x1F, 0xFF, 0xE0, 0x01, 0xFF, 0xFF, 0xFF, 0x07, 0xFF, 0xFF, 0xFF,
260 0x07, 0xFF, 0xFF, 0xFF, 0x07, 0xFF, 0xFF, 0xFF, 0x07, 0xFF, 0xFF, 0xFF, 0x07, 0xFF, 0xFF, 0xFF,
261 0x0F, 0xFF, 0xFF, 0xFF, 0x3F, 0xFF, 0xFF, 0xFC, 0xFF, 0xFF, 0xFF, 0xF0, 0xFF, 0xFF, 0xFF, 0xE0,
262 0x1F, 0xFF, 0xFF, 0xC0, 0x00, 0xFF, 0xFF, 0x80, 0x00, 0x03, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x40,
263 0x1F, 0xFC, 0x10, 0x06, 0x10, 0x06, 0x10, 0x06, 0x10, 0x06, 0x10, 0x06, 0x10, 0x06, 0x10, 0x04,
264 0x1F, 0xFC, 0x0F, 0xFE, 0x0F, 0xFF, 0x18, 0x67, 0x34, 0x06, 0x69, 0x64, 0x72, 0xC8, 0x3F, 0xF0,
265 0x1F, 0xFC, 0x1F, 0xFE, 0x1F, 0xFE, 0x1F, 0xFE, 0x1F, 0xFE, 0x1F, 0xFE, 0x1F, 0xFE, 0x1F, 0xFC,
266 0x1F, 0xFC, 0x07, 0xFF, 0x1F, 0xFF, 0x3F, 0xFF, 0x3F, 0xFF, 0x7F, 0xFE, 0xFF, 0xFC, 0x07, 0xF8,
267 0x00, 0x00, 0x00, 0x80, 0x79, 0x7C, 0x0C, 0x0C, 0xCC, 0xCC, 0xCD, 0x97, 0x97, 0x90, 0xE7, 0x97,
268 0x97, 0x97, 0xDD, 0xD9, 0x79, 0x7C, 0xE7, 0xD5, 0x5E, 0x58, 0xCE, 0xD7, 0x97, 0x9C, 0xDD, 0x5D,
269 0x7D, 0xB7, 0xDD, 0x59, 0x79, 0x7C, 0x9D, 0x10, 0x1D, 0xD9, 0xCE, 0xD7, 0x97, 0x9C, 0xDD, 0x0C,
270 0xCC, 0xE7, 0xDD, 0xD9, 0x79, 0x7C, 0xED, 0xDD, 0xDD, 0x79, 0xCE, 0xE7, 0xE7, 0x90, 0xE7, 0x77,
271 0x97, 0x97, 0xDD, 0x79, 0x79, 0x7C, 0xCC, 0xDC, 0xCD, 0xC8, 0xDD, 0x97, 0x97, 0x99, 0x7C, 0xDD,
272 0xDD, 0xDE, 0xDE, 0xDE, 0x7E, 0x7C, 0xCC, 0xCC, 0xCD, 0xCD, 0xDD, 0xDE, 0x99, 0x0C, 0x8C, 0xCC,
273 0xCC, 0xCC, 0xCD, 0xED, 0x77, 0xCC, 0xCC, 0xCD, 0xDD, 0xED, 0xCE, 0xDE, 0x9C, 0xCD, 0xCD, 0xCD,
274 0x0D, 0xCC, 0xCE, 0xE7, 0xDC, 0xDC, 0xDC, 0xDC, 0xDC, 0xCC, 0xDE, 0x99, 0x97, 0x97, 0x9D, 0xDD,
275 0xDD, 0xDE, 0xE9, 0x77, 0x00, 0x00, 0x01, 0x00, 0xC2, 0xC2, 0xC2, 0xF5, 0xF5, 0xF5, 0xF6, 0xF6,
276 0xF6, 0x2B, 0x2B, 0x2B, 0xF7, 0xFA, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xF6, 0xA5, 0xC2, 0xC2, 0xC2,
277 0xC2, 0xC2, 0xC2, 0xC2, 0xF8, 0x81, 0xFA, 0xC2, 0xC2, 0xC2, 0xC2, 0xF6, 0xA5, 0xC2, 0x81, 0xAA,
278 0xAA, 0xAA, 0xFB, 0xC2, 0xF8, 0x81, 0xFB, 0xC2, 0xC2, 0xC2, 0xC2, 0xF6, 0xA5, 0xF9, 0x7F, 0x7F,
279 0x7F, 0x56, 0x81, 0xC2, 0xF8, 0x81, 0x81, 0xC2, 0xC2, 0xC2, 0xC2, 0xF6, 0xA5, 0xF9, 0x0A, 0xF6,
280 0x0A, 0x56, 0xFB, 0xC2, 0xF8, 0x81, 0xFB, 0xC2, 0xC2, 0xC2, 0xC2, 0xF6, 0xA5, 0xF9, 0xF6, 0xF6,
281 0xF6, 0x56, 0x81, 0xC2, 0x56, 0x81, 0x81, 0xC2, 0xC2, 0xC2, 0xC2, 0xF6, 0xA5, 0xF9, 0xF9, 0xF9,
282 0xF9, 0xF9, 0xC2, 0xC2, 0xF8, 0x81, 0xFB, 0xC2, 0xC2, 0xC2, 0xC2, 0xF6, 0xA5, 0xC2, 0xC2, 0xC2,
283 0xC2, 0xC2, 0xC2, 0xC2, 0x56, 0xFA, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0x2B, 0x2B, 0x2B, 0xF7, 0xF7,
284 0xF7, 0xF7, 0xF7, 0xB9, 0x56, 0x81, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xF6, 0x56, 0xF9,
285 0xFA, 0xFA, 0xFB, 0xFB, 0xFB, 0x81, 0xFA, 0x81, 0xC2, 0xC2, 0xC2, 0xF6, 0xF6, 0xF7, 0x2B, 0x2B,
286 0x2B, 0xF8, 0xF8, 0xF8, 0xF9, 0xFA, 0x81, 0xFB, 0xC2, 0xC2, 0xF5, 0xF7, 0x93, 0xF7, 0xF7, 0xF7,
287 0xF7, 0x2B, 0x2B, 0x2B, 0x2B, 0xFB, 0x81, 0xFB, 0xC2, 0xC2, 0xF5, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7,
288 0xF9, 0xFB, 0xFB, 0xF9, 0xF7, 0xFB, 0x81, 0xFB, 0xC2, 0xF6, 0xF8, 0xF9, 0x2B, 0xF9, 0x2B, 0xF9,
289 0xF6, 0xF8, 0x2B, 0xF8, 0xF7, 0xFB, 0xFB, 0xC2, 0xF9, 0xF7, 0xF9, 0xF7, 0xF9, 0xF7, 0xF9, 0x2B,
290 0xF9, 0x2B, 0xF8, 0x2B, 0x81, 0xAC, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xF9, 0xF9, 0xF9,
291 0xF9, 0xF9, 0xF9, 0x81, 0xAC, 0xC2, 0xC2, 0xC2, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x09, 0xD8,
292 0x00, 0x00, 0x08, 0xD8, 0x00, 0x00, 0x00, 0x96, 0x02, 0x1C, 0xC1, 0xC4, 0x18, 0x9C, 0x00, 0x00,
293 0x00, 0x1C, 0x00, 0x96, 0x00, 0x05, 0x69, 0x63, 0x6C, 0x34, 0x00, 0x00, 0x00, 0x32, 0x69, 0x63,
294 0x6C, 0x38, 0x00, 0x00, 0x00, 0x3E, 0x49, 0x43, 0x4E, 0x23, 0x00, 0x00, 0x00, 0x4A, 0x69, 0x63,
295 0x73, 0x23, 0x00, 0x00, 0x00, 0x56, 0x69, 0x63, 0x73, 0x34, 0x00, 0x00, 0x00, 0x62, 0x69, 0x63,
296 0x73, 0x38, 0x00, 0x00, 0x00, 0x6E, 0xBF, 0xB9, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x02, 0x1C,
297 0xE2, 0x10, 0xBF, 0xB9, 0xFF, 0xFF, 0x00, 0x00, 0x02, 0x04, 0x02, 0x1C, 0xE1, 0xAC, 0xBF, 0xB9,
298 0xFF, 0xFF, 0x00, 0x00, 0x06, 0x08, 0x02, 0x1C, 0xE1, 0xA4, 0xBF, 0xB9, 0xFF, 0xFF, 0x00, 0x00,
299 0x07, 0x0C, 0x02, 0x1C, 0xE1, 0xF8, 0xBF, 0xB9, 0xFF, 0xFF, 0x00, 0x00, 0x07, 0x50, 0x02, 0x1C,
300 0xE1, 0xDC, 0xBF, 0xB9, 0xFF, 0xFF, 0x00, 0x00, 0x07, 0xD4, 0x02, 0x1C, 0xE1, 0xD0
301 };
302
303 static bool use_streams[ 'Z'-'A'+1 ];
304
305 static bool is_ntfs_volume( char *rootdir )
306 {
307 bool ret = false;
308 char tst_file[_MAX_PATH], tst_stream[_MAX_PATH];
309 sprintf( tst_file, "%sb2query.tmp", rootdir );
310 sprintf( tst_stream, "%s:AFP_AfpInfo", tst_file );
311 if(!exists(tst_file)) {
312 if(create_file( tst_file, 0 )) {
313 if(create_file( tst_stream, 0 )) {
314 ret = true;
315 }
316 DeleteFile( tst_file );
317 }
318 }
319 return ret;
320 }
321
322
323 // !!UNC
324 void init_posix_emu(void)
325 {
326 if(!validate_stat_struct) {
327 ErrorAlert( "Invalid struct my_stat -- edit posix_emu.h" );
328 QuitEmulator();
329 }
330
331 #if DEBUG_EXTFS
332 debug_extfs = PrefsFindInt16("debugextfs");
333
334 debug_extfs = DB_EXTFS_LOUD;
335
336 if(debug_extfs != DB_EXTFS_NONE) {
337 extfs_log_open( EXTFS_LOG_FILE_NAME );
338 }
339 #endif
340
341 // We cannot use ExtFS "RootPath" because of the virtual desktop.
342 if(PrefsFindBool("enableextfs")) {
343 PrefsReplaceString("extfs", "");
344 } else {
345 PrefsRemoveItem("extfs");
346 D(bug("extfs disabled by user\n"));
347 #if DEBUG_EXTFS
348 extfs_log_close();
349 #endif
350 return;
351 }
352
353 const char *extdrives = PrefsFindString("extdrives");
354
355 // Set up drive list.
356 int outinx = 0;
357 for( char letter = 'A'; letter <= 'Z'; letter++ ) {
358 if(extdrives && !strchr(extdrives,letter)) continue;
359 int i = (int)( letter - 'A' );
360 char rootdir[20];
361 wsprintf( rootdir, "%c:\\", letter );
362 use_streams[ letter - 'A' ] = false;
363 switch(GetDriveType(rootdir)) {
364 case DRIVE_FIXED:
365 case DRIVE_REMOTE:
366 case DRIVE_RAMDISK:
367 // TODO: NTFS AFP?
368 // fall
369 case DRIVE_REMOVABLE:
370 case DRIVE_CDROM:
371 if(outinx < sizeof(host_drive_list)) {
372 host_drive_list[outinx] = letter;
373 outinx += 2;
374 }
375 }
376 }
377
378 // Set up virtual desktop root.
379 // TODO: this should be customizable.
380 GetModuleFileName( NULL, virtual_root, sizeof(virtual_root) );
381 char *p = strrchr( virtual_root, '\\' );
382 if(p) {
383 *(++p) = 0;
384 strcat( virtual_root, desktop_name );
385 } else {
386 // should never happen
387 sprintf( virtual_root, "C:\\%s", desktop_name );
388 }
389 CreateDirectory( virtual_root, 0 );
390
391 // Set up an icon looking like "My Computer"
392 // Can be overwritten just like any other folder custom icon.
393 if(my_access(custom_icon_name,0) != 0) {
394 int fd = my_creat( custom_icon_name, 0 );
395 if(fd >= 0) {
396 my_close(fd);
397 fd = open_rfork( custom_icon_name, O_RDWR|O_CREAT );
398 if(fd >= 0) {
399 my_write( fd, my_comp_icon, sizeof(my_comp_icon) );
400 my_close(fd);
401 static uint8 host_finfo[SIZEOF_FInfo];
402 uint32 finfo = Host2MacAddr(host_finfo);
403 get_finfo(custom_icon_name, finfo, 0, false);
404 WriteMacInt16(finfo + fdFlags, kIsInvisible);
405 set_finfo(custom_icon_name, finfo, 0, false);
406 get_finfo(my_computer, finfo, 0, true);
407 WriteMacInt16(finfo + fdFlags, ReadMacInt16(finfo + fdFlags) | kHasCustomIcon);
408 set_finfo(my_computer, finfo, 0, true);
409 } else {
410 my_remove(custom_icon_name);
411 }
412 }
413 }
414 }
415
416 void final_posix_emu(void)
417 {
418 #if DEBUG_EXTFS
419 extfs_log_close();
420 #endif
421 }
422
423 static void charset_host2mac( char *s )
424 {
425 int i, len=strlen(s), code;
426
427 for( i=len-3; i>=0; i-- ) {
428 if( s[i] == '%' && isxdigit(s[i+1]) && isxdigit(s[i+2]) ) {
429 sscanf( &s[i], "%%%02X", &code );
430 memmove( &s[i], &s[i+2], strlen(&s[i+2])+1 );
431 s[i] = code;
432 }
433 }
434 }
435
436 static void charset_mac2host( char *s )
437 {
438 int i, convert, len = strlen(s);
439
440 D(bug("charset_mac2host(%s)...\n", s));
441
442 for( i=len-1; i>=0; i-- ) {
443 convert = 0;
444 switch( (unsigned char)s[i] ) {
445 // case '\r': // handled by "default"
446 // case '\n':
447 // case '\t':
448 case '/':
449 // case '\\': // Backslash is tricky -- "s" is a full path!
450 // case ':':
451 case '*':
452 case '?':
453 case '"':
454 case '<':
455 case '>':
456 case '|':
457 case '%':
458 convert = 1;
459 break;
460 default:
461 if((unsigned char)s[i] < ' ') convert = 1;
462 break;
463 }
464 if(convert) {
465 char sml[10];
466 sprintf( sml, "%%%02X", s[i] );
467 memmove( &s[i+2], &s[i], strlen(&s[i])+1 );
468 memmove( &s[i], sml, 3 );
469 }
470 }
471 D(bug("charset_mac2host = %s\n", s));
472 }
473
474 static void make_mask(
475 char *mask,
476 const char *dir,
477 const char *a1,
478 const char *a2
479 )
480 {
481 strcpy( mask, dir );
482
483 int len = strlen(mask);
484 if( len && mask[len-1] != '\\' ) strcat( mask, "\\" );
485
486 if( a1 ) strcat( mask, a1 );
487 if( a2 ) strcat( mask, a2 );
488 }
489
490 // !!UNC
491 static char *translate( const char *path, char *buffer )
492 {
493 char *l = host_drive_list;
494 char *p = (char *)path;
495
496 while(*l) {
497 if(toupper(p[1]) == toupper(*l)) break;
498 l += strlen(l) + 1;
499 }
500
501 if(p[0] == '\\' && *l && (p[2] == 0 || p[2] == ':' || p[2] == '\\')) {
502 p += 2;
503 if(*p == ':') p++;
504 if(*p == '\\') p++;
505 sprintf( buffer, "%c:\\%s", *l, p );
506 } else {
507 if(*path == '\\') {
508 sprintf( buffer, "%s%s", virtual_root, path );
509 } else {
510 int len = strlen(path);
511 if(len == 0 || path[len-1] == '\\') {
512 make_mask( buffer, virtual_root, path, my_computer );
513 } else {
514 make_mask( buffer, virtual_root, path, 0 );
515 }
516 }
517 }
518 charset_mac2host( buffer );
519
520 return buffer;
521 }
522
523 // helpers
524 static void strip_trailing_bs( char *path )
525 {
526 int len = strlen(path);
527 if(len > 0 && path[len-1] == '\\') path[len-1] = 0;
528 }
529
530 #if 0 /* defined is util_windows.cpp */
531 static int exists( const char *p )
532 {
533 WIN32_FIND_DATA fdata;
534
535 int result = 0;
536
537 HANDLE h = FindFirstFile( p, &fdata );
538 if(h != INVALID_HANDLE_VALUE) {
539 result = 1;
540 FindClose( h );
541 }
542
543 D(bug("exists(%s) = %d\n", p, result));
544
545 return result;
546 }
547 #endif
548
549 static int is_dir( char *p )
550 {
551 WIN32_FIND_DATA fdata;
552
553 int result = 0;
554
555 HANDLE h = FindFirstFile( p, &fdata );
556 if(h != INVALID_HANDLE_VALUE) {
557 result = (fdata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0;
558 FindClose( h );
559 }
560 return result;
561 }
562
563 static int myRemoveDirectory( const char *source )
564 {
565 HANDLE fh;
566 WIN32_FIND_DATA FindFileData;
567 int ok, result = 1;
568 char mask[_MAX_PATH];
569
570 D(bug("removing folder %s\n", source));
571
572 make_mask( mask, source, "*.*", 0 );
573
574 fh = FindFirstFile( mask, &FindFileData );
575 ok = fh != INVALID_HANDLE_VALUE;
576 while(ok) {
577 make_mask( mask, source, FindFileData.cFileName, 0 );
578 D(bug("removing item %s\n", mask));
579 int isdir = (FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0;
580 if(isdir) {
581 // must delete ".finf", ".rsrc" but not ".", ".."
582 if(strcmp(FindFileData.cFileName,".") && strcmp(FindFileData.cFileName,"..")) {
583 result = myRemoveDirectory( mask );
584 if(!result) break;
585 }
586 } else {
587 D(bug("DeleteFile %s\n", mask));
588 result = DeleteFile( mask );
589 if(!result) break;
590 }
591 ok = FindNextFile( fh, &FindFileData );
592 }
593 if(fh != INVALID_HANDLE_VALUE) FindClose( fh );
594 if(result) {
595 D(bug("RemoveDirectory %s\n", source));
596 result = RemoveDirectory( source );
597 }
598 return result;
599 }
600
601 static void make_folders( char *path )
602 {
603 char local_path[_MAX_PATH], *p;
604 strcpy( local_path, path );
605 p = strrchr( local_path, '\\' );
606 if(p) {
607 *p = 0;
608 if(strlen(local_path) > 3) {
609 make_folders(local_path);
610 mkdir(local_path);
611 }
612 }
613 }
614
615 // !!UNC
616 static bool is_same_drive( char *p1, char *p2 )
617 {
618 return toupper(*p1) == toupper(*p2);
619 }
620
621 // Used when the drives are known to be different.
622 // Can't use MoveFileEx() etc because of the Win9x limitations.
623 // It would simulate CopyFile*() -- DeleteFile*() anyway
624 int file_move_copy( char *src, char *dst, bool delete_old )
625 {
626 int result = 0;
627 my_errno = 0;
628
629 D(bug("file_copy %s -> %s\n", src, dst));
630
631 // Fail if exists -- it's up to MacOS to move things to Trash
632 if(CopyFile(src,dst,TRUE)) {
633 if(delete_old && !DeleteFile(src)) {
634 result = -1;
635 my_errno = EACCES;
636 }
637 } else {
638 result = -1;
639 if(exists(src))
640 my_errno = EACCES;
641 else
642 my_errno = ENOENT;
643 }
644 return result;
645 }
646
647 int file_move( char *src, char *dst )
648 {
649 return file_move_copy( src, dst, true );
650 }
651
652 int file_copy( char *src, char *dst )
653 {
654 return file_move_copy( src, dst, false );
655 }
656
657 int folder_copy( char *folder_src, char *folder_dst )
658 {
659 HANDLE fh;
660 WIN32_FIND_DATA FindFileData;
661 int ok, result = 0;
662 char mask[_MAX_PATH];
663
664 D(bug("copying folder %s -> \n", folder_src, folder_dst));
665
666 my_errno = 0;
667
668 if(!CreateDirectory( folder_dst, 0 )) {
669 my_errno = EACCES;
670 return -1;
671 }
672
673 make_mask( mask, folder_src, "*.*", 0 );
674
675 fh = FindFirstFile( mask, &FindFileData );
676 ok = fh != INVALID_HANDLE_VALUE;
677 while(ok) {
678 make_mask( mask, folder_src, FindFileData.cFileName, 0 );
679 int isdir = (FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0;
680 char target[_MAX_PATH];
681 make_mask( target, folder_dst, FindFileData.cFileName, 0 );
682 D(bug("copying item %s -> %s\n", mask, target));
683 if(isdir) {
684 if(strcmp(FindFileData.cFileName,".") && strcmp(FindFileData.cFileName,"..")) {
685 result = folder_copy( mask, target );
686 if(result < 0) break;
687 }
688 } else {
689 result = file_copy( mask, target );
690 if(result < 0) break;
691 }
692 ok = FindNextFile( fh, &FindFileData );
693 }
694 if(fh != INVALID_HANDLE_VALUE) FindClose( fh );
695 return result;
696 }
697
698 // dir enumeration
699 void closedir( struct DIR *d )
700 {
701 DISABLE_ERRORS;
702 if(d) {
703 if(d->h != INVALID_HANDLE_VALUE && d->h != VIRTUAL_ROOT_ID) {
704 FindClose( d->h );
705 }
706 delete d;
707 }
708 RESTORE_ERRORS;
709 }
710
711 static int make_dentry( struct DIR *d )
712 {
713 int ok = 0;
714
715 memset( &d->de, 0, sizeof(d->de) );
716 if(d->h != INVALID_HANDLE_VALUE) {
717 if( (d->FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0 &&
718 *d->FindFileData.cFileName == '.')
719 {
720 ok = 0;
721 } else {
722 strncpy( d->de.d_name, d->FindFileData.cFileName, sizeof(d->de.d_name)-1 );
723 d->de.d_name[sizeof(d->de.d_name)-1] = 0;
724 charset_host2mac( d->de.d_name );
725 ok = 1;
726 }
727 }
728 return ok;
729 }
730
731 struct dirent *readdir( struct DIR *d )
732 {
733 DISABLE_ERRORS;
734
735 dirent *de = 0;
736
737 if(d) {
738 if(d->h != INVALID_HANDLE_VALUE) {
739 if(d->h == VIRTUAL_ROOT_ID) {
740 make_dentry(d);
741 de = &d->de;
742 d->vname_list += strlen(d->vname_list) + 1;
743 if(*d->vname_list) {
744 strcpy( d->FindFileData.cFileName, d->vname_list );
745 d->FindFileData.dwFileAttributes = FILE_ATTRIBUTE_DIRECTORY;
746 } else {
747 // Out of static drive entries. Continue with other stuff.
748 char mask[MAX_PATH_LENGTH];
749 make_mask( mask, virtual_root, "*.*", 0 );
750 d->h = FindFirstFile( mask, &d->FindFileData );
751 }
752 } else {
753 int done = 0;
754 do {
755 if(make_dentry(d)) {
756 de = &d->de;
757 done = 1;
758 }
759 if(!FindNextFile( d->h, &d->FindFileData )) {
760 FindClose( d->h );
761 d->h = INVALID_HANDLE_VALUE;
762 done = 1;
763 }
764 } while(!done);
765 }
766 }
767 }
768
769 if(de) {
770 D(bug("readdir found %s\n", de->d_name));
771 }
772
773 RESTORE_ERRORS;
774
775 return de;
776 }
777
778 struct DIR *opendir( const char *path )
779 {
780 DISABLE_ERRORS;
781 DIR *d = new DIR;
782 if(d) {
783 memset( d, 0, sizeof(DIR) );
784 if(*path == 0) {
785 d->vname_list = host_drive_list;
786 if(d->vname_list) {
787 d->h = VIRTUAL_ROOT_ID;
788 strcpy( d->FindFileData.cFileName, d->vname_list );
789 d->FindFileData.dwFileAttributes = FILE_ATTRIBUTE_DIRECTORY;
790 } else {
791 d->h = INVALID_HANDLE_VALUE;
792 }
793 } else {
794 char mask[MAX_PATH_LENGTH];
795 make_mask( mask, MRP(path), "*.*", 0 );
796
797 D(bug("opendir path=%s, mask=%s\n", path, mask));
798
799 d->h = FindFirstFile( mask, &d->FindFileData );
800 if(d->h == INVALID_HANDLE_VALUE) {
801 delete d;
802 d = 0;
803 }
804 }
805 }
806
807 D(bug("opendir(%s,%s) = %08x\n", path, MRP(path), d));
808
809 RESTORE_ERRORS;
810
811 return d;
812 }
813
814 static void dump_stat( const struct my_stat *st )
815 {
816 D(bug("stat: size = %ld, mode = %ld, a = %ld, m = %ld, c = %ld\n", st->st_size, st->st_mode, st->st_atime, st->st_mtime, st->st_ctime));
817 }
818
819
820
821 // Exported hook functions
822 int my_stat( const char *path, struct my_stat *st )
823 {
824 DISABLE_ERRORS;
825
826 int result;
827
828 if(*path == 0) {
829 /// virtual root
830 memset( st, 0, sizeof(struct my_stat) );
831 st->st_mode = _S_IFDIR;
832 result = 0;
833 my_errno = 0;
834 } else {
835 result = stat( MRP(path), (struct stat *)st );
836 if(result < 0) {
837 my_errno = errno;
838 } else {
839 my_errno = 0;
840 }
841 }
842
843 D(bug("stat(%s,%s) = %d\n", path, MRP(path), result));
844 if(result >= 0) dump_stat( st );
845 RESTORE_ERRORS;
846 return result;
847 }
848
849 int my_fstat( int fd, struct my_stat *st )
850 {
851 DISABLE_ERRORS;
852 int result = fstat( fd, (struct stat *)st );
853 if(result < 0) {
854 my_errno = errno;
855 } else {
856 my_errno = 0;
857 }
858 D(bug("fstat(%d) = %d\n", fd, result));
859 if(result >= 0) dump_stat( st );
860 RESTORE_ERRORS;
861 return result;
862 }
863
864 int my_open( const char *path, int mode, ... )
865 {
866 DISABLE_ERRORS;
867 int result;
868 char *p = MRP(path);
869
870 // Windows "open" does not handle _O_CREAT and _O_BINARY as it should
871 if(mode & _O_CREAT) {
872 if(exists(p)) {
873 result = open( p, mode & ~_O_CREAT );
874 D(bug("open-nocreat(%s,%s,%d) = %d\n", path, p, mode, result));
875 } else {
876 result = creat( p, _S_IWRITE|_S_IREAD );
877 if(result < 0) {
878 make_folders(p);
879 result = creat( p, _S_IWRITE|_S_IREAD );
880 }
881 D(bug("open-creat(%s,%s,%d) = %d\n", path, p, mode, result));
882 }
883 } else {
884 result = open( p, mode );
885 D(bug("open(%s,%s,%d) = %d\n", path, p, mode, result));
886 }
887 if(result < 0) {
888 my_errno = errno;
889 } else {
890 setmode(result, _O_BINARY);
891 my_errno = 0;
892 }
893 RESTORE_ERRORS;
894 return result;
895 }
896
897 int my_rename( const char *old_path, const char *new_path )
898 {
899 DISABLE_ERRORS;
900 int result = -1;
901 char *p_old = MRP(old_path);
902 char *p_new = MRP2(new_path);
903
904 result = my_access(old_path,0);
905 if(result < 0) {
906 // my_errno already set
907 } else {
908 if(is_same_drive(p_old,p_new)) {
909 result = rename( p_old, p_new );
910 if(result != 0) { // by definition, rename may also return a positive value to indicate an error
911 my_errno = errno;
912 } else {
913 my_errno = 0;
914 }
915 } else {
916 if(is_dir(p_old)) {
917 result = folder_copy( p_old, p_new );
918 // my_errno already set
919 if(result >= 0) {
920 if(myRemoveDirectory( p_old )) {
921 my_errno = 0;
922 result = 0;
923 } else {
924 // there is no proper error code for this failure.
925 my_errno = EACCES;
926 result = -1;
927 }
928 }
929 } else {
930 result = file_move( p_old, p_new );
931 // my_errno already set
932 }
933 }
934 }
935 D(bug("rename(%s,%s,%s,%s) = %d\n", old_path, p_old, new_path, p_new, result));
936 RESTORE_ERRORS;
937 return result;
938 }
939
940 int my_access( const char *path, int mode )
941 {
942 DISABLE_ERRORS;
943 char *p = MRP(path);
944 WIN32_FIND_DATA fdata;
945
946 int result;
947
948 if(is_dir(p)) {
949 // access does not work for folders.
950 HANDLE h = FindFirstFile( p, &fdata );
951 if(h != INVALID_HANDLE_VALUE) {
952 FindClose( h );
953 if(mode == W_OK) {
954 if( (fdata.dwFileAttributes & FILE_ATTRIBUTE_READONLY) == 0 ) {
955 result = 0;
956 my_errno = 0;
957 } else {
958 result = -1;
959 my_errno = EACCES;
960 }
961 } else {
962 result = 0;
963 my_errno = 0;
964 }
965 } else {
966 result = -1;
967 my_errno = ENOENT;
968 }
969 } else {
970 // W_OK, F_OK are ok.
971 result = access(p,mode);
972 if(result < 0) {
973 my_errno = errno;
974 } else {
975 my_errno = 0;
976 }
977 }
978
979 D(bug("access(%s,%s,%d) = %d\n", path, MRP(path), mode, result));
980 RESTORE_ERRORS;
981 return result;
982 }
983
984 int my_mkdir( const char *path, int mode )
985 {
986 DISABLE_ERRORS;
987 char *p = MRP(path);
988 strip_trailing_bs(p);
989 int result = mkdir( p );
990 if(result < 0) {
991 make_folders(p);
992 result = mkdir( p );
993 }
994 if(result < 0) {
995 my_errno = errno;
996 } else {
997 my_errno = 0;
998 }
999 D(bug("mkdir(%s,%s,%d) = %d\n", path, p, mode, result));
1000 RESTORE_ERRORS;
1001 return result;
1002 }
1003
1004 int my_remove( const char *path )
1005 {
1006 DISABLE_ERRORS;
1007 char *p = MRP(path);
1008 strip_trailing_bs(p);
1009 int result;
1010 if(is_dir(p)) {
1011 result = myRemoveDirectory( p );
1012 } else {
1013 D(bug("DeleteFile %s\n", p));
1014 result = DeleteFile( p );
1015 }
1016 if(result) {
1017 result = 0;
1018 my_errno = 0;
1019 } else {
1020 result = -1;
1021 if(exists(p)) {
1022 my_errno = EACCES;
1023 } else {
1024 my_errno = ENOENT;
1025 }
1026 }
1027 D(bug("remove(%s,%s) = %d\n", path, p, result));
1028 RESTORE_ERRORS;
1029 return result;
1030 }
1031
1032 int my_creat( const char *path, int mode )
1033 {
1034 DISABLE_ERRORS;
1035 char *p = MRP(path);
1036 int result = creat( p, _S_IWRITE|_S_IREAD ); // note mode
1037 if(result < 0) {
1038 make_folders(p);
1039 result = creat( p, _S_IWRITE|_S_IREAD ); // note mode
1040 }
1041 if(result < 0) {
1042 my_errno = errno;
1043 } else {
1044 setmode(result, _O_BINARY);
1045 my_errno = 0;
1046 }
1047 D(bug("creat(%s,%s,%d) = %d\n", path, p, mode,result));
1048 RESTORE_ERRORS;
1049 return result;
1050 }
1051
1052 int my_chsize( int fd, size_t sz )
1053 {
1054 DISABLE_ERRORS;
1055 int result = chsize(fd,sz);
1056 if(result < 0) {
1057 my_errno = errno;
1058 } else {
1059 my_errno = 0;
1060 }
1061 RESTORE_ERRORS;
1062 return result;
1063 }
1064
1065 int my_close( int fd )
1066 {
1067 DISABLE_ERRORS;
1068 int result = close(fd);
1069 if(result < 0) {
1070 my_errno = errno;
1071 } else {
1072 my_errno = 0;
1073 }
1074 RESTORE_ERRORS;
1075 D(bug("close(%d) = %d\n", fd, result));
1076 return result;
1077 }
1078
1079 long my_lseek( int fd, long offset, int origin )
1080 {
1081 DISABLE_ERRORS;
1082 int result = lseek( fd, offset, origin );
1083 if(result < 0) {
1084 my_errno = errno;
1085 } else {
1086 my_errno = 0;
1087 }
1088 RESTORE_ERRORS;
1089 return result;
1090 }
1091
1092 int my_read( int fd, void *buffer, unsigned int count )
1093 {
1094 DISABLE_ERRORS;
1095 int result = read( fd, buffer, count );
1096 if(result < 0) {
1097 my_errno = errno;
1098 } else {
1099 my_errno = 0;
1100 }
1101 RESTORE_ERRORS;
1102 D(bug("read(%ld,%08x,%ld) = %d\n", fd, buffer, count, result));
1103
1104 return result;
1105 }
1106
1107 int my_write( int fd, const void *buffer, unsigned int count )
1108 {
1109 DISABLE_ERRORS;
1110 int result = write( fd, buffer, count );
1111 if(result < 0) {
1112 my_errno = errno;
1113 } else {
1114 my_errno = 0;
1115 }
1116 RESTORE_ERRORS;
1117 D(bug("write(%ld,%08x,%ld) = %d\n", fd, buffer, count, result));
1118 return result;
1119 }