Changeset 9011 for trunk/src/kernel32/Fileio.cpp
- Timestamp:
- Aug 16, 2002, 11:56:30 AM (23 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/kernel32/Fileio.cpp
r8675 r9011 1 /* $Id: Fileio.cpp,v 1.6 6 2002-06-15 11:27:03sandervl Exp $ */1 /* $Id: Fileio.cpp,v 1.67 2002-08-16 09:56:30 sandervl Exp $ */ 2 2 3 3 /* … … 7 7 * Copyright 1998 Patrick Haller 8 8 * 9 * Some parts copied from Wine (CopyFileExA/W, FindFirstFileExW) 9 * Some parts based on Wine code (CopyFileExA/W, FindFirstFileExW, 10 * GetShortPathNameA/W, GetLongPathNameA/W) 10 11 * 11 12 * Copyright 1993 John Burton … … 42 43 #include <ctype.h> 43 44 #include "fileio.h" 44 45 #if 0 46 #define IS_END_OF_NAME(ch) (!(ch) || ((ch) == '/') || ((ch) == '\\')) 47 #define INVALID_DOS_CHARS "*?<>|\"+=,;[] \345" 48 #define FILE_toupper(a) toupper(a) 49 #define FILE_tolower(a) tolower(a) 45 #include <win/file.h> 46 50 47 51 48 /*********************************************************************** 52 49 * DOSFS_ValidDOSName 53 50 * 54 * Return 1 if Unixfile 'name' is also a valid MS-DOS name51 * Return 1 if OS/2 file 'name' is also a valid MS-DOS name 55 52 * (i.e. contains only valid DOS chars, lower-case only, fits in 8.3 format). 56 53 * File name can be terminated by '\0', '\\' or '/'. … … 58 55 static int DOSFS_ValidDOSName( const char *name, int ignore_case ) 59 56 { 60 static const char invalid_chars[] = INVALID_DOS_CHARS;57 static const char invalid_chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" INVALID_DOS_CHARS; 61 58 const char *p = name; 62 59 const char *invalid = ignore_case ? (invalid_chars + 26) : invalid_chars; … … 95 92 * DOSFS_Hash 96 93 * 97 * Transform a Unixfile name into a hashed DOS name. If the name is a valid94 * Transform an OS/2 file name into a hashed DOS name. If the name is a valid 98 95 * DOS name, it is converted to upper-case; otherwise it is replaced by a 99 96 * hashed version that fits in 8.3 format. … … 101 98 * 'buffer' must be at least 13 characters long. 102 99 */ 103 void DOSFS_Hash( LPCSTR name, LPSTR buffer, BOOL dir_format, 104 BOOL ignore_case ) 100 101 static void DOSFS_Hash( LPCSTR name, LPSTR buffer, BOOL dir_format, 102 BOOL ignore_case ) 105 103 { 106 104 static const char invalid_chars[] = INVALID_DOS_CHARS "~."; … … 185 183 if (!dir_format) *dst = '\0'; 186 184 } 187 #endif 185 188 186 //****************************************************************************** 189 187 //****************************************************************************** … … 632 630 BOOL rc; 633 631 632 #if 0 633 if((strstr(lpszFile, "odin32_") || strstr(lpszFile, "pe_")) && strstr(lpszFile, ".log")) { 634 return TRUE; 635 } 636 #endif 634 637 rc = OSLibDosDelete((LPSTR)lpszFile); 635 638 if(!rc) { 636 639 dprintf(("DeleteFileA %s returned FALSE; last error %x", lpszFile, GetLastError())); 637 if(GetLastError() == 20) {638 return TRUE;639 }640 if(GetLastError() == ERROR_BAD_UNIT) { 641 return TRUE; 642 } 640 643 } 641 644 else dprintf(("DeleteFileA %s", lpszFile)); … … 1179 1182 DWORD cchBuffer) 1180 1183 { 1181 int length; 1182 1183 dprintf(("KERNEL32: GetShortPathNameA of %s, just copying it", lpszLongPath)); 1184 char short_name[MAX_PATHNAME_LEN]; /* Long pathname in Unix format */ 1185 int length, marker = 0; 1186 LPSTR tmpshortpath,tmplongpath; 1187 DWORD attr, sp = 0, lp = 0; 1188 int tmplen, drive; 1189 1190 dprintf(("KERNEL32: GetShortPathNameA %s", lpszLongPath)); 1184 1191 1185 1192 if(!lpszLongPath) { … … 1187 1194 return 0; 1188 1195 } 1189 1190 length = lstrlenA(lpszLongPath) + 1; 1191 if(length > cchBuffer) { 1192 if(lpszShortPath) { 1193 *lpszShortPath = 0; 1196 if (!lpszLongPath[0]) { 1197 SetLastError(ERROR_BAD_PATHNAME); 1198 return 0; 1199 } 1200 1201 if ( ( tmpshortpath = (char*) HeapAlloc ( GetProcessHeap(), 0, MAX_PATHNAME_LEN ) ) == NULL ) { 1202 SetLastError ( ERROR_NOT_ENOUGH_MEMORY ); 1203 return 0; 1204 } 1205 1206 if ( ( tmplongpath = (char*) HeapAlloc ( GetProcessHeap(), 0, MAX_PATHNAME_LEN ) ) == NULL ) { 1207 SetLastError ( ERROR_NOT_ENOUGH_MEMORY ); 1208 return 0; 1209 } 1210 1211 lstrcpyA(tmplongpath,lpszLongPath); 1212 1213 /* check for drive letter */ 1214 if ( lpszLongPath[1] == ':' ) { 1215 tmpshortpath[0] = lpszLongPath[0]; 1216 tmpshortpath[1] = ':'; 1217 sp = 2; 1218 lp = 2; 1219 } 1220 1221 //todo: check drive validity! 1222 1223 while ( lpszLongPath[lp] ) { 1224 marker = 0; 1225 /* check for path delimiters and reproduce them */ 1226 if ( lpszLongPath[lp] == '\\' || lpszLongPath[lp] == '/' ) { 1227 if (!sp || tmpshortpath[sp-1]!= '\\') 1228 { 1229 /* strip double "\\" */ 1230 tmpshortpath[sp] = '\\'; 1231 sp++; 1232 } 1233 tmpshortpath[sp]=0;/*terminate string*/ 1234 lp++; 1235 continue; 1194 1236 } 1195 return(length); //return length required (including 0 terminator) 1196 } 1197 lstrcpyA(lpszShortPath, lpszLongPath); 1198 return(length-1); 1237 1238 tmplen = strcspn ( lpszLongPath + lp, "\\/" ); 1239 lstrcpynA ( tmpshortpath+sp, lpszLongPath + lp, tmplen+1 ); 1240 1241 /* Check, if the current element is a valid dos name */ 1242 if ( DOSFS_ValidDOSName ( lpszLongPath + lp, TRUE ) ) { 1243 sp += tmplen; 1244 lp += tmplen; 1245 continue; 1246 } 1247 1248 if (tmplongpath[lp + tmplen] == '\\') 1249 { 1250 tmplongpath[lp + tmplen] = 0; 1251 marker = 1; 1252 } 1253 1254 attr = GetFileAttributesA(tmplongpath); 1255 1256 if (attr == -1) 1257 { 1258 SetLastError ( ERROR_FILE_NOT_FOUND ); 1259 HeapFree ( GetProcessHeap(), 0, tmpshortpath ); 1260 HeapFree ( GetProcessHeap(), 0, tmplongpath ); 1261 return 0; 1262 } 1263 1264 DOSFS_Hash(tmpshortpath+sp, short_name, FALSE, TRUE ); 1265 1266 strcpy( tmpshortpath+sp, short_name); 1267 sp += strlen ( tmpshortpath+sp ); 1268 if (marker) 1269 tmplongpath[lp + tmplen] = '\\'; 1270 lp += tmplen; 1271 1272 } 1273 1274 tmpshortpath[sp] = 0; 1275 1276 lstrcpynA ( lpszShortPath, tmpshortpath, cchBuffer ); 1277 dprintf(("returning %s\n", lpszShortPath)); 1278 tmplen = strlen ( lpszShortPath ); 1279 1280 HeapFree ( GetProcessHeap(), 0, tmpshortpath ); 1281 HeapFree ( GetProcessHeap(), 0, tmplongpath ); 1282 1283 return tmplen; 1199 1284 } 1200 1285 //****************************************************************************** … … 1203 1288 DWORD cchBuffer) 1204 1289 { 1205 int length; 1206 1207 dprintf(("KERNEL32: GetShortPathNameW; just copying it")); 1208 if(!lpszLongPath) { 1209 SetLastError(ERROR_INVALID_PARAMETER); 1210 return 0; 1211 } 1212 1213 length = lstrlenW(lpszLongPath) + 1; 1214 if(length > cchBuffer) { 1215 if(lpszShortPath) { 1216 *lpszShortPath = 0; 1217 } 1218 return(length); //return length required (including 0 terminator) 1219 } 1220 lstrcpyW(lpszShortPath, lpszLongPath); 1221 return(length-1); 1290 LPSTR longpathA, shortpathA; 1291 DWORD ret = 0; 1292 1293 longpathA = HEAP_strdupWtoA( GetProcessHeap(), 0, lpszLongPath ); 1294 shortpathA = (LPSTR) HeapAlloc ( GetProcessHeap(), 0, cchBuffer ); 1295 1296 ret = GetShortPathNameA ( longpathA, shortpathA, cchBuffer ); 1297 if (cchBuffer > 0 && !MultiByteToWideChar( CP_ACP, 0, shortpathA, -1, lpszShortPath, cchBuffer )) 1298 lpszShortPath[cchBuffer-1] = 0; 1299 HeapFree( GetProcessHeap(), 0, longpathA ); 1300 HeapFree( GetProcessHeap(), 0, shortpathA ); 1301 1302 return ret; 1222 1303 } 1223 1304 //****************************************************************************** … … 1234 1315 DWORD cchBuffer ) 1235 1316 { 1236 int length; 1237 1238 dprintf(("GetLongPathNameA %x %s %d", lpszShortPath, lpszLongPath, cchBuffer)); 1239 dprintf(("WARNING: WIN98 ONLY!!")); 1317 int tmplen; 1318 char short_name[MAX_PATHNAME_LEN]; /* Long pathname in Unix format */ 1319 WIN32_FIND_DATAA FindFileData; 1320 HANDLE hFind; 1321 DWORD sp = 0, lp = 0,attr; 1322 LPSTR tmpshortpath,tmplongpath; 1323 1324 dprintf(("GetLongPathNameA %s %x %d", lpszShortPath, lpszLongPath, cchBuffer)); 1240 1325 1241 if(!lpszShortPath) { 1242 SetLastError(ERROR_INVALID_PARAMETER); 1326 if(!lpszShortPath) { 1327 SetLastError(ERROR_INVALID_PARAMETER); 1328 return 0; 1329 } 1330 1331 if ( ( tmpshortpath = (char*) HeapAlloc ( GetProcessHeap(), 0, MAX_PATHNAME_LEN ) ) == NULL ) { 1332 SetLastError ( ERROR_NOT_ENOUGH_MEMORY ); 1243 1333 return 0; 1244 } 1245 1246 length = lstrlenA(lpszShortPath) + 1; 1247 if(length > cchBuffer) { 1248 if(lpszLongPath) { 1249 *lpszLongPath = 0; 1334 } 1335 1336 if ( ( tmplongpath = (char*) HeapAlloc ( GetProcessHeap(), 0, MAX_PATHNAME_LEN ) ) == NULL ) { 1337 SetLastError ( ERROR_NOT_ENOUGH_MEMORY ); 1338 return 0; 1339 } 1340 1341 lstrcpyA(tmpshortpath,lpszShortPath); 1342 1343 /* check for drive letter */ 1344 if ( lpszShortPath[1] == ':' ) { 1345 tmplongpath[0] = lpszShortPath[0]; 1346 tmplongpath[1] = ':'; 1347 sp = 2; 1348 lp = 2; 1349 } 1350 1351 //todo: check drive validity! 1352 1353 while ( lpszShortPath[lp] ) { 1354 1355 /* check for path delimiters and reproduce them */ 1356 if ( lpszShortPath[lp] == '\\' || lpszShortPath[lp] == '/' ) { 1357 if (!sp || tmplongpath[sp-1]!= '\\') 1358 { 1359 /* strip double "\\" */ 1360 tmplongpath[sp] = '\\'; 1361 sp++; 1362 } 1363 tmplongpath[sp]=0;/*terminate string*/ 1364 lp++; 1365 continue; 1250 1366 } 1251 return(length); //return length required (including 0 terminator) 1252 } 1253 lstrcpyA(lpszLongPath, lpszShortPath); 1254 return(length-1); 1367 1368 tmplen = strcspn ( lpszShortPath + lp, "\\/" ); 1369 lstrcpynA ( tmplongpath+sp, lpszShortPath + lp, tmplen+1 ); 1370 1371 attr = GetFileAttributesA(tmplongpath); 1372 if (attr != -1) 1373 { 1374 sp += tmplen; 1375 lp += tmplen; 1376 continue; 1377 } 1378 else 1379 // it may be hashed name or name with weird characters! 1380 if ((tmplongpath+sp)[4] == '~') 1381 { 1382 //hashed entry Wine does linear dir search.. incredible.. we will be 1383 //better ;) 1384 if (strchr(tmplongpath+sp,'_')) 1385 { 1386 (tmplongpath+sp)[0] = '*'; 1387 (tmplongpath+sp)[1] = 0; 1388 } 1389 else 1390 { 1391 (tmplongpath+sp)[4] = '*'; 1392 (tmplongpath+sp)[5] = 0; 1393 } 1394 hFind = FindFirstFileExA(tmplongpath, FindExInfoStandard, &FindFileData, 1395 FindExSearchNameMatch, NULL, 0 ); 1396 1397 if (hFind == INVALID_HANDLE_VALUE) 1398 { 1399 //no possible variants! 1400 SetLastError ( ERROR_FILE_NOT_FOUND ); 1401 HeapFree ( GetProcessHeap(), 0, tmpshortpath ); 1402 HeapFree ( GetProcessHeap(), 0, tmplongpath ); 1403 return 0; 1404 } 1405 else 1406 do 1407 { 1408 DOSFS_Hash(FindFileData.cFileName, short_name, FALSE, TRUE ); 1409 //this happens on files like [hello world] 1410 if (!lstrncmpA(short_name, lpszShortPath+lp, (lpszShortPath+lp+tmplen)[-1] == '.' ? tmplen-1 : tmplen )) 1411 { 1412 strcpy( tmplongpath+sp, FindFileData.cFileName); 1413 sp += strlen ( tmplongpath+sp ); 1414 lp += tmplen; 1415 break; 1416 } 1417 } 1418 while (FindNextFileA(hFind, &FindFileData)); 1419 1420 // no FindClose() here or else GetLastError() will not give its error 1421 if (GetLastError() == ERROR_NO_MORE_FILES) 1422 { 1423 FindClose(hFind); 1424 SetLastError ( ERROR_FILE_NOT_FOUND ); 1425 HeapFree ( GetProcessHeap(), 0, tmpshortpath ); 1426 HeapFree ( GetProcessHeap(), 0, tmplongpath ); 1427 return 0; 1428 } 1429 FindClose(hFind); 1430 } 1431 else 1432 { 1433 // if this file can't be found in common or hashed files 1434 // it does not exist 1435 SetLastError ( ERROR_FILE_NOT_FOUND ); 1436 HeapFree ( GetProcessHeap(), 0, tmpshortpath ); 1437 HeapFree ( GetProcessHeap(), 0, tmplongpath ); 1438 return 0; 1439 } 1440 } 1441 tmplongpath[sp] = 0; 1442 1443 lstrcpynA ( lpszLongPath, tmplongpath, cchBuffer ); 1444 dprintf(("returning %s\n", lpszLongPath)); 1445 tmplen = strlen ( lpszLongPath ); 1446 1447 HeapFree ( GetProcessHeap(), 0, tmpshortpath ); 1448 HeapFree ( GetProcessHeap(), 0, tmplongpath ); 1449 1450 return tmplen; 1255 1451 } 1256 1452 //******************************************************************************
Note:
See TracChangeset
for help on using the changeset viewer.