- Timestamp:
- Jun 9, 2020 11:53:39 PM (4 years ago)
- Location:
- trunk/src/kWorker
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/kWorker/Makefile.kmk
r3361 r3366 55 55 /DYNAMICBASE:NO /FIXED 56 56 kWorker_LDFLAGS.win.x86 = /BASE:0x00010000 57 kWorker_LDFLAGS.win.amd64 = /BASE:0x0000000420000000 57 kWorker_LDFLAGS.win.amd64 = /BASE:0x0000000420000000 /STACK:16777216,262144 58 58 59 59 #kWorker_LDFLAGS.win.x86 = \ … … 165 165 # A couple of dummy DLLs we use for grabbing LDR TLS entries. 166 166 # 167 DLLS += kWorkerTls1K kWorkerTls1K01 kWorkerTls1K02 kWorkerTls1K03 kWorkerTls1K04 kWorkerTls1K05 kWorkerTls1K06 kWorkerTls1K07 \ 168 kWorkerTls1K08 kWorkerTls1K09 kWorkerTls1K10 kWorkerTls1K11 kWorkerTls1K12 kWorkerTls1K13 kWorkerTls1K14 kWorkerTls1K15 167 DLLS += kWorkerTls1K kWorkerTls1K01 kWorkerTls1K02 kWorkerTls1K03 kWorkerTls1K04 kWorkerTls1K05 kWorkerTls1K06 kWorkerTls1K07 169 168 kWorkerTls1K_TEMPLATE = BIN-STATIC-THREADED 170 169 kWorkerTls1K_DEFS = TLS_SIZE=1024 … … 179 178 kWorkerTls1K06_EXTENDS = kWorkerTls1K 180 179 kWorkerTls1K07_EXTENDS = kWorkerTls1K 181 kWorkerTls1K08_EXTENDS = kWorkerTls1K 182 kWorkerTls1K09_EXTENDS = kWorkerTls1K 183 kWorkerTls1K10_EXTENDS = kWorkerTls1K 184 kWorkerTls1K11_EXTENDS = kWorkerTls1K 185 kWorkerTls1K12_EXTENDS = kWorkerTls1K 186 kWorkerTls1K13_EXTENDS = kWorkerTls1K 187 kWorkerTls1K14_EXTENDS = kWorkerTls1K 188 kWorkerTls1K15_EXTENDS = kWorkerTls1K 189 190 DLLS += kWorkerTls64K kWorkerTls512K 191 180 181 182 DLLS += kWorkerTls64K kWorkerTls64K01 kWorkerTls64K02 kWorkerTls64K03 kWorkerTls64K04 kWorkerTls64K05 kWorkerTls64K06 kWorkerTls64K07 192 183 kWorkerTls64K_TEMPLATE = BIN-STATIC-THREADED 193 184 kWorkerTls64K_DEFS = TLS_SIZE=65536 … … 195 186 kWorkerTls64K_LDFLAGS = /Entry:DummyDllEntry 196 187 188 kWorkerTls64K01_EXTENDS = kWorkerTls64K 189 kWorkerTls64K02_EXTENDS = kWorkerTls64K 190 kWorkerTls64K03_EXTENDS = kWorkerTls64K 191 kWorkerTls64K04_EXTENDS = kWorkerTls64K 192 kWorkerTls64K05_EXTENDS = kWorkerTls64K 193 kWorkerTls64K06_EXTENDS = kWorkerTls64K 194 kWorkerTls64K07_EXTENDS = kWorkerTls64K 195 196 197 DLLS += kWorkerTls128K kWorkerTls128K01 kWorkerTls128K02 kWorkerTls128K03 kWorkerTls128K04 kWorkerTls128K05 kWorkerTls128K06 kWorkerTls128K07 198 kWorkerTls128K_TEMPLATE = BIN-STATIC-THREADED 199 kWorkerTls128K_DEFS = TLS_SIZE=131072 200 kWorkerTls128K_SOURCES = kWorkerTlsXxxK.c 201 kWorkerTls128K_LDFLAGS = /Entry:DummyDllEntry 202 203 kWorkerTls128K01_EXTENDS = kWorkerTls128K 204 kWorkerTls128K02_EXTENDS = kWorkerTls128K 205 kWorkerTls128K03_EXTENDS = kWorkerTls128K 206 kWorkerTls128K04_EXTENDS = kWorkerTls128K 207 kWorkerTls128K05_EXTENDS = kWorkerTls128K 208 kWorkerTls128K06_EXTENDS = kWorkerTls128K 209 kWorkerTls128K07_EXTENDS = kWorkerTls128K 210 211 212 DLLS += kWorkerTls512K kWorkerTls512K01 kWorkerTls512K02 kWorkerTls512K03 kWorkerTls512K04 kWorkerTls512K05 kWorkerTls512K06 kWorkerTls512K07 197 213 kWorkerTls512K_TEMPLATE = BIN-STATIC-THREADED 198 214 kWorkerTls512K_DEFS = TLS_SIZE=524288 … … 200 216 kWorkerTls512K_LDFLAGS = /Entry:DummyDllEntry 201 217 218 kWorkerTls512K01_EXTENDS = kWorkerTls512K 219 kWorkerTls512K02_EXTENDS = kWorkerTls512K 220 kWorkerTls512K03_EXTENDS = kWorkerTls512K 221 kWorkerTls512K04_EXTENDS = kWorkerTls512K 222 kWorkerTls512K05_EXTENDS = kWorkerTls512K 223 kWorkerTls512K06_EXTENDS = kWorkerTls512K 224 kWorkerTls512K07_EXTENDS = kWorkerTls512K 225 202 226 203 227 include $(KBUILD_PATH)/subfooter.kmk -
trunk/src/kWorker/kWorker.c
r3365 r3366 390 390 } aQuickZeroChunks[3]; 391 391 392 /** TLS index if one was allocated, otherwise KU32_MAX. */ 392 /** Pointer to g_abInitData of the kWorkerTlsXxxK.c instance. 393 * This member is set by kwLdrTlsAllocationHook. */ 394 KU8 *pabTlsInitData; 395 /** Pointer to the g_pvWorkerModule variable in kWorkerTlsXxxK.c (our instance 396 * of it). This member is set by kwLdrTlsAllocationHook. Used by our 397 * destructor to prevent after-free references. */ 398 PKWMODULE *ppTlsWorkerModuleVar; 399 /** TLS index if one was allocated, otherwise KU32_MAX. 400 * This member is set by kwLdrTlsAllocationHook. */ 393 401 KU32 idxTls; 394 402 /** Offset (RVA) of the TLS initialization data. */ … … 665 673 /** The handle. */ 666 674 HANDLE hHandle; 675 /** The current owner (GetCurrentThreadId). */ 676 KU32 tidOwner; 667 677 668 678 /** Type specific data. */ … … 876 886 877 887 888 /** Critical section protecting the below handle members below. 889 * @note Does not protect the individual handles. */ 890 CRITICAL_SECTION HandlesLock; 878 891 /** Handle table. */ 879 892 PKWHANDLE *papHandles; … … 1112 1125 { L"kWorkerTls1K06.dll", K_FALSE }, 1113 1126 { L"kWorkerTls1K07.dll", K_FALSE }, 1114 { L"kWorkerTls1K08.dll", K_FALSE },1115 { L"kWorkerTls1K09.dll", K_FALSE },1116 { L"kWorkerTls1K10.dll", K_FALSE },1117 { L"kWorkerTls1K11.dll", K_FALSE },1118 { L"kWorkerTls1K12.dll", K_FALSE },1119 { L"kWorkerTls1K13.dll", K_FALSE },1120 { L"kWorkerTls1K14.dll", K_FALSE },1121 { L"kWorkerTls1K15.dll", K_FALSE },1122 1127 }; 1123 1128 … … 1125 1130 static KWTLSDLL g_aTls64KDlls[] = 1126 1131 { 1127 { L"kWorkerTls64K.dll", K_FALSE }, 1132 { L"kWorkerTls64K.dll", K_FALSE }, 1133 { L"kWorkerTls64K01.dll", K_FALSE }, 1134 { L"kWorkerTls64K02.dll", K_FALSE }, 1135 { L"kWorkerTls64K03.dll", K_FALSE }, 1136 { L"kWorkerTls64K04.dll", K_FALSE }, 1137 { L"kWorkerTls64K05.dll", K_FALSE }, 1138 { L"kWorkerTls64K06.dll", K_FALSE }, 1139 { L"kWorkerTls64K07.dll", K_FALSE }, 1140 }; 1141 1142 /** The 128KB TLS DLLs. */ 1143 static KWTLSDLL g_aTls128KDlls[] = 1144 { 1145 { L"kWorkerTls128K.dll", K_FALSE }, 1146 { L"kWorkerTls128K01.dll", K_FALSE }, 1147 { L"kWorkerTls128K02.dll", K_FALSE }, 1148 { L"kWorkerTls128K03.dll", K_FALSE }, 1149 { L"kWorkerTls128K04.dll", K_FALSE }, 1150 { L"kWorkerTls128K05.dll", K_FALSE }, 1151 { L"kWorkerTls128K06.dll", K_FALSE }, 1152 { L"kWorkerTls128K07.dll", K_FALSE }, 1128 1153 }; 1129 1154 … … 1131 1156 static KWTLSDLL g_aTls512KDlls[] = 1132 1157 { 1133 { L"kWorkerTls512K.dll", K_FALSE }, 1158 { L"kWorkerTls512K.dll", K_FALSE }, 1159 { L"kWorkerTls512K01.dll", K_FALSE }, 1160 { L"kWorkerTls512K02.dll", K_FALSE }, 1161 { L"kWorkerTls512K03.dll", K_FALSE }, 1162 { L"kWorkerTls512K04.dll", K_FALSE }, 1163 { L"kWorkerTls512K05.dll", K_FALSE }, 1164 { L"kWorkerTls512K06.dll", K_FALSE }, 1165 { L"kWorkerTls512K07.dll", K_FALSE }, 1134 1166 }; 1135 1167 … … 1139 1171 { 1024, K_ELEMENTS(g_aTls1KDlls), g_aTls1KDlls }, 1140 1172 { 64*1024, K_ELEMENTS(g_aTls64KDlls), g_aTls64KDlls }, 1173 { 128*1024, K_ELEMENTS(g_aTls128KDlls), g_aTls128KDlls }, 1141 1174 { 512*1024, K_ELEMENTS(g_aTls512KDlls), g_aTls512KDlls }, 1142 1175 }; … … 1294 1327 static char *kwSandboxDoGetEnvA(PKWSANDBOX pSandbox, const char *pchVar, KSIZE cchVar); 1295 1328 static KBOOL kwSandboxHandleTableEnter(PKWSANDBOX pSandbox, PKWHANDLE pHandle, HANDLE hHandle); 1329 static PKWHANDLE kwSandboxHandleLookup(HANDLE hFile); 1330 static PKWHANDLE kwSandboxHandleGet(HANDLE hFile); 1331 K_INLINE void kwSandboxHandlePut(PKWHANDLE pHandle); 1296 1332 #ifdef WITH_CONSOLE_OUTPUT_BUFFERING 1297 1333 static void kwSandboxConsoleWriteA(PKWSANDBOX pSandbox, PKWOUTPUTSTREAMBUF pLineBuf, const char *pchBuffer, KU32 cchToWrite); … … 1404 1440 { 1405 1441 DWORD const dwSavedErr = GetLastError(); 1442 1443 #if defined(KW_LOG_ENABLED) && defined(WITH_LOG_FILE) 1444 va_list vaCopy; 1445 # if defined(va_copy) || !defined(_MSC_VER) || _MSC_VER >= 1700 /*??*/ 1446 va_copy(vaCopy, va); 1447 # else 1448 vaCopy = va; 1449 # endif 1450 kwDebuggerPrintf("kWorker: error: "); 1451 kwDebuggerPrintfV(pszFormat, vaCopy); 1452 #endif 1406 1453 1407 1454 fprintf(stderr, "kWorker: error: "); … … 1872 1919 if (--pMod->cRefs == 0) 1873 1920 { 1921 /* Make sure it doesn't receive any more native TLS callbacks.if non-native. */ 1922 if (!pMod->fNative && pMod->u.Manual.ppTlsWorkerModuleVar) 1923 { 1924 *pMod->u.Manual.ppTlsWorkerModuleVar = NULL; 1925 pMod->u.Manual.ppTlsWorkerModuleVar = NULL; 1926 } 1927 1874 1928 /* Unlink it from the hash table. */ 1875 1929 if (!pMod->fExe) … … 2241 2295 if (!SetDllDirectoryW(pExe->pwszPath)) 2242 2296 kwErrPrintf("SetDllDirectoryW failed: %u\n", GetLastError()); 2297 KW_LOG(("kwLdrModuleCreateNative: Applied SetDllDirectoryW hack (%ls)\n", pExe->pwszPath)); 2243 2298 *pwzFilename = wcSaved; 2244 2299 } 2300 else 2301 KW_LOG(("kwLdrModuleCreateNative: Warning! Too early for SetDllDirectoryW hack\n")); 2302 2245 2303 2246 2304 /* … … 2489 2547 2490 2548 /** 2549 * Called from the TLS allocation DLL when ever the native loader wants to issue 2550 * a TLS callback after the initial kwLdrTlsAllocationHook callout. 2551 * 2552 * @param hDll The DLL handle. 2553 * @param dwReason The callback reason. 2554 * @param pvContext Some context value that seems to always be NULL. 2555 * @param pMod Out internal module. 2556 */ 2557 static void kwLdrTlsNativeLoaderCallback(void *hDll, DWORD dwReason, void *pvContext, PKWMODULE pMod) 2558 { 2559 if ( pMod 2560 && pMod->u.Manual.enmState == KWMODSTATE_READY) 2561 { 2562 KWLDR_LOG(("kwLdrTlsNativeLoaderCallback: hDll=%p dwReason=%#x pvContext=%p pMod=%p\n", 2563 hDll, dwReason, pvContext, pMod)); 2564 if (pMod->u.Manual.cTlsCallbacks) 2565 { 2566 PIMAGE_TLS_CALLBACK *ppfnCallback = (PIMAGE_TLS_CALLBACK *)&pMod->u.Manual.pbLoad[pMod->u.Manual.offTlsCallbacks]; 2567 do 2568 { 2569 KWLDR_LOG(("kwLdrTlsNativeLoaderCallback: Calling TLS callback %p(%p, %#x, %p) - %s\n", 2570 *ppfnCallback, pMod->hOurMod, dwReason, pvContext, pMod->pszPath)); 2571 (*ppfnCallback)(pMod->hOurMod, dwReason, pvContext); 2572 ppfnCallback++; 2573 } while (*ppfnCallback); 2574 } 2575 } 2576 else 2577 KWLDR_LOG(("kwLdrTlsNativeLoaderCallback: hDll=%p dwReason=%#x pvContext=%p pMod=%p - skipped\n", 2578 hDll, dwReason, pvContext, pMod)); 2579 } 2580 2581 2582 /** 2491 2583 * Called from TLS allocation DLL during DLL_PROCESS_ATTACH. 2492 2584 * 2493 * @param hDll The DLL handle. 2494 * @param idxTls The allocated TLS index. 2495 * @param ppfnTlsCallback Pointer to the TLS callback table entry. 2496 */ 2497 __declspec(dllexport) void kwLdrTlsAllocationHook(void *hDll, ULONG idxTls, PIMAGE_TLS_CALLBACK *ppfnTlsCallback) 2585 * @returns Address of the callback function (kwLdrTlsNativeLoaderCallback). 2586 * @param hDll The DLL handle. 2587 * @param idxTls The allocated TLS index. 2588 * @param pabInitData The init data in the TLS allocation DLL 2589 * (g_abInitData). 2590 * @param ppWorkerModuleVar Pointer to the variable holding the pMod 2591 * callback parameter value (g_pvWorkerModule). 2592 * 2593 * @see KWLDRTLSALLOCATIONHOOK in kWorkerTlsXxxxK.c 2594 */ 2595 __declspec(dllexport) KUPTR kwLdrTlsAllocationHook(void *hDll, ULONG idxTls, KU8 *pabInitData, PKWMODULE *ppWorkerModuleVar) 2498 2596 { 2499 2597 /* … … 2503 2601 if (pMod) 2504 2602 { 2505 PPEB pPeb = kwSandboxGetProcessEnvironmentBlock(); 2506 LIST_ENTRY *pHead; 2507 LIST_ENTRY *pCur; 2508 2509 pMod->u.Manual.idxTls = idxTls; 2510 KWLDR_LOG(("kwLdrTlsAllocationHook: idxTls=%d (%#x) for %s\n", idxTls, idxTls, pMod->pszPath)); 2511 2512 /* 2513 * Try sabotage the DLL name so we can load this module again. 2514 */ 2515 /** @todo this doesn't work W10 18363 */ 2516 pHead = &pPeb->Ldr->InMemoryOrderModuleList; 2517 for (pCur = pHead->Blink; pCur != pHead; pCur = pCur->Blink) 2518 { 2519 LDR_DATA_TABLE_ENTRY *pMte; 2520 pMte = (LDR_DATA_TABLE_ENTRY *)((KUPTR)pCur - K_OFFSETOF(LDR_DATA_TABLE_ENTRY, InMemoryOrderLinks)); 2521 if (((KUPTR)pMte->DllBase & ~(KUPTR)31) == ((KUPTR)hDll & ~(KUPTR)31)) 2522 { 2523 PUNICODE_STRING pStr = &pMte->FullDllName; 2524 KSIZE off = pStr->Length / sizeof(pStr->Buffer[0]); 2525 pStr->Buffer[--off]++; 2526 pStr->Buffer[--off]++; 2527 pStr->Buffer[--off]++; 2528 KWLDR_LOG(("kwLdrTlsAllocationHook: patched the MTE (%p) for %p\n", pMte, hDll)); 2529 break; 2530 } 2531 } 2532 } 2603 if ( pMod->u.Manual.idxTls == KU32_MAX 2604 && pMod->u.Manual.pabTlsInitData == NULL) 2605 { 2606 pMod->u.Manual.idxTls = idxTls; 2607 pMod->u.Manual.pabTlsInitData = pabInitData; 2608 pMod->u.Manual.ppTlsWorkerModuleVar = ppWorkerModuleVar; 2609 KWLDR_LOG(("kwLdrTlsAllocationHook: idxTls=%d (%#x) for %s\n", idxTls, idxTls, pMod->pszPath)); 2610 2611 #if 0 /** @todo this doesn't work W10 18363 */ 2612 { 2613 /* 2614 * Try sabotage the DLL name so we can load this module again. 2615 */ 2616 PPEB pPeb = kwSandboxGetProcessEnvironmentBlock(); 2617 LIST_ENTRY *pHead; 2618 LIST_ENTRY *pCur; 2619 2620 pHead = &pPeb->Ldr->InMemoryOrderModuleList; 2621 for (pCur = pHead->Blink; pCur != pHead; pCur = pCur->Blink) 2622 { 2623 LDR_DATA_TABLE_ENTRY *pMte; 2624 pMte = (LDR_DATA_TABLE_ENTRY *)((KUPTR)pCur - K_OFFSETOF(LDR_DATA_TABLE_ENTRY, InMemoryOrderLinks)); 2625 if (((KUPTR)pMte->DllBase & ~(KUPTR)31) == ((KUPTR)hDll & ~(KUPTR)31)) 2626 { 2627 PUNICODE_STRING pStr = &pMte->FullDllName; 2628 KSIZE off = pStr->Length / sizeof(pStr->Buffer[0]); 2629 pStr->Buffer[--off]++; 2630 pStr->Buffer[--off]++; 2631 pStr->Buffer[--off]++; 2632 KWLDR_LOG(("kwLdrTlsAllocationHook: patched the MTE (%p) for %p\n", pMte, hDll)); 2633 break; 2634 } 2635 } 2636 } 2637 #endif 2638 2639 /* 2640 * Don't return a callback function unless the module has callbacks to service. 2641 */ 2642 if (pMod->u.Manual.cTlsCallbacks > 0) 2643 { 2644 *ppWorkerModuleVar = pMod; 2645 return (KUPTR)kwLdrTlsNativeLoaderCallback; 2646 } 2647 return 0; 2648 } 2649 KWLDR_LOG(("kwLdrTlsAllocationHook: WTF? pMod=%p: idxTls=%#x pabTlsInitData=%p\n", 2650 pMod, pMod->u.Manual.idxTls, pMod->u.Manual.pabTlsInitData)); 2651 } 2652 return 0; 2533 2653 } 2534 2654 … … 2639 2759 pwszTlsDll = g_aTlsDlls[iTlsDll].paDlls[iTlsDllSub].pwszName; 2640 2760 2641 pMod->u.Manual.idxTls = KU32_MAX; 2761 pMod->u.Manual.pabTlsInitData = NULL; 2762 pMod->u.Manual.ppTlsWorkerModuleVar = NULL; 2763 pMod->u.Manual.idxTls = KU32_MAX; 2764 2642 2765 pMod->u.Manual.offTlsInitData = (KU32)((KUPTR)paEntries[0].StartAddressOfRawData - (KUPTR)pMod->u.Manual.pbLoad); 2643 2766 pMod->u.Manual.cbTlsInitData = (KU32)(paEntries[0].EndAddressOfRawData - paEntries[0].StartAddressOfRawData); … … 2663 2786 2664 2787 *(KU32 *)&pMod->u.Manual.pbCopy[offIndex] = pMod->u.Manual.idxTls; 2665 KWLDR_LOG(("kwLdrModuleCreateNonNativeSetupTls: idxTls=%d hmodTlsDll=%p (%ls) cbData=%#x\n", 2666 pMod->u.Manual.idxTls, hmodTlsDll, pwszTlsDll, cbData)); 2788 KWLDR_LOG(("kwLdrModuleCreateNonNativeSetupTls: idxTls=%d hmodTlsDll=%p (%ls) cbData=%#x pabTlsInitData=%p\n", 2789 pMod->u.Manual.idxTls, hmodTlsDll, pwszTlsDll, cbData, pMod->u.Manual.pabTlsInitData)); 2790 2791 kHlpAssert(pMod->u.Manual.pabTlsInitData); 2792 if (pMod->u.Manual.pabTlsInitData && pMod->u.Manual.cbTlsInitData) 2793 kHlpMemCopy(pMod->u.Manual.pabTlsInitData, &pMod->u.Manual.pbCopy[pMod->u.Manual.offTlsInitData], 2794 pMod->u.Manual.cbTlsInitData); 2667 2795 } 2668 2796 return 0; … … 2748 2876 pMod->u.Manual.cQuickZeroChunks = 0; 2749 2877 pMod->u.Manual.cQuickCopyChunks = 0; 2878 pMod->u.Manual.pabTlsInitData = NULL; 2879 pMod->u.Manual.ppTlsWorkerModuleVar = NULL; 2750 2880 pMod->u.Manual.idxTls = KU32_MAX; 2751 2881 pMod->u.Manual.offTlsInitData = KU32_MAX; … … 2990 3120 || kHlpStrNICompAscii(pszFilename, TUPLE("ucrtbase")) == 0 2991 3121 || kHlpStrNICompAscii(pszFilename, TUPLE("api-ms-win-crt-")) == 0 3122 #if 1 /* for debugging, only for debugging. */ 3123 || kHlpStrICompAscii(pszFilename, "c1.dll") == 0 3124 || kHlpStrICompAscii(pszFilename, "c1xx.dll") == 0 3125 || kHlpStrICompAscii(pszFilename, "c2.dll") == 0 3126 #endif 2992 3127 ; 2993 3128 } … … 3074 3209 || kHlpStrNICompAscii(pszFilename, TUPLE("vcruntime")) == 0 3075 3210 || ( enmLocation != KWLOCATION_UNKNOWN 3076 && kwLdrIsVirtualApiModule(pszFilename, kHlpStrLen(pszFilename))); 3211 && kwLdrIsVirtualApiModule(pszFilename, kHlpStrLen(pszFilename))) 3212 #if 1 /* for debugging, only for debugging. */ 3213 //|| kHlpStrICompAscii(pszFilename, "c1.dll") == 0 3214 //|| kHlpStrICompAscii(pszFilename, "c1xx.dll") == 0 3215 // || kHlpStrICompAscii(pszFilename, "c2.dll") == 0 3216 #endif 3217 ; 3077 3218 } 3078 3219 … … 3490 3631 if (pMod->u.Manual.cTlsCallbacks) 3491 3632 { 3492 PIMAGE_TLS_CALLBACK *p Callback = (PIMAGE_TLS_CALLBACK *)&pMod->u.Manual.pbLoad[pMod->u.Manual.offTlsCallbacks];3633 PIMAGE_TLS_CALLBACK *ppfnCallback = (PIMAGE_TLS_CALLBACK *)&pMod->u.Manual.pbLoad[pMod->u.Manual.offTlsCallbacks]; 3493 3634 do 3494 3635 { 3495 KWLDR_LOG(("%s: Calling TLS callback %p(%p,%#x,0)\n", pMod->pszPath, *p Callback, pMod->hOurMod, dwReason));3496 (*p Callback)(pMod->hOurMod, dwReason, 0);3497 } while (*++p Callback);3636 KWLDR_LOG(("%s: Calling TLS callback %p(%p,%#x,0)\n", pMod->pszPath, *ppfnCallback, pMod->hOurMod, dwReason)); 3637 (*ppfnCallback)(pMod->hOurMod, dwReason, 0); 3638 } while (*++ppfnCallback); 3498 3639 } 3499 3640 } … … 5651 5792 KBOOL fNeedSuffix = K_FALSE; 5652 5793 const char *pszCur = kwSandboxDoGetEnvA(&g_Sandbox, "PATH", 4); 5653 while (*pszCur != '\0') 5654 { 5655 /* Find the end of the component */ 5656 KSIZE cch = 0; 5657 while (pszCur[cch] != ';' && pszCur[cch] != '\0') 5658 cch++; 5659 5660 if ( cch > 0 /* wrong, but whatever */ 5661 && cch + 1 + cchFilename + cchSuffix < sizeof(szPath)) 5794 kHlpAssert(pszCur); 5795 if (pszCur) 5796 { 5797 while (*pszCur != '\0') 5662 5798 { 5663 char *pszDst = kHlpMemPCopy(szPath, pszCur, cch); 5664 if ( szPath[cch - 1] != ':' 5665 && szPath[cch - 1] != '/' 5666 && szPath[cch - 1] != '\\') 5667 *pszDst++ = '\\'; 5668 pszDst = kHlpMemPCopy(pszDst, pszFilename, cchFilename); 5669 if (fNeedSuffix) 5670 pszDst = kHlpMemPCopy(pszDst, ".dll", 4); 5671 *pszDst = '\0'; 5672 5673 if (kwFsPathExists(szPath)) 5799 /* Find the end of the component */ 5800 KSIZE cch = 0; 5801 while (pszCur[cch] != ';' && pszCur[cch] != '\0') 5802 cch++; 5803 5804 if ( cch > 0 /* wrong, but whatever */ 5805 && cch + 1 + cchFilename + cchSuffix < sizeof(szPath)) 5674 5806 { 5675 KWLDR_LOG(("kwSandbox_Kernel32_Native_LoadLibraryExA: %s -> %s\n", pszFilename, szPath)); 5676 pszFilename = szPath; 5677 break; 5807 char *pszDst = kHlpMemPCopy(szPath, pszCur, cch); 5808 if ( szPath[cch - 1] != ':' 5809 && szPath[cch - 1] != '/' 5810 && szPath[cch - 1] != '\\') 5811 *pszDst++ = '\\'; 5812 pszDst = kHlpMemPCopy(pszDst, pszFilename, cchFilename); 5813 if (fNeedSuffix) 5814 pszDst = kHlpMemPCopy(pszDst, ".dll", 4); 5815 *pszDst = '\0'; 5816 5817 if (kwFsPathExists(szPath)) 5818 { 5819 KWLDR_LOG(("kwSandbox_Kernel32_Native_LoadLibraryExA: %s -> %s\n", pszFilename, szPath)); 5820 pszFilename = szPath; 5821 break; 5822 } 5678 5823 } 5824 5825 /* Advance */ 5826 pszCur += cch; 5827 while (*pszCur == ';') 5828 pszCur++; 5679 5829 } 5680 5681 /* Advance */5682 pszCur += cch;5683 while (*pszCur == ';')5684 pszCur++;5685 5830 } 5686 5831 } … … 6281 6426 case KFSLOOKUPERROR_PATH_COMP_NOT_FOUND: 6282 6427 case KFSLOOKUPERROR_PATH_COMP_NOT_DIR: 6428 case KFSLOOKUPERROR_PATH_TOO_SHORT: 6283 6429 return ERROR_PATH_NOT_FOUND; 6284 6430 … … 6414 6560 pHandle->hHandle = hFile; 6415 6561 pHandle->dwDesiredAccess = dwDesiredAccess; 6562 pHandle->tidOwner = KU32_MAX; 6416 6563 pHandle->u.pTempFile = pTempFile; 6417 6564 if (kwSandboxHandleTableEnter(&g_Sandbox, pHandle, hFile)) … … 6890 7037 pHandle->hHandle = *phFile; 6891 7038 pHandle->dwDesiredAccess = dwDesiredAccess; 7039 pHandle->tidOwner = KU32_MAX; 6892 7040 pHandle->u.pCachedFile = pCachedFile; 6893 7041 if (kwSandboxHandleTableEnter(&g_Sandbox, pHandle, pHandle->hHandle)) … … 6946 7094 * Check for include files and similar that we do read-only caching of. 6947 7095 */ 6948 if (dwCreationDisposition == FILE_OPEN_IF)7096 if (dwCreationDisposition == OPEN_EXISTING) 6949 7097 { 6950 7098 if ( dwDesiredAccess == GENERIC_READ … … 6981 7129 { 6982 7130 KWFS_LOG(("CreateFileA(%ls) -> INVALID_HANDLE_VALUE, ERROR_FILE_NOT_FOUND\n", pszFilename)); 7131 SetLastError(ERROR_FILE_NOT_FOUND); 6983 7132 return INVALID_HANDLE_VALUE; 6984 7133 } … … 6991 7140 { 6992 7141 KWFS_LOG(("CreateFileA(%s) -> INVALID_HANDLE_VALUE, ERROR_FILE_NOT_FOUND\n", pszFilename)); 7142 SetLastError(ERROR_FILE_NOT_FOUND); 6993 7143 return INVALID_HANDLE_VALUE; 6994 7144 } … … 6997 7147 { 6998 7148 KWFS_LOG(("CreateFileA(%s) -> INVALID_HANDLE_VALUE, ERROR_PATH_NOT_FOUND\n", pszFilename)); 7149 SetLastError(ERROR_PATH_NOT_FOUND); 6999 7150 return INVALID_HANDLE_VALUE; 7000 7151 } … … 7016 7167 hFile = CreateFileA(pszFilename, dwDesiredAccess, dwShareMode, pSecAttrs, 7017 7168 dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile); 7018 if (hFile != INVALID_HANDLE_VALUE) 7019 { 7020 kHlpAssert( KW_HANDLE_TO_INDEX(hFile) >= g_Sandbox.cHandles 7021 || g_Sandbox.papHandles[KW_HANDLE_TO_INDEX(hFile)] == NULL); 7022 } 7169 kHlpAssert(hFile == INVALID_HANDLE_VALUE || kwSandboxHandleLookup(hFile) == NULL); 7170 7023 7171 KWFS_LOG(("CreateFileA(%s) -> %p\n", pszFilename, hFile)); 7024 7172 return hFile; … … 7055 7203 * Check for include files and similar that we do read-only caching of. 7056 7204 */ 7057 if (dwCreationDisposition == FILE_OPEN_IF)7205 if (dwCreationDisposition == OPEN_EXISTING) 7058 7206 { 7059 7207 if ( dwDesiredAccess == GENERIC_READ … … 7089 7237 { 7090 7238 KWFS_LOG(("CreateFileW(%ls) -> INVALID_HANDLE_VALUE, ERROR_FILE_NOT_FOUND\n", pwszFilename)); 7239 SetLastError(ERROR_FILE_NOT_FOUND); 7240 #if 0 7241 if ( pFsObj->cchName > sizeof("generated.h") 7242 && kHlpStrICompAscii(&pFsObj->pszName[pFsObj->cchName - sizeof("generated.h") + 1], "generated.h") == 0) 7243 kwErrPrintf("CreateFileW(%ls) -> ERROR_FILE_NOT_FOUND; pFsObj->fFlags=%#x\n", pwszFilename, pFsObj->fFlags); 7244 #endif 7091 7245 return INVALID_HANDLE_VALUE; 7092 7246 } … … 7098 7252 else if (enmError == KFSLOOKUPERROR_NOT_FOUND) 7099 7253 { 7254 #if 0 7255 KSIZE cwcFilename = kwUtf16Len(pwszFilename); 7256 if ( cwcFilename > sizeof("generated.h") 7257 && memcmp(&pwszFilename[cwcFilename - sizeof("generated.h") + 1], 7258 L"generated.h", sizeof(L"generated.h")) == 0) 7259 kwErrPrintf("CreateFileW(%ls) -> ERROR_FILE_NOT_FOUND; (KFSLOOKUPERROR_NOT_FOUND)\n", pwszFilename, pFsObj->fFlags); 7260 #endif 7100 7261 KWFS_LOG(("CreateFileW(%ls) -> INVALID_HANDLE_VALUE, ERROR_FILE_NOT_FOUND\n", pwszFilename)); 7262 SetLastError(ERROR_FILE_NOT_FOUND); 7101 7263 return INVALID_HANDLE_VALUE; 7102 7264 } … … 7104 7266 || enmError == KFSLOOKUPERROR_PATH_COMP_NOT_DIR) 7105 7267 { 7268 #if 0 7269 KSIZE cwcFilename = kwUtf16Len(pwszFilename); 7270 if ( cwcFilename > sizeof("generated.h") 7271 && memcmp(&pwszFilename[cwcFilename - sizeof("generated.h") + 1], 7272 L"generated.h", sizeof(L"generated.h")) == 0) 7273 kwErrPrintf("CreateFileW(%ls) -> ERROR_PATH_NOT_FOUND; (%d)\n", pwszFilename, enmError); 7274 #endif 7106 7275 KWFS_LOG(("CreateFileW(%ls) -> INVALID_HANDLE_VALUE, ERROR_PATH_NOT_FOUND\n", pwszFilename)); 7276 SetLastError(ERROR_PATH_NOT_FOUND); 7107 7277 return INVALID_HANDLE_VALUE; 7108 7278 } … … 7133 7303 hFile = CreateFileW(pwszFilename, dwDesiredAccess, dwShareMode, pSecAttrs, 7134 7304 dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile); 7135 if (hFile != INVALID_HANDLE_VALUE) 7136 { 7137 kHlpAssert( KW_HANDLE_TO_INDEX(hFile) >= g_Sandbox.cHandles 7138 || g_Sandbox.papHandles[KW_HANDLE_TO_INDEX(hFile)] == NULL); 7139 } 7305 kHlpAssert(hFile == INVALID_HANDLE_VALUE || kwSandboxHandleLookup(hFile) == NULL); 7306 7140 7307 KWFS_LOG(("CreateFileW(%ls) -> %p\n", pwszFilename, hFile)); 7141 7308 return hFile; … … 7143 7310 7144 7311 7312 7145 7313 /** Kernel32 - SetFilePointer */ 7146 7314 static DWORD WINAPI kwSandbox_Kernel32_SetFilePointer(HANDLE hFile, LONG cbMove, PLONG pcbMoveHi, DWORD dwMoveMethod) 7147 7315 { 7148 KUPTR const idxHandle = KW_HANDLE_TO_INDEX(hFile); 7149 kHlpAssert(GetCurrentThreadId() == g_Sandbox.idMainThread); 7150 if (idxHandle < g_Sandbox.cHandles) 7151 { 7152 PKWHANDLE pHandle = g_Sandbox.papHandles[idxHandle]; 7153 if (pHandle != NULL) 7154 { 7155 KU32 cbFile; 7156 KI64 offMove = pcbMoveHi ? ((KI64)*pcbMoveHi << 32) | cbMove : cbMove; 7157 switch (pHandle->enmType) 7158 { 7159 case KWHANDLETYPE_FSOBJ_READ_CACHE: 7160 cbFile = pHandle->u.pCachedFile->cbCached; 7161 break; 7316 PKWHANDLE pHandle = kwSandboxHandleGet(hFile); 7317 if (pHandle != NULL) 7318 { 7319 KU32 cbFile; 7320 KI64 offMove = pcbMoveHi ? ((KI64)*pcbMoveHi << 32) | cbMove : cbMove; 7321 switch (pHandle->enmType) 7322 { 7323 case KWHANDLETYPE_FSOBJ_READ_CACHE: 7324 cbFile = pHandle->u.pCachedFile->cbCached; 7325 break; 7162 7326 #ifdef WITH_TEMP_MEMORY_FILES 7163 7164 7165 7166 7327 case KWHANDLETYPE_TEMP_FILE: 7328 cbFile = pHandle->u.pTempFile->cbFile; 7329 break; 7330 case KWHANDLETYPE_TEMP_FILE_MAPPING: 7167 7331 #endif 7168 case KWHANDLETYPE_OUTPUT_BUF: 7169 default: 7170 kHlpAssertFailed(); 7171 SetLastError(ERROR_INVALID_FUNCTION); 7332 case KWHANDLETYPE_OUTPUT_BUF: 7333 default: 7334 kHlpAssertFailed(); 7335 kwSandboxHandlePut(pHandle); 7336 SetLastError(ERROR_INVALID_FUNCTION); 7337 return INVALID_SET_FILE_POINTER; 7338 } 7339 7340 switch (dwMoveMethod) 7341 { 7342 case FILE_BEGIN: 7343 break; 7344 case FILE_CURRENT: 7345 offMove += pHandle->offFile; 7346 break; 7347 case FILE_END: 7348 offMove += cbFile; 7349 break; 7350 default: 7351 KWFS_LOG(("SetFilePointer(%p) - invalid seek method %u! [cached]\n", hFile)); 7352 kwSandboxHandlePut(pHandle); 7353 SetLastError(ERROR_INVALID_PARAMETER); 7354 return INVALID_SET_FILE_POINTER; 7355 } 7356 if (offMove >= 0) 7357 { 7358 if (offMove >= (KSSIZE)cbFile) 7359 { 7360 #ifdef WITH_TEMP_MEMORY_FILES 7361 /* For read-only files, seeking beyond the end isn't useful to us, so clamp it. */ 7362 if (pHandle->enmType != KWHANDLETYPE_TEMP_FILE) 7363 #endif 7364 offMove = (KSSIZE)cbFile; 7365 #ifdef WITH_TEMP_MEMORY_FILES 7366 /* For writable files, seeking beyond the end is fine, but check that we've got 7367 the type range for the request. */ 7368 else if (((KU64)offMove & KU32_MAX) != (KU64)offMove) 7369 { 7370 kHlpAssertMsgFailed(("%#llx\n", offMove)); 7371 kwSandboxHandlePut(pHandle); 7372 SetLastError(ERROR_SEEK); 7172 7373 return INVALID_SET_FILE_POINTER; 7173 } 7174 7175 switch (dwMoveMethod) 7176 { 7177 case FILE_BEGIN: 7178 break; 7179 case FILE_CURRENT: 7180 offMove += pHandle->offFile; 7181 break; 7182 case FILE_END: 7183 offMove += cbFile; 7184 break; 7185 default: 7186 KWFS_LOG(("SetFilePointer(%p) - invalid seek method %u! [cached]\n", hFile)); 7187 SetLastError(ERROR_INVALID_PARAMETER); 7188 return INVALID_SET_FILE_POINTER; 7189 } 7190 if (offMove >= 0) 7191 { 7192 if (offMove >= (KSSIZE)cbFile) 7193 { 7194 #ifdef WITH_TEMP_MEMORY_FILES 7195 /* For read-only files, seeking beyond the end isn't useful to us, so clamp it. */ 7196 if (pHandle->enmType != KWHANDLETYPE_TEMP_FILE) 7374 } 7197 7375 #endif 7198 offMove = (KSSIZE)cbFile; 7199 #ifdef WITH_TEMP_MEMORY_FILES 7200 /* For writable files, seeking beyond the end is fine, but check that we've got 7201 the type range for the request. */ 7202 else if (((KU64)offMove & KU32_MAX) != (KU64)offMove) 7203 { 7204 kHlpAssertMsgFailed(("%#llx\n", offMove)); 7205 SetLastError(ERROR_SEEK); 7206 return INVALID_SET_FILE_POINTER; 7207 } 7208 #endif 7209 } 7210 pHandle->offFile = (KU32)offMove; 7211 } 7212 else 7213 { 7214 KWFS_LOG(("SetFilePointer(%p) - negative seek! [cached]\n", hFile)); 7215 SetLastError(ERROR_NEGATIVE_SEEK); 7216 return INVALID_SET_FILE_POINTER; 7217 } 7218 if (pcbMoveHi) 7219 *pcbMoveHi = (KU64)offMove >> 32; 7220 KWFS_LOG(("SetFilePointer(%p,%#x,?,%u) -> %#llx [%s]\n", hFile, cbMove, dwMoveMethod, offMove, 7221 pHandle->enmType == KWHANDLETYPE_FSOBJ_READ_CACHE ? "cached" : "temp")); 7222 SetLastError(NO_ERROR); 7223 return (KU32)offMove; 7224 } 7225 } 7376 } 7377 pHandle->offFile = (KU32)offMove; 7378 } 7379 else 7380 { 7381 KWFS_LOG(("SetFilePointer(%p) - negative seek! [cached]\n", hFile)); 7382 kwSandboxHandlePut(pHandle); 7383 SetLastError(ERROR_NEGATIVE_SEEK); 7384 return INVALID_SET_FILE_POINTER; 7385 } 7386 if (pcbMoveHi) 7387 *pcbMoveHi = (KU64)offMove >> 32; 7388 KWFS_LOG(("SetFilePointer(%p,%#x,?,%u) -> %#llx [%s]\n", hFile, cbMove, dwMoveMethod, offMove, 7389 pHandle->enmType == KWHANDLETYPE_FSOBJ_READ_CACHE ? "cached" : "temp")); 7390 kwSandboxHandlePut(pHandle); 7391 SetLastError(NO_ERROR); 7392 return (KU32)offMove; 7393 } 7394 7226 7395 KWFS_LOG(("SetFilePointer(%p, %d, %p=%d, %d)\n", hFile, cbMove, pcbMoveHi ? *pcbMoveHi : 0, dwMoveMethod)); 7227 7396 return SetFilePointer(hFile, cbMove, pcbMoveHi, dwMoveMethod); … … 7233 7402 DWORD dwMoveMethod) 7234 7403 { 7235 KUPTR const idxHandle = KW_HANDLE_TO_INDEX(hFile); 7236 kHlpAssert(GetCurrentThreadId() == g_Sandbox.idMainThread); 7237 if (idxHandle < g_Sandbox.cHandles) 7238 { 7239 PKWHANDLE pHandle = g_Sandbox.papHandles[idxHandle]; 7240 if (pHandle != NULL) 7241 { 7242 KI64 offMyMove = offMove.QuadPart; 7243 KU32 cbFile; 7244 switch (pHandle->enmType) 7245 { 7246 case KWHANDLETYPE_FSOBJ_READ_CACHE: 7247 cbFile = pHandle->u.pCachedFile->cbCached; 7248 break; 7404 PKWHANDLE pHandle = kwSandboxHandleGet(hFile); 7405 if (pHandle != NULL) 7406 { 7407 KI64 offMyMove = offMove.QuadPart; 7408 KU32 cbFile; 7409 switch (pHandle->enmType) 7410 { 7411 case KWHANDLETYPE_FSOBJ_READ_CACHE: 7412 cbFile = pHandle->u.pCachedFile->cbCached; 7413 break; 7249 7414 #ifdef WITH_TEMP_MEMORY_FILES 7250 7251 7252 7253 7415 case KWHANDLETYPE_TEMP_FILE: 7416 cbFile = pHandle->u.pTempFile->cbFile; 7417 break; 7418 case KWHANDLETYPE_TEMP_FILE_MAPPING: 7254 7419 #endif 7255 case KWHANDLETYPE_OUTPUT_BUF: 7256 default: 7257 kHlpAssertFailed(); 7258 SetLastError(ERROR_INVALID_FUNCTION); 7259 return INVALID_SET_FILE_POINTER; 7260 } 7261 7262 switch (dwMoveMethod) 7263 { 7264 case FILE_BEGIN: 7265 break; 7266 case FILE_CURRENT: 7267 offMyMove += pHandle->offFile; 7268 break; 7269 case FILE_END: 7270 offMyMove += cbFile; 7271 break; 7272 default: 7273 KWFS_LOG(("SetFilePointer(%p) - invalid seek method %u! [cached]\n", hFile)); 7274 SetLastError(ERROR_INVALID_PARAMETER); 7275 return INVALID_SET_FILE_POINTER; 7276 } 7277 if (offMyMove >= 0) 7278 { 7279 if (offMyMove >= (KSSIZE)cbFile) 7420 case KWHANDLETYPE_OUTPUT_BUF: 7421 default: 7422 kHlpAssertFailed(); 7423 kwSandboxHandlePut(pHandle); 7424 SetLastError(ERROR_INVALID_FUNCTION); 7425 return FALSE; 7426 } 7427 7428 switch (dwMoveMethod) 7429 { 7430 case FILE_BEGIN: 7431 break; 7432 case FILE_CURRENT: 7433 offMyMove += pHandle->offFile; 7434 break; 7435 case FILE_END: 7436 offMyMove += cbFile; 7437 break; 7438 default: 7439 KWFS_LOG(("SetFilePointer(%p) - invalid seek method %u! [cached]\n", hFile)); 7440 kwSandboxHandlePut(pHandle); 7441 SetLastError(ERROR_INVALID_PARAMETER); 7442 return FALSE; 7443 } 7444 if (offMyMove >= 0) 7445 { 7446 if (offMyMove >= (KSSIZE)cbFile) 7447 { 7448 #ifdef WITH_TEMP_MEMORY_FILES 7449 /* For read-only files, seeking beyond the end isn't useful to us, so clamp it. */ 7450 if (pHandle->enmType != KWHANDLETYPE_TEMP_FILE) 7451 #endif 7452 offMyMove = (KSSIZE)cbFile; 7453 #ifdef WITH_TEMP_MEMORY_FILES 7454 /* For writable files, seeking beyond the end is fine, but check that we've got 7455 the type range for the request. */ 7456 else if (((KU64)offMyMove & KU32_MAX) != (KU64)offMyMove) 7280 7457 { 7281 #ifdef WITH_TEMP_MEMORY_FILES 7282 /* For read-only files, seeking beyond the end isn't useful to us, so clamp it. */ 7283 if (pHandle->enmType != KWHANDLETYPE_TEMP_FILE) 7458 kHlpAssertMsgFailed(("%#llx\n", offMyMove)); 7459 kwSandboxHandlePut(pHandle); 7460 SetLastError(ERROR_SEEK); 7461 return FALSE; 7462 } 7284 7463 #endif 7285 offMyMove = (KSSIZE)cbFile; 7286 #ifdef WITH_TEMP_MEMORY_FILES 7287 /* For writable files, seeking beyond the end is fine, but check that we've got 7288 the type range for the request. */ 7289 else if (((KU64)offMyMove & KU32_MAX) != (KU64)offMyMove) 7290 { 7291 kHlpAssertMsgFailed(("%#llx\n", offMyMove)); 7292 SetLastError(ERROR_SEEK); 7293 return INVALID_SET_FILE_POINTER; 7294 } 7295 #endif 7296 } 7297 pHandle->offFile = (KU32)offMyMove; 7298 } 7299 else 7300 { 7301 KWFS_LOG(("SetFilePointerEx(%p) - negative seek! [cached]\n", hFile)); 7302 SetLastError(ERROR_NEGATIVE_SEEK); 7303 return INVALID_SET_FILE_POINTER; 7304 } 7305 if (poffNew) 7306 poffNew->QuadPart = offMyMove; 7307 KWFS_LOG(("SetFilePointerEx(%p,%#llx,,%u) -> TRUE, %#llx [%s]\n", hFile, offMove.QuadPart, dwMoveMethod, offMyMove, 7308 pHandle->enmType == KWHANDLETYPE_FSOBJ_READ_CACHE ? "cached" : "temp")); 7309 return TRUE; 7310 } 7464 } 7465 pHandle->offFile = (KU32)offMyMove; 7466 } 7467 else 7468 { 7469 KWFS_LOG(("SetFilePointerEx(%p) - negative seek! [cached]\n", hFile)); 7470 kwSandboxHandlePut(pHandle); 7471 SetLastError(ERROR_NEGATIVE_SEEK); 7472 return FALSE; 7473 } 7474 if (poffNew) 7475 poffNew->QuadPart = offMyMove; 7476 KWFS_LOG(("SetFilePointerEx(%p,%#llx,,%u) -> TRUE, %#llx [%s]\n", hFile, offMove.QuadPart, dwMoveMethod, offMyMove, 7477 pHandle->enmType == KWHANDLETYPE_FSOBJ_READ_CACHE ? "cached" : "temp")); 7478 kwSandboxHandlePut(pHandle); 7479 return TRUE; 7311 7480 } 7312 7481 KWFS_LOG(("SetFilePointerEx(%p)\n", hFile)); … … 7319 7488 LPOVERLAPPED pOverlapped) 7320 7489 { 7321 BOOL 7322 KUPTR const idxHandle = KW_HANDLE_TO_INDEX(hFile);7490 BOOL fRet; 7491 PKWHANDLE pHandle = kwSandboxHandleGet(hFile); 7323 7492 g_cReadFileCalls++; 7324 kHlpAssert(GetCurrentThreadId() == g_Sandbox.idMainThread); 7325 if (idxHandle < g_Sandbox.cHandles) 7326 { 7327 PKWHANDLE pHandle = g_Sandbox.papHandles[idxHandle]; 7328 if (pHandle != NULL) 7329 { 7330 switch (pHandle->enmType) 7331 { 7332 case KWHANDLETYPE_FSOBJ_READ_CACHE: 7493 if (pHandle != NULL) 7494 { 7495 switch (pHandle->enmType) 7496 { 7497 case KWHANDLETYPE_FSOBJ_READ_CACHE: 7498 { 7499 PKFSWCACHEDFILE pCachedFile = pHandle->u.pCachedFile; 7500 KU32 cbActually = pCachedFile->cbCached - pHandle->offFile; 7501 if (cbActually > cbToRead) 7502 cbActually = cbToRead; 7503 7504 #ifdef WITH_HASH_MD5_CACHE 7505 if (g_Sandbox.pHashHead) 7333 7506 { 7334 PKFSWCACHEDFILE pCachedFile = pHandle->u.pCachedFile; 7335 KU32 cbActually = pCachedFile->cbCached - pHandle->offFile; 7507 g_Sandbox.LastHashRead.pCachedFile = pCachedFile; 7508 g_Sandbox.LastHashRead.offRead = pHandle->offFile; 7509 g_Sandbox.LastHashRead.cbRead = cbActually; 7510 g_Sandbox.LastHashRead.pvRead = pvBuffer; 7511 } 7512 #endif 7513 7514 kHlpMemCopy(pvBuffer, &pCachedFile->pbCached[pHandle->offFile], cbActually); 7515 pHandle->offFile += cbActually; 7516 7517 kHlpAssert(!pOverlapped); kHlpAssert(pcbActuallyRead); 7518 *pcbActuallyRead = cbActually; 7519 7520 g_cbReadFileFromReadCached += cbActually; 7521 g_cbReadFileTotal += cbActually; 7522 g_cReadFileFromReadCached++; 7523 7524 KWFS_LOG(("ReadFile(%p,,%#x) -> TRUE, %#x bytes [cached]\n", hFile, cbToRead, cbActually)); 7525 kwSandboxHandlePut(pHandle); 7526 return TRUE; 7527 } 7528 7529 #ifdef WITH_TEMP_MEMORY_FILES 7530 case KWHANDLETYPE_TEMP_FILE: 7531 { 7532 PKWFSTEMPFILE pTempFile = pHandle->u.pTempFile; 7533 KU32 cbActually; 7534 if (pHandle->offFile < pTempFile->cbFile) 7535 { 7536 cbActually = pTempFile->cbFile - pHandle->offFile; 7336 7537 if (cbActually > cbToRead) 7337 7538 cbActually = cbToRead; 7338 7539 7339 #ifdef WITH_HASH_MD5_CACHE 7340 if ( g_Sandbox.pHashHead)7540 /* Copy the data. */ 7541 if (cbActually > 0) 7341 7542 { 7342 g_Sandbox.LastHashRead.pCachedFile = pCachedFile; 7343 g_Sandbox.LastHashRead.offRead = pHandle->offFile; 7344 g_Sandbox.LastHashRead.cbRead = cbActually; 7345 g_Sandbox.LastHashRead.pvRead = pvBuffer; 7543 KU32 cbLeft; 7544 KU32 offSeg; 7545 KWFSTEMPFILESEG const *paSegs = pTempFile->paSegs; 7546 7547 /* Locate the segment containing the byte at offFile. */ 7548 KU32 iSeg = pTempFile->cSegs - 1; 7549 kHlpAssert(pTempFile->cSegs > 0); 7550 while (paSegs[iSeg].offData > pHandle->offFile) 7551 iSeg--; 7552 7553 /* Copy out the data. */ 7554 cbLeft = cbActually; 7555 offSeg = (pHandle->offFile - paSegs[iSeg].offData); 7556 for (;;) 7557 { 7558 KU32 cbAvail = paSegs[iSeg].cbDataAlloc - offSeg; 7559 if (cbAvail >= cbLeft) 7560 { 7561 kHlpMemCopy(pvBuffer, &paSegs[iSeg].pbData[offSeg], cbLeft); 7562 break; 7563 } 7564 7565 pvBuffer = kHlpMemPCopy(pvBuffer, &paSegs[iSeg].pbData[offSeg], cbAvail); 7566 cbLeft -= cbAvail; 7567 offSeg = 0; 7568 iSeg++; 7569 kHlpAssert(iSeg < pTempFile->cSegs); 7570 } 7571 7572 /* Update the file offset. */ 7573 pHandle->offFile += cbActually; 7346 7574 } 7347 #endif7348 7349 kHlpMemCopy(pvBuffer, &pCachedFile->pbCached[pHandle->offFile], cbActually);7350 pHandle->offFile += cbActually;7351 7352 kHlpAssert(!pOverlapped); kHlpAssert(pcbActuallyRead);7353 *pcbActuallyRead = cbActually;7354 7355 g_cbReadFileFromReadCached += cbActually;7356 g_cbReadFileTotal += cbActually;7357 g_cReadFileFromReadCached++;7358 7359 KWFS_LOG(("ReadFile(%p,,%#x) -> TRUE, %#x bytes [cached]\n", hFile, cbToRead, cbActually));7360 return TRUE;7361 7575 } 7362 7363 #ifdef WITH_TEMP_MEMORY_FILES 7364 case KWHANDLETYPE_TEMP_FILE: 7365 { 7366 PKWFSTEMPFILE pTempFile = pHandle->u.pTempFile; 7367 KU32 cbActually; 7368 if (pHandle->offFile < pTempFile->cbFile) 7369 { 7370 cbActually = pTempFile->cbFile - pHandle->offFile; 7371 if (cbActually > cbToRead) 7372 cbActually = cbToRead; 7373 7374 /* Copy the data. */ 7375 if (cbActually > 0) 7376 { 7377 KU32 cbLeft; 7378 KU32 offSeg; 7379 KWFSTEMPFILESEG const *paSegs = pTempFile->paSegs; 7380 7381 /* Locate the segment containing the byte at offFile. */ 7382 KU32 iSeg = pTempFile->cSegs - 1; 7383 kHlpAssert(pTempFile->cSegs > 0); 7384 while (paSegs[iSeg].offData > pHandle->offFile) 7385 iSeg--; 7386 7387 /* Copy out the data. */ 7388 cbLeft = cbActually; 7389 offSeg = (pHandle->offFile - paSegs[iSeg].offData); 7390 for (;;) 7391 { 7392 KU32 cbAvail = paSegs[iSeg].cbDataAlloc - offSeg; 7393 if (cbAvail >= cbLeft) 7394 { 7395 kHlpMemCopy(pvBuffer, &paSegs[iSeg].pbData[offSeg], cbLeft); 7396 break; 7397 } 7398 7399 pvBuffer = kHlpMemPCopy(pvBuffer, &paSegs[iSeg].pbData[offSeg], cbAvail); 7400 cbLeft -= cbAvail; 7401 offSeg = 0; 7402 iSeg++; 7403 kHlpAssert(iSeg < pTempFile->cSegs); 7404 } 7405 7406 /* Update the file offset. */ 7407 pHandle->offFile += cbActually; 7408 } 7409 } 7410 /* Read does not commit file space, so return zero bytes. */ 7411 else 7412 cbActually = 0; 7413 7414 kHlpAssert(!pOverlapped); kHlpAssert(pcbActuallyRead); 7415 *pcbActuallyRead = cbActually; 7416 7417 g_cbReadFileTotal += cbActually; 7418 g_cbReadFileFromInMemTemp += cbActually; 7419 g_cReadFileFromInMemTemp++; 7420 7421 KWFS_LOG(("ReadFile(%p,,%#x) -> TRUE, %#x bytes [temp]\n", hFile, cbToRead, (KU32)cbActually)); 7422 return TRUE; 7423 } 7424 7425 case KWHANDLETYPE_TEMP_FILE_MAPPING: 7576 /* Read does not commit file space, so return zero bytes. */ 7577 else 7578 cbActually = 0; 7579 7580 kHlpAssert(!pOverlapped); kHlpAssert(pcbActuallyRead); 7581 *pcbActuallyRead = cbActually; 7582 7583 g_cbReadFileTotal += cbActually; 7584 g_cbReadFileFromInMemTemp += cbActually; 7585 g_cReadFileFromInMemTemp++; 7586 7587 KWFS_LOG(("ReadFile(%p,,%#x) -> TRUE, %#x bytes [temp]\n", hFile, cbToRead, (KU32)cbActually)); 7588 kwSandboxHandlePut(pHandle); 7589 return TRUE; 7590 } 7591 7592 case KWHANDLETYPE_TEMP_FILE_MAPPING: 7426 7593 #endif /* WITH_TEMP_MEMORY_FILES */ 7427 7428 7429 7430 SetLastError(ERROR_INVALID_FUNCTION);7431 *pcbActuallyRead = 0;7432 return FALSE;7433 }7594 case KWHANDLETYPE_OUTPUT_BUF: 7595 default: 7596 kHlpAssertFailed(); 7597 kwSandboxHandlePut(pHandle); 7598 SetLastError(ERROR_INVALID_FUNCTION); 7599 *pcbActuallyRead = 0; 7600 return FALSE; 7434 7601 } 7435 7602 } … … 7447 7614 LPOVERLAPPED_COMPLETION_ROUTINE pfnCompletionRoutine) 7448 7615 { 7449 KUPTR const idxHandle = KW_HANDLE_TO_INDEX(hFile); 7450 kHlpAssert(GetCurrentThreadId() == g_Sandbox.idMainThread); 7451 if (idxHandle < g_Sandbox.cHandles) 7452 { 7453 PKWHANDLE pHandle = g_Sandbox.papHandles[idxHandle]; 7454 if (pHandle != NULL) 7455 { 7456 kHlpAssertFailed(); 7457 } 7458 } 7616 kHlpAssert(kwSandboxHandleLookup(hFile) == NULL); 7459 7617 7460 7618 KWFS_LOG(("ReadFile(%p)\n", hFile)); … … 7657 7815 LPOVERLAPPED pOverlapped) 7658 7816 { 7817 PKWHANDLE pHandle = kwSandboxHandleGet(hFile); 7659 7818 BOOL fRet; 7660 KUPTR const idxHandle = KW_HANDLE_TO_INDEX(hFile);7661 7819 g_cWriteFileCalls++; 7662 kHlpAssert(GetCurrentThreadId() == g_Sandbox.idMainThread || g_rcCtrlC != 0); 7663 if (idxHandle < g_Sandbox.cHandles) 7664 { 7665 PKWHANDLE pHandle = g_Sandbox.papHandles[idxHandle]; 7666 if (pHandle != NULL) 7667 { 7668 switch (pHandle->enmType) 7669 { 7820 if (pHandle != NULL) 7821 { 7822 switch (pHandle->enmType) 7823 { 7670 7824 # ifdef WITH_TEMP_MEMORY_FILES 7671 case KWHANDLETYPE_TEMP_FILE: 7825 case KWHANDLETYPE_TEMP_FILE: 7826 { 7827 PKWFSTEMPFILE pTempFile = pHandle->u.pTempFile; 7828 7829 kHlpAssert(!pOverlapped); 7830 kHlpAssert(pcbActuallyWritten); 7831 7832 if (kwFsTempFileEnsureSpace(pTempFile, pHandle->offFile, cbToWrite)) 7672 7833 { 7673 PKWFSTEMPFILE pTempFile = pHandle->u.pTempFile; 7674 7675 kHlpAssert(!pOverlapped); 7676 kHlpAssert(pcbActuallyWritten); 7677 7678 if (kwFsTempFileEnsureSpace(pTempFile, pHandle->offFile, cbToWrite)) 7834 KU32 cbLeft; 7835 KU32 offSeg; 7836 7837 /* Locate the segment containing the byte at offFile. */ 7838 KWFSTEMPFILESEG const *paSegs = pTempFile->paSegs; 7839 KU32 iSeg = pTempFile->cSegs - 1; 7840 kHlpAssert(pTempFile->cSegs > 0); 7841 while (paSegs[iSeg].offData > pHandle->offFile) 7842 iSeg--; 7843 7844 /* Copy in the data. */ 7845 cbLeft = cbToWrite; 7846 offSeg = (pHandle->offFile - paSegs[iSeg].offData); 7847 for (;;) 7679 7848 { 7680 KU32 cbLeft; 7681 KU32 offSeg; 7682 7683 /* Locate the segment containing the byte at offFile. */ 7684 KWFSTEMPFILESEG const *paSegs = pTempFile->paSegs; 7685 KU32 iSeg = pTempFile->cSegs - 1; 7686 kHlpAssert(pTempFile->cSegs > 0); 7687 while (paSegs[iSeg].offData > pHandle->offFile) 7688 iSeg--; 7689 7690 /* Copy in the data. */ 7691 cbLeft = cbToWrite; 7692 offSeg = (pHandle->offFile - paSegs[iSeg].offData); 7693 for (;;) 7849 KU32 cbAvail = paSegs[iSeg].cbDataAlloc - offSeg; 7850 if (cbAvail >= cbLeft) 7694 7851 { 7695 KU32 cbAvail = paSegs[iSeg].cbDataAlloc - offSeg; 7696 if (cbAvail >= cbLeft) 7697 { 7698 kHlpMemCopy(&paSegs[iSeg].pbData[offSeg], pvBuffer, cbLeft); 7699 break; 7700 } 7701 7702 kHlpMemCopy(&paSegs[iSeg].pbData[offSeg], pvBuffer, cbAvail); 7703 pvBuffer = (KU8 const *)pvBuffer + cbAvail; 7704 cbLeft -= cbAvail; 7705 offSeg = 0; 7706 iSeg++; 7707 kHlpAssert(iSeg < pTempFile->cSegs); 7852 kHlpMemCopy(&paSegs[iSeg].pbData[offSeg], pvBuffer, cbLeft); 7853 break; 7708 7854 } 7709 7855 7710 /* Update the file offset. */ 7711 pHandle->offFile += cbToWrite; 7712 if (pHandle->offFile > pTempFile->cbFile) 7713 pTempFile->cbFile = pHandle->offFile; 7714 7715 *pcbActuallyWritten = cbToWrite; 7716 7717 g_cbWriteFileTotal += cbToWrite; 7718 g_cbWriteFileToInMemTemp += cbToWrite; 7719 g_cWriteFileToInMemTemp++; 7720 7721 KWFS_LOG(("WriteFile(%p,,%#x) -> TRUE [temp]\n", hFile, cbToWrite)); 7722 return TRUE; 7856 kHlpMemCopy(&paSegs[iSeg].pbData[offSeg], pvBuffer, cbAvail); 7857 pvBuffer = (KU8 const *)pvBuffer + cbAvail; 7858 cbLeft -= cbAvail; 7859 offSeg = 0; 7860 iSeg++; 7861 kHlpAssert(iSeg < pTempFile->cSegs); 7723 7862 } 7724 7863 7725 kHlpAssertFailed(); 7726 *pcbActuallyWritten = 0; 7727 SetLastError(ERROR_NOT_ENOUGH_MEMORY); 7728 return FALSE; 7729 } 7730 # endif 7731 7732 case KWHANDLETYPE_FSOBJ_READ_CACHE: 7733 kHlpAssertFailed(); 7734 SetLastError(ERROR_ACCESS_DENIED); 7735 *pcbActuallyWritten = 0; 7736 return FALSE; 7737 7738 # if defined(WITH_STD_OUT_ERR_BUFFERING) || defined(WITH_CONSOLE_OUTPUT_BUFFERING) 7739 /* 7740 * Standard output & error. 7741 */ 7742 case KWHANDLETYPE_OUTPUT_BUF: 7743 { 7744 PKWOUTPUTSTREAMBUF pOutBuf = pHandle->u.pOutBuf; 7745 if (pOutBuf->fIsConsole) 7746 { 7747 kwSandboxConsoleWriteA(&g_Sandbox, pOutBuf, (const char *)pvBuffer, cbToWrite); 7748 KWOUT_LOG(("WriteFile(%p [console]) -> TRUE\n", hFile)); 7749 } 7750 else 7751 { 7752 # ifdef WITH_STD_OUT_ERR_BUFFERING 7753 kwSandboxOutBufWrite(&g_Sandbox, pOutBuf, (const char *)pvBuffer, cbToWrite); 7754 KWOUT_LOG(("WriteFile(%p [std%s], 's*.*', %#x) -> TRUE\n", hFile, 7755 pOutBuf == &g_Sandbox.StdErr ? "err" : "out", cbToWrite, cbToWrite, pvBuffer, cbToWrite)); 7756 # else 7757 kHlpAssertFailed(); 7758 # endif 7759 } 7760 if (pcbActuallyWritten) 7761 *pcbActuallyWritten = cbToWrite; 7864 /* Update the file offset. */ 7865 pHandle->offFile += cbToWrite; 7866 if (pHandle->offFile > pTempFile->cbFile) 7867 pTempFile->cbFile = pHandle->offFile; 7868 7869 *pcbActuallyWritten = cbToWrite; 7870 7762 7871 g_cbWriteFileTotal += cbToWrite; 7872 g_cbWriteFileToInMemTemp += cbToWrite; 7873 g_cWriteFileToInMemTemp++; 7874 7875 KWFS_LOG(("WriteFile(%p,,%#x) -> TRUE [temp]\n", hFile, cbToWrite)); 7876 kwSandboxHandlePut(pHandle); 7763 7877 return TRUE; 7764 7878 } 7879 7880 kHlpAssertFailed(); 7881 kwSandboxHandlePut(pHandle); 7882 *pcbActuallyWritten = 0; 7883 SetLastError(ERROR_NOT_ENOUGH_MEMORY); 7884 return FALSE; 7885 } 7765 7886 # endif 7766 7887 7767 default: 7888 case KWHANDLETYPE_FSOBJ_READ_CACHE: 7889 kHlpAssertFailed(); 7890 kwSandboxHandlePut(pHandle); 7891 SetLastError(ERROR_ACCESS_DENIED); 7892 *pcbActuallyWritten = 0; 7893 return FALSE; 7894 7895 # if defined(WITH_STD_OUT_ERR_BUFFERING) || defined(WITH_CONSOLE_OUTPUT_BUFFERING) 7896 /* 7897 * Standard output & error. 7898 */ 7899 case KWHANDLETYPE_OUTPUT_BUF: 7900 { 7901 PKWOUTPUTSTREAMBUF pOutBuf = pHandle->u.pOutBuf; 7902 if (pOutBuf->fIsConsole) 7903 { 7904 kwSandboxConsoleWriteA(&g_Sandbox, pOutBuf, (const char *)pvBuffer, cbToWrite); 7905 KWOUT_LOG(("WriteFile(%p [console]) -> TRUE\n", hFile)); 7906 } 7907 else 7908 { 7909 # ifdef WITH_STD_OUT_ERR_BUFFERING 7910 kwSandboxOutBufWrite(&g_Sandbox, pOutBuf, (const char *)pvBuffer, cbToWrite); 7911 KWOUT_LOG(("WriteFile(%p [std%s], 's*.*', %#x) -> TRUE\n", hFile, 7912 pOutBuf == &g_Sandbox.StdErr ? "err" : "out", cbToWrite, cbToWrite, pvBuffer, cbToWrite)); 7913 # else 7914 kHlpAssertFailed(); 7915 # endif 7916 } 7917 if (pcbActuallyWritten) 7918 *pcbActuallyWritten = cbToWrite; 7919 g_cbWriteFileTotal += cbToWrite; 7920 kwSandboxHandlePut(pHandle); 7921 return TRUE; 7922 } 7923 # endif 7924 7925 default: 7768 7926 #ifdef WITH_TEMP_MEMORY_FILES 7769 7927 case KWHANDLETYPE_TEMP_FILE_MAPPING: 7770 7928 #endif 7771 7772 SetLastError(ERROR_INVALID_FUNCTION);7773 *pcbActuallyWritten = 0;7774 return FALSE;7775 }7929 kHlpAssertFailed(); 7930 kwSandboxHandlePut(pHandle); 7931 SetLastError(ERROR_INVALID_FUNCTION); 7932 *pcbActuallyWritten = 0; 7933 return FALSE; 7776 7934 } 7777 7935 } … … 7789 7947 LPOVERLAPPED_COMPLETION_ROUTINE pfnCompletionRoutine) 7790 7948 { 7791 KUPTR const idxHandle = KW_HANDLE_TO_INDEX(hFile); 7792 kHlpAssert(GetCurrentThreadId() == g_Sandbox.idMainThread); 7793 if (idxHandle < g_Sandbox.cHandles) 7794 { 7795 PKWHANDLE pHandle = g_Sandbox.papHandles[idxHandle]; 7796 if (pHandle != NULL) 7797 { 7798 kHlpAssertFailed(); 7799 } 7800 } 7949 kHlpAssert(kwSandboxHandleLookup(hFile) == NULL); 7801 7950 7802 7951 KWFS_LOG(("WriteFileEx(%p)\n", hFile)); … … 7811 7960 static BOOL WINAPI kwSandbox_Kernel32_SetEndOfFile(HANDLE hFile) 7812 7961 { 7813 KUPTR const idxHandle = KW_HANDLE_TO_INDEX(hFile);7814 kHlpAssert(GetCurrentThreadId() == g_Sandbox.idMainThread);7815 if (idxHandle < g_Sandbox.cHandles)7816 {7817 PKWHANDLE pHandle = g_Sandbox.papHandles[idxHandle];7818 if (pHandle != NULL)7819 {7820 switch (pHandle->enmType)7821 {7822 case KWHANDLETYPE_TEMP_FILE:7962 PKWHANDLE pHandle = kwSandboxHandleGet(hFile); 7963 if (pHandle != NULL) 7964 { 7965 switch (pHandle->enmType) 7966 { 7967 case KWHANDLETYPE_TEMP_FILE: 7968 { 7969 PKWFSTEMPFILE pTempFile = pHandle->u.pTempFile; 7970 if ( pHandle->offFile > pTempFile->cbFile 7971 && !kwFsTempFileEnsureSpace(pTempFile, pHandle->offFile, 0)) 7823 7972 { 7824 PKWFSTEMPFILE pTempFile = pHandle->u.pTempFile; 7825 if ( pHandle->offFile > pTempFile->cbFile 7826 && !kwFsTempFileEnsureSpace(pTempFile, pHandle->offFile, 0)) 7827 { 7828 kHlpAssertFailed(); 7829 SetLastError(ERROR_NOT_ENOUGH_MEMORY); 7830 return FALSE; 7831 } 7832 7833 pTempFile->cbFile = pHandle->offFile; 7834 KWFS_LOG(("SetEndOfFile(%p) -> TRUE (cbFile=%#x)\n", hFile, pTempFile->cbFile)); 7835 return TRUE; 7973 kHlpAssertFailed(); 7974 kwSandboxHandlePut(pHandle); 7975 SetLastError(ERROR_NOT_ENOUGH_MEMORY); 7976 return FALSE; 7836 7977 } 7837 7978 7838 case KWHANDLETYPE_FSOBJ_READ_CACHE: 7839 kHlpAssertFailed(); 7840 SetLastError(ERROR_ACCESS_DENIED); 7841 return FALSE; 7979 pTempFile->cbFile = pHandle->offFile; 7980 KWFS_LOG(("SetEndOfFile(%p) -> TRUE (cbFile=%#x)\n", hFile, pTempFile->cbFile)); 7981 kwSandboxHandlePut(pHandle); 7982 return TRUE; 7983 } 7984 7985 case KWHANDLETYPE_FSOBJ_READ_CACHE: 7986 kHlpAssertFailed(); 7987 kwSandboxHandlePut(pHandle); 7988 SetLastError(ERROR_ACCESS_DENIED); 7989 return FALSE; 7842 7990 7843 7991 # ifdef WITH_CONSOLE_OUTPUT_BUFFERING 7844 case KWHANDLETYPE_OUTPUT_BUF: 7845 kHlpAssertFailed(); 7846 SetLastError(pHandle->u.pOutBuf->fIsConsole ? ERROR_INVALID_OPERATION : ERROR_ACCESS_DENIED); 7847 return FALSE; 7992 case KWHANDLETYPE_OUTPUT_BUF: 7993 kHlpAssertFailed(); 7994 kwSandboxHandlePut(pHandle); 7995 SetLastError(pHandle->u.pOutBuf->fIsConsole ? ERROR_INVALID_OPERATION : ERROR_ACCESS_DENIED); 7996 return FALSE; 7848 7997 # endif 7849 7998 7850 7851 7852 7853 SetLastError(ERROR_INVALID_FUNCTION);7854 return FALSE;7855 }7999 default: 8000 case KWHANDLETYPE_TEMP_FILE_MAPPING: 8001 kHlpAssertFailed(); 8002 kwSandboxHandlePut(pHandle); 8003 SetLastError(ERROR_INVALID_FUNCTION); 8004 return FALSE; 7856 8005 } 7857 8006 } … … 7865 8014 static BOOL WINAPI kwSandbox_Kernel32_GetFileType(HANDLE hFile) 7866 8015 { 7867 KUPTR const idxHandle = KW_HANDLE_TO_INDEX(hFile); 7868 kHlpAssert(GetCurrentThreadId() == g_Sandbox.idMainThread); 7869 if (idxHandle < g_Sandbox.cHandles) 7870 { 7871 PKWHANDLE pHandle = g_Sandbox.papHandles[idxHandle]; 7872 if (pHandle != NULL) 7873 { 7874 switch (pHandle->enmType) 7875 { 7876 case KWHANDLETYPE_FSOBJ_READ_CACHE: 7877 KWFS_LOG(("GetFileType(%p) -> FILE_TYPE_DISK [cached]\n", hFile)); 7878 return FILE_TYPE_DISK; 7879 7880 case KWHANDLETYPE_TEMP_FILE: 7881 KWFS_LOG(("GetFileType(%p) -> FILE_TYPE_DISK [temp]\n", hFile)); 7882 return FILE_TYPE_DISK; 8016 PKWHANDLE pHandle = kwSandboxHandleGet(hFile); 8017 if (pHandle != NULL) 8018 { 8019 switch (pHandle->enmType) 8020 { 8021 case KWHANDLETYPE_FSOBJ_READ_CACHE: 8022 KWFS_LOG(("GetFileType(%p) -> FILE_TYPE_DISK [cached]\n", hFile)); 8023 kwSandboxHandlePut(pHandle); 8024 return FILE_TYPE_DISK; 8025 8026 case KWHANDLETYPE_TEMP_FILE: 8027 KWFS_LOG(("GetFileType(%p) -> FILE_TYPE_DISK [temp]\n", hFile)); 8028 kwSandboxHandlePut(pHandle); 8029 return FILE_TYPE_DISK; 7883 8030 7884 8031 #ifdef WITH_CONSOLE_OUTPUT_BUFFERING 7885 case KWHANDLETYPE_OUTPUT_BUF: 8032 case KWHANDLETYPE_OUTPUT_BUF: 8033 { 8034 PKWOUTPUTSTREAMBUF pOutBuf = pHandle->u.pOutBuf; 8035 DWORD fRet; 8036 if (pOutBuf->fFileType != KU8_MAX) 7886 8037 { 7887 PKWOUTPUTSTREAMBUF pOutBuf = pHandle->u.pOutBuf; 7888 DWORD fRet; 7889 if (pOutBuf->fFileType != KU8_MAX) 7890 { 7891 fRet = (pOutBuf->fFileType & 0xf) | ((pOutBuf->fFileType & (FILE_TYPE_REMOTE >> 8)) << 8); 7892 KWFS_LOG(("GetFileType(%p) -> %#x [outbuf]\n", hFile, fRet)); 7893 } 7894 else 7895 { 7896 fRet = GetFileType(hFile); 7897 KWFS_LOG(("GetFileType(%p) -> %#x [outbuf, fallback]\n", hFile, fRet)); 7898 } 7899 return fRet; 8038 fRet = (pOutBuf->fFileType & 0xf) | ((pOutBuf->fFileType & (FILE_TYPE_REMOTE >> 8)) << 8); 8039 KWFS_LOG(("GetFileType(%p) -> %#x [outbuf]\n", hFile, fRet)); 7900 8040 } 8041 else 8042 { 8043 fRet = GetFileType(hFile); 8044 KWFS_LOG(("GetFileType(%p) -> %#x [outbuf, fallback]\n", hFile, fRet)); 8045 } 8046 kwSandboxHandlePut(pHandle); 8047 return fRet; 8048 } 7901 8049 #endif 7902 7903 } 7904 } 8050 } 8051 kwSandboxHandlePut(pHandle); 7905 8052 } 7906 8053 … … 7913 8060 static DWORD WINAPI kwSandbox_Kernel32_GetFileSize(HANDLE hFile, LPDWORD pcbHighDword) 7914 8061 { 7915 KUPTR const idxHandle = KW_HANDLE_TO_INDEX(hFile); 7916 kHlpAssert(GetCurrentThreadId() == g_Sandbox.idMainThread); 7917 if (idxHandle < g_Sandbox.cHandles) 7918 { 7919 PKWHANDLE pHandle = g_Sandbox.papHandles[idxHandle]; 7920 if (pHandle != NULL) 7921 { 7922 if (pcbHighDword) 7923 *pcbHighDword = 0; 7924 SetLastError(NO_ERROR); 7925 switch (pHandle->enmType) 7926 { 7927 case KWHANDLETYPE_FSOBJ_READ_CACHE: 7928 KWFS_LOG(("GetFileSize(%p) -> %#x [cached]\n", hFile, pHandle->u.pCachedFile->cbCached)); 7929 return pHandle->u.pCachedFile->cbCached; 7930 7931 case KWHANDLETYPE_TEMP_FILE: 7932 KWFS_LOG(("GetFileSize(%p) -> %#x [temp]\n", hFile, pHandle->u.pTempFile->cbFile)); 7933 return pHandle->u.pTempFile->cbFile; 7934 7935 case KWHANDLETYPE_OUTPUT_BUF: 7936 /* do default */ 7937 break; 7938 7939 default: 7940 kHlpAssertFailed(); 7941 SetLastError(ERROR_INVALID_FUNCTION); 7942 return INVALID_FILE_SIZE; 7943 } 7944 } 8062 PKWHANDLE pHandle = kwSandboxHandleGet(hFile); 8063 if (pHandle != NULL) 8064 { 8065 if (pcbHighDword) 8066 *pcbHighDword = 0; 8067 SetLastError(NO_ERROR); 8068 switch (pHandle->enmType) 8069 { 8070 case KWHANDLETYPE_FSOBJ_READ_CACHE: 8071 KWFS_LOG(("GetFileSize(%p) -> %#x [cached]\n", hFile, pHandle->u.pCachedFile->cbCached)); 8072 kwSandboxHandlePut(pHandle); 8073 return pHandle->u.pCachedFile->cbCached; 8074 8075 case KWHANDLETYPE_TEMP_FILE: 8076 KWFS_LOG(("GetFileSize(%p) -> %#x [temp]\n", hFile, pHandle->u.pTempFile->cbFile)); 8077 kwSandboxHandlePut(pHandle); 8078 return pHandle->u.pTempFile->cbFile; 8079 8080 case KWHANDLETYPE_OUTPUT_BUF: 8081 /* do default */ 8082 break; 8083 8084 default: 8085 kHlpAssertFailed(); 8086 kwSandboxHandlePut(pHandle); 8087 SetLastError(ERROR_INVALID_FUNCTION); 8088 return INVALID_FILE_SIZE; 8089 } 8090 kwSandboxHandlePut(pHandle); 7945 8091 } 7946 8092 … … 7953 8099 static BOOL WINAPI kwSandbox_Kernel32_GetFileSizeEx(HANDLE hFile, PLARGE_INTEGER pcbFile) 7954 8100 { 7955 KUPTR const idxHandle = KW_HANDLE_TO_INDEX(hFile); 7956 kHlpAssert(GetCurrentThreadId() == g_Sandbox.idMainThread); 7957 if (idxHandle < g_Sandbox.cHandles) 7958 { 7959 PKWHANDLE pHandle = g_Sandbox.papHandles[idxHandle]; 7960 if (pHandle != NULL) 7961 { 7962 switch (pHandle->enmType) 7963 { 7964 case KWHANDLETYPE_FSOBJ_READ_CACHE: 7965 KWFS_LOG(("GetFileSizeEx(%p) -> TRUE, %#x [cached]\n", hFile, pHandle->u.pCachedFile->cbCached)); 7966 pcbFile->QuadPart = pHandle->u.pCachedFile->cbCached; 7967 return TRUE; 7968 7969 case KWHANDLETYPE_TEMP_FILE: 7970 KWFS_LOG(("GetFileSizeEx(%p) -> TRUE, %#x [temp]\n", hFile, pHandle->u.pTempFile->cbFile)); 7971 pcbFile->QuadPart = pHandle->u.pTempFile->cbFile; 7972 return TRUE; 7973 7974 case KWHANDLETYPE_OUTPUT_BUF: 7975 /* do default */ 7976 break; 7977 7978 default: 7979 kHlpAssertFailed(); 7980 SetLastError(ERROR_INVALID_FUNCTION); 7981 return INVALID_FILE_SIZE; 7982 } 7983 } 8101 PKWHANDLE pHandle = kwSandboxHandleGet(hFile); 8102 if (pHandle != NULL) 8103 { 8104 switch (pHandle->enmType) 8105 { 8106 case KWHANDLETYPE_FSOBJ_READ_CACHE: 8107 KWFS_LOG(("GetFileSizeEx(%p) -> TRUE, %#x [cached]\n", hFile, pHandle->u.pCachedFile->cbCached)); 8108 pcbFile->QuadPart = pHandle->u.pCachedFile->cbCached; 8109 kwSandboxHandlePut(pHandle); 8110 return TRUE; 8111 8112 case KWHANDLETYPE_TEMP_FILE: 8113 KWFS_LOG(("GetFileSizeEx(%p) -> TRUE, %#x [temp]\n", hFile, pHandle->u.pTempFile->cbFile)); 8114 pcbFile->QuadPart = pHandle->u.pTempFile->cbFile; 8115 kwSandboxHandlePut(pHandle); 8116 return TRUE; 8117 8118 case KWHANDLETYPE_OUTPUT_BUF: 8119 /* do default */ 8120 break; 8121 8122 default: 8123 kHlpAssertFailed(); 8124 kwSandboxHandlePut(pHandle); 8125 SetLastError(ERROR_INVALID_FUNCTION); 8126 return INVALID_FILE_SIZE; 8127 } 8128 kwSandboxHandlePut(pHandle); 7984 8129 } 7985 8130 … … 7995 8140 { 7996 8141 HANDLE hMapping; 7997 KUPTR const idxHandle = KW_HANDLE_TO_INDEX(hFile); 7998 kHlpAssert(GetCurrentThreadId() == g_Sandbox.idMainThread); 7999 if (idxHandle < g_Sandbox.cHandles) 8000 { 8001 PKWHANDLE pHandle = g_Sandbox.papHandles[idxHandle]; 8002 if (pHandle != NULL) 8003 { 8004 switch (pHandle->enmType) 8005 { 8006 case KWHANDLETYPE_TEMP_FILE: 8142 PKWHANDLE pHandle = kwSandboxHandleGet(hFile); 8143 if (pHandle != NULL) 8144 { 8145 switch (pHandle->enmType) 8146 { 8147 case KWHANDLETYPE_TEMP_FILE: 8148 { 8149 PKWFSTEMPFILE pTempFile = pHandle->u.pTempFile; 8150 if ( ( fProtect == PAGE_READONLY 8151 || fProtect == PAGE_EXECUTE_READ) 8152 && dwMaximumSizeHigh == 0 8153 && ( dwMaximumSizeLow == 0 8154 || dwMaximumSizeLow == pTempFile->cbFile) 8155 && pwszName == NULL) 8007 8156 { 8008 PKWFSTEMPFILE pTempFile = pHandle->u.pTempFile; 8009 if ( ( fProtect == PAGE_READONLY 8010 || fProtect == PAGE_EXECUTE_READ) 8011 && dwMaximumSizeHigh == 0 8012 && ( dwMaximumSizeLow == 0 8013 || dwMaximumSizeLow == pTempFile->cbFile) 8014 && pwszName == NULL) 8015 { 8016 hMapping = kwFsTempFileCreateHandle(pHandle->u.pTempFile, GENERIC_READ, K_TRUE /*fMapping*/); 8017 KWFS_LOG(("CreateFileMappingW(%p, %u) -> %p [temp]\n", hFile, fProtect, hMapping)); 8018 return hMapping; 8019 } 8020 kHlpAssertMsgFailed(("fProtect=%#x cb=%#x'%08x name=%p\n", 8021 fProtect, dwMaximumSizeHigh, dwMaximumSizeLow, pwszName)); 8022 SetLastError(ERROR_ACCESS_DENIED); 8023 return INVALID_HANDLE_VALUE; 8024 } 8025 8026 /* moc.exe benefits from this. */ 8027 case KWHANDLETYPE_FSOBJ_READ_CACHE: 8028 { 8029 PKFSWCACHEDFILE pCachedFile = pHandle->u.pCachedFile; 8030 if ( ( fProtect == PAGE_READONLY 8031 || fProtect == PAGE_EXECUTE_READ) 8032 && dwMaximumSizeHigh == 0 8033 && ( dwMaximumSizeLow == 0 8034 || dwMaximumSizeLow == pCachedFile->cbCached) 8035 && pwszName == NULL) 8036 { 8037 if (kwFsObjCacheCreateFileHandle(pCachedFile, GENERIC_READ, FALSE /*fInheritHandle*/, 8038 K_FALSE /*fIsFileHandle*/, &hMapping)) 8039 { /* likely */ } 8040 else 8041 hMapping = NULL; 8042 KWFS_LOG(("CreateFileMappingW(%p, %u) -> %p [cached]\n", hFile, fProtect, hMapping)); 8043 return hMapping; 8044 } 8045 8046 /* Do fallback (for .pch). */ 8047 kHlpAssertMsg(fProtect == PAGE_WRITECOPY, 8048 ("fProtect=%#x cb=%#x'%08x name=%p\n", 8049 fProtect, dwMaximumSizeHigh, dwMaximumSizeLow, pwszName)); 8050 8051 hMapping = CreateFileMappingW(hFile, pSecAttrs, fProtect, dwMaximumSizeHigh, dwMaximumSizeLow, pwszName); 8052 KWFS_LOG(("CreateFileMappingW(%p, %p, %#x, %#x, %#x, %p) -> %p [cached-fallback]\n", 8053 hFile, pSecAttrs, fProtect, dwMaximumSizeHigh, dwMaximumSizeLow, pwszName, hMapping)); 8157 hMapping = kwFsTempFileCreateHandle(pHandle->u.pTempFile, GENERIC_READ, K_TRUE /*fMapping*/); 8158 KWFS_LOG(("CreateFileMappingW(%p, %u) -> %p [temp]\n", hFile, fProtect, hMapping)); 8159 kwSandboxHandlePut(pHandle); 8054 8160 return hMapping; 8055 8161 } 8056 8057 /** @todo read cached memory mapped files too for moc. */ 8058 } 8059 } 8162 kHlpAssertMsgFailed(("fProtect=%#x cb=%#x'%08x name=%p\n", 8163 fProtect, dwMaximumSizeHigh, dwMaximumSizeLow, pwszName)); 8164 kwSandboxHandlePut(pHandle); 8165 SetLastError(ERROR_ACCESS_DENIED); 8166 return INVALID_HANDLE_VALUE; 8167 } 8168 8169 /* moc.exe benefits from this. */ 8170 case KWHANDLETYPE_FSOBJ_READ_CACHE: 8171 { 8172 PKFSWCACHEDFILE pCachedFile = pHandle->u.pCachedFile; 8173 if ( ( fProtect == PAGE_READONLY 8174 || fProtect == PAGE_EXECUTE_READ) 8175 && dwMaximumSizeHigh == 0 8176 && ( dwMaximumSizeLow == 0 8177 || dwMaximumSizeLow == pCachedFile->cbCached) 8178 && pwszName == NULL) 8179 { 8180 if (kwFsObjCacheCreateFileHandle(pCachedFile, GENERIC_READ, FALSE /*fInheritHandle*/, 8181 K_FALSE /*fIsFileHandle*/, &hMapping)) 8182 { /* likely */ } 8183 else 8184 hMapping = NULL; 8185 KWFS_LOG(("CreateFileMappingW(%p, %u) -> %p [cached]\n", hFile, fProtect, hMapping)); 8186 kwSandboxHandlePut(pHandle); 8187 return hMapping; 8188 } 8189 8190 /* Do fallback (for .pch). */ 8191 kHlpAssertMsg(fProtect == PAGE_WRITECOPY, 8192 ("fProtect=%#x cb=%#x'%08x name=%p\n", 8193 fProtect, dwMaximumSizeHigh, dwMaximumSizeLow, pwszName)); 8194 8195 hMapping = CreateFileMappingW(hFile, pSecAttrs, fProtect, dwMaximumSizeHigh, dwMaximumSizeLow, pwszName); 8196 KWFS_LOG(("CreateFileMappingW(%p, %p, %#x, %#x, %#x, %p) -> %p [cached-fallback]\n", 8197 hFile, pSecAttrs, fProtect, dwMaximumSizeHigh, dwMaximumSizeLow, pwszName, hMapping)); 8198 kwSandboxHandlePut(pHandle); 8199 return hMapping; 8200 } 8201 8202 /** @todo read cached memory mapped files too for moc. */ 8203 } 8204 kwSandboxHandlePut(pHandle); 8060 8205 } 8061 8206 … … 8072 8217 { 8073 8218 PVOID pvRet; 8074 KUPTR const idxHandle = KW_HANDLE_TO_INDEX(hSection); 8075 kHlpAssert(GetCurrentThreadId() == g_Sandbox.idMainThread); 8076 if (idxHandle < g_Sandbox.cHandles) 8077 { 8078 PKWHANDLE pHandle = g_Sandbox.papHandles[idxHandle]; 8079 if (pHandle != NULL) 8080 { 8081 KU32 idxMapping; 8219 PKWHANDLE pHandle = kwSandboxHandleGet(hSection); 8220 if (pHandle != NULL) 8221 { 8222 KU32 idxMapping; 8223 8224 /* 8225 * Ensure one free entry in the mapping tracking table first, 8226 * since this is common to both temporary and cached files. 8227 */ 8228 if (g_Sandbox.cMemMappings + 1 <= g_Sandbox.cMemMappingsAlloc) 8229 { /* likely */ } 8230 else 8231 { 8232 void *pvNew; 8233 KU32 cNew = g_Sandbox.cMemMappingsAlloc; 8234 if (cNew) 8235 cNew *= 2; 8236 else 8237 cNew = 32; 8238 pvNew = kHlpRealloc(g_Sandbox.paMemMappings, cNew * sizeof(g_Sandbox.paMemMappings[0])); 8239 if (pvNew) 8240 g_Sandbox.paMemMappings = (PKWMEMMAPPING)pvNew; 8241 else 8242 { 8243 kwErrPrintf("Failed to grow paMemMappings from %#x to %#x!\n", g_Sandbox.cMemMappingsAlloc, cNew); 8244 kwSandboxHandlePut(pHandle); 8245 SetLastError(ERROR_NOT_ENOUGH_MEMORY); 8246 return NULL; 8247 } 8248 g_Sandbox.cMemMappingsAlloc = cNew; 8249 } 8250 8251 /* 8252 * Type specific work. 8253 */ 8254 switch (pHandle->enmType) 8255 { 8256 case KWHANDLETYPE_FSOBJ_READ_CACHE: 8257 case KWHANDLETYPE_TEMP_FILE: 8258 case KWHANDLETYPE_OUTPUT_BUF: 8259 default: 8260 kHlpAssertFailed(); 8261 kwSandboxHandlePut(pHandle); 8262 SetLastError(ERROR_INVALID_OPERATION); 8263 return NULL; 8264 8265 case KWHANDLETYPE_TEMP_FILE_MAPPING: 8266 { 8267 PKWFSTEMPFILE pTempFile = pHandle->u.pTempFile; 8268 if ( dwDesiredAccess == FILE_MAP_READ 8269 && offFileHigh == 0 8270 && offFileLow == 0 8271 && (cbToMap == 0 || cbToMap == pTempFile->cbFile) ) 8272 { 8273 kHlpAssert(pTempFile->cMappings == 0 || pTempFile->cSegs == 1); 8274 if (pTempFile->cSegs != 1) 8275 { 8276 KU32 iSeg; 8277 KU32 cbLeft; 8278 KU32 cbAll = pTempFile->cbFile ? (KU32)K_ALIGN_Z(pTempFile->cbFile, 0x2000) : 0x1000; 8279 KU8 *pbAll = NULL; 8280 int rc = kHlpPageAlloc((void **)&pbAll, cbAll, KPROT_READWRITE, K_FALSE); 8281 if (rc != 0) 8282 { 8283 kHlpAssertFailed(); 8284 SetLastError(ERROR_NOT_ENOUGH_MEMORY); 8285 return NULL; 8286 } 8287 8288 cbLeft = pTempFile->cbFile; 8289 for (iSeg = 0; iSeg < pTempFile->cSegs && cbLeft > 0; iSeg++) 8290 { 8291 KU32 cbToCopy = K_MIN(cbLeft, pTempFile->paSegs[iSeg].cbDataAlloc); 8292 kHlpMemCopy(&pbAll[pTempFile->paSegs[iSeg].offData], pTempFile->paSegs[iSeg].pbData, cbToCopy); 8293 cbLeft -= cbToCopy; 8294 } 8295 8296 for (iSeg = 0; iSeg < pTempFile->cSegs; iSeg++) 8297 { 8298 kHlpPageFree(pTempFile->paSegs[iSeg].pbData, pTempFile->paSegs[iSeg].cbDataAlloc); 8299 pTempFile->paSegs[iSeg].pbData = NULL; 8300 pTempFile->paSegs[iSeg].cbDataAlloc = 0; 8301 } 8302 8303 pTempFile->cSegs = 1; 8304 pTempFile->cbFileAllocated = cbAll; 8305 pTempFile->paSegs[0].cbDataAlloc = cbAll; 8306 pTempFile->paSegs[0].pbData = pbAll; 8307 pTempFile->paSegs[0].offData = 0; 8308 } 8309 8310 pTempFile->cMappings++; 8311 kHlpAssert(pTempFile->cMappings == 1); 8312 8313 pvRet = pTempFile->paSegs[0].pbData; 8314 KWFS_LOG(("CreateFileMappingW(%p) -> %p [temp]\n", hSection, pvRet)); 8315 break; 8316 } 8317 8318 kHlpAssertMsgFailed(("dwDesiredAccess=%#x offFile=%#x'%08x cbToMap=%#x (cbFile=%#x)\n", 8319 dwDesiredAccess, offFileHigh, offFileLow, cbToMap, pTempFile->cbFile)); 8320 kwSandboxHandlePut(pHandle); 8321 SetLastError(ERROR_NOT_ENOUGH_MEMORY); 8322 return NULL; 8323 } 8082 8324 8083 8325 /* 8084 * Ensure one free entry in the mapping tracking table first, 8085 * since this is common to both temporary and cached files. 8326 * This is simple in comparison to the above temporary file code. 8086 8327 */ 8087 if (g_Sandbox.cMemMappings + 1 <= g_Sandbox.cMemMappingsAlloc) 8088 { /* likely */ } 8089 else 8090 { 8091 void *pvNew; 8092 KU32 cNew = g_Sandbox.cMemMappingsAlloc; 8093 if (cNew) 8094 cNew *= 2; 8095 else 8096 cNew = 32; 8097 pvNew = kHlpRealloc(g_Sandbox.paMemMappings, cNew * sizeof(g_Sandbox.paMemMappings[0])); 8098 if (pvNew) 8099 g_Sandbox.paMemMappings = (PKWMEMMAPPING)pvNew; 8100 else 8328 case KWHANDLETYPE_FSOBJ_READ_CACHE_MAPPING: 8329 { 8330 PKFSWCACHEDFILE pCachedFile = pHandle->u.pCachedFile; 8331 if ( dwDesiredAccess == FILE_MAP_READ 8332 && offFileHigh == 0 8333 && offFileLow == 0 8334 && (cbToMap == 0 || cbToMap == pCachedFile->cbCached) ) 8101 8335 { 8102 kwErrPrintf("Failed to grow paMemMappings from %#x to %#x!\n", g_Sandbox.cMemMappingsAlloc, cNew);8103 SetLastError(ERROR_NOT_ENOUGH_MEMORY);8104 return NULL;8336 pvRet = pCachedFile->pbCached; 8337 KWFS_LOG(("CreateFileMappingW(%p) -> %p [cached]\n", hSection, pvRet)); 8338 break; 8105 8339 } 8106 g_Sandbox.cMemMappingsAlloc = cNew; 8107 } 8108 8109 /* 8110 * Type specific work. 8111 */ 8112 switch (pHandle->enmType) 8113 { 8114 case KWHANDLETYPE_FSOBJ_READ_CACHE: 8115 case KWHANDLETYPE_TEMP_FILE: 8116 case KWHANDLETYPE_OUTPUT_BUF: 8117 default: 8118 kHlpAssertFailed(); 8119 SetLastError(ERROR_INVALID_OPERATION); 8120 return NULL; 8121 8122 case KWHANDLETYPE_TEMP_FILE_MAPPING: 8123 { 8124 PKWFSTEMPFILE pTempFile = pHandle->u.pTempFile; 8125 if ( dwDesiredAccess == FILE_MAP_READ 8126 && offFileHigh == 0 8127 && offFileLow == 0 8128 && (cbToMap == 0 || cbToMap == pTempFile->cbFile) ) 8129 { 8130 kHlpAssert(pTempFile->cMappings == 0 || pTempFile->cSegs == 1); 8131 if (pTempFile->cSegs != 1) 8132 { 8133 KU32 iSeg; 8134 KU32 cbLeft; 8135 KU32 cbAll = pTempFile->cbFile ? (KU32)K_ALIGN_Z(pTempFile->cbFile, 0x2000) : 0x1000; 8136 KU8 *pbAll = NULL; 8137 int rc = kHlpPageAlloc((void **)&pbAll, cbAll, KPROT_READWRITE, K_FALSE); 8138 if (rc != 0) 8139 { 8140 kHlpAssertFailed(); 8141 SetLastError(ERROR_NOT_ENOUGH_MEMORY); 8142 return NULL; 8143 } 8144 8145 cbLeft = pTempFile->cbFile; 8146 for (iSeg = 0; iSeg < pTempFile->cSegs && cbLeft > 0; iSeg++) 8147 { 8148 KU32 cbToCopy = K_MIN(cbLeft, pTempFile->paSegs[iSeg].cbDataAlloc); 8149 kHlpMemCopy(&pbAll[pTempFile->paSegs[iSeg].offData], pTempFile->paSegs[iSeg].pbData, cbToCopy); 8150 cbLeft -= cbToCopy; 8151 } 8152 8153 for (iSeg = 0; iSeg < pTempFile->cSegs; iSeg++) 8154 { 8155 kHlpPageFree(pTempFile->paSegs[iSeg].pbData, pTempFile->paSegs[iSeg].cbDataAlloc); 8156 pTempFile->paSegs[iSeg].pbData = NULL; 8157 pTempFile->paSegs[iSeg].cbDataAlloc = 0; 8158 } 8159 8160 pTempFile->cSegs = 1; 8161 pTempFile->cbFileAllocated = cbAll; 8162 pTempFile->paSegs[0].cbDataAlloc = cbAll; 8163 pTempFile->paSegs[0].pbData = pbAll; 8164 pTempFile->paSegs[0].offData = 0; 8165 } 8166 8167 pTempFile->cMappings++; 8168 kHlpAssert(pTempFile->cMappings == 1); 8169 8170 pvRet = pTempFile->paSegs[0].pbData; 8171 KWFS_LOG(("CreateFileMappingW(%p) -> %p [temp]\n", hSection, pvRet)); 8172 break; 8173 } 8174 8175 kHlpAssertMsgFailed(("dwDesiredAccess=%#x offFile=%#x'%08x cbToMap=%#x (cbFile=%#x)\n", 8176 dwDesiredAccess, offFileHigh, offFileLow, cbToMap, pTempFile->cbFile)); 8177 SetLastError(ERROR_NOT_ENOUGH_MEMORY); 8178 return NULL; 8179 } 8180 8181 /* 8182 * This is simple in comparison to the above temporary file code. 8183 */ 8184 case KWHANDLETYPE_FSOBJ_READ_CACHE_MAPPING: 8185 { 8186 PKFSWCACHEDFILE pCachedFile = pHandle->u.pCachedFile; 8187 if ( dwDesiredAccess == FILE_MAP_READ 8188 && offFileHigh == 0 8189 && offFileLow == 0 8190 && (cbToMap == 0 || cbToMap == pCachedFile->cbCached) ) 8191 { 8192 pvRet = pCachedFile->pbCached; 8193 KWFS_LOG(("CreateFileMappingW(%p) -> %p [cached]\n", hSection, pvRet)); 8194 break; 8195 } 8196 kHlpAssertMsgFailed(("dwDesiredAccess=%#x offFile=%#x'%08x cbToMap=%#x (cbFile=%#x)\n", 8197 dwDesiredAccess, offFileHigh, offFileLow, cbToMap, pCachedFile->cbCached)); 8198 SetLastError(ERROR_NOT_ENOUGH_MEMORY); 8199 return NULL; 8200 } 8201 } 8202 8203 /* 8204 * Insert into the mapping tracking table. This is common 8205 * and we should only get here with a non-NULL pvRet. 8206 * 8207 * Note! We could look for duplicates and do ref counting, but it's 8208 * easier to just append for now. 8209 */ 8210 kHlpAssert(pvRet != NULL); 8211 idxMapping = g_Sandbox.cMemMappings; 8212 kHlpAssert(idxMapping < g_Sandbox.cMemMappingsAlloc); 8213 8214 g_Sandbox.paMemMappings[idxMapping].cRefs = 1; 8215 g_Sandbox.paMemMappings[idxMapping].pvMapping = pvRet; 8216 g_Sandbox.paMemMappings[idxMapping].enmType = pHandle->enmType; 8217 g_Sandbox.paMemMappings[idxMapping].u.pCachedFile = pHandle->u.pCachedFile; 8218 g_Sandbox.cMemMappings++; 8219 8220 return pvRet; 8221 } 8340 kHlpAssertMsgFailed(("dwDesiredAccess=%#x offFile=%#x'%08x cbToMap=%#x (cbFile=%#x)\n", 8341 dwDesiredAccess, offFileHigh, offFileLow, cbToMap, pCachedFile->cbCached)); 8342 kwSandboxHandlePut(pHandle); 8343 SetLastError(ERROR_NOT_ENOUGH_MEMORY); 8344 return NULL; 8345 } 8346 } 8347 8348 /* 8349 * Insert into the mapping tracking table. This is common 8350 * and we should only get here with a non-NULL pvRet. 8351 * 8352 * Note! We could look for duplicates and do ref counting, but it's 8353 * easier to just append for now. 8354 */ 8355 kHlpAssert(pvRet != NULL); 8356 idxMapping = g_Sandbox.cMemMappings; 8357 kHlpAssert(idxMapping < g_Sandbox.cMemMappingsAlloc); 8358 8359 g_Sandbox.paMemMappings[idxMapping].cRefs = 1; 8360 g_Sandbox.paMemMappings[idxMapping].pvMapping = pvRet; 8361 g_Sandbox.paMemMappings[idxMapping].enmType = pHandle->enmType; 8362 g_Sandbox.paMemMappings[idxMapping].u.pCachedFile = pHandle->u.pCachedFile; 8363 g_Sandbox.cMemMappings++; 8364 8365 kwSandboxHandlePut(pHandle); 8366 return pvRet; 8222 8367 } 8223 8368 … … 8234 8379 { 8235 8380 PVOID pvRet; 8236 KUPTR const idxHandle = KW_HANDLE_TO_INDEX(hSection); 8237 kHlpAssert(GetCurrentThreadId() == g_Sandbox.idMainThread); 8238 if (idxHandle < g_Sandbox.cHandles) 8239 { 8240 PKWHANDLE pHandle = g_Sandbox.papHandles[idxHandle]; 8241 if (pHandle != NULL) 8242 { 8243 switch (pHandle->enmType) 8244 { 8245 case KWHANDLETYPE_TEMP_FILE_MAPPING: 8246 KWFS_LOG(("MapViewOfFileEx(%p, %#x, %#x, %#x, %#x, %p) - temporary file!\n", 8247 hSection, dwDesiredAccess, offFileHigh, offFileLow, cbToMap, pvMapAddr)); 8248 if (!pvMapAddr) 8249 return kwSandbox_Kernel32_MapViewOfFile(hSection, dwDesiredAccess, offFileHigh, offFileLow, cbToMap); 8381 PKWHANDLE pHandle = kwSandboxHandleGet(hSection); 8382 if (pHandle != NULL) 8383 { 8384 switch (pHandle->enmType) 8385 { 8386 case KWHANDLETYPE_TEMP_FILE_MAPPING: 8387 KWFS_LOG(("MapViewOfFileEx(%p, %#x, %#x, %#x, %#x, %p) - temporary file!\n", 8388 hSection, dwDesiredAccess, offFileHigh, offFileLow, cbToMap, pvMapAddr)); 8389 if (!pvMapAddr) 8390 pvRet = kwSandbox_Kernel32_MapViewOfFile(hSection, dwDesiredAccess, offFileHigh, offFileLow, cbToMap); 8391 else 8392 { 8250 8393 kHlpAssertFailed(); 8251 8394 SetLastError(ERROR_NOT_ENOUGH_MEMORY); 8252 return NULL; 8253 8254 case KWHANDLETYPE_FSOBJ_READ_CACHE_MAPPING: 8255 KWFS_LOG(("MapViewOfFileEx(%p, %#x, %#x, %#x, %#x, %p) - read cached file!\n", 8256 hSection, dwDesiredAccess, offFileHigh, offFileLow, cbToMap, pvMapAddr)); 8257 if (!pvMapAddr) 8258 return kwSandbox_Kernel32_MapViewOfFile(hSection, dwDesiredAccess, offFileHigh, offFileLow, cbToMap); 8259 /* We can use fallback here as the handle is an actual section handle. */ 8260 break; 8261 8262 case KWHANDLETYPE_FSOBJ_READ_CACHE: 8263 case KWHANDLETYPE_TEMP_FILE: 8264 case KWHANDLETYPE_OUTPUT_BUF: 8265 default: 8266 kHlpAssertFailed(); 8267 SetLastError(ERROR_INVALID_OPERATION); 8268 return NULL; 8269 } 8270 } 8395 } 8396 kwSandboxHandlePut(pHandle); 8397 return NULL; 8398 8399 case KWHANDLETYPE_FSOBJ_READ_CACHE_MAPPING: 8400 KWFS_LOG(("MapViewOfFileEx(%p, %#x, %#x, %#x, %#x, %p) - read cached file!\n", 8401 hSection, dwDesiredAccess, offFileHigh, offFileLow, cbToMap, pvMapAddr)); 8402 if (!pvMapAddr) 8403 { 8404 pvRet = kwSandbox_Kernel32_MapViewOfFile(hSection, dwDesiredAccess, offFileHigh, offFileLow, cbToMap); 8405 kwSandboxHandlePut(pHandle); 8406 return pvRet; 8407 } 8408 /* We can use fallback here as the handle is an actual section handle. */ 8409 break; 8410 8411 case KWHANDLETYPE_FSOBJ_READ_CACHE: 8412 case KWHANDLETYPE_TEMP_FILE: 8413 case KWHANDLETYPE_OUTPUT_BUF: 8414 default: 8415 kHlpAssertFailed(); 8416 kwSandboxHandlePut(pHandle); 8417 SetLastError(ERROR_INVALID_OPERATION); 8418 return NULL; 8419 } 8420 kwSandboxHandlePut(pHandle); 8271 8421 } 8272 8422 … … 8329 8479 if (hSrcProc == GetCurrentProcess()) 8330 8480 { 8331 KUPTR const idxHandle = KW_HANDLE_TO_INDEX(hSrc); 8332 kHlpAssert(GetCurrentThreadId() == g_Sandbox.idMainThread); 8333 if (idxHandle < g_Sandbox.cHandles) 8334 { 8335 PKWHANDLE pHandle = g_Sandbox.papHandles[idxHandle]; 8336 if (pHandle) 8337 { 8338 fRet = DuplicateHandle(hSrcProc, hSrc, hDstProc, phNew, dwDesiredAccess, fInheritHandle, dwOptions); 8339 if (fRet) 8481 PKWHANDLE pHandle = kwSandboxHandleGet(hSrc); 8482 if (pHandle) 8483 { 8484 fRet = DuplicateHandle(hSrcProc, hSrc, hDstProc, phNew, dwDesiredAccess, fInheritHandle, dwOptions); 8485 if (fRet) 8486 { 8487 if (kwSandboxHandleTableEnter(&g_Sandbox, pHandle, *phNew)) 8340 8488 { 8341 if (kwSandboxHandleTableEnter(&g_Sandbox, pHandle, *phNew)) 8342 { 8343 pHandle->cRefs++; 8344 KWFS_LOG(("DuplicateHandle(%p, %p, %p, , %#x, %d, %#x) -> TRUE, %p [intercepted handle] enmType=%d cRef=%d\n", 8345 hSrcProc, hSrc, hDstProc, dwDesiredAccess, fInheritHandle, dwOptions, *phNew, 8346 pHandle->enmType, pHandle->cRefs)); 8347 } 8348 else 8349 { 8350 fRet = FALSE; 8351 SetLastError(ERROR_NOT_ENOUGH_MEMORY); 8352 KWFS_LOG(("DuplicateHandle(%p, %p, %p, , %#x, %d, %#x) -> !FALSE!, %p [intercepted handle] enmType=%d\n", 8353 hSrcProc, hSrc, hDstProc, dwDesiredAccess, fInheritHandle, dwOptions, *phNew, pHandle->enmType)); 8354 } 8489 pHandle->cRefs++; 8490 KWFS_LOG(("DuplicateHandle(%p, %p, %p, , %#x, %d, %#x) -> TRUE, %p [intercepted handle] enmType=%d cRef=%d\n", 8491 hSrcProc, hSrc, hDstProc, dwDesiredAccess, fInheritHandle, dwOptions, *phNew, 8492 pHandle->enmType, pHandle->cRefs)); 8355 8493 } 8356 8494 else 8357 KWFS_LOG(("DuplicateHandle(%p, %p, %p, , %#x, %d, %#x) -> FALSE [intercepted handle] enmType=%d\n", 8358 hSrcProc, hSrc, hDstProc, dwDesiredAccess, fInheritHandle, dwOptions, pHandle->enmType)); 8359 return fRet; 8360 } 8495 { 8496 fRet = FALSE; 8497 SetLastError(ERROR_NOT_ENOUGH_MEMORY); 8498 KWFS_LOG(("DuplicateHandle(%p, %p, %p, , %#x, %d, %#x) -> !FALSE!, %p [intercepted handle] enmType=%d\n", 8499 hSrcProc, hSrc, hDstProc, dwDesiredAccess, fInheritHandle, dwOptions, *phNew, pHandle->enmType)); 8500 } 8501 } 8502 else 8503 KWFS_LOG(("DuplicateHandle(%p, %p, %p, , %#x, %d, %#x) -> FALSE [intercepted handle] enmType=%d\n", 8504 hSrcProc, hSrc, hDstProc, dwDesiredAccess, fInheritHandle, dwOptions, pHandle->enmType)); 8505 kwSandboxHandlePut(pHandle); 8506 return fRet; 8361 8507 } 8362 8508 } … … 8377 8523 BOOL fRet; 8378 8524 KUPTR const idxHandle = KW_HANDLE_TO_INDEX(hObject); 8379 kHlpAssert(GetCurrentThreadId() == g_Sandbox.idMainThread || g_rcCtrlC != 0); 8380 if (idxHandle < g_Sandbox.cHandles) 8381 { 8382 PKWHANDLE pHandle = g_Sandbox.papHandles[idxHandle]; 8383 if (pHandle) 8384 { 8385 /* Prevent the closing of the standard output and error handles. */ 8386 if ( pHandle->enmType != KWHANDLETYPE_OUTPUT_BUF 8387 || idxHandle != KW_HANDLE_TO_INDEX(pHandle->hHandle)) 8388 { 8389 fRet = CloseHandle(hObject); 8390 if (fRet) 8525 PKWHANDLE pHandle = kwSandboxHandleGet(hObject); 8526 if (pHandle) 8527 { 8528 /* Prevent the closing of the standard output and error handles. */ 8529 if ( pHandle->enmType != KWHANDLETYPE_OUTPUT_BUF 8530 || idxHandle != KW_HANDLE_TO_INDEX(pHandle->hHandle) /* why this?!? */) 8531 { 8532 fRet = CloseHandle(hObject); 8533 if (fRet) 8534 { 8535 EnterCriticalSection(&g_Sandbox.HandlesLock); 8536 pHandle = g_Sandbox.papHandles[idxHandle]; 8537 g_Sandbox.papHandles[idxHandle] = NULL; 8538 g_Sandbox.cActiveHandles--; 8539 kHlpAssert(g_Sandbox.cActiveHandles >= g_Sandbox.cFixedHandles); 8540 if (--pHandle->cRefs == 0) 8391 8541 { 8392 PKWHANDLE pHandle = g_Sandbox.papHandles[idxHandle]; 8393 g_Sandbox.papHandles[idxHandle] = NULL; 8394 g_Sandbox.cActiveHandles--; 8395 kHlpAssert(g_Sandbox.cActiveHandles >= g_Sandbox.cFixedHandles); 8396 if (--pHandle->cRefs == 0) 8542 #ifdef WITH_TEMP_MEMORY_FILES 8543 if (pHandle->enmType == KWHANDLETYPE_TEMP_FILE) 8397 8544 { 8398 #ifdef WITH_TEMP_MEMORY_FILES 8399 if (pHandle->enmType == KWHANDLETYPE_TEMP_FILE) 8400 { 8401 kHlpAssert(pHandle->u.pTempFile->cActiveHandles > 0); 8402 pHandle->u.pTempFile->cActiveHandles--; 8403 } 8545 kHlpAssert(pHandle->u.pTempFile->cActiveHandles > 0); 8546 pHandle->u.pTempFile->cActiveHandles--; 8547 } 8404 8548 #endif 8405 kHlpFree(pHandle); 8406 KWFS_LOG(("CloseHandle(%p) -> TRUE [intercepted handle, freed]\n", hObject)); 8407 } 8408 else 8409 KWFS_LOG(("CloseHandle(%p) -> TRUE [intercepted handle, not freed]\n", hObject)); 8549 kHlpFree(pHandle); 8550 KWFS_LOG(("CloseHandle(%p) -> TRUE [intercepted handle, freed]\n", hObject)); 8410 8551 } 8411 8552 else 8412 KWFS_LOG(("CloseHandle(%p) -> FALSE [intercepted handle] err=%u!\n", hObject, GetLastError())); 8413 } 8414 else 8415 { 8553 { 8554 KWFS_LOG(("CloseHandle(%p) -> TRUE [intercepted handle, not freed]\n", hObject)); 8555 kwSandboxHandlePut(pHandle); 8556 } 8557 LeaveCriticalSection(&g_Sandbox.HandlesLock); 8558 return fRet; 8559 } 8560 KWFS_LOG(("CloseHandle(%p) -> FALSE [intercepted handle] err=%u!\n", hObject, GetLastError())); 8561 } 8562 else 8563 { 8416 8564 #ifdef WITH_CONSOLE_OUTPUT_BUFFERING 8417 8418 8565 KWFS_LOG(("CloseHandle(%p) -> TRUE [intercepted handle] Ignored closing of std%s!\n", 8566 hObject, hObject == g_Sandbox.StdErr.hOutput ? "err" : "out")); 8419 8567 #else 8420 8568 KWFS_LOG(("CloseHandle(%p) -> TRUE [intercepted handle] Ignored closing of stdXXX!\n", hObject)); 8421 8569 #endif 8422 8423 8424 return fRet;8425 }8570 fRet = TRUE; 8571 } 8572 kwSandboxHandlePut(pHandle); 8573 return fRet; 8426 8574 } 8427 8575 … … 9349 9497 KW_LOG(("VirtualAlloc: pvAddr=%p cb=%p type=%#x prot=%#x -> %p (last=%d)\n", 9350 9498 pvAddr, cb, fAllocType, fProt, pvMem, GetLastError())); 9351 if (pvAddr && pvAddr != pvMem) 9499 if ( pvAddr 9500 && pvAddr != pvMem 9501 && !( fAllocType == MEM_RESERVE /* After mapping the PCH, VS2019 ends up here (happens */ 9502 && fProt == PAGE_READWRITE /* in real cl.exe runs too). Just shut it up to avoid confusion. */ 9503 #if K_ARCH_BITS >= 64 9504 && cb > 0x10000000 /* seen 67c00000, 33e00000, ++ */ 9505 #else 9506 && cb > 0x04000000 /* no idea */ 9507 #endif 9508 ) 9509 ) 9352 9510 kwErrPrintf("VirtualAlloc %p LB %#x (%#x,%#x) failed: %p / %u\n", 9353 9511 pvAddr, cb, fAllocType, fProt, pvMem, GetLastError()); … … 10346 10504 pXcptRec = (PEXCEPTION_RECORD)alloca(sizeof(*pXcptRec)); 10347 10505 kHlpMemSet(pXcptRec, 0, sizeof(*pXcptRec)); 10348 pXcptRec->ExceptionCode = STATUS_UNWIND;10506 pXcptRec->ExceptionCode = (DWORD)STATUS_UNWIND; 10349 10507 pXcptRec->ExceptionFlags = EH_UNWINDING; 10350 10508 } … … 10435 10593 10436 10594 10595 /** @todo consider hooking NtQueryDirectoryFile as c1xx.dll/c1.dll in 2019 10596 * uses it directly to read the content of include directories, however 10597 * they do it one file at the time. We already have the info in the 10598 * cache (where we do bulk reads). There are a lot of calls for the 10599 * SDK include directories, as one can imagine. */ 10437 10600 10438 10601 /** … … 10912 11075 kHlpAssertReturn(idxHandle < KW_HANDLE_MAX, K_FALSE); 10913 11076 11077 EnterCriticalSection(&g_Sandbox.HandlesLock); 11078 10914 11079 /* 10915 11080 * Grow handle table. … … 10924 11089 if (!pvNew) 10925 11090 { 11091 LeaveCriticalSection(&g_Sandbox.HandlesLock); 10926 11092 KW_LOG(("Out of memory growing handle table to %u handles\n", cHandles)); 10927 11093 return K_FALSE; … … 10936 11102 * Check that the entry is unused then insert it. 10937 11103 */ 10938 kHlpAssert Return(pSandbox->papHandles[idxHandle] == NULL, K_FALSE);11104 kHlpAssertStmtReturn(pSandbox->papHandles[idxHandle] == NULL, LeaveCriticalSection(&g_Sandbox.HandlesLock), K_FALSE); 10939 11105 pSandbox->papHandles[idxHandle] = pHandle; 10940 11106 pSandbox->cActiveHandles++; 11107 LeaveCriticalSection(&g_Sandbox.HandlesLock); 10941 11108 return K_TRUE; 11109 } 11110 11111 11112 /** 11113 * Safely looks up a handle, does not get it and it must not be 'put'. 11114 * 11115 * @returns Pointer to the handle structure if found, otherwise NULL. 11116 * @param hFile The handle to resolve. 11117 */ 11118 static PKWHANDLE kwSandboxHandleLookup(HANDLE hFile) 11119 { 11120 KUPTR const idxHandle = KW_HANDLE_TO_INDEX(hFile); 11121 EnterCriticalSection(&g_Sandbox.HandlesLock); 11122 if (idxHandle < g_Sandbox.cHandles) 11123 { 11124 PKWHANDLE pHandle = g_Sandbox.papHandles[idxHandle]; 11125 LeaveCriticalSection(&g_Sandbox.HandlesLock); 11126 return pHandle; 11127 } 11128 LeaveCriticalSection(&g_Sandbox.HandlesLock); 11129 return NULL; 11130 } 11131 11132 11133 /** 11134 * Safely gets a handle, must be "put" when done with it. 11135 * 11136 * @returns Pointer to the handle structure if found, otherwise NULL. 11137 * @param hFile The handle to resolve. 11138 */ 11139 static PKWHANDLE kwSandboxHandleGet(HANDLE hFile) 11140 { 11141 KUPTR const idxHandle = KW_HANDLE_TO_INDEX(hFile); 11142 EnterCriticalSection(&g_Sandbox.HandlesLock); 11143 if (idxHandle < g_Sandbox.cHandles) 11144 { 11145 PKWHANDLE pHandle = g_Sandbox.papHandles[idxHandle]; 11146 if (pHandle) 11147 { 11148 kHlpAssertMsg(pHandle->tidOwner == KU32_MAX, ("hFile=%p tidOwner=%#x\n", hFile, pHandle->tidOwner)); 11149 pHandle->tidOwner = GetCurrentThreadId(); 11150 LeaveCriticalSection(&g_Sandbox.HandlesLock); 11151 return pHandle; 11152 } 11153 } 11154 LeaveCriticalSection(&g_Sandbox.HandlesLock); 11155 return NULL; 11156 } 11157 11158 11159 /** 11160 * Puts a handle returned by kwSandboxHandleGet. 11161 * 11162 * @param pHandle The handle to "put". 11163 */ 11164 K_INLINE void kwSandboxHandlePut(PKWHANDLE pHandle) 11165 { 11166 kHlpAssertMsg(pHandle->tidOwner == GetCurrentThreadId(), 11167 ("hFile tidOwner=%#x tidMe=%#x\n", pHandle->hHandle, pHandle->tidOwner, GetCurrentThreadId())); 11168 pHandle->tidOwner = KU32_MAX; 10942 11169 } 10943 11170 … … 11215 11442 11216 11443 /* Open handles, except fixed handles (stdout and stderr). */ 11444 EnterCriticalSection(&pSandbox->HandlesLock); 11217 11445 if (pSandbox->cActiveHandles > pSandbox->cFixedHandles) 11218 11446 { … … 11267 11495 kHlpAssert(pSandbox->cActiveHandles == pSandbox->cFixedHandles); 11268 11496 } 11497 LeaveCriticalSection(&pSandbox->HandlesLock); 11269 11498 11270 11499 /* Reset memory mappings - This assumes none of the DLLs keeps any of our mappings open! */ … … 11473 11702 if (rc == 0) 11474 11703 { 11704 if (g_cVerbose > 2) 11705 fprintf(stderr, "kWorker: info: Executing (sandboxed): %s\n", g_Sandbox.pszCmdLine); 11706 11475 11707 /* 11476 11708 * Do module initialization. … … 11799 12031 * Expand pszSpecialEnv if present. 11800 12032 */ 11801 if ( *pszSpecialEnv)12033 if (pszSpecialEnv && *pszSpecialEnv) 11802 12034 { 11803 12035 rcExit = kSubmitHandleSpecialEnvVar(cEnvVars, papszEnvVars, pszSpecialEnv, &pszSpecialEnvFree); … … 12619 12851 int rc = 0; 12620 12852 const char *pszArg = argv[i]; 12621 if (*pszArg == 'k' && kHlpStrComp(pszArg, "kSubmit") == 0) 12622 { 12623 if (*piState != 0) 12624 { 12625 pCur = (PKWONETEST)kHlpAllocZ(sizeof(*pCur)); 12626 if (!pCur) 12627 return kwErrPrintfRc(2, "Out of memory!\n"); 12628 pCur->fVirgin = K_TRUE; 12629 pCur->pszCwd = pszDefaultCwd; 12630 pCur->cRuns = 1; 12631 pCur->pNext = *ppHead; 12632 *ppHead = pCur; 12633 *piState = 0; 12634 } 12635 else if (!pCur->fVirgin) 12636 return kwErrPrintfRc(2, "Unexpected 'kSubmit' as argument #%u\n", i); 12637 pCur->pszJobSrc = pszJobSrc; 12638 pCur->iJobSrc = i; 12639 continue; /* (to stay virgin) */ 12640 } 12641 else if (*pszArg == '-' && *piState == 0) 12853 if (*pszArg == 'k') 12854 { 12855 if (kHlpStrComp(pszArg, "kSubmit") == 0) 12856 { 12857 if (*piState != 0) 12858 { 12859 pCur = (PKWONETEST)kHlpAllocZ(sizeof(*pCur)); 12860 if (!pCur) 12861 return kwErrPrintfRc(2, "Out of memory!\n"); 12862 pCur->fVirgin = K_TRUE; 12863 pCur->pszCwd = pszDefaultCwd; 12864 pCur->cRuns = 1; 12865 pCur->pNext = *ppHead; 12866 *ppHead = pCur; 12867 *piState = 0; 12868 } 12869 else if (!pCur->fVirgin) 12870 return kwErrPrintfRc(2, "Unexpected 'kSubmit' as argument #%u\n", i); 12871 pCur->pszJobSrc = pszJobSrc; 12872 pCur->iJobSrc = i; 12873 continue; /* (to stay virgin) */ 12874 } 12875 12876 /* Ignore "kWorker 378172/62:" sequences that kmk/kSubmit spews out on failure. */ 12877 if ( kHlpStrComp(pszArg, "kWorker") == 0 12878 && i + 1 < argc 12879 && (unsigned)(argv[i + 1][0] - '0') <= 9) 12880 { 12881 i++; 12882 continue; 12883 } 12884 } 12885 12886 if ( *pszArg == '-' 12887 && ( *piState == 0 12888 || pszArg[1] == '@')) 12642 12889 { 12643 12890 const char *pszValue = NULL; … … 12935 13182 } 12936 13183 #endif 13184 /// quick and dirty... 13185 LoadLibraryA("E:\\vbox\\svn\\trunk\\tools\\win.amd64\\vcc\\v14.2\\Tools\\MSVC\\14.26.28801\\bin\\Hostx64\\x64\\mspdbcore.dll"); 12937 13186 12938 13187 /* … … 12965 13214 return kwErrPrintfRc(3, "VirtualProtect(%p, %#x, PAGE_EXECUTE_READWRITE,NULL) failed: %u\n", 12966 13215 g_abDefLdBuf, sizeof(g_abDefLdBuf), GetLastError()); 13216 InitializeCriticalSection(&g_Sandbox.HandlesLock); 12967 13217 InitializeCriticalSection(&g_Sandbox.VirtualAllocLock); 12968 13218 … … 12983 13233 g_Sandbox.HandleStdOut.cRefs = 0x10001; 12984 13234 g_Sandbox.HandleStdOut.dwDesiredAccess = GENERIC_WRITE; 13235 g_Sandbox.HandleStdOut.tidOwner = KU32_MAX; 12985 13236 g_Sandbox.HandleStdOut.u.pOutBuf = &g_Sandbox.StdOut; 12986 13237 g_Sandbox.HandleStdOut.hHandle = g_Sandbox.StdOut.hOutput; … … 13007 13258 g_Sandbox.HandleStdErr.cRefs = 0x10001; 13008 13259 g_Sandbox.HandleStdErr.dwDesiredAccess = GENERIC_WRITE; 13260 g_Sandbox.HandleStdErr.tidOwner = KU32_MAX; 13009 13261 g_Sandbox.HandleStdErr.u.pOutBuf = &g_Sandbox.StdErr; 13010 13262 g_Sandbox.HandleStdErr.hHandle = g_Sandbox.StdErr.hOutput; … … 13129 13381 return kwErrPrintfRc(2, "--priority takes an argument!\n"); 13130 13382 } 13383 else if ( strcmp(argv[i], "--verbose") == 0 13384 || strcmp(argv[i], "-v") == 0) 13385 g_cVerbose++; 13131 13386 else if ( strcmp(argv[i], "--help") == 0 13132 13387 || strcmp(argv[i], "-h") == 0 … … 13136 13391 "usage: kWorker <--help|-h>\n" 13137 13392 "usage: kWorker <--version|-V>\n" 13393 "usage: kWorker [--volatile dir] --full-test kSubmit ...\n" 13138 13394 "usage: kWorker [--volatile dir] --test [<times> [--chdir <dir>] [--breakpoint] -- args\n" 13139 13395 "\n" -
trunk/src/kWorker/kWorkerTlsXxxK.c
r3361 r3366 34 34 * Structures and Typedefs * 35 35 *********************************************************************************************************************************/ 36 typedef void KWLDRTLSALLOCATIONHOOK(void *hDll, ULONG idxTls, PIMAGE_TLS_CALLBACK *ppfnTlsCallback); 36 typedef void KWLDRTLSCALLBACK(void *hDll, DWORD dwReason, void *pvContext, void *pvWorkerModule); 37 typedef KWLDRTLSCALLBACK *PKWLDRTLSCALLBACK; 38 typedef PKWLDRTLSCALLBACK KWLDRTLSALLOCATIONHOOK(void *hDll, ULONG idxTls, char *pabInitData, void **ppvWorkerModule); 37 39 38 40 … … 48 50 /** The TLS pointer array. The 2nd entry is NULL and serve to terminate the array. 49 51 * The first entry can be used by kWorker if it needs to. */ 50 __declspec(dllexport) PIMAGE_TLS_CALLBACK g_apfnTlsCallbacks[2]= { DummyTlsCallback, NULL };52 __declspec(dllexport) PIMAGE_TLS_CALLBACK g_apfnTlsCallbacks[2] = { DummyTlsCallback, NULL }; 51 53 52 54 /** 53 55 * The TLS index. 54 56 */ 55 __declspec(dllexport) ULONG g_idxTls = ~(ULONG)0; 57 __declspec(dllexport) ULONG g_idxTls = ~(ULONG)0; 58 59 /** 60 * Callback context. 61 */ 62 __declspec(dllexport) void *g_pvWorkerModule = NULL; 63 64 /** 65 * Regular callback method (returned by kwLdrTlsAllocationHook). 66 */ 67 __declspec(dllexport) PKWLDRTLSCALLBACK g_pfnWorkerCallback = NULL; 68 69 56 70 57 71 /** 58 72 * Initialization data. 73 * kWorker will copy the init data of the target DLL here. 59 74 */ 60 //static char const g_abDummy[TLS_SIZE] = {0x42}; 61 static char g_abDummy[TLS_SIZE] = {0}; 75 static char g_abInitData[TLS_SIZE] = {0}; 62 76 63 77 /** … … 68 82 __declspec(allocate(".rdata$T")) const IMAGE_TLS_DIRECTORY _tls_used = 69 83 { 70 (ULONG_PTR)&g_ab Dummy,71 (ULONG_PTR)&g_ab Dummy + sizeof(g_abDummy),84 (ULONG_PTR)&g_abInitData, 85 (ULONG_PTR)&g_abInitData + sizeof(g_abInitData), 72 86 (ULONG_PTR)&g_idxTls, 73 87 (ULONG_PTR)&g_apfnTlsCallbacks, … … 75 89 IMAGE_SCN_ALIGN_32BYTES 76 90 }; 91 92 93 /** 94 * Just a dummy callback function in case the allocation hook gambit fails below 95 * (see KWLDRTLSCALLBACK). 96 */ 97 static void DummyWorkerCallback(void *hDll, DWORD dwReason, void *pvContext, void *pvWorkerModule) 98 { 99 (void)hDll; (void)dwReason; (void)pvContext; (void)pvWorkerModule; 100 } 77 101 78 102 … … 86 110 __declspec(dllexport) void __stdcall DummyTlsCallback(void *hDll, DWORD dwReason, void *pvContext) 87 111 { 88 (void)hDll; (void)dwReason; (void)pvContext; 89 if (dwReason == DLL_PROCESS_ATTACH) 112 if (g_pfnWorkerCallback) 113 g_pfnWorkerCallback(hDll, dwReason, pvContext, g_pvWorkerModule); 114 else 90 115 { 91 //HMODULE hModExe = (HMODULE)(ULONG_PTR)KWORKER_BASE; 92 HMODULE hModExe = GetModuleHandleW(NULL); 93 KWLDRTLSALLOCATIONHOOK *pfnHook = (KWLDRTLSALLOCATIONHOOK *)GetProcAddress(hModExe, "kwLdrTlsAllocationHook"); 94 if (pfnHook) 116 g_pfnWorkerCallback = DummyWorkerCallback; 117 if (dwReason == DLL_PROCESS_ATTACH) 95 118 { 96 pfnHook(hDll, g_idxTls, &g_apfnTlsCallbacks[0]); 97 return; 119 HMODULE hModExe = GetModuleHandleW(NULL); 120 KWLDRTLSALLOCATIONHOOK *pfnHook = (KWLDRTLSALLOCATIONHOOK *)GetProcAddress(hModExe, "kwLdrTlsAllocationHook"); 121 if (pfnHook) 122 g_pfnWorkerCallback = pfnHook(hDll, g_idxTls, g_abInitData, &g_pvWorkerModule); 123 else 124 __debugbreak(); 98 125 } 99 __debugbreak();100 126 } 101 127 }
Note:
See TracChangeset
for help on using the changeset viewer.