VirtualBox

Changeset 3366 in kBuild for trunk


Ignore:
Timestamp:
Jun 9, 2020 11:53:39 PM (4 years ago)
Author:
bird
Message:

kWorker: More complete TLS handling. More TLS DLLs. Make handle table management thread safe. Lots more stack for new 201x compilers. ++

Location:
trunk/src/kWorker
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/kWorker/Makefile.kmk

    r3361 r3366  
    5555        /DYNAMICBASE:NO /FIXED
    5656kWorker_LDFLAGS.win.x86   = /BASE:0x00010000
    57 kWorker_LDFLAGS.win.amd64 = /BASE:0x0000000420000000
     57kWorker_LDFLAGS.win.amd64 = /BASE:0x0000000420000000 /STACK:16777216,262144
    5858
    5959#kWorker_LDFLAGS.win.x86 = \
     
    165165# A couple of dummy DLLs we use for grabbing LDR TLS entries.
    166166#
    167 DLLS += kWorkerTls1K kWorkerTls1K01 kWorkerTls1K02 kWorkerTls1K03 kWorkerTls1K04 kWorkerTls1K05 kWorkerTls1K06 kWorkerTls1K07 \
    168         kWorkerTls1K08 kWorkerTls1K09 kWorkerTls1K10 kWorkerTls1K11 kWorkerTls1K12 kWorkerTls1K13 kWorkerTls1K14 kWorkerTls1K15
     167DLLS += kWorkerTls1K kWorkerTls1K01 kWorkerTls1K02 kWorkerTls1K03 kWorkerTls1K04 kWorkerTls1K05 kWorkerTls1K06 kWorkerTls1K07
    169168kWorkerTls1K_TEMPLATE   = BIN-STATIC-THREADED
    170169kWorkerTls1K_DEFS       = TLS_SIZE=1024
     
    179178kWorkerTls1K06_EXTENDS = kWorkerTls1K
    180179kWorkerTls1K07_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
     182DLLS += kWorkerTls64K kWorkerTls64K01 kWorkerTls64K02 kWorkerTls64K03 kWorkerTls64K04 kWorkerTls64K05 kWorkerTls64K06 kWorkerTls64K07
    192183kWorkerTls64K_TEMPLATE  = BIN-STATIC-THREADED
    193184kWorkerTls64K_DEFS      = TLS_SIZE=65536
     
    195186kWorkerTls64K_LDFLAGS   = /Entry:DummyDllEntry
    196187
     188kWorkerTls64K01_EXTENDS = kWorkerTls64K
     189kWorkerTls64K02_EXTENDS = kWorkerTls64K
     190kWorkerTls64K03_EXTENDS = kWorkerTls64K
     191kWorkerTls64K04_EXTENDS = kWorkerTls64K
     192kWorkerTls64K05_EXTENDS = kWorkerTls64K
     193kWorkerTls64K06_EXTENDS = kWorkerTls64K
     194kWorkerTls64K07_EXTENDS = kWorkerTls64K
     195
     196
     197DLLS += kWorkerTls128K kWorkerTls128K01 kWorkerTls128K02 kWorkerTls128K03 kWorkerTls128K04 kWorkerTls128K05 kWorkerTls128K06 kWorkerTls128K07
     198kWorkerTls128K_TEMPLATE  = BIN-STATIC-THREADED
     199kWorkerTls128K_DEFS      = TLS_SIZE=131072
     200kWorkerTls128K_SOURCES   = kWorkerTlsXxxK.c
     201kWorkerTls128K_LDFLAGS   = /Entry:DummyDllEntry
     202
     203kWorkerTls128K01_EXTENDS = kWorkerTls128K
     204kWorkerTls128K02_EXTENDS = kWorkerTls128K
     205kWorkerTls128K03_EXTENDS = kWorkerTls128K
     206kWorkerTls128K04_EXTENDS = kWorkerTls128K
     207kWorkerTls128K05_EXTENDS = kWorkerTls128K
     208kWorkerTls128K06_EXTENDS = kWorkerTls128K
     209kWorkerTls128K07_EXTENDS = kWorkerTls128K
     210
     211
     212DLLS += kWorkerTls512K kWorkerTls512K01 kWorkerTls512K02 kWorkerTls512K03 kWorkerTls512K04 kWorkerTls512K05 kWorkerTls512K06 kWorkerTls512K07
    197213kWorkerTls512K_TEMPLATE = BIN-STATIC-THREADED
    198214kWorkerTls512K_DEFS     = TLS_SIZE=524288
     
    200216kWorkerTls512K_LDFLAGS  = /Entry:DummyDllEntry
    201217
     218kWorkerTls512K01_EXTENDS = kWorkerTls512K
     219kWorkerTls512K02_EXTENDS = kWorkerTls512K
     220kWorkerTls512K03_EXTENDS = kWorkerTls512K
     221kWorkerTls512K04_EXTENDS = kWorkerTls512K
     222kWorkerTls512K05_EXTENDS = kWorkerTls512K
     223kWorkerTls512K06_EXTENDS = kWorkerTls512K
     224kWorkerTls512K07_EXTENDS = kWorkerTls512K
     225
    202226
    203227include $(KBUILD_PATH)/subfooter.kmk
  • trunk/src/kWorker/kWorker.c

    r3365 r3366  
    390390            } aQuickZeroChunks[3];
    391391
    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. */
    393401            KU32                idxTls;
    394402            /** Offset (RVA) of the TLS initialization data. */
     
    665673    /** The handle. */
    666674    HANDLE              hHandle;
     675    /** The current owner (GetCurrentThreadId). */
     676    KU32                tidOwner;
    667677
    668678    /** Type specific data. */
     
    876886
    877887
     888    /** Critical section protecting the below handle members below.
     889     * @note Does not protect the individual handles.  */
     890    CRITICAL_SECTION HandlesLock;
    878891    /** Handle table. */
    879892    PKWHANDLE      *papHandles;
     
    11121125    { L"kWorkerTls1K06.dll", K_FALSE },
    11131126    { 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 },
    11221127};
    11231128
     
    11251130static KWTLSDLL     g_aTls64KDlls[] =
    11261131{
    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. */
     1143static 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 },
    11281153};
    11291154
     
    11311156static KWTLSDLL     g_aTls512KDlls[] =
    11321157{
    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 },
    11341166};
    11351167
     
    11391171    {     1024, K_ELEMENTS(g_aTls1KDlls),   g_aTls1KDlls },
    11401172    {  64*1024, K_ELEMENTS(g_aTls64KDlls),  g_aTls64KDlls },
     1173    { 128*1024, K_ELEMENTS(g_aTls128KDlls), g_aTls128KDlls },
    11411174    { 512*1024, K_ELEMENTS(g_aTls512KDlls), g_aTls512KDlls },
    11421175};
     
    12941327static char *kwSandboxDoGetEnvA(PKWSANDBOX pSandbox, const char *pchVar, KSIZE cchVar);
    12951328static KBOOL kwSandboxHandleTableEnter(PKWSANDBOX pSandbox, PKWHANDLE pHandle, HANDLE hHandle);
     1329static PKWHANDLE kwSandboxHandleLookup(HANDLE hFile);
     1330static PKWHANDLE kwSandboxHandleGet(HANDLE hFile);
     1331K_INLINE void kwSandboxHandlePut(PKWHANDLE pHandle);
    12961332#ifdef WITH_CONSOLE_OUTPUT_BUFFERING
    12971333static void kwSandboxConsoleWriteA(PKWSANDBOX pSandbox, PKWOUTPUTSTREAMBUF pLineBuf, const char *pchBuffer, KU32 cchToWrite);
     
    14041440{
    14051441    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
    14061453
    14071454    fprintf(stderr, "kWorker: error: ");
     
    18721919    if (--pMod->cRefs == 0)
    18731920    {
     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
    18741928        /* Unlink it from the hash table. */
    18751929        if (!pMod->fExe)
     
    22412295        if (!SetDllDirectoryW(pExe->pwszPath))
    22422296            kwErrPrintf("SetDllDirectoryW failed: %u\n", GetLastError());
     2297        KW_LOG(("kwLdrModuleCreateNative: Applied SetDllDirectoryW hack (%ls)\n", pExe->pwszPath));
    22432298        *pwzFilename = wcSaved;
    22442299    }
     2300    else
     2301        KW_LOG(("kwLdrModuleCreateNative: Warning! Too early for SetDllDirectoryW hack\n"));
     2302
    22452303
    22462304    /*
     
    24892547
    24902548/**
     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 */
     2557static 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/**
    24912583 * Called from TLS allocation DLL during DLL_PROCESS_ATTACH.
    24922584 *
    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)
    24982596{
    24992597    /*
     
    25032601    if (pMod)
    25042602    {
    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;
    25332653}
    25342654
     
    26392759        pwszTlsDll = g_aTlsDlls[iTlsDll].paDlls[iTlsDllSub].pwszName;
    26402760
    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
    26422765        pMod->u.Manual.offTlsInitData = (KU32)((KUPTR)paEntries[0].StartAddressOfRawData - (KUPTR)pMod->u.Manual.pbLoad);
    26432766        pMod->u.Manual.cbTlsInitData  = (KU32)(paEntries[0].EndAddressOfRawData - paEntries[0].StartAddressOfRawData);
     
    26632786
    26642787        *(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);
    26672795    }
    26682796    return 0;
     
    27482876                    pMod->u.Manual.cQuickZeroChunks = 0;
    27492877                    pMod->u.Manual.cQuickCopyChunks = 0;
     2878                    pMod->u.Manual.pabTlsInitData       = NULL;
     2879                    pMod->u.Manual.ppTlsWorkerModuleVar = NULL;
    27502880                    pMod->u.Manual.idxTls           = KU32_MAX;
    27512881                    pMod->u.Manual.offTlsInitData   = KU32_MAX;
     
    29903120        || kHlpStrNICompAscii(pszFilename, TUPLE("ucrtbase"))        == 0
    29913121        || 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
    29923127        ;
    29933128}
     
    30743209        || kHlpStrNICompAscii(pszFilename, TUPLE("vcruntime")) == 0
    30753210        || (   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        ;
    30773218}
    30783219
     
    34903631    if (pMod->u.Manual.cTlsCallbacks)
    34913632    {
    3492         PIMAGE_TLS_CALLBACK *pCallback = (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];
    34933634        do
    34943635        {
    3495             KWLDR_LOG(("%s: Calling TLS callback %p(%p,%#x,0)\n", pMod->pszPath, *pCallback, pMod->hOurMod, dwReason));
    3496             (*pCallback)(pMod->hOurMod, dwReason, 0);
    3497         } while (*++pCallback);
     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);
    34983639    }
    34993640}
     
    56515792            KBOOL fNeedSuffix = K_FALSE;
    56525793            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')
    56625798                {
    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))
    56745806                    {
    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                        }
    56785823                    }
     5824
     5825                    /* Advance */
     5826                    pszCur += cch;
     5827                    while (*pszCur == ';')
     5828                        pszCur++;
    56795829                }
    5680 
    5681                 /* Advance */
    5682                 pszCur += cch;
    5683                 while (*pszCur == ';')
    5684                     pszCur++;
    56855830            }
    56865831        }
     
    62816426        case KFSLOOKUPERROR_PATH_COMP_NOT_FOUND:
    62826427        case KFSLOOKUPERROR_PATH_COMP_NOT_DIR:
     6428        case KFSLOOKUPERROR_PATH_TOO_SHORT:
    62836429            return ERROR_PATH_NOT_FOUND;
    62846430
     
    64146560            pHandle->hHandle            = hFile;
    64156561            pHandle->dwDesiredAccess    = dwDesiredAccess;
     6562            pHandle->tidOwner           = KU32_MAX;
    64166563            pHandle->u.pTempFile        = pTempFile;
    64176564            if (kwSandboxHandleTableEnter(&g_Sandbox, pHandle, hFile))
     
    68907037            pHandle->hHandle            = *phFile;
    68917038            pHandle->dwDesiredAccess    = dwDesiredAccess;
     7039            pHandle->tidOwner           = KU32_MAX;
    68927040            pHandle->u.pCachedFile      = pCachedFile;
    68937041            if (kwSandboxHandleTableEnter(&g_Sandbox, pHandle, pHandle->hHandle))
     
    69467094     * Check for include files and similar that we do read-only caching of.
    69477095     */
    6948     if (dwCreationDisposition == FILE_OPEN_IF)
     7096    if (dwCreationDisposition == OPEN_EXISTING)
    69497097    {
    69507098        if (   dwDesiredAccess == GENERIC_READ
     
    69817129                            {
    69827130                                KWFS_LOG(("CreateFileA(%ls) -> INVALID_HANDLE_VALUE, ERROR_FILE_NOT_FOUND\n", pszFilename));
     7131                                SetLastError(ERROR_FILE_NOT_FOUND);
    69837132                                return INVALID_HANDLE_VALUE;
    69847133                            }
     
    69917140                        {
    69927141                            KWFS_LOG(("CreateFileA(%s) -> INVALID_HANDLE_VALUE, ERROR_FILE_NOT_FOUND\n", pszFilename));
     7142                            SetLastError(ERROR_FILE_NOT_FOUND);
    69937143                            return INVALID_HANDLE_VALUE;
    69947144                        }
     
    69977147                        {
    69987148                            KWFS_LOG(("CreateFileA(%s) -> INVALID_HANDLE_VALUE, ERROR_PATH_NOT_FOUND\n", pszFilename));
     7149                            SetLastError(ERROR_PATH_NOT_FOUND);
    69997150                            return INVALID_HANDLE_VALUE;
    70007151                        }
     
    70167167    hFile = CreateFileA(pszFilename, dwDesiredAccess, dwShareMode, pSecAttrs,
    70177168                        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
    70237171    KWFS_LOG(("CreateFileA(%s) -> %p\n", pszFilename, hFile));
    70247172    return hFile;
     
    70557203     * Check for include files and similar that we do read-only caching of.
    70567204     */
    7057     if (dwCreationDisposition == FILE_OPEN_IF)
     7205    if (dwCreationDisposition == OPEN_EXISTING)
    70587206    {
    70597207        if (   dwDesiredAccess == GENERIC_READ
     
    70897237                            {
    70907238                                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
    70917245                                return INVALID_HANDLE_VALUE;
    70927246                            }
     
    70987252                        else if (enmError == KFSLOOKUPERROR_NOT_FOUND)
    70997253                        {
     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
    71007261                            KWFS_LOG(("CreateFileW(%ls) -> INVALID_HANDLE_VALUE, ERROR_FILE_NOT_FOUND\n", pwszFilename));
     7262                            SetLastError(ERROR_FILE_NOT_FOUND);
    71017263                            return INVALID_HANDLE_VALUE;
    71027264                        }
     
    71047266                                 || enmError == KFSLOOKUPERROR_PATH_COMP_NOT_DIR)
    71057267                        {
     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
    71067275                            KWFS_LOG(("CreateFileW(%ls) -> INVALID_HANDLE_VALUE, ERROR_PATH_NOT_FOUND\n", pwszFilename));
     7276                            SetLastError(ERROR_PATH_NOT_FOUND);
    71077277                            return INVALID_HANDLE_VALUE;
    71087278                        }
     
    71337303    hFile = CreateFileW(pwszFilename, dwDesiredAccess, dwShareMode, pSecAttrs,
    71347304                        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
    71407307    KWFS_LOG(("CreateFileW(%ls) -> %p\n", pwszFilename, hFile));
    71417308    return hFile;
     
    71437310
    71447311
     7312
    71457313/** Kernel32 - SetFilePointer */
    71467314static DWORD WINAPI kwSandbox_Kernel32_SetFilePointer(HANDLE hFile, LONG cbMove, PLONG pcbMoveHi, DWORD dwMoveMethod)
    71477315{
    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;
    71627326#ifdef WITH_TEMP_MEMORY_FILES
    7163                 case KWHANDLETYPE_TEMP_FILE:
    7164                     cbFile = pHandle->u.pTempFile->cbFile;
    7165                     break;
    7166                 case KWHANDLETYPE_TEMP_FILE_MAPPING:
     7327            case KWHANDLETYPE_TEMP_FILE:
     7328                cbFile = pHandle->u.pTempFile->cbFile;
     7329                break;
     7330            case KWHANDLETYPE_TEMP_FILE_MAPPING:
    71677331#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);
    71727373                    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                }
    71977375#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
    72267395    KWFS_LOG(("SetFilePointer(%p, %d, %p=%d, %d)\n", hFile, cbMove, pcbMoveHi ? *pcbMoveHi : 0, dwMoveMethod));
    72277396    return SetFilePointer(hFile, cbMove, pcbMoveHi, dwMoveMethod);
     
    72337402                                                       DWORD dwMoveMethod)
    72347403{
    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;
    72497414#ifdef WITH_TEMP_MEMORY_FILES
    7250                 case KWHANDLETYPE_TEMP_FILE:
    7251                     cbFile = pHandle->u.pTempFile->cbFile;
    7252                     break;
    7253                 case KWHANDLETYPE_TEMP_FILE_MAPPING:
     7415            case KWHANDLETYPE_TEMP_FILE:
     7416                cbFile = pHandle->u.pTempFile->cbFile;
     7417                break;
     7418            case KWHANDLETYPE_TEMP_FILE_MAPPING:
    72547419#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)
    72807457                {
    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                }
    72847463#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;
    73117480    }
    73127481    KWFS_LOG(("SetFilePointerEx(%p)\n", hFile));
     
    73197488                                               LPOVERLAPPED pOverlapped)
    73207489{
    7321     BOOL        fRet;
    7322     KUPTR const idxHandle = KW_HANDLE_TO_INDEX(hFile);
     7490    BOOL      fRet;
     7491    PKWHANDLE pHandle = kwSandboxHandleGet(hFile);
    73237492    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)
    73337506                {
    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;
    73367537                    if (cbActually > cbToRead)
    73377538                        cbActually = cbToRead;
    73387539
    7339 #ifdef WITH_HASH_MD5_CACHE
    7340                     if (g_Sandbox.pHashHead)
     7540                    /* Copy the data. */
     7541                    if (cbActually > 0)
    73417542                    {
    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;
    73467574                    }
    7347 #endif
    7348 
    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;
    73617575                }
    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:
    74267593#endif /* WITH_TEMP_MEMORY_FILES */
    7427                 case KWHANDLETYPE_OUTPUT_BUF:
    7428                 default:
    7429                     kHlpAssertFailed();
    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;
    74347601        }
    74357602    }
     
    74477614                                                 LPOVERLAPPED_COMPLETION_ROUTINE pfnCompletionRoutine)
    74487615{
    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);
    74597617
    74607618    KWFS_LOG(("ReadFile(%p)\n", hFile));
     
    76577815                                                LPOVERLAPPED pOverlapped)
    76587816{
     7817    PKWHANDLE   pHandle = kwSandboxHandleGet(hFile);
    76597818    BOOL        fRet;
    7660     KUPTR const idxHandle = KW_HANDLE_TO_INDEX(hFile);
    76617819    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        {
    76707824# 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))
    76727833                {
    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 (;;)
    76797848                    {
    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)
    76947851                        {
    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;
    77087854                        }
    77097855
    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);
    77237862                    }
    77247863
    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
    77627871                    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);
    77637877                    return TRUE;
    77647878                }
     7879
     7880                kHlpAssertFailed();
     7881                kwSandboxHandlePut(pHandle);
     7882                *pcbActuallyWritten = 0;
     7883                SetLastError(ERROR_NOT_ENOUGH_MEMORY);
     7884                return FALSE;
     7885            }
    77657886# endif
    77667887
    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:
    77687926#ifdef WITH_TEMP_MEMORY_FILES
    7769                 case KWHANDLETYPE_TEMP_FILE_MAPPING:
     7927            case KWHANDLETYPE_TEMP_FILE_MAPPING:
    77707928#endif
    7771                     kHlpAssertFailed();
    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;
    77767934        }
    77777935    }
     
    77897947                                                  LPOVERLAPPED_COMPLETION_ROUTINE pfnCompletionRoutine)
    77907948{
    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);
    78017950
    78027951    KWFS_LOG(("WriteFileEx(%p)\n", hFile));
     
    78117960static BOOL WINAPI kwSandbox_Kernel32_SetEndOfFile(HANDLE hFile)
    78127961{
    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))
    78237972                {
    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;
    78367977                }
    78377978
    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;
    78427990
    78437991# 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;
    78487997# endif
    78497998
    7850                 default:
    7851                 case KWHANDLETYPE_TEMP_FILE_MAPPING:
    7852                     kHlpAssertFailed();
    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;
    78568005        }
    78578006    }
     
    78658014static BOOL WINAPI kwSandbox_Kernel32_GetFileType(HANDLE hFile)
    78668015{
    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;
    78838030
    78848031#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)
    78868037                {
    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));
    79008040                }
     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            }
    79018049#endif
    7902 
    7903             }
    7904         }
     8050        }
     8051        kwSandboxHandlePut(pHandle);
    79058052    }
    79068053
     
    79138060static DWORD WINAPI kwSandbox_Kernel32_GetFileSize(HANDLE hFile, LPDWORD pcbHighDword)
    79148061{
    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);
    79458091    }
    79468092
     
    79538099static BOOL WINAPI kwSandbox_Kernel32_GetFileSizeEx(HANDLE hFile, PLARGE_INTEGER pcbFile)
    79548100{
    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);
    79848129    }
    79858130
     
    79958140{
    79968141    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)
    80078156                {
    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);
    80548160                    return hMapping;
    80558161                }
    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);
    80608205    }
    80618206
     
    80728217{
    80738218    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            }
    80828324
    80838325            /*
    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.
    80868327             */
    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) )
    81018335                {
    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;
    81058339                }
    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;
    82228367    }
    82238368
     
    82348379{
    82358380    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                {
    82508393                    kHlpAssertFailed();
    82518394                    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);
    82718421    }
    82728422
     
    83298479    if (hSrcProc == GetCurrentProcess())
    83308480    {
    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))
    83408488                {
    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));
    83558493                }
    83568494                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;
    83618507        }
    83628508    }
     
    83778523    BOOL        fRet;
    83788524    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)
    83918541                {
    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)
    83978544                    {
    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                    }
    84048548#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));
    84108551                }
    84118552                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        {
    84168564#ifdef WITH_CONSOLE_OUTPUT_BUFFERING
    8417                 KWFS_LOG(("CloseHandle(%p) -> TRUE [intercepted handle] Ignored closing of std%s!\n",
    8418                           hObject, hObject == g_Sandbox.StdErr.hOutput ? "err" : "out"));
     8565            KWFS_LOG(("CloseHandle(%p) -> TRUE [intercepted handle] Ignored closing of std%s!\n",
     8566                      hObject, hObject == g_Sandbox.StdErr.hOutput ? "err" : "out"));
    84198567#else
    8420                 KWFS_LOG(("CloseHandle(%p) -> TRUE [intercepted handle] Ignored closing of stdXXX!\n", hObject));
     8568            KWFS_LOG(("CloseHandle(%p) -> TRUE [intercepted handle] Ignored closing of stdXXX!\n", hObject));
    84218569#endif
    8422                 fRet = TRUE;
    8423             }
    8424             return fRet;
    8425         }
     8570            fRet = TRUE;
     8571        }
     8572        kwSandboxHandlePut(pHandle);
     8573        return fRet;
    84268574    }
    84278575
     
    93499497            KW_LOG(("VirtualAlloc: pvAddr=%p cb=%p type=%#x prot=%#x -> %p (last=%d)\n",
    93509498                    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               )
    93529510                kwErrPrintf("VirtualAlloc %p LB %#x (%#x,%#x) failed: %p / %u\n",
    93539511                            pvAddr, cb, fAllocType, fProt, pvMem, GetLastError());
     
    1034610504            pXcptRec = (PEXCEPTION_RECORD)alloca(sizeof(*pXcptRec));
    1034710505            kHlpMemSet(pXcptRec, 0, sizeof(*pXcptRec));
    10348             pXcptRec->ExceptionCode  = STATUS_UNWIND;
     10506            pXcptRec->ExceptionCode  = (DWORD)STATUS_UNWIND;
    1034910507            pXcptRec->ExceptionFlags = EH_UNWINDING;
    1035010508        }
     
    1043510593
    1043610594
     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. */
    1043710600
    1043810601/**
     
    1091211075    kHlpAssertReturn(idxHandle < KW_HANDLE_MAX, K_FALSE);
    1091311076
     11077    EnterCriticalSection(&g_Sandbox.HandlesLock);
     11078
    1091411079    /*
    1091511080     * Grow handle table.
     
    1092411089        if (!pvNew)
    1092511090        {
     11091            LeaveCriticalSection(&g_Sandbox.HandlesLock);
    1092611092            KW_LOG(("Out of memory growing handle table to %u handles\n", cHandles));
    1092711093            return K_FALSE;
     
    1093611102     * Check that the entry is unused then insert it.
    1093711103     */
    10938     kHlpAssertReturn(pSandbox->papHandles[idxHandle] == NULL, K_FALSE);
     11104    kHlpAssertStmtReturn(pSandbox->papHandles[idxHandle] == NULL, LeaveCriticalSection(&g_Sandbox.HandlesLock), K_FALSE);
    1093911105    pSandbox->papHandles[idxHandle] = pHandle;
    1094011106    pSandbox->cActiveHandles++;
     11107    LeaveCriticalSection(&g_Sandbox.HandlesLock);
    1094111108    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 */
     11118static 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 */
     11139static 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 */
     11164K_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;
    1094211169}
    1094311170
     
    1121511442
    1121611443    /* Open handles, except fixed handles (stdout and stderr). */
     11444    EnterCriticalSection(&pSandbox->HandlesLock);
    1121711445    if (pSandbox->cActiveHandles > pSandbox->cFixedHandles)
    1121811446    {
     
    1126711495        kHlpAssert(pSandbox->cActiveHandles == pSandbox->cFixedHandles);
    1126811496    }
     11497    LeaveCriticalSection(&pSandbox->HandlesLock);
    1126911498
    1127011499    /* Reset memory mappings - This assumes none of the DLLs keeps any of our mappings open! */
     
    1147311702    if (rc == 0)
    1147411703    {
     11704        if (g_cVerbose > 2)
     11705            fprintf(stderr, "kWorker: info: Executing (sandboxed): %s\n", g_Sandbox.pszCmdLine);
     11706
    1147511707        /*
    1147611708         * Do module initialization.
     
    1179912031     * Expand pszSpecialEnv if present.
    1180012032     */
    11801     if (*pszSpecialEnv)
     12033    if (pszSpecialEnv && *pszSpecialEnv)
    1180212034    {
    1180312035        rcExit = kSubmitHandleSpecialEnvVar(cEnvVars, papszEnvVars, pszSpecialEnv, &pszSpecialEnvFree);
     
    1261912851        int         rc     = 0;
    1262012852        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] == '@'))
    1264212889        {
    1264312890            const char *pszValue = NULL;
     
    1293513182    }
    1293613183#endif
     13184/// quick and dirty...
     13185LoadLibraryA("E:\\vbox\\svn\\trunk\\tools\\win.amd64\\vcc\\v14.2\\Tools\\MSVC\\14.26.28801\\bin\\Hostx64\\x64\\mspdbcore.dll");
    1293713186
    1293813187    /*
     
    1296513214        return kwErrPrintfRc(3, "VirtualProtect(%p, %#x, PAGE_EXECUTE_READWRITE,NULL) failed: %u\n",
    1296613215                             g_abDefLdBuf, sizeof(g_abDefLdBuf), GetLastError());
     13216    InitializeCriticalSection(&g_Sandbox.HandlesLock);
    1296713217    InitializeCriticalSection(&g_Sandbox.VirtualAllocLock);
    1296813218
     
    1298313233    g_Sandbox.HandleStdOut.cRefs           = 0x10001;
    1298413234    g_Sandbox.HandleStdOut.dwDesiredAccess = GENERIC_WRITE;
     13235    g_Sandbox.HandleStdOut.tidOwner        = KU32_MAX;
    1298513236    g_Sandbox.HandleStdOut.u.pOutBuf       = &g_Sandbox.StdOut;
    1298613237    g_Sandbox.HandleStdOut.hHandle         = g_Sandbox.StdOut.hOutput;
     
    1300713258    g_Sandbox.HandleStdErr.cRefs           = 0x10001;
    1300813259    g_Sandbox.HandleStdErr.dwDesiredAccess = GENERIC_WRITE;
     13260    g_Sandbox.HandleStdErr.tidOwner        = KU32_MAX;
    1300913261    g_Sandbox.HandleStdErr.u.pOutBuf       = &g_Sandbox.StdErr;
    1301013262    g_Sandbox.HandleStdErr.hHandle         = g_Sandbox.StdErr.hOutput;
     
    1312913381                return kwErrPrintfRc(2, "--priority takes an argument!\n");
    1313013382        }
     13383        else if (   strcmp(argv[i], "--verbose") == 0
     13384                 || strcmp(argv[i], "-v") == 0)
     13385            g_cVerbose++;
    1313113386        else if (   strcmp(argv[i], "--help") == 0
    1313213387                 || strcmp(argv[i], "-h") == 0
     
    1313613391                   "usage: kWorker <--help|-h>\n"
    1313713392                   "usage: kWorker <--version|-V>\n"
     13393                   "usage: kWorker [--volatile dir] --full-test kSubmit ...\n"
    1313813394                   "usage: kWorker [--volatile dir] --test [<times> [--chdir <dir>] [--breakpoint] -- args\n"
    1313913395                   "\n"
  • trunk/src/kWorker/kWorkerTlsXxxK.c

    r3361 r3366  
    3434*   Structures and Typedefs                                                                                                      *
    3535*********************************************************************************************************************************/
    36 typedef void KWLDRTLSALLOCATIONHOOK(void *hDll, ULONG idxTls, PIMAGE_TLS_CALLBACK *ppfnTlsCallback);
     36typedef void KWLDRTLSCALLBACK(void *hDll, DWORD dwReason, void *pvContext, void *pvWorkerModule);
     37typedef KWLDRTLSCALLBACK *PKWLDRTLSCALLBACK;
     38typedef PKWLDRTLSCALLBACK KWLDRTLSALLOCATIONHOOK(void *hDll, ULONG idxTls, char *pabInitData, void **ppvWorkerModule);
    3739
    3840
     
    4850/** The TLS pointer array. The 2nd entry is NULL and serve to terminate the array.
    4951 * 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 };
    5153
    5254/**
    5355 * The TLS index.
    5456 */
    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
    5670
    5771/**
    5872 * Initialization data.
     73 * kWorker will copy the init data of the target DLL here.
    5974 */
    60 //static char const g_abDummy[TLS_SIZE] = {0x42};
    61 static char g_abDummy[TLS_SIZE] = {0};
     75static char g_abInitData[TLS_SIZE] = {0};
    6276
    6377/**
     
    6882__declspec(allocate(".rdata$T")) const IMAGE_TLS_DIRECTORY _tls_used =
    6983{
    70     (ULONG_PTR)&g_abDummy,
    71     (ULONG_PTR)&g_abDummy + sizeof(g_abDummy),
     84    (ULONG_PTR)&g_abInitData,
     85    (ULONG_PTR)&g_abInitData + sizeof(g_abInitData),
    7286    (ULONG_PTR)&g_idxTls,
    7387    (ULONG_PTR)&g_apfnTlsCallbacks,
     
    7589    IMAGE_SCN_ALIGN_32BYTES
    7690};
     91
     92
     93/**
     94 * Just a dummy callback function in case the allocation hook gambit fails below
     95 * (see KWLDRTLSCALLBACK).
     96 */
     97static void DummyWorkerCallback(void *hDll, DWORD dwReason, void *pvContext, void *pvWorkerModule)
     98{
     99    (void)hDll; (void)dwReason; (void)pvContext; (void)pvWorkerModule;
     100}
    77101
    78102
     
    86110__declspec(dllexport) void __stdcall DummyTlsCallback(void *hDll, DWORD dwReason, void *pvContext)
    87111{
    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
    90115    {
    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)
    95118        {
    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();
    98125        }
    99         __debugbreak();
    100126    }
    101127}
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette