Changeset 2835 in kBuild
- Timestamp:
- Aug 23, 2016 2:08:36 AM (9 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/kWorker/kWorker.c
r2834 r2835 223 223 typedef struct KWFSHASHA 224 224 { 225 /** Next entry with the same hash . */225 /** Next entry with the same hash table slot. */ 226 226 PKWFSHASHA pNext; 227 227 /** Path hash value. */ … … 244 244 typedef struct KWFSHASHW 245 245 { 246 /** Next entry with the same hash . */246 /** Next entry with the same hash table slot. */ 247 247 PKWFSHASHW pNext; 248 248 /** Path hash value. */ … … 255 255 PKWFSOBJ pFsObj; 256 256 } KWFSHASHW; 257 258 259 260 /** Pointer to a normalized path hash table entry. */ 261 typedef struct KWFSNORMHASHA *PKWFSNORMHASHA; 262 /** 263 * Normalized path hash table entry. 264 * 265 * Note! This looks like it's duplicating KWFSHASHW/KWFSHASHA/KWFSOBJ, but 266 * it also handles paths that not cachable. 267 */ 268 typedef struct KWFSNORMHASHA 269 { 270 /** Next entry with the same hash table slot. */ 271 PKWFSNORMHASHA pNext; 272 /** The input path. */ 273 const char *pszPath; 274 /** The length of the input path. */ 275 KU16 cchPath; 276 /** The length of the normalized path. */ 277 KU16 cchNormPath; 278 /** The hash. */ 279 KU32 uHashPath; 280 /** The normalized path (variable size). */ 281 char szNormPath[1]; 282 } KWFSNORMHASHA; 257 283 258 284 … … 437 463 /** File system hash table for UTF-16 filename strings. */ 438 464 static PKWFSHASHW g_apFsUtf16Paths[1021]; 465 /** Cached normalized path results. */ 466 static PKWFSNORMHASHA g_apFsNormalizedPathsA[1021]; 439 467 /** Special file system object returned if the path is invalid. */ 440 468 static KWFSOBJ g_FsPathNotFound = … … 622 650 623 651 /** 624 * Normalizes the path so we get a consistent hash.625 *626 * @returns status code.627 * @param pszPath The path.628 * @param pszNormPath The output buffer.629 * @param cbNormPath The size of the output buffer.630 */631 static int kwPathNormalize(const char *pszPath, char *pszNormPath, KSIZE cbNormPath)632 {633 char *pchSlash;634 nt_fullpath(pszPath, pszNormPath, cbNormPath);635 636 pchSlash = kHlpStrChr(pszNormPath, '/');637 while (pchSlash)638 {639 *pchSlash = '\\';640 pchSlash = kHlpStrChr(pchSlash + 1, '/');641 }642 643 return 0;644 }645 646 647 /**648 652 * Hashes a string. 649 653 * … … 820 824 SetLastError(ERROR_INSUFFICIENT_BUFFER); 821 825 return (DWORD)cbDst; 826 } 827 828 829 /** 830 * Normalizes the path so we get a consistent hash. 831 * 832 * @returns status code. 833 * @param pszPath The path. 834 * @param pszNormPath The output buffer. 835 * @param cbNormPath The size of the output buffer. 836 */ 837 static int kwPathNormalize(const char *pszPath, char *pszNormPath, KSIZE cbNormPath) 838 { 839 char *pchSlash; 840 KSIZE cchNormPath; 841 842 /* 843 * We hash these to speed stuff up (nt_fullpath isn't cheap and we're 844 * gonna have many repeat queries and assume nobody do case changes to 845 * anything essential while kmk is running). 846 */ 847 KU32 uHashPath; 848 KU32 cchPath = (KU32)kwStrHashEx(pszPath, &uHashPath); 849 KU32 const idxHashTab = uHashPath % K_ELEMENTS(g_apFsNormalizedPathsA); 850 PKWFSNORMHASHA pHashEntry = g_apFsNormalizedPathsA[idxHashTab]; 851 if (pHashEntry) 852 { 853 do 854 { 855 if ( pHashEntry->uHashPath == uHashPath 856 && pHashEntry->cchPath == cchPath 857 && kHlpMemComp(pHashEntry->pszPath, pszPath, cchPath) == 0) 858 { 859 if (cbNormPath > pHashEntry->cchNormPath) 860 { 861 KWFS_LOG(("kwPathNormalize(%s) - hit\n", pszPath)); 862 kHlpMemCopy(pszNormPath, pHashEntry->szNormPath, pHashEntry->cchNormPath + 1); 863 return 0; 864 } 865 return KERR_BUFFER_OVERFLOW; 866 } 867 pHashEntry = pHashEntry->pNext; 868 } while (pHashEntry); 869 } 870 871 /* 872 * Do it the slow way. 873 */ 874 nt_fullpath(pszPath, pszNormPath, cbNormPath); 875 /** @todo nt_fullpath overflow handling?!?!? */ 876 877 pchSlash = kHlpStrChr(pszNormPath, '/'); 878 while (pchSlash) 879 { 880 *pchSlash = '\\'; 881 pchSlash = kHlpStrChr(pchSlash + 1, '/'); 882 } 883 884 /* 885 * Create a new hash table entry (ignore failures). 886 */ 887 cchNormPath = kHlpStrLen(pszNormPath); 888 if (cchNormPath < KU16_MAX && cchPath < KU16_MAX) 889 { 890 pHashEntry = (PKWFSNORMHASHA)kHlpAlloc(sizeof(*pHashEntry) + cchNormPath + 1 + cchPath + 1); 891 if (pHashEntry) 892 { 893 pHashEntry->cchNormPath = (KU16)cchNormPath; 894 pHashEntry->cchPath = (KU16)cchPath; 895 pHashEntry->uHashPath = uHashPath; 896 pHashEntry->pszPath = (char *)kHlpMemCopy(&pHashEntry->szNormPath[cchNormPath + 1], pszPath, cchPath + 1); 897 kHlpMemCopy(pHashEntry->szNormPath, pszNormPath, cchNormPath + 1); 898 899 pHashEntry->pNext = g_apFsNormalizedPathsA[idxHashTab]; 900 g_apFsNormalizedPathsA[idxHashTab] = pHashEntry; 901 } 902 } 903 904 return 0; 822 905 } 823 906 … … 1362 1445 1363 1446 /** 1447 * Check if the path leads to a regular file (that exists). 1448 * 1449 * @returns K_TRUE / K_FALSE 1450 * @param pszPath Path to the file to check out. 1451 */ 1452 static KBOOL kwLdrModuleIsRegularFile(const char *pszPath) 1453 { 1454 /* For stuff with .DLL extensions, we can use the GetFileAttribute cache to speed this up! */ 1455 KSIZE cchPath = kHlpStrLen(pszPath); 1456 if ( cchPath > 3 1457 && pszPath[cchPath - 4] == '.' 1458 && (pszPath[cchPath - 3] == 'd' || pszPath[cchPath - 3] == 'D') 1459 && (pszPath[cchPath - 2] == 'l' || pszPath[cchPath - 2] == 'L') 1460 && (pszPath[cchPath - 1] == 'l' || pszPath[cchPath - 1] == 'L') ) 1461 { 1462 PKWFSOBJ pFsObj = kwFsLookupA(pszPath); 1463 if (pFsObj) 1464 { 1465 if (!(pFsObj->fAttribs & (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_DEVICE))) /* also checks invalid */ 1466 return K_TRUE; 1467 } 1468 } 1469 else 1470 { 1471 BirdStat_T Stat; 1472 int rc = birdStatFollowLink(pszPath, &Stat); 1473 if (rc == 0) 1474 { 1475 if (S_ISREG(Stat.st_mode)) 1476 return K_TRUE; 1477 } 1478 } 1479 return K_FALSE; 1480 } 1481 1482 1483 /** 1364 1484 * Worker for kwLdrModuleResolveAndLookup that checks out one possibility. 1365 1485 * … … 1380 1500 * Does the file exists and is it a regular file? 1381 1501 */ 1382 BirdStat_T Stat; 1383 int rc = birdStatFollowLink(pszPath, &Stat); 1384 if (rc == 0) 1385 { 1386 if (S_ISREG(Stat.st_mode)) 1387 { 1502 if (kwLdrModuleIsRegularFile(pszPath)) 1503 { 1504 /* 1505 * Yes! Normalize it and look it up in the hash table. 1506 */ 1507 char szNormPath[1024]; 1508 int rc = kwPathNormalize(pszPath, szNormPath, sizeof(szNormPath)); 1509 if (rc == 0) 1510 { 1511 const char *pszName; 1512 KU32 const uHashPath = kwStrHash(szNormPath); 1513 unsigned idxHash = uHashPath % K_ELEMENTS(g_apModules); 1514 PKWMODULE pMod = g_apModules[idxHash]; 1515 if (pMod) 1516 { 1517 do 1518 { 1519 if ( pMod->uHashPath == uHashPath 1520 && kHlpStrComp(pMod->pszPath, szNormPath) == 0) 1521 return kwLdrModuleRetain(pMod); 1522 pMod = pMod->pNext; 1523 } while (pMod); 1524 } 1525 1388 1526 /* 1389 * Yes! Normalize it and look it up in the hash table.1527 * Not in the hash table, so we have to load it from scratch. 1390 1528 */ 1391 char szNormPath[1024]; 1392 rc = kwPathNormalize(pszPath, szNormPath, sizeof(szNormPath)); 1393 if (rc == 0) 1394 { 1395 const char *pszName; 1396 KU32 const uHashPath = kwStrHash(szNormPath); 1397 unsigned idxHash = uHashPath % K_ELEMENTS(g_apModules); 1398 PKWMODULE pMod = g_apModules[idxHash]; 1399 if (pMod) 1400 { 1401 do 1402 { 1403 if ( pMod->uHashPath == uHashPath 1404 && kHlpStrComp(pMod->pszPath, szNormPath) == 0) 1405 return kwLdrModuleRetain(pMod); 1406 pMod = pMod->pNext; 1407 } while (pMod); 1408 } 1409 1410 /* 1411 * Not in the hash table, so we have to load it from scratch. 1412 */ 1413 pszName = kHlpGetFilename(szNormPath); 1414 if (kwLdrModuleCanLoadNatively(pszName, enmLocation)) 1415 pMod = kwLdrModuleCreateNative(szNormPath, uHashPath, 1416 kwLdrModuleShouldDoNativeReplacements(pszName, enmLocation)); 1417 else 1418 pMod = kwLdrModuleCreateNonNative(szNormPath, uHashPath, K_FALSE /*fExe*/, pExeMod); 1419 if (pMod) 1420 return pMod; 1421 return (PKWMODULE)~(KUPTR)0; 1422 } 1529 pszName = kHlpGetFilename(szNormPath); 1530 if (kwLdrModuleCanLoadNatively(pszName, enmLocation)) 1531 pMod = kwLdrModuleCreateNative(szNormPath, uHashPath, 1532 kwLdrModuleShouldDoNativeReplacements(pszName, enmLocation)); 1533 else 1534 pMod = kwLdrModuleCreateNonNative(szNormPath, uHashPath, K_FALSE /*fExe*/, pExeMod); 1535 if (pMod) 1536 return pMod; 1537 return (PKWMODULE)~(KUPTR)0; 1423 1538 } 1424 1539 } … … 3180 3295 static DWORD WINAPI kwSandbox_Kernel32_SetFilePointer(HANDLE hFile, LONG cbMove, PLONG pcbMoveHi, DWORD dwMoveMethod) 3181 3296 { 3297 KUPTR const idxHandle = KW_HANDLE_TO_INDEX(hFile); 3298 if (idxHandle < g_Sandbox.cHandles) 3299 { 3300 PKWHANDLE pHandle = g_Sandbox.papHandles[idxHandle]; 3301 if (pHandle != NULL) 3302 { 3303 KI64 offMove = pcbMoveHi ? ((KI64)*pcbMoveHi << 32) | cbMove : cbMove; 3304 switch (pHandle->enmType) 3305 { 3306 case KWHANDLETYPE_FSOBJ_READ_CACHE: 3307 { 3308 PKWFSOBJ pFsObj = pHandle->u.pFsObj; 3309 switch (dwMoveMethod) 3310 { 3311 case FILE_BEGIN: 3312 break; 3313 case FILE_CURRENT: 3314 offMove += pHandle->offFile; 3315 break; 3316 case FILE_END: 3317 offMove += pFsObj->cbCached; 3318 break; 3319 default: 3320 KWFS_LOG(("SetFilePointer(%p) - invalid seek method %u! [cached]\n", hFile)); 3321 SetLastError(ERROR_INVALID_PARAMETER); 3322 return INVALID_SET_FILE_POINTER; 3323 } 3324 if (offMove >= 0) 3325 { 3326 if (offMove >= (KSSIZE)pFsObj->cbCached) 3327 offMove = (KSSIZE)pFsObj->cbCached; 3328 pHandle->offFile = (KU32)offMove; 3329 } 3330 else 3331 { 3332 KWFS_LOG(("SetFilePointer(%p) - negative seek! [cached]\n", hFile)); 3333 SetLastError(ERROR_NEGATIVE_SEEK); 3334 return INVALID_SET_FILE_POINTER; 3335 } 3336 if (pcbMoveHi) 3337 *pcbMoveHi = (KU64)offMove >> 32; 3338 KWFS_LOG(("SetFilePointer(%p) -> %#llx [cached]\n", hFile, offMove)); 3339 return (KU32)offMove; 3340 } 3341 default: 3342 kHlpAssertFailed(); 3343 } 3344 } 3345 } 3182 3346 KWFS_LOG(("SetFilePointer(%p)\n", hFile)); 3183 3347 return SetFilePointer(hFile, cbMove, pcbMoveHi, dwMoveMethod); … … 3186 3350 3187 3351 /** Kernel32 - SetFilePointerEx */ 3188 static BOOL WINAPI kwSandbox_Kernel32_SetFilePointerEx(HANDLE hFile, LARGE_INTEGER pcbMove, PLARGE_INTEGER poffNew,3352 static BOOL WINAPI kwSandbox_Kernel32_SetFilePointerEx(HANDLE hFile, LARGE_INTEGER offMove, PLARGE_INTEGER poffNew, 3189 3353 DWORD dwMoveMethod) 3190 3354 { 3355 KUPTR const idxHandle = KW_HANDLE_TO_INDEX(hFile); 3356 if (idxHandle < g_Sandbox.cHandles) 3357 { 3358 PKWHANDLE pHandle = g_Sandbox.papHandles[idxHandle]; 3359 if (pHandle != NULL) 3360 { 3361 KI64 offMyMove = offMove.QuadPart; 3362 switch (pHandle->enmType) 3363 { 3364 case KWHANDLETYPE_FSOBJ_READ_CACHE: 3365 { 3366 PKWFSOBJ pFsObj = pHandle->u.pFsObj; 3367 switch (dwMoveMethod) 3368 { 3369 case FILE_BEGIN: 3370 break; 3371 case FILE_CURRENT: 3372 offMyMove += pHandle->offFile; 3373 break; 3374 case FILE_END: 3375 offMyMove += pFsObj->cbCached; 3376 break; 3377 default: 3378 KWFS_LOG(("SetFilePointerEx(%p) - invalid seek method %u! [cached]\n", hFile)); 3379 SetLastError(ERROR_INVALID_PARAMETER); 3380 return FALSE; 3381 } 3382 if (offMyMove >= 0) 3383 { 3384 if (offMyMove >= (KSSIZE)pFsObj->cbCached) 3385 offMyMove = (KSSIZE)pFsObj->cbCached; 3386 pHandle->offFile = (KU32)offMyMove; 3387 } 3388 else 3389 { 3390 KWFS_LOG(("SetFilePointerEx(%p) - negative seek! [cached]\n", hFile)); 3391 SetLastError(ERROR_NEGATIVE_SEEK); 3392 return INVALID_SET_FILE_POINTER; 3393 } 3394 if (poffNew) 3395 poffNew->QuadPart = offMyMove; 3396 KWFS_LOG(("SetFilePointerEx(%p) -> TRUE, %#llx [cached]\n", hFile, offMyMove)); 3397 return TRUE; 3398 } 3399 default: 3400 kHlpAssertFailed(); 3401 } 3402 } 3403 } 3191 3404 KWFS_LOG(("SetFilePointerEx(%p)\n", hFile)); 3192 return SetFilePointerEx(hFile, pcbMove, poffNew, dwMoveMethod);3405 return SetFilePointerEx(hFile, offMove, poffNew, dwMoveMethod); 3193 3406 } 3194 3407 3195 3408 3196 3409 /** Kernel32 - ReadFile */ 3197 static BOOL WINAPI kwSandbox_Kernel32_ReadFile(HANDLE hFile, LPVOID pvBuffer, DWORD cbTo Write, LPDWORD pcbActuallyWritten,3410 static BOOL WINAPI kwSandbox_Kernel32_ReadFile(HANDLE hFile, LPVOID pvBuffer, DWORD cbToRead, LPDWORD pcbActuallyRead, 3198 3411 LPOVERLAPPED pOverlapped) 3199 3412 { 3413 KUPTR const idxHandle = KW_HANDLE_TO_INDEX(hFile); 3414 if (idxHandle < g_Sandbox.cHandles) 3415 { 3416 PKWHANDLE pHandle = g_Sandbox.papHandles[idxHandle]; 3417 if (pHandle != NULL) 3418 { 3419 switch (pHandle->enmType) 3420 { 3421 case KWHANDLETYPE_FSOBJ_READ_CACHE: 3422 { 3423 PKWFSOBJ pFsObj = pHandle->u.pFsObj; 3424 KSIZE cbActually = pFsObj->cbCached - pHandle->offFile; 3425 if (cbActually > cbToRead) 3426 cbActually = cbToRead; 3427 3428 kHlpMemCopy(pvBuffer, &pFsObj->pbCached[pHandle->offFile], cbActually); 3429 pHandle->offFile += (KU32)cbActually; 3430 3431 kHlpAssert(!pOverlapped); kHlpAssert(pcbActuallyRead); 3432 *pcbActuallyRead = (KU32)cbActually; 3433 3434 KWFS_LOG(("ReadFile(%p,,%#x) -> TRUE, %#x bytes [cached]\n", hFile, cbToRead, (KU32)cbActually)); 3435 return TRUE; 3436 } 3437 default: 3438 kHlpAssertFailed(); 3439 } 3440 } 3441 } 3442 3200 3443 KWFS_LOG(("ReadFile(%p)\n", hFile)); 3201 return ReadFile(hFile, pvBuffer, cbToWrite, pcbActuallyWritten, pOverlapped); 3444 return ReadFile(hFile, pvBuffer, cbToRead, pcbActuallyRead, pOverlapped); 3445 } 3446 3447 3448 /** Kernel32 - ReadFileEx */ 3449 static BOOL WINAPI kwSandbox_Kernel32_ReadFileEx(HANDLE hFile, LPVOID pvBuffer, DWORD cbToRead, LPOVERLAPPED pOverlapped, 3450 LPOVERLAPPED_COMPLETION_ROUTINE pfnCompletionRoutine) 3451 { 3452 KUPTR const idxHandle = KW_HANDLE_TO_INDEX(hFile); 3453 if (idxHandle < g_Sandbox.cHandles) 3454 { 3455 PKWHANDLE pHandle = g_Sandbox.papHandles[idxHandle]; 3456 if (pHandle != NULL) 3457 { 3458 kHlpAssertFailed(); 3459 } 3460 } 3461 3462 KWFS_LOG(("ReadFile(%p)\n", hFile)); 3463 return ReadFileEx(hFile, pvBuffer, cbToRead, pOverlapped, pfnCompletionRoutine); 3202 3464 } 3203 3465 … … 3338 3600 { TUPLE("CreateFileW"), NULL, (KUPTR)kwSandbox_Kernel32_CreateFileW }, 3339 3601 { TUPLE("ReadFile"), NULL, (KUPTR)kwSandbox_Kernel32_ReadFile }, 3602 { TUPLE("ReadFileEx"), NULL, (KUPTR)kwSandbox_Kernel32_ReadFileEx }, 3340 3603 { TUPLE("SetFilePointer"), NULL, (KUPTR)kwSandbox_Kernel32_SetFilePointer }, 3341 3604 { TUPLE("SetFilePointerEx"), NULL, (KUPTR)kwSandbox_Kernel32_SetFilePointerEx }, … … 3416 3679 { TUPLE("CreateFileA"), NULL, (KUPTR)kwSandbox_Kernel32_CreateFileA }, 3417 3680 { TUPLE("CreateFileW"), NULL, (KUPTR)kwSandbox_Kernel32_CreateFileW }, 3418 #if 03419 3681 { TUPLE("ReadFile"), NULL, (KUPTR)kwSandbox_Kernel32_ReadFile }, 3682 { TUPLE("ReadFileEx"), NULL, (KUPTR)kwSandbox_Kernel32_ReadFileEx }, 3420 3683 { TUPLE("SetFilePointer"), NULL, (KUPTR)kwSandbox_Kernel32_SetFilePointer }, 3421 3684 { TUPLE("SetFilePointerEx"), NULL, (KUPTR)kwSandbox_Kernel32_SetFilePointerEx }, 3422 #endif3423 3685 { TUPLE("CloseHandle"), NULL, (KUPTR)kwSandbox_Kernel32_CloseHandle }, 3424 3686 { TUPLE("GetFileAttributesA"), NULL, (KUPTR)kwSandbox_Kernel32_GetFileAttributesA }, … … 3701 3963 int i; 3702 3964 argv[2] = "\"E:/vbox/svn/trunk/tools/win.x86/vcc/v10sp1/bin/amd64/cl.exe\" -c -c -TP -nologo -Zi -Zi -Zl -GR- -EHsc -GF -Zc:wchar_t- -Oy- -MT -W4 -Wall -wd4065 -wd4996 -wd4127 -wd4706 -wd4201 -wd4214 -wd4510 -wd4512 -wd4610 -wd4514 -wd4820 -wd4365 -wd4987 -wd4710 -wd4061 -wd4986 -wd4191 -wd4574 -wd4917 -wd4711 -wd4611 -wd4571 -wd4324 -wd4505 -wd4263 -wd4264 -wd4738 -wd4242 -wd4244 -WX -RTCsu -IE:/vbox/svn/trunk/tools/win.x86/vcc/v10sp1/include -IE:/vbox/svn/trunk/tools/win.x86/vcc/v10sp1/atlmfc/include -IE:/vbox/svn/trunk/tools/win.x86/sdk/v7.1/Include -IE:/vbox/svn/trunk/include -IE:/vbox/svn/trunk/out/win.amd64/debug -IE:/vbox/svn/trunk/tools/win.x86/vcc/v10sp1/include -IE:/vbox/svn/trunk/tools/win.x86/vcc/v10sp1/atlmfc/include -DVBOX -DVBOX_WITH_64_BITS_GUESTS -DVBOX_WITH_REM -DVBOX_WITH_RAW_MODE -DDEBUG -DDEBUG_bird -DDEBUG_USERNAME=bird -DRT_OS_WINDOWS -D__WIN__ -DRT_ARCH_AMD64 -D__AMD64__ -D__WIN64__ -DVBOX_WITH_DEBUGGER -DRT_LOCK_STRICT -DRT_LOCK_STRICT_ORDER -DIN_RING3 -DLOG_DISABLED -DIN_BLD_PROG -D_CRT_SECURE_NO_DEPRECATE -FdE:/vbox/svn/trunk/out/win.amd64/debug/obj/VBoxBs2Linker/VBoxBs2Linker-obj.pdb -FD -FoE:/vbox/svn/trunk/out/win.amd64/debug/obj/VBoxBs2Linker/VBoxBs2Linker.obj E:\\vbox\\svn\\trunk\\src\\VBox\\ValidationKit\\bootsectors\\VBoxBs2Linker.cpp"; 3703 #if 13965 #if 0 3704 3966 rc = kwExecCmdLine(argv[1], argv[2]); 3705 //rc = kwExecCmdLine(argv[1], argv[2]);3967 rc = kwExecCmdLine(argv[1], argv[2]); 3706 3968 K_NOREF(i); 3707 3969 #else 3970 // run 4: 32.67/1024 = 0x0 (0.031904296875) 3971 // run 3: 32.77/1024 = 0x0 (0.032001953125) 3708 3972 // run 2: 34/1024 = 0x0 (0.033203125) 3709 3973 // run 1: 37/1024 = 0x0 (0.0361328125)
Note:
See TracChangeset
for help on using the changeset viewer.