Changeset 3361 for trunk/src


Ignore:
Timestamp:
Jun 8, 2020, 9:27:14 PM (5 years ago)
Author:
bird
Message:

kWorker: Adjustments for VC++ 14.2. Fixed bug in GetFileAttributesExW/A where we'd forget to set the return value on success. Reduced the size of the Tls DLLs, but having to add more as the re-load-same-dll hack doesn't work anymore.

Location:
trunk/src/kWorker
Files:
3 edited

Legend:

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

    r3355 r3361  
    3434kWorker_DEFS.debug = K_STRICT
    3535kWorker_DEFS.release = NASSERT
     36ifeq ($(USERNAME),bird)
     37kWorker_CFLAGS = -W4 -wd4127 -wd4100 -wd4214 -wd4201 -wd4204
     38endif
    3639kWorker_SOURCES = \
    3740        kWorker.c \
     
    5053        $(PATH_SDK_WINDDK71_LIB_WNET)/psapi.lib
    5154kWorker_LDFLAGS.win = \
    52         /BASE:0x10000 /DYNAMICBASE:NO /FIXED
     55        /DYNAMICBASE:NO /FIXED
     56kWorker_LDFLAGS.win.x86   = /BASE:0x00010000
     57kWorker_LDFLAGS.win.amd64 = /BASE:0x0000000420000000
     58
    5359#kWorker_LDFLAGS.win.x86 = \
    5460#       /SAFESEH:NO - doesn't help anyone.
     
    159165# A couple of dummy DLLs we use for grabbing LDR TLS entries.
    160166#
    161 DLLS += kWorkerTls1K kWorkerTls64K kWorkerTls512K
     167DLLS += kWorkerTls1K kWorkerTls1K01 kWorkerTls1K02 kWorkerTls1K03 kWorkerTls1K04 kWorkerTls1K05 kWorkerTls1K06 kWorkerTls1K07 \
     168        kWorkerTls1K08 kWorkerTls1K09 kWorkerTls1K10 kWorkerTls1K11 kWorkerTls1K12 kWorkerTls1K13 kWorkerTls1K14 kWorkerTls1K15
    162169kWorkerTls1K_TEMPLATE   = BIN-STATIC-THREADED
    163 kWorkerTls1K_DEFS       = KWORKER_BASE=0x10000 TLS_SIZE=1024
     170kWorkerTls1K_DEFS       = TLS_SIZE=1024
    164171kWorkerTls1K_SOURCES    = kWorkerTlsXxxK.c
    165172kWorkerTls1K_LDFLAGS    = /Entry:DummyDllEntry
    166173
     174kWorkerTls1K01_EXTENDS = kWorkerTls1K
     175kWorkerTls1K02_EXTENDS = kWorkerTls1K
     176kWorkerTls1K03_EXTENDS = kWorkerTls1K
     177kWorkerTls1K04_EXTENDS = kWorkerTls1K
     178kWorkerTls1K05_EXTENDS = kWorkerTls1K
     179kWorkerTls1K06_EXTENDS = kWorkerTls1K
     180kWorkerTls1K07_EXTENDS = kWorkerTls1K
     181kWorkerTls1K08_EXTENDS = kWorkerTls1K
     182kWorkerTls1K09_EXTENDS = kWorkerTls1K
     183kWorkerTls1K10_EXTENDS = kWorkerTls1K
     184kWorkerTls1K11_EXTENDS = kWorkerTls1K
     185kWorkerTls1K12_EXTENDS = kWorkerTls1K
     186kWorkerTls1K13_EXTENDS = kWorkerTls1K
     187kWorkerTls1K14_EXTENDS = kWorkerTls1K
     188kWorkerTls1K15_EXTENDS = kWorkerTls1K
     189
     190DLLS += kWorkerTls64K kWorkerTls512K
     191
    167192kWorkerTls64K_TEMPLATE  = BIN-STATIC-THREADED
    168 kWorkerTls64K_DEFS      = KWORKER_BASE=0x10000 TLS_SIZE=65536
     193kWorkerTls64K_DEFS      = TLS_SIZE=65536
    169194kWorkerTls64K_SOURCES   = kWorkerTlsXxxK.c
    170195kWorkerTls64K_LDFLAGS   = /Entry:DummyDllEntry
    171196
    172197kWorkerTls512K_TEMPLATE = BIN-STATIC-THREADED
    173 kWorkerTls512K_DEFS     = KWORKER_BASE=0x10000 TLS_SIZE=524288
     198kWorkerTls512K_DEFS     = TLS_SIZE=524288
    174199kWorkerTls512K_SOURCES  = kWorkerTlsXxxK.c
    175200kWorkerTls512K_LDFLAGS  = /Entry:DummyDllEntry
  • trunk/src/kWorker/kWorker.c

    r3355 r3361  
    320320    /** The windows module handle. */
    321321    HMODULE             hOurMod;
     322    /** Parent (real) module if this is a virtual API module (api-ms-*.dll or
     323     * ext-ms-*.dll). Referenced. */
     324    PKWMODULE           pVirtualApiMod;
    322325    /** The of the loaded image bits. */
    323326    KSIZE               cbImage;
     
    348351            /** The state. */
    349352            KWMODSTATE          enmState;
     353            /** The re-init state. */
     354            KWMODSTATE          enmReInitState;
    350355#if defined(KBUILD_OS_WINDOWS) && defined(KBUILD_ARCH_AMD64)
    351356            /** The number of entries in the table. */
     
    443448
    444449
     450/** One TLS DLL. */
     451typedef struct KWTLSDLL
     452{
     453    const wchar_t  *pwszName;   /**< The DLL name. */
     454    KBOOL           fUsed;      /**< Set if used, clear if not. */
     455} KWTLSDLL;
     456typedef KWTLSDLL *PKWTLSDLL;
     457
     458/**
     459 * TLS DLL tracker.
     460 */
     461typedef struct KWTLSDLLENTRY
     462{
     463    KU32            cbTls;      /**< Max TLS size. */
     464    KU32            cDlls;      /**< Number of DLLs we ship (paDlls). */
     465    PKWTLSDLL       paDlls;     /**< Array of DLLs we ship. */
     466} KWTLSDLLENTRY;
     467typedef KWTLSDLLENTRY *PKWTLSDLLENTRY;
     468
     469
    445470/**
    446471 * A cached file.
     
    794819typedef struct KWSANDBOX
    795820{
     821    /** Jump buffer (first for alignment reasons). */
     822    jmp_buf     JmpBuf;
    796823    /** The tool currently running in the sandbox. */
    797824    PKWTOOL     pTool;
    798     /** Jump buffer. */
    799     jmp_buf     JmpBuf;
    800825    /** The thread ID of the main thread (owner of JmpBuf). */
    801826    DWORD       idMainThread;
     
    866891    PKWFSTEMPFILE   pTempFileHead;
    867892
     893    /** Critical section protecting pVirtualAllocHead. */
     894    CRITICAL_SECTION VirtualAllocLock;
    868895    /** Head of the virtual alloc allocations. */
    869896    PKWVIRTALLOC    pVirtualAllocHead;
     
    948975    KU32        iSlot;
    949976
    950     /** The CRT module data.    */
     977    /** The CRT module data. */
    951978    PKWMODULE   pModule;
    952     /** Pointer to the malloc function.   */
     979    /** Pointer to the malloc function. */
    953980    void * (__cdecl *pfnMalloc)(size_t);
     981    /** Pointer to the beginthreadex function. */
     982    uintptr_t (__cdecl *pfnBeginThreadEx)(void *, unsigned, unsigned (__stdcall *)(void *), void *, unsigned, unsigned *);
    954983
    955984} KWCRTSLOT;
     
    10641093static PKWMODULE    g_pModPendingTlsAlloc = NULL;
    10651094
     1095/** The 1KB TLS DLLs. */
     1096static KWTLSDLL     g_aTls1KDlls[] =
     1097{
     1098    { L"kWorkerTls1K.dll",   K_FALSE },
     1099    { L"kWorkerTls1K01.dll", K_FALSE },
     1100    { L"kWorkerTls1K02.dll", K_FALSE },
     1101    { L"kWorkerTls1K03.dll", K_FALSE },
     1102    { L"kWorkerTls1K04.dll", K_FALSE },
     1103    { L"kWorkerTls1K05.dll", K_FALSE },
     1104    { L"kWorkerTls1K06.dll", K_FALSE },
     1105    { L"kWorkerTls1K07.dll", K_FALSE },
     1106    { L"kWorkerTls1K08.dll", K_FALSE },
     1107    { L"kWorkerTls1K09.dll", K_FALSE },
     1108    { L"kWorkerTls1K10.dll", K_FALSE },
     1109    { L"kWorkerTls1K11.dll", K_FALSE },
     1110    { L"kWorkerTls1K12.dll", K_FALSE },
     1111    { L"kWorkerTls1K13.dll", K_FALSE },
     1112    { L"kWorkerTls1K14.dll", K_FALSE },
     1113    { L"kWorkerTls1K15.dll", K_FALSE },
     1114};
     1115
     1116/** The 64KB TLS DLLs. */
     1117static KWTLSDLL     g_aTls64KDlls[] =
     1118{
     1119    { L"kWorkerTls64K.dll", K_FALSE },
     1120};
     1121
     1122/** The 512KB TLS DLLs. */
     1123static KWTLSDLL     g_aTls512KDlls[] =
     1124{
     1125    { L"kWorkerTls512K.dll", K_FALSE },
     1126};
     1127
     1128/** The TLS DLLs grouped by size. */
     1129static KWTLSDLLENTRY const g_aTlsDlls[] =
     1130{
     1131    {     1024, K_ELEMENTS(g_aTls1KDlls),   g_aTls1KDlls },
     1132    {  64*1024, K_ELEMENTS(g_aTls64KDlls),  g_aTls64KDlls },
     1133    { 512*1024, K_ELEMENTS(g_aTls512KDlls), g_aTls512KDlls },
     1134};
     1135
    10661136/** CRT slots.
    10671137 * @note The number of entires here must match CRT_SLOT_FUNCTION_WRAPPER. */
    10681138static KWCRTSLOT    g_aCrtSlots[32];
     1139
     1140/** windbg .reload statements. vs   */
     1141char                g_szReloads[4096];
     1142/** Current offset into g_szReloads. */
     1143KU32 volatile       g_cchReloads;
    10691144
    10701145/** The file system cache. */
     
    12061281                                       const char *pszSearchPath, PKWMODULE *ppMod);
    12071282static PKWMODULE kwLdrModuleForLoadedNative(const char *pszName, KBOOL fEnsureCrtSlot, KBOOL fAlwaysPresent);
     1283static PKWMODULE kwLdrModuleForLoadedNativeByHandle(HMODULE hModule, KBOOL fEnsureCrtSlot, const char *pszLogName);
     1284static int kwLdrModuleCreateCrtSlot(PKWMODULE pModule);
     1285static PKWMODULE kwToolLocateModuleByHandle(PKWTOOL pTool, HMODULE hmod);
    12081286static char *kwSandboxDoGetEnvA(PKWSANDBOX pSandbox, const char *pchVar, KSIZE cchVar);
    12091287static KBOOL kwSandboxHandleTableEnter(PKWSANDBOX pSandbox, PKWHANDLE pHandle, HANDLE hHandle);
     
    17711849{
    17721850    kHlpAssert(pMod->cRefs > 0);
    1773     kHlpAssert(pMod->cRefs < 64);
     1851    kHlpAssert(pMod->cRefs < 64 || pMod->fNative /* kernelbase.dll and VC++ 14.2 */);
    17741852    pMod->cRefs++;
    17751853    return pMod;
     
    17891867        if (!pMod->fExe)
    17901868        {
    1791             PKWMODULE pPrev = NULL;
    17921869            unsigned  idx   = pMod->uHashPath % K_ELEMENTS(g_apModules);
    17931870            if (g_apModules[idx] == pMod)
     
    18641941    }
    18651942    else
    1866         kHlpAssert(pMod->cRefs < 64);
     1943        kHlpAssert(pMod->cRefs < 64 || pMod->fNative /* kernelbase.dll and VC++ 14.2 */);
    18671944}
    18681945
     
    19682045                {
    19692046                    IMAGE_IMPORT_BY_NAME const *pName     = (IMAGE_IMPORT_BY_NAME const *)&pbImage[off];
    1970                     KSIZE const                 cchSymbol = kHlpStrLen(pName->Name);
     2047                    KSIZE const                 cchSymbol = kHlpStrLen((const char *)&pName->Name[0]);
    19712048                    KU32                        i         = g_cSandboxNativeReplacements;
    19722049                    while (i-- > 0)
     
    19772054                                || kHlpStrICompAscii(g_aSandboxNativeReplacements[i].pszModule, pszImport) == 0)
    19782055                            {
    1979                                 KW_LOG(("%s: replacing %s!%s\n", pMod->pLdrMod->pszName, pszImport, pName->Name));
     2056                                KWLDR_LOG(("%s: replacing %s!%s\n", pMod->pLdrMod->pszName, pszImport, pName->Name));
    19802057
    19812058                                /* The .rdata section is normally read-only, so we need to make it writable first. */
     
    20032080                                            case PAGE_EXECUTE_WRITECOPY:
    20042081                                                /* Already writable, nothing to do. */
     2082                                                fRc = TRUE;
    20052083                                                break;
    20062084
     
    20812159 */
    20822160static PKWMODULE kwLdrModuleCreateForNativekLdrModule(PKLDRMOD pLdrMod, const char *pszPath, KSIZE cbPath, KU32 uHashPath,
    2083                                                       KBOOL fDoReplacements)
     2161                                                      KBOOL fDoReplacements, PKWMODULE pVirtualApiMod)
    20842162{
    20852163    /*
     
    20892167    if (pMod)
    20902168    {
    2091         pMod->pwszPath      = (wchar_t *)(pMod + 1);
     2169        pMod->pwszPath          = (wchar_t *)(pMod + 1);
    20922170        kwStrToUtf16(pszPath, (wchar_t *)pMod->pwszPath, cbPath * 2);
    2093         pMod->pszPath       = (char *)kHlpMemCopy((char *)&pMod->pwszPath[cbPath * 2], pszPath, cbPath);
    2094         pMod->uHashPath     = uHashPath;
    2095         pMod->cRefs         = 1;
    2096         pMod->offFilename   = (KU16)(kHlpGetFilename(pszPath) - pszPath);
    2097         pMod->offFilenameW  = (KU16)(kwPathGetFilenameW(pMod->pwszPath) - pMod->pwszPath);
    2098         pMod->fExe          = K_FALSE;
    2099         pMod->fNative       = K_TRUE;
    2100         pMod->pLdrMod       = pLdrMod;
    2101         pMod->hOurMod       = (HMODULE)(KUPTR)pLdrMod->aSegments[0].MapAddress;
    2102         pMod->cbImage       = (KSIZE)kLdrModSize(pLdrMod);
    2103         pMod->iCrtSlot      = KU8_MAX;
    2104         pMod->fNeedReInit   = K_FALSE;
     2171        pMod->pszPath           = (char *)kHlpMemCopy((char *)&pMod->pwszPath[cbPath * 2], pszPath, cbPath);
     2172        pMod->uHashPath         = uHashPath;
     2173        pMod->cRefs             = 1;
     2174        pMod->offFilename       = (KU16)(kHlpGetFilename(pszPath) - pszPath);
     2175        pMod->offFilenameW      = (KU16)(kwPathGetFilenameW(pMod->pwszPath) - pMod->pwszPath);
     2176        pMod->fExe              = K_FALSE;
     2177        pMod->fNative           = K_TRUE;
     2178        pMod->pLdrMod           = pLdrMod;
     2179        pMod->hOurMod           = (HMODULE)(KUPTR)pLdrMod->aSegments[0].MapAddress;
     2180        pMod->cbImage           = (KSIZE)kLdrModSize(pLdrMod);
     2181        pMod->iCrtSlot          = KU8_MAX;
     2182        pMod->fNeedReInit       = K_FALSE;
    21052183        pMod->pszMsPdbSrvEndpoint = NULL;
    21062184        pMod->fReInitOnMsPdbSrvEndpointChange = kHlpStrNICompAscii(&pMod->pszPath[pMod->offFilename], TUPLE("mspdb")) == 0;
     2185        pMod->pVirtualApiMod    = pVirtualApiMod;
     2186        if (pVirtualApiMod)
     2187            kwLdrModuleRetain(pVirtualApiMod);
    21072188
    21082189        if (fDoReplacements)
     
    21132194        }
    21142195
    2115         KW_LOG(("New module: %p LB %#010x %s (native)\n",
    2116                 (KUPTR)pMod->pLdrMod->aSegments[0].MapAddress, kLdrModSize(pMod->pLdrMod), pMod->pszPath));
     2196        KWLDR_LOG(("New module: %p LB %#010x %s (native%s%s)\n",
     2197                   (KUPTR)pMod->pLdrMod->aSegments[0].MapAddress, kLdrModSize(pMod->pLdrMod), pMod->pszPath,
     2198                   pVirtualApiMod ? ", virtual api => " : "", pVirtualApiMod ? pVirtualApiMod->pszPath : ""));
    21172199        g_cModules++;
    21182200        return kwLdrModuleLink(pMod);
     
    21342216static PKWMODULE kwLdrModuleCreateNative(const char *pszPath, KU32 uHashPath, KBOOL fDoReplacements)
    21352217{
     2218    PKLDRMOD pLdrMod;
     2219    int rc;
     2220
    21362221    /*
    2137      * Open the module and check the type.
     2222     * HACK ALERT! Make sure the application path is searched when looking for
     2223     * imports in the module we're loading.
    21382224     */
    2139     PKLDRMOD pLdrMod;
    2140     int rc = kLdrModOpenNative(pszPath, KLDRMOD_OPEN_FLAGS_NATIVE_ALLOW_INIT_TERM, &pLdrMod);
     2225    /** @todo improve on this hack!  */
     2226    PKWMODULE pExe = g_Sandbox.pTool ? g_Sandbox.pTool->u.Sandboxed.pExe : NULL;
     2227    if (pExe)
     2228    {
     2229        /* HACK ALERT! */
     2230        wchar_t *pwzFilename = (wchar_t *)&pExe->pwszPath[pExe->offFilenameW];
     2231        wchar_t wcSaved = pExe->pwszPath[pExe->offFilenameW];
     2232        *pwzFilename = '\0';
     2233        if (!SetDllDirectoryW(pExe->pwszPath))
     2234            kwErrPrintf("SetDllDirectoryW failed: %u\n", GetLastError());
     2235        *pwzFilename = wcSaved;
     2236    }
     2237
     2238    /*
     2239     * Load the library and create a module structure for it.
     2240     */
     2241    rc = kLdrModOpenNative(pszPath, KLDRMOD_OPEN_FLAGS_NATIVE_ALLOW_INIT_TERM, &pLdrMod);
    21412242    if (rc == 0)
    21422243    {
    2143         PKWMODULE pMod = kwLdrModuleCreateForNativekLdrModule(pLdrMod, pszPath, kHlpStrLen(pszPath) + 1,
    2144                                                               uHashPath, fDoReplacements);
     2244        KSIZE     cchPath = kHlpStrLen(pszPath);
     2245        PKWMODULE pMod = kwLdrModuleCreateForNativekLdrModule(pLdrMod, pszPath, cchPath + 1, uHashPath,
     2246                                                              fDoReplacements, NULL /*pVirtualApiMod*/);
    21452247        if (pMod)
    21462248            return pMod;
     
    21482250    }
    21492251    return NULL;
     2252}
     2253
     2254
     2255/**
     2256 * Checks if the given name could be a virtual API module or not.
     2257 */
     2258static KBOOL kwLdrIsVirtualApiModule(const char *pszName, KSIZE cchName)
     2259{
     2260    if (cchName <= 7)
     2261        return K_FALSE;
     2262    switch (*pszName)
     2263    {
     2264        default:
     2265            return K_FALSE;
     2266        case 'a':
     2267        case 'A':
     2268            if (pszName[1] != 'p' && pszName[1] != 'P')
     2269                return K_FALSE;
     2270            if (pszName[2] != 'i' && pszName[2] != 'I')
     2271                return K_FALSE;
     2272            break;
     2273        case 'e':
     2274        case 'E':
     2275            if (pszName[1] != 'x' && pszName[1] != 'X')
     2276                return K_FALSE;
     2277            if (pszName[2] != 't' && pszName[2] != 'T')
     2278                return K_FALSE;
     2279            break;
     2280    }
     2281    if (pszName[3] != '-')
     2282        return K_FALSE;
     2283    if (pszName[4] != 'm' && pszName[4] != 'M')
     2284        return K_FALSE;
     2285    if (pszName[5] != 's' && pszName[5] != 'S')
     2286        return K_FALSE;
     2287    if (pszName[6] != '-')
     2288        return K_FALSE;
     2289    return K_TRUE;
     2290}
     2291
     2292
     2293/**
     2294 * Try load what seems to be a virtual API DLL.
     2295 *
     2296 * This is a worker for kwLdrModuleResolveAndLookup and
     2297 * kwSandbox_Kernel32_LoadLibraryExA_VirtualApiModule.
     2298 *
     2299 * @returns Pointer to module on success, NULL on failure.
     2300 * @param   pszName             The name of the module.  This must be
     2301 *                              normalized already!
     2302 * @param   cchName             The length of the name.
     2303 */
     2304static PKWMODULE kwLdrModuleTryLoadVirtualDll(const char *pszName, KSIZE cchName)
     2305{
     2306    HMODULE     hModule;
     2307
     2308    /*
     2309     * Look it up in the hash table.
     2310     */
     2311    KU32 const  uHashPath = kwStrHash(pszName);
     2312    unsigned    idxHash   = uHashPath % K_ELEMENTS(g_apModules);
     2313    PKWMODULE   pMod      = g_apModules[idxHash];
     2314    if (pMod)
     2315    {
     2316        do
     2317        {
     2318            if (   pMod->uHashPath == uHashPath
     2319                && kHlpStrComp(pMod->pszPath, pszName) == 0)
     2320                return kwLdrModuleRetain(pMod);
     2321            pMod = pMod->pNextHash;
     2322        } while (pMod);
     2323    }
     2324
     2325    /*
     2326     * Not found. Try load it.
     2327     */
     2328    hModule = LoadLibraryA(pszName);
     2329    if (!hModule)
     2330    {
     2331        KWLDR_LOG(("kwLdrModuleTryLoadVirtualDll: %s failed (%u)\n", pszName, GetLastError()));
     2332        return NULL;
     2333    }
     2334
     2335    /*
     2336     * Loaded successfully.  Create a module for the real module.
     2337     */
     2338    pMod = kwLdrModuleForLoadedNativeByHandle(hModule, K_FALSE /*fEnsureCrtSlot*/, pszName);
     2339    if (pMod)
     2340    {
     2341        /* Create a module for the virtual API name too, unless it is actually a real DLL. */
     2342        if (stricmp(&pMod->pszPath[pMod->offFilename], pszName) != 0)
     2343        {
     2344            PKLDRMOD pLdrMod;
     2345            int rc = kLdrModOpenNativeByHandle((KUPTR)hModule, KLDRMOD_OPEN_FLAGS_NATIVE_ALLOW_INIT_TERM, &pLdrMod);
     2346            if (rc == 0)
     2347            {
     2348                PKWMODULE pVirtMod = kwLdrModuleCreateForNativekLdrModule(pLdrMod, pszName, cchName + 1, kwStrHash(pszName),
     2349                                                                          K_FALSE /*fDoReplacements*/, pMod /*pVirtualApiMod*/);
     2350                if (pVirtMod)
     2351                {
     2352                    kwLdrModuleRelease(pMod);
     2353                    pMod = pVirtMod;
     2354                }
     2355                else
     2356                {
     2357                    kLdrModClose(pLdrMod);
     2358                    kwErrPrintf("out of memory\n");
     2359                }
     2360            }
     2361            else
     2362                kwErrPrintf("kLdrModOpenNativeByHandle failed for %p / '%s': %d\n", hModule, pszName, rc);
     2363        }
     2364        else
     2365            KWLDR_LOG(("kwLdrModuleTryLoadVirtualDll: %s -> %s - A real DLL!\n", pszName, pMod->pszPath));
     2366    }
     2367
     2368    return pMod;
    21502369}
    21512370
     
    22142433                            pMod->u.Manual.aQuickCopyChunks[iChunk].pbSrc    = &pMod->u.Manual.pbCopy[(KSIZE)paSegs[iSeg].RVA];
    22152434                            pMod->u.Manual.aQuickCopyChunks[iChunk].cbToCopy = paSegs[iSeg].cbMapped - cbTrailingZeros;
    2216                             pMod->u.Manual.cQuickCopyChunks = iChunk + 1;
     2435                            pMod->u.Manual.cQuickCopyChunks = (KU8)(iChunk + 1);
    22172436                            KWLDR_LOG(("aQuickCopyChunks[%u]: %#p LB %#" KSIZE_PRI " <- %p (%*.*s)\n", iChunk,
    22182437                                       pMod->u.Manual.aQuickCopyChunks[iChunk].pbDst,
     
    22312450                                                                            + pMod->u.Manual.aQuickCopyChunks[iChunk].cbToCopy;
    22322451                            pMod->u.Manual.aQuickZeroChunks[iZero].cbToZero = cbTrailingZeros;
    2233                             pMod->u.Manual.cQuickZeroChunks = iZero + 1;
     2452                            pMod->u.Manual.cQuickZeroChunks = (KU8)(iZero + 1);
    22342453                            KWLDR_LOG(("aQuickZeroChunks[%u]: %#p LB %#" KSIZE_PRI " <- zero (%*.*s)\n", iZero,
    22352454                                       pMod->u.Manual.aQuickZeroChunks[iZero].pbDst,
     
    22862505         * Try sabotage the DLL name so we can load this module again.
    22872506         */
     2507/** @todo this doesn't work W10 18363   */
    22882508        pHead = &pPeb->Ldr->InMemoryOrderModuleList;
    22892509        for (pCur = pHead->Blink; pCur != pHead; pCur = pCur->Blink)
     
    23302550        KU32 const                  cEntries  = pTlsDir->Size / sizeof(IMAGE_TLS_DIRECTORY);
    23312551        KU32                        iEntry;
     2552        KU32                        iTlsDll;
     2553        KU32                        iTlsDllSub;
    23322554        KUPTR                       offIndex;
    23332555        KUPTR                       offCallbacks;
     
    23842606        /*
    23852607         * Make the allocation by loading a new instance of one of the TLS dlls.
    2386          * The DLL will make a call to
     2608         * The DLL will make a call to kwLdrTlsAllocationHook.
    23872609         */
    23882610        offIndex     = (KUPTR)paEntries[0].AddressOfIndex     - (KUPTR)pMod->u.Manual.pbLoad;
     
    23902612        puCallbacks  = (KUPTR const *)&pbImg[offCallbacks];
    23912613        cbData = paEntries[0].SizeOfZeroFill + (paEntries[0].EndAddressOfRawData - paEntries[0].StartAddressOfRawData);
    2392         if (cbData <= 1024)
    2393             pwszTlsDll = L"kWorkerTls1K.dll";
    2394         else if (cbData <= 65536)
    2395             pwszTlsDll = L"kWorkerTls64K.dll";
    2396         else if (cbData <= 524288)
    2397             pwszTlsDll = L"kWorkerTls512K.dll";
    2398         else
    2399         {
    2400             kwErrPrintf("TLS data size in %s is too big: %u (%#p), max 512KB\n", pMod->pszPath, (unsigned)cbData, cbData);
    2401             return -1;
    2402         }
     2614
     2615        /** @todo find better strategy here. Like temporary copy or whatever when
     2616         *        there is more than a single user. */
     2617        for (iTlsDll = 0; cbData > g_aTlsDlls[iTlsDll].cbTls;)
     2618            if (++iTlsDll >= K_ELEMENTS(g_aTlsDlls))
     2619            {
     2620                kwErrPrintf("TLS data size in %s is too big: %u (%#p), max 512KB\n", pMod->pszPath, (unsigned)cbData, cbData);
     2621                return -1;
     2622            }
     2623        for (iTlsDllSub = 0; g_aTlsDlls[iTlsDll].paDlls[iTlsDllSub].fUsed;)
     2624            if (++iTlsDllSub >= g_aTlsDlls[iTlsDll].cDlls)
     2625            {
     2626                kwErrPrintf("No unused TLS DLLs for %s of size %u!\n", pMod->pszPath, (unsigned)cbData);
     2627                return -1;
     2628            }
     2629
     2630        g_aTlsDlls[iTlsDll].paDlls[iTlsDllSub].fUsed = K_TRUE;
     2631        pwszTlsDll = g_aTlsDlls[iTlsDll].paDlls[iTlsDllSub].pwszName;
    24032632
    24042633        pMod->u.Manual.idxTls         = KU32_MAX;
     
    25422771                        {
    25432772                            KI32 iImp;
     2773                            KU32 cchReloads;
    25442774
    25452775                            /*
     
    25482778                            pMod->hOurMod = (HMODULE)pMod->u.Manual.pbLoad;
    25492779                            kwLdrModuleLink(pMod);
    2550                             KW_LOG(("New module: %p LB %#010x %s (kLdr)\n",
    2551                                     pMod->u.Manual.pbLoad, pMod->cbImage, pMod->pszPath));
    2552                             KW_LOG(("TODO: .reload /f %s=%p\n", pMod->pszPath, pMod->u.Manual.pbLoad));
     2780                            KWLDR_LOG(("New module: %p LB %#010x %s (kLdr)\n",
     2781                                       pMod->u.Manual.pbLoad, pMod->cbImage, pMod->pszPath));
     2782                            KWLDR_LOG(("TODO: .reload /f %s=%p\n", pMod->pszPath, pMod->u.Manual.pbLoad));
    25532783                            kwDebuggerPrintf("TODO: .reload /f %s=%p\n", pMod->pszPath, pMod->u.Manual.pbLoad);
     2784                            cchReloads = g_cchReloads;
     2785                            if (cchReloads + 80 < sizeof(g_szReloads))
     2786                            {
     2787                                cchReloads += _snprintf(&g_szReloads[cchReloads], sizeof(g_szReloads) - cchReloads,
     2788                                                        "%s.reload /f %s=%p\n", cchReloads ? "; " : "",
     2789                                                        pMod->pszPath, pMod->u.Manual.pbLoad);
     2790                                g_cchReloads = cchReloads;
     2791                            }
    25542792
    25552793                            for (iImp = 0; iImp < cImports; iImp++)
     
    26112849                                        pMod->u.Manual.pvBits = pMod->u.Manual.pbCopy;
    26122850                                        pMod->u.Manual.enmState = KWMODSTATE_NEEDS_BITS;
     2851                                        pMod->u.Manual.enmReInitState = KWMODSTATE_NEEDS_BITS;
     2852                                        if (   g_Sandbox.pTool
     2853                                            && (   g_Sandbox.pTool->u.Sandboxed.enmHint == KWTOOLHINT_VISUAL_CPP_CL
     2854                                                || g_Sandbox.pTool->u.Sandboxed.enmHint == KWTOOLHINT_VISUAL_CPP_LINK)
     2855                                            && !pMod->fExe)
     2856                                            pMod->u.Manual.enmReInitState = KWMODSTATE_READY;
    26132857                                        g_cModules++;
    26142858                                        g_cNonNativeModules++;
     
    26752919                        || !g_aSandboxReplacements[i].fOnlyExe)
    26762920                    {
    2677                         KW_LOG(("replacing %s!%s\n",&pImpMod->pszPath[pImpMod->offFilename], g_aSandboxReplacements[i].pszFunction));
    2678                         *puValue = g_aSandboxReplacements[i].pfnReplacement;
     2921                        KWLDR_LOG(("replacing %s!%s\n",&pImpMod->pszPath[pImpMod->offFilename], g_aSandboxReplacements[i].pszFunction));
     2922                        if (!g_aSandboxReplacements[i].fCrtSlotArray)
     2923                            *puValue = g_aSandboxReplacements[i].pfnReplacement;
     2924                        else
     2925                        {
     2926                            if (pImpMod->iCrtSlot == KU8_MAX)
     2927                            {
     2928                                rc = kwLdrModuleCreateCrtSlot(pImpMod);
     2929                                if (rc)
     2930                                    KWLDR_LOG(("kwLdrModuleGetImportCallback: kwLdrModuleCreateCrtSlot failed: %d\n", rc));
     2931                            }
     2932                            *puValue = ((KUPTR *)g_aSandboxReplacements[i].pfnReplacement)[pImpMod->iCrtSlot];
     2933                        }
    26792934                    }
    26802935                    break;
     
    26842939
    26852940    //printf("iImport=%u (%s) %*.*s rc=%d\n", iImport, &pImpMod->pszPath[pImpMod->offFilename], cchSymbol, cchSymbol, pchSymbol, rc);
    2686     KW_LOG(("iImport=%u (%s) %*.*s rc=%d\n", iImport, &pImpMod->pszPath[pImpMod->offFilename], cchSymbol, cchSymbol, pchSymbol, rc));
     2941    KWLDR_LOG(("iImport=%u (%s) %*.*s rc=%d\n", iImport, &pImpMod->pszPath[pImpMod->offFilename], cchSymbol, cchSymbol, pchSymbol, rc));
    26872942    return rc;
    26882943
     
    27212976    if (enmLocation != KWLOCATION_SYSTEM32)
    27222977        return K_TRUE;
    2723     return kHlpStrNICompAscii(pszFilename, TUPLE("msvc"))   == 0
    2724         || kHlpStrNICompAscii(pszFilename, TUPLE("msdis"))  == 0
    2725         || kHlpStrNICompAscii(pszFilename, TUPLE("mspdb"))  == 0;
     2978    return kHlpStrNICompAscii(pszFilename, TUPLE("msvc"))            == 0
     2979        || kHlpStrNICompAscii(pszFilename, TUPLE("msdis"))           == 0
     2980        || kHlpStrNICompAscii(pszFilename, TUPLE("mspdb"))           == 0
     2981        || kHlpStrNICompAscii(pszFilename, TUPLE("vcruntime"))       == 0
     2982        || kHlpStrNICompAscii(pszFilename, TUPLE("ucrtbase"))        == 0
     2983        || kHlpStrNICompAscii(pszFilename, TUPLE("api-ms-win-crt-")) == 0
     2984        ;
    27262985}
    27272986
     
    27753034    if (enmLocation == KWLOCATION_UNKNOWN_NATIVE)
    27763035        return K_TRUE;
     3036    if (   enmLocation == KWLOCATION_UNKNOWN
     3037        && kwLdrIsVirtualApiModule(pszFilename, kHlpStrLen(pszFilename)))
     3038        return K_TRUE;
    27773039
    27783040    /* If the location is unknown, we must check if it's some dynamic loading
     
    27973059    }
    27983060
    2799     return kHlpStrNICompAscii(pszFilename, TUPLE("msvc"))   == 0
    2800         || kHlpStrNICompAscii(pszFilename, TUPLE("msdis"))  == 0
    2801         || kHlpStrNICompAscii(pszFilename, TUPLE("mspdb"))  == 0;
     3061    return kHlpStrNICompAscii(pszFilename, TUPLE("msvc"))      == 0
     3062        || kHlpStrNICompAscii(pszFilename, TUPLE("msdis"))     == 0
     3063        || kHlpStrNICompAscii(pszFilename, TUPLE("mspdb"))     == 0
     3064        || kHlpStrNICompAscii(pszFilename, TUPLE("tbbmalloc")) == 0
     3065        || kHlpStrNICompAscii(pszFilename, TUPLE("ucrtbase"))  == 0
     3066        || kHlpStrNICompAscii(pszFilename, TUPLE("vcruntime")) == 0
     3067        || (   enmLocation != KWLOCATION_UNKNOWN
     3068            && kwLdrIsVirtualApiModule(pszFilename, kHlpStrLen(pszFilename)));
    28023069}
    28033070
     
    29293196    KSIZE       cchSuffix   = fNeedSuffix ? 4 : 0;
    29303197
     3198    /* Virtual API module.  Normalize and try load it. */
     3199    if (pMod == NULL && cchName > 7 && kwLdrIsVirtualApiModule(pszName, cchName))
     3200    {
     3201        if (cchName + cchSuffix >= sizeof(szPath))
     3202            return KERR_BUFFER_OVERFLOW;
     3203        kHlpMemCopy(szPath, pszName, cchName);
     3204        if (fNeedSuffix)
     3205            kHlpMemCopy(&szPath[cchName], ".dll", sizeof(".dll"));
     3206        szPath[cchName + cchSuffix] = '\0';
     3207        _strlwr(szPath);
     3208        pMod = kwLdrModuleTryLoadVirtualDll(szPath, cchName + cchSuffix);
     3209    }
    29313210
    29323211    /* The import path. */
     
    30433322                kwErrPrintf("Failed to resolved 'malloc' in '%s': %d\n", pModule->pszPath, rc);
    30443323
     3324            rc = kLdrModQuerySymbol(pModule->pLdrMod, NULL /*pvBits*/, KLDRMOD_BASEADDRESS_MAP, KU32_MAX, "_beginthreadex", 14,
     3325                                    NULL /*pvszVersion*/, NULL /*pfnGetForwarder*/, NULL /*pvUser*/, &uAddr, NULL);
     3326            *(KUPTR *)&g_aCrtSlots[iSlot].pfnBeginThreadEx = rc == 0 ? (KUPTR)uAddr : 0;
     3327            //if (rc != 0)
     3328            //    kwErrPrintf("Failed to resolved '_beginthreadex' in '%s': %d\n", pModule->pszPath, rc);
     3329
    30453330            return 0;
    30463331        }
    30473332    kwErrPrintf("Out of CRT slots!\n");
    30483333    return KERR_NO_MEMORY;
     3334}
     3335
     3336
     3337/**
     3338 * Locates the module structure for an already loaded native module.
     3339 *
     3340 * This will create a module structure if needed.
     3341 *
     3342 * @returns Pointer to the module structure on success, NULL on failure.
     3343 * @param   hModule         The native module handle.
     3344 * @param   fEnsureCrtSlot  Whether to ensure that it has a valid CRT slot.
     3345 * @param   pszLogName      The name to use for logging/errors.
     3346 */
     3347static PKWMODULE kwLdrModuleForLoadedNativeByHandle(HMODULE hModule, KBOOL fEnsureCrtSlot, const char *pszLogName)
     3348{
     3349    /*
     3350     * Get a normalized path for it.
     3351     */
     3352    char szModPath[1024];
     3353    if (GetModuleFileNameA(hModule, szModPath, sizeof(szModPath)) > 0)
     3354    {
     3355        char szNormPath[1024];
     3356        int rc = kwPathNormalize(szModPath, szNormPath, sizeof(szNormPath));
     3357        if (rc == 0)
     3358        {
     3359            /*
     3360             * Hash the path and look it up.
     3361             */
     3362            KU32        uHashPath;
     3363            KSIZE const cchPath   = kwStrHashEx(szNormPath, &uHashPath);
     3364            unsigned    idxHash   = uHashPath % K_ELEMENTS(g_apModules);
     3365            PKWMODULE   pMod      = g_apModules[idxHash];
     3366            if (pMod)
     3367            {
     3368                do
     3369                {
     3370                    if (   pMod->uHashPath == uHashPath
     3371                        && kHlpStrComp(pMod->pszPath, szNormPath) == 0)
     3372                    {
     3373                        kwLdrModuleRetain(pMod);
     3374                        break;
     3375                    }
     3376                    pMod = pMod->pNextHash;
     3377                } while (pMod);
     3378            }
     3379
     3380            /*
     3381             * If not in the hash table, so create a module entry.
     3382             */
     3383            if (!pMod)
     3384            {
     3385                PKLDRMOD pLdrMod;
     3386                rc = kLdrModOpenNativeByHandle((KUPTR)hModule, KLDRMOD_OPEN_FLAGS_NATIVE_ALLOW_INIT_TERM, &pLdrMod);
     3387                if (rc == 0)
     3388                {
     3389                    /** @todo more accurately determine location  */
     3390                    const char *pszFilename = kHlpGetFilename(szNormPath);
     3391                    KBOOL fDoReplacements = kwLdrModuleShouldDoNativeReplacements(pszFilename, KWLOCATION_SYSTEM32);
     3392                    pMod = kwLdrModuleCreateForNativekLdrModule(pLdrMod, szNormPath, cchPath + 1, uHashPath,
     3393                                                                fDoReplacements, NULL /*pVirtualApiMod*/);
     3394                    if (!pMod)
     3395                    {
     3396                        kLdrModClose(pLdrMod);
     3397                        kwErrPrintf("out of memory\n");
     3398                    }
     3399                }
     3400                else
     3401                    kwErrPrintf("kLdrModOpenNativeByHandle failed for %p / '%s': %d\n", hModule, pszLogName, rc);
     3402            }
     3403            if (pMod)
     3404            {
     3405                /*
     3406                 * Create a CRT slot for the module if necessary.
     3407                 */
     3408                if (!fEnsureCrtSlot || pMod->iCrtSlot != KU8_MAX)
     3409                    return pMod;
     3410                rc = kwLdrModuleCreateCrtSlot(pMod);
     3411                if (rc == 0)
     3412                    return pMod;
     3413                kwLdrModuleRelease(pMod);
     3414            }
     3415        }
     3416        else
     3417            kwErrPrintf("kwPathNormalize failed for '%s' (%s): %u!\n", szModPath, pszLogName, GetLastError());
     3418    }
     3419    else
     3420        kwErrPrintf("GetModuleFileNameA failed for '%s': %u!\n", pszLogName, GetLastError());
     3421    return NULL;
    30493422}
    30503423
     
    30643437{
    30653438    /*
    3066      * Locate the module and get a normalized path for it.
     3439     * Locate the module handle and pass it to kwLdrModuleForLoadedNativeByHandle.
    30673440     */
    30683441    HANDLE hModule = GetModuleHandleA(pszName);
    30693442    if (hModule)
    3070     {
    3071         char szModPath[1024];
    3072         if (GetModuleFileNameA(hModule, szModPath, sizeof(szModPath)) > 0)
    3073         {
    3074             char szNormPath[1024];
    3075             int rc = kwPathNormalize(szModPath, szNormPath, sizeof(szNormPath));
    3076             if (rc == 0)
    3077             {
    3078                 /*
    3079                  * Hash the path and look it up.
    3080                  */
    3081                 KU32        uHashPath;
    3082                 KSIZE const cchPath   = kwStrHashEx(szNormPath, &uHashPath);
    3083                 unsigned    idxHash   = uHashPath % K_ELEMENTS(g_apModules);
    3084                 PKWMODULE   pMod      = g_apModules[idxHash];
    3085                 if (pMod)
    3086                 {
    3087                     do
    3088                     {
    3089                         if (   pMod->uHashPath == uHashPath
    3090                             && kHlpStrComp(pMod->pszPath, szNormPath) == 0)
    3091                         {
    3092                             kwLdrModuleRetain(pMod);
    3093                             break;
    3094                         }
    3095                         pMod = pMod->pNextHash;
    3096                     } while (pMod);
    3097                 }
    3098 
    3099                 /*
    3100                  * If not in the hash table, so create a module entry.
    3101                  */
    3102                 if (!pMod)
    3103                 {
    3104                     PKLDRMOD pLdrMod;
    3105                     rc = kLdrModOpenNativeByHandle((KUPTR)hModule, KLDRMOD_OPEN_FLAGS_NATIVE_ALLOW_INIT_TERM, &pLdrMod);
    3106                     if (rc == 0)
    3107                     {
    3108                         pMod = kwLdrModuleCreateForNativekLdrModule(pLdrMod, szNormPath, cchPath + 1, uHashPath,
    3109                                                                     K_FALSE /*fDoReplacements*/);
    3110                         if (!pMod)
    3111                         {
    3112                             kLdrModClose(pLdrMod);
    3113                             kwErrPrintf("out of memory\n");
    3114                         }
    3115                     }
    3116                     else
    3117                         kwErrPrintf("kLdrModOpenNativeByHandle failed for %p / '%s': %d\n", hModule, pszName, rc);
    3118                 }
    3119                 if (pMod)
    3120                 {
    3121                     /*
    3122                      * Create a CRT slot for the module if necessary.
    3123                      */
    3124                     if (!fEnsureCrtSlot || pMod->iCrtSlot != KU8_MAX)
    3125                         return pMod;
    3126                     rc = kwLdrModuleCreateCrtSlot(pMod);
    3127                     if (rc == 0)
    3128                         return pMod;
    3129                     kwLdrModuleRelease(pMod);
    3130                 }
    3131             }
    3132             else
    3133                 kwErrPrintf("kwPathNormalize failed for '%s' (%s): %u!\n", szModPath, pszName, GetLastError());
    3134         }
    3135         else
    3136             kwErrPrintf("GetModuleFileNameA failed for '%s': %u!\n", pszName, GetLastError());
    3137     }
    3138     else if (fAlwaysPresent)
     3443        return kwLdrModuleForLoadedNativeByHandle(hModule, fEnsureCrtSlot, pszName);
     3444    if (fAlwaysPresent)
    31393445        kwErrPrintf("Module '%s' was not found by GetModuleHandleA/W!\n", pszName);
    31403446    return NULL;
     
    33463652    PKWDYNLOAD      pDynLoad;
    33473653
     3654    if (pTool)
     3655    { /* likely */ }
     3656    else
     3657        return NULL;
     3658
    33483659    /* The executable. */
    33493660    if (   hmod == NULL
    3350         || pTool->u.Sandboxed.pExe->hOurMod == hmod)
    3351         return kwLdrModuleRetain(pTool->u.Sandboxed.pExe);
     3661        || (pTool->u.Sandboxed.pExe && pTool->u.Sandboxed.pExe->hOurMod == hmod))
     3662    {
     3663        if (pTool->u.Sandboxed.pExe)
     3664            return kwLdrModuleRetain(pTool->u.Sandboxed.pExe);
     3665        return NULL;
     3666    }
    33523667
    33533668    /*
     
    33623677        for (;;)
    33633678        {
    3364             KUPTR const uHModThis = (KUPTR)papMods[i]->hOurMod;
    3365             if (uHMod < uHModThis)
     3679            KUPTR const uHModCur = (KUPTR)papMods[i]->hOurMod;
     3680            if (uHMod < uHModCur)
    33663681            {
    33673682                iEnd = i--;
     
    33713686                    break;
    33723687            }
    3373             else if (uHMod != uHModThis)
     3688            else if (uHMod != uHModCur)
    33743689            {
    33753690                iStart = ++i;
     
    33793694                    break;
    33803695            }
     3696            /* We've got a match.  Always return the non-virtual module (first) when there is one. */
     3697            else if (!papMods[i]->pVirtualApiMod)
     3698                return kwLdrModuleRetain(papMods[i]);
    33813699            else
     3700            {
     3701                while (i > 0 && papMods[i - 1]->pVirtualApiMod && papMods[i - 1]->hOurMod == hmod)
     3702                    i--;
    33823703                return kwLdrModuleRetain(papMods[i]);
     3704            }
    33833705
    33843706            i = iStart + (iEnd - iStart) / 2;
     
    34303752        for (;;)
    34313753        {
    3432             KUPTR const uHModThis = (KUPTR)papMods[i]->hOurMod;
    3433             if (uHMod < uHModThis)
     3754            PKWMODULE   pCurMod  = papMods[i];
     3755            KUPTR const uHModCur = (KUPTR)pCurMod->hOurMod;
     3756            if (uHMod < uHModCur)
    34343757            {
    34353758                iEnd = i;
     
    34393762                    break;
    34403763            }
    3441             else if (uHMod != uHModThis)
     3764            else if (uHMod != uHModCur)
    34423765            {
    34433766                iStart = ++i;
     
    34493772            else
    34503773            {
    3451                 /* Already there in the table. */
     3774                /* Already there in the table. The non-virtual module must be the first
     3775                   entry if we've got duplicate hmod values because of virtual modules.  */
     3776                if (pMod != pCurMod)
     3777                {
     3778                    /* Skip to the last module with the same hmod. */
     3779                    while (i + 1 < iEnd && (KUPTR)(pCurMod = papMods[i + 1])->hOurMod == uHMod)
     3780                    {
     3781                        if (pMod == pCurMod)
     3782                            return 0;
     3783                        i++;
     3784                    }
     3785
     3786                    /* Then scan backwards till the first one. */
     3787                    while (i > 0 && (KUPTR)(pCurMod = papMods[i - 1])->hOurMod == uHMod)
     3788                    {
     3789                        if (pMod == pCurMod)
     3790                            return 0;
     3791                        i--;
     3792                    }
     3793                    pCurMod = papMods[i];
     3794                    if (pMod != pCurMod)
     3795                    {
     3796                        if (pMod->pVirtualApiMod && !pCurMod->pVirtualApiMod)
     3797                            i++;
     3798                        break;
     3799                    }
     3800                }
    34523801                return 0;
    34533802            }
     
    34603809        {
    34613810            kHlpAssert(papMods[iStart] != pMod);
    3462             kHlpAssert((KUPTR)papMods[iStart]->hOurMod != uHMod);
    3463         }
    3464         kHlpAssert(i == 0 || (KUPTR)papMods[i - 1]->hOurMod < uHMod);
    3465         kHlpAssert(i == pTool->u.Sandboxed.cModules || (KUPTR)papMods[i]->hOurMod > uHMod);
     3811            kHlpAssert(   (KUPTR)papMods[iStart]->hOurMod != uHMod
     3812                       || pMod->pVirtualApiMod
     3813                       || papMods[iStart]->pVirtualApiMod);
     3814        }
     3815        kHlpAssert(i == 0 || (KUPTR)papMods[i - 1]->hOurMod <= uHMod);
     3816        kHlpAssert(i == pTool->u.Sandboxed.cModules || (KUPTR)papMods[i]->hOurMod >= uHMod);
    34663817#endif
    34673818    }
     
    34853836    papMods[i] = kwLdrModuleRetain(pMod);
    34863837    pTool->u.Sandboxed.cModules++;
    3487     KW_LOG(("kwToolAddModule: %u modules after adding %p=%s\n", pTool->u.Sandboxed.cModules, uHMod, pMod->pszPath));
     3838    KWLDR_LOG(("kwToolAddModule: %u modules after adding %p=%s\n", pTool->u.Sandboxed.cModules, uHMod, pMod->pszPath));
    34883839    return 0;
    34893840}
     
    35003851{
    35013852    int rc = kwToolAddModule(pTool, pMod);
     3853    if (pMod->pVirtualApiMod && rc == 0)
     3854        rc = kwToolAddModule(pTool, pMod->pVirtualApiMod);
    35023855    if (!pMod->fNative && rc == 0)
    35033856    {
     
    35123865        }
    35133866    }
     3867
    35143868    return 0;
    35153869}
     
    38174171            break;
    38184172        pfFlags = pchPool;
    3819         PUTC((char)_ARG_NONZERO);
     4173        PUTC((unsigned char)_ARG_NONZERO);
    38204174        PUTV;
    38214175        bs = 0; chQuote = 0;
     
    39794333        return NULL;
    39804334    }
    3981     KW_LOG(("_onexit(%p) - IGNORED\n", pfnFunc));
    3982     return pfnFunc;
     4335    //KW_LOG(("_onexit(%p) - IGNORED\n", pfnFunc));
     4336    //return pfnFunc;
    39834337}
    39844338
     
    40044358        return -1;
    40054359    }
    4006     KW_LOG(("atexit(%p) - IGNORED!\n", pfnFunc));
    4007     return 0;
     4360    //KW_LOG(("atexit(%p) - IGNORED!\n", pfnFunc));
     4361    //return 0;
    40084362}
    40094363
     
    42414595
    42424596/** _beginthreadex - create a new thread. */
    4243 static uintptr_t __cdecl kwSandbox_msvcrt__beginthreadex(void *pvSecAttr, unsigned cbStack,
    4244                                                          unsigned (__stdcall *pfnThreadProc)(void *), void *pvUser,
    4245                                                          unsigned fCreate, unsigned *pidThread)
    4246 {
     4597static uintptr_t __cdecl kwSandbox_msvcrt__beginthreadex_wrapped(void *pvSecAttr, unsigned cbStack,
     4598                                                                 unsigned (__stdcall *pfnThreadProc)(void *), void *pvUser,
     4599                                                                 unsigned fCreate, unsigned *pidThread, PKWCRTSLOT pSlot)
     4600{
     4601    /*
     4602     * Since the VC++ 12 (VS 2013) compiler, the 2nd pass is now threaded.
     4603     * Let it do whatever it needs to.
     4604     */
     4605    KW_LOG(("kwSandbox_msvcrt__beginthreadex: pvSecAttr=%p (inh=%d) cbStack=%#x pfnThreadProc=%p pvUser=%p fCreate=%#x pidThread=%p\n",
     4606            pvSecAttr, pvSecAttr ? ((LPSECURITY_ATTRIBUTES)pvSecAttr)->bInheritHandle : 0, cbStack,
     4607            pfnThreadProc, pvUser, fCreate, pidThread));
     4608    if (   g_Sandbox.pTool->u.Sandboxed.enmHint == KWTOOLHINT_VISUAL_CPP_CL
     4609        && pSlot->pfnBeginThreadEx)
     4610    {
     4611        uintptr_t rcRet = pSlot->pfnBeginThreadEx(pvSecAttr, cbStack, pfnThreadProc, pvUser, fCreate, pidThread);
     4612        KW_LOG(("kwSandbox_msvcrt__beginthreadex: returns %p *pidThread=%#x\n", rcRet, pidThread ? *pidThread : -1));
     4613        return rcRet;
     4614    }
     4615
    42474616    kHlpAssert(GetCurrentThreadId() == g_Sandbox.idMainThread);
    42484617    KWFS_TODO();
    42494618    return 0;
    42504619}
     4620
     4621CRT_SLOT_FUNCTION_WRAPPER(uintptr_t __cdecl, kwSandbox_msvcrt__beginthreadex,
     4622                          (void *pvSecAttr, unsigned cbStack, unsigned (__stdcall *pfnThreadProc)(void *),
     4623                           void *pvUser, unsigned fCreate, unsigned *pidThread),
     4624                          (pvSecAttr, cbStack, pfnThreadProc, pvUser, fCreate, pidThread, &g_aCrtSlots[iCrtSlot]));
     4625
    42514626
    42524627
     
    42864661        }
    42874662        *psz++ = '\0';
    4288         kHlpAssert(psz - pszzEnv == cbNeeded);
     4663        kHlpAssert((KUPTR)(psz - pszzEnv) == cbNeeded);
    42894664    }
    42904665
     
    43024677    fprintf(stderr, "  %u:%p=<eos>\n\n", iVar, pszCur);
    43034678    pszCur++;
    4304     fprintf(stderr, "ended at %p, after %u bytes (exepcted %u)\n", pszCur, pszCur - pszzEnv, cbNeeded);
     4679    fprintf(stderr, "ended at %p, after %u bytes (expected %u)\n", pszCur, pszCur - pszzEnv, cbNeeded);
    43054680#endif
    43064681    return pszzEnv;
     
    43434718        }
    43444719        *pwsz++ = '\0';
    4345         kHlpAssert(pwsz - pwszzEnv == cwcNeeded);
     4720        kHlpAssert((KUPTR)(pwsz - pwszzEnv) == cwcNeeded);
    43464721    }
    43474722
     
    50545429        pDynLoad->pNext = g_Sandbox.pTool->u.Sandboxed.pDynLoadHead;
    50555430        g_Sandbox.pTool->u.Sandboxed.pDynLoadHead = pDynLoad;
    5056         KW_LOG(("LoadLibraryExA(%s,,[resource]) -> %p\n", pDynLoad->szRequest, pDynLoad->hmod));
     5431        KWLDR_LOG(("LoadLibraryExA(%s,,[resource]) -> %p\n", pDynLoad->szRequest, pDynLoad->hmod));
    50575432    }
    50585433    else
     
    50675442static HMODULE WINAPI kwSandbox_Kernel32_LoadLibraryExA_VirtualApiModule(PKWDYNLOAD pDynLoad, DWORD fFlags)
    50685443{
    5069     HMODULE     hmod;
     5444    static const char s_szDll[] = ".dll";
     5445    KSIZE       cbFilename = kHlpStrLen(pDynLoad->szRequest) + 1;
    50705446    PKWMODULE   pMod;
    5071     KU32        uHashPath;
    5072     KSIZE       idxHash;
    50735447    char        szNormPath[256];
    5074     KSIZE       cbFilename = kHlpStrLen(pDynLoad->szRequest) + 1;
    50755448
    50765449    /*
    5077      * Lower case it and make it ends with .dll.
     5450     * Lower case it and make sure it ends with .dll.
    50785451     */
    5079     if (cbFilename <= sizeof(szNormPath))
    5080     {
    5081         static const char s_szDll[] = ".dll";
    5082         kHlpMemCopy(szNormPath, pDynLoad->szRequest, cbFilename);
    5083         _strlwr(szNormPath);
    5084         if (   (   cbFilename <= 4
    5085                 || strcmp(&szNormPath[cbFilename - 5], s_szDll) != 0)
    5086             && cbFilename + sizeof(s_szDll) - 1 <= sizeof(szNormPath))
    5087         {
    5088             memcpy(&szNormPath[cbFilename - sizeof(s_szDll)], s_szDll, sizeof(s_szDll));
    5089             cbFilename += sizeof(s_szDll) - 1;
    5090         }
    5091     }
    5092     else
     5452    if (cbFilename > sizeof(szNormPath))
    50935453    {
    50945454        SetLastError(ERROR_FILENAME_EXCED_RANGE);
    50955455        return NULL;
    50965456    }
     5457    kHlpMemCopy(szNormPath, pDynLoad->szRequest, cbFilename);
     5458    _strlwr(szNormPath);
     5459    kHlpAssert(cbFilename > 7 /* api-ms- */ );
     5460    if (strcmp(&szNormPath[cbFilename - 5], s_szDll) != 0)
     5461    {
     5462        if (cbFilename + sizeof(s_szDll) - 1 > sizeof(szNormPath))
     5463        {
     5464            SetLastError(ERROR_FILENAME_EXCED_RANGE);
     5465            return NULL;
     5466        }
     5467
     5468        memcpy(&szNormPath[cbFilename - sizeof(s_szDll)], s_szDll, sizeof(s_szDll));
     5469        cbFilename += sizeof(s_szDll) - 1;
     5470    }
    50975471
    50985472    /*
    5099      * Check if it has already been loaded so we don't create an unnecessary
    5100      * loader module for it.
     5473     * Try load it.
    51015474     */
    5102     uHashPath = kwStrHash(szNormPath);
    5103     idxHash   = uHashPath % K_ELEMENTS(g_apModules);
    5104     pMod      = g_apModules[idxHash];
     5475    pMod = kwLdrModuleTryLoadVirtualDll(szNormPath, cbFilename - 1);
    51055476    if (pMod)
    51065477    {
    5107         do
    5108         {
    5109             if (   pMod->uHashPath == uHashPath
    5110                 && kHlpStrComp(pMod->pszPath, szNormPath) == 0)
    5111             {
    5112                 pDynLoad->pMod = kwLdrModuleRetain(pMod);
    5113                 pDynLoad->hmod = pMod->hOurMod;
    5114 
    5115                 pDynLoad->pNext = g_Sandbox.pTool->u.Sandboxed.pDynLoadHead;
    5116                 g_Sandbox.pTool->u.Sandboxed.pDynLoadHead = pDynLoad;
    5117                 KW_LOG(("LoadLibraryExA(%s,,) -> %p [virtual API module - already loaded]\n", pDynLoad->szRequest, pDynLoad->hmod));
    5118                 return pDynLoad->hmod;
    5119             }
    5120             pMod = pMod->pNextHash;
    5121         } while (pMod);
    5122     }
    5123 
    5124 
    5125     /*
    5126      * Try load it and make a kLdr module for it.
    5127      */
    5128     hmod = LoadLibraryExA(szNormPath, NULL /*hFile*/, fFlags);
    5129     if (hmod)
    5130     {
    5131         PKLDRMOD pLdrMod;
    5132         int rc = kLdrModOpenNativeByHandle((KUPTR)hmod, KLDRMOD_OPEN_FLAGS_NATIVE_ALLOW_INIT_TERM, &pLdrMod);
    5133         if (rc == 0)
    5134         {
    5135             PKWMODULE pMod = kwLdrModuleCreateForNativekLdrModule(pLdrMod, szNormPath, cbFilename, uHashPath,
    5136                                                                   K_FALSE /*fDoReplacements*/);
    5137             if (pMod)
    5138             {
    5139                 kwToolAddModuleAndImports(g_Sandbox.pTool, pMod);
    5140 
    5141                 pDynLoad->pMod = pMod;
    5142                 pDynLoad->hmod = hmod;
    5143 
    5144                 pDynLoad->pNext = g_Sandbox.pTool->u.Sandboxed.pDynLoadHead;
    5145                 g_Sandbox.pTool->u.Sandboxed.pDynLoadHead = pDynLoad;
    5146                 KW_LOG(("LoadLibraryExA(%s,,) -> %p [virtual API module - new]\n", pDynLoad->szRequest, pDynLoad->hmod));
    5147                 return hmod;
    5148             }
    5149             KWFS_TODO();
    5150         }
    5151         else
    5152             KWFS_TODO();
     5478        kwToolAddModuleAndImports(g_Sandbox.pTool, pMod);
     5479
     5480        pDynLoad->pMod = pMod;
     5481        pDynLoad->hmod = pMod->hOurMod;
     5482
     5483        pDynLoad->pNext = g_Sandbox.pTool->u.Sandboxed.pDynLoadHead;
     5484        g_Sandbox.pTool->u.Sandboxed.pDynLoadHead = pDynLoad;
     5485        KWLDR_LOG(("LoadLibraryExA(%s,,) -> %p [virtual API module - new]\n", pDynLoad->szRequest, pDynLoad->hmod));
     5486        return pDynLoad->hmod;
    51535487    }
    51545488    kHlpFree(pDynLoad);
    5155     return hmod;
     5489    return NULL;
    51565490}
    51575491
     
    51665500    int         rc;
    51675501    kHlpAssert(GetCurrentThreadId() == g_Sandbox.idMainThread);
     5502    //fprintf(stderr, "LoadLibraryExA: %s, %#x\n", pszFilename, fFlags);
    51685503
    51695504    /*
     
    51935528            if (rc == 0)
    51945529            {
    5195                 KW_LOG(("LoadLibraryExA(%s,,) -> %p [cached]\n", pszFilename, pDynLoad->hmod));
     5530                KWLDR_LOG(("LoadLibraryExA(%s,,) -> %p [cached]\n", pszFilename, pDynLoad->hmod));
    51965531                return pDynLoad->hmod;
    51975532            }
     
    52115546    else
    52125547    {
    5213         KW_LOG(("LoadLibraryExA: Out of memory!\n"));
     5548        KWLDR_LOG(("LoadLibraryExA: Out of memory!\n"));
    52145549        SetLastError(ERROR_NOT_ENOUGH_MEMORY);
    52155550        return NULL;
     
    52285563     * Special case: api-ms-win-core-synch-l1-2-0 and friends (32-bit yasm, built with VS2015).
    52295564     */
    5230     if (   strnicmp(pszFilename, TUPLE("api-ms-")) == 0
     5565    if (   kwLdrIsVirtualApiModule(pszFilename, cchFilename)
    52315566        && kHlpIsFilenameOnly(pszFilename))
    52325567        return kwSandbox_Kernel32_LoadLibraryExA_VirtualApiModule(pDynLoad, fFlags);
     
    52635598        if (rc == 0)
    52645599        {
    5265             KW_LOG(("LoadLibraryExA(%s,,) -> %p\n", pszFilename, pDynLoad->hmod));
     5600            KWLDR_LOG(("LoadLibraryExA(%s,,) -> %p\n", pszFilename, pDynLoad->hmod));
    52665601            return pDynLoad->hmod;
    52675602        }
     
    54795814                    || pDynLoad->pMod->u.Manual.enmState == KWMODSTATE_READY)
    54805815                {
    5481                     KW_LOG(("kwSandbox_Kernel32_GetModuleHandleA(%s,,) -> %p [dynload]\n", pszModule, pDynLoad->hmod));
     5816                    KWLDR_LOG(("kwSandbox_Kernel32_GetModuleHandleA(%s,,) -> %p [dynload]\n", pszModule, pDynLoad->hmod));
    54825817                    return pDynLoad->hmod;
    54835818                }
     
    54925827     * to and go via the g_aGetModuleHandleCache cache.
    54935828     */
    5494     if (strnicmp(pszModule, "api-ms-win-", 11) == 0)
     5829/** @todo virtual api DLLs */
     5830    if (kHlpStrNICompAscii(pszModule, "api-ms-win-", 11) == 0)
    54955831    {
    54965832        HMODULE hmod = GetModuleHandleA(pszModule);
     
    55045840            if (hmod == GetModuleHandleW(L"NTDLL.DLL"))
    55055841                return kwSandbox_Kernel32_GetModuleHandleA("NTDLL.DLL");
     5842            if (hmod == GetModuleHandleW(L"UCRTBASE.DLL"))
     5843                return kwSandbox_Kernel32_GetModuleHandleA("UCRTBASE.DLL");
    55065844        }
    55075845        else
     
    56155953    KWFS_TODO();
    56165954#endif
    5617     return -1;
     5955    return ~(UINT)0;
    56185956}
    56195957
     
    57226060                               < g_Sandbox.pTool->u.Sandboxed.pExe->cbImage)
    57236061                        {
    5724                             uValue = g_aSandboxGetProcReplacements[i].pfnReplacement;
     6062                            if (!g_aSandboxReplacements[i].fCrtSlotArray)
     6063                                uValue = g_aSandboxGetProcReplacements[i].pfnReplacement;
     6064                            else
     6065                            {
     6066                                if (pMod->iCrtSlot == KU8_MAX)
     6067                                {
     6068                                    int rc = kwLdrModuleCreateCrtSlot(pMod);
     6069                                    if (rc)
     6070                                    {
     6071                                        KW_LOG(("GetProcAddress: kwLdrModuleCreateCrtSlot failed: %d\n", rc));
     6072                                        SetLastError(ERROR_INTERNAL_ERROR);
     6073                                        return NULL;
     6074                                    }
     6075                                }
     6076                                uValue = ((KUPTR *)g_aSandboxGetProcReplacements[i].pfnReplacement)[pMod->iCrtSlot];
     6077                            }
     6078
    57256079                            KW_LOG(("GetProcAddress(%s, %s) -> %p replaced\n", pMod->pszPath, pszProc, (KUPTR)uValue));
    57266080                        }
     
    58396193            for (;;)
    58406194            {
    5841                 KUPTR const uHModThis = (KUPTR)papMods[i]->hOurMod;
    5842                 if (uPC < uHModThis)
     6195                KUPTR const uHModCur = (KUPTR)papMods[i]->hOurMod;
     6196                if (uPC < uHModCur)
    58436197                {
    58446198                    iEnd = i;
     
    58486202                        break;
    58496203                }
    5850                 else if (uPC != uHModThis)
     6204                else if (uPC != uHModCur)
    58516205                {
    58526206                    iStart = ++i;
     
    59726326            return K_TRUE;
    59736327        }
     6328
     6329        /* In VC2019 there is also one {UUID} file in temp: */
     6330        if (pwszName[0] == '{')
     6331        {
     6332            KSIZE cwcName = kwUtf16Len(pwszName);
     6333            if (   cwcName == sizeof("{4465DDD9-E494-471B-996B-9B556E25AEF8}") - 1
     6334                && pwszName[37] == '}'
     6335                && iswalnum(pwszName[1])   // 4
     6336                && iswalnum(pwszName[2])   // 4
     6337                && iswalnum(pwszName[3])   // 6
     6338                && iswalnum(pwszName[4])   // 5
     6339                && iswalnum(pwszName[5])   // d
     6340                && iswalnum(pwszName[6])   // d
     6341                && iswalnum(pwszName[7])   // d
     6342                && iswalnum(pwszName[8])   // 9
     6343                && pwszName[9] == '-'      // -
     6344                && iswalnum(pwszName[10])  // e
     6345                && iswalnum(pwszName[11])  // 4
     6346                && iswalnum(pwszName[12])  // 9
     6347                && iswalnum(pwszName[13])  // 4
     6348                && pwszName[14] == '-'     // -
     6349                && iswalnum(pwszName[15])  // 4
     6350                && iswalnum(pwszName[16])  // 7
     6351                && iswalnum(pwszName[17])  // 1
     6352                && iswalnum(pwszName[18])  // b
     6353                && pwszName[19] == '-'     // -
     6354                && iswalnum(pwszName[20])  // 9
     6355                && iswalnum(pwszName[21])  // 9
     6356                && iswalnum(pwszName[22])  // 6
     6357                && iswalnum(pwszName[23])  // b
     6358                && pwszName[24] == '-'     // -
     6359                && iswalnum(pwszName[25])  // 9
     6360                && iswalnum(pwszName[26])  // b
     6361                && iswalnum(pwszName[27])  // 5
     6362                && iswalnum(pwszName[28])  // 5
     6363                && iswalnum(pwszName[29])  // 6
     6364                && iswalnum(pwszName[30])  // e
     6365                && iswalnum(pwszName[31])  // 2
     6366                && iswalnum(pwszName[32])  // 5
     6367                && iswalnum(pwszName[33])  // a
     6368                && iswalnum(pwszName[34])  // 3
     6369                && iswalnum(pwszName[35])  // f
     6370                && iswalnum(pwszName[36])) // 8
     6371                return K_TRUE;
     6372        }
    59746373    }
    59756374    return K_FALSE;
     
    60296428
    60306429
    6031 static HANDLE kwFsTempFileCreateW(const wchar_t *pwszFilename, DWORD dwDesiredAccess, DWORD dwCreationDisposition)
     6430static HANDLE kwFsTempFileCreateW(const wchar_t *pwszFilename, DWORD dwDesiredAccess, DWORD dwCreationDisposition,
     6431                                  KBOOL *pfFallback)
    60326432{
    60336433    HANDLE hFile;
     
    60536453     * Create a new temporary file instance if not found.
    60546454     */
     6455    *pfFallback = K_FALSE;
    60556456    if (pTempFile == NULL)
    60566457    {
     
    60616462            case CREATE_ALWAYS:
    60626463            case OPEN_ALWAYS:
     6464            case CREATE_NEW:
    60636465                dwErr = NO_ERROR;
    60646466                break;
    60656467
    6066             case CREATE_NEW:
    6067                 kHlpAssertFailed();
    6068                 SetLastError(ERROR_ALREADY_EXISTS);
    6069                 return INVALID_HANDLE_VALUE;
    6070 
    60716468            case OPEN_EXISTING:
    60726469            case TRUNCATE_EXISTING:
     6470                *pfFallback = K_TRUE;
    60736471                kHlpAssertFailed();
    60746472                SetLastError(ERROR_FILE_NOT_FOUND);
     
    61136511                break;
    61146512            case OPEN_ALWAYS:
    6115                 dwErr = ERROR_ALREADY_EXISTS ;
     6513                dwErr = ERROR_ALREADY_EXISTS;
    61166514                break;
    61176515
     
    63696767    kHlpAssertReturn(pFsObj->pParent->hDir != INVALID_HANDLE_VALUE, NULL);
    63706768
    6371     Ios.Information = -1;
     6769    Ios.Information = ~(ULONG_PTR)0;
    63726770    Ios.u.Status    = -1;
    63736771
     
    66277025        && kwFsIsClTempFileW(pwszFilename))
    66287026    {
    6629         hFile = kwFsTempFileCreateW(pwszFilename, dwDesiredAccess, dwCreationDisposition);
    6630         KWFS_LOG(("CreateFileW(%ls) -> %p [temp]\n", pwszFilename, hFile));
    6631         return hFile;
     7027        KBOOL fFallback = K_FALSE;
     7028        hFile = kwFsTempFileCreateW(pwszFilename, dwDesiredAccess, dwCreationDisposition, &fFallback);
     7029        if (!fFallback)
     7030        {
     7031            KWFS_LOG(("CreateFileW(%ls) -> %p [temp]\n", pwszFilename, hFile));
     7032            return hFile;
     7033        }
    66327034    }
    66337035#endif
     
    70897491            {
    70907492                pOutBuf->u.Fully.cchBufAlloc = sizeof(pOutBuf->abPadding);
    7091                 pOutBuf->u.Fully.pchBuf      = pOutBuf->abPadding;
     7493                pOutBuf->u.Fully.pchBuf      = (char *)&pOutBuf->abPadding[0];
    70927494            }
    70937495        }
     
    80428444            fRet = INVALID_FILE_ATTRIBUTES;
    80438445        }
    8044 
     8446#ifndef NDEBUG
     8447        {
     8448            DWORD fCheck = GetFileAttributesW(pwszFilename);
     8449            kHlpAssertMsg(fCheck == fRet, ("fCheck=%x vs fRet=%#x diff=%#x; %ls\n", fCheck, fRet, fCheck ^ fRet, pwszFilename));
     8450        }
     8451#endif
    80458452        KWFS_LOG(("GetFileAttributesW(%ls) -> %#x [cached]\n", pwszFilename, fRet));
    80468453        return fRet;
     
    80788485                *(KU64 *)&pData->ftLastWriteTime  = birdNtTimeFromTimeSpec(&pFsObj->Stats.st_mtim);
    80798486                kFsCacheObjRelease(g_pFsCache, pFsObj);
     8487                fRet = TRUE;
    80808488            }
    80818489            else
     
    80918499        }
    80928500
     8501#ifdef K_STRICT
     8502        {
     8503            WIN32_FILE_ATTRIBUTE_DATA CheckData = { 0 };
     8504            DWORD const dwErrSaved = GetLastError();
     8505            BOOL const fRetCheck = GetFileAttributesExA(pszFilename, enmLevel, &CheckData);
     8506            kHlpAssertMsg(fRet == fRetCheck, ("fRet=%d fRetCheck=%d; %s\n", fRet, fRetCheck, pszFilename));
     8507            if (fRetCheck && fRet)
     8508            {
     8509# define ASSERT_FS_FIELD_EQUAL_A(pResult, pExpected, pszFilename, Field, szFmt) \
     8510    kHlpAssertMsg((pResult)->Field == (pExpected)->Field, (#Field ": " szFmt " , expected " szFmt "; %s\n", (pResult)->Field, (pExpected)->Field, pszFilename))
     8511                ASSERT_FS_FIELD_EQUAL_A(pData, &CheckData, pszFilename, dwFileAttributes, "%#x");
     8512                ASSERT_FS_FIELD_EQUAL_A(pData, &CheckData, pszFilename, nFileSizeHigh, "%#x");
     8513                ASSERT_FS_FIELD_EQUAL_A(pData, &CheckData, pszFilename, nFileSizeLow, "%#x");
     8514                ASSERT_FS_FIELD_EQUAL_A(pData, &CheckData, pszFilename, ftCreationTime.dwHighDateTime, "%#x");
     8515                ASSERT_FS_FIELD_EQUAL_A(pData, &CheckData, pszFilename, ftCreationTime.dwLowDateTime, "%#x");
     8516                ASSERT_FS_FIELD_EQUAL_A(pData, &CheckData, pszFilename, ftLastWriteTime.dwHighDateTime, "%#x");
     8517                ASSERT_FS_FIELD_EQUAL_A(pData, &CheckData, pszFilename, ftLastWriteTime.dwLowDateTime, "%#x");
     8518            }
     8519            else
     8520                kHlpAssertMsg(dwErrSaved == GetLastError(), ("%u, expected %u; %s\n", dwErrSaved, GetLastError(), pszFilename));
     8521            SetLastError(dwErrSaved);
     8522        }
     8523#endif
    80938524        KWFS_LOG(("GetFileAttributesA(%s,%d,) -> %d [cached]\n", pszFilename, enmLevel, fRet));
    80948525        return fRet;
     
    81258556                *(KU64 *)&pData->ftLastWriteTime  = birdNtTimeFromTimeSpec(&pFsObj->Stats.st_mtim);
    81268557                kFsCacheObjRelease(g_pFsCache, pFsObj);
     8558                fRet = TRUE;
    81278559            }
    81288560            else
     
    81388570        }
    81398571
    8140         KWFS_LOG(("GetFileAttributesW(%ls,%d,) -> %d [cached]\n", pwszFilename, enmLevel, fRet));
     8572#ifdef K_STRICT
     8573        {
     8574            WIN32_FILE_ATTRIBUTE_DATA CheckData = { 0 };
     8575            DWORD const dwErrSaved = GetLastError();
     8576            BOOL const fRetCheck = GetFileAttributesExW(pwszFilename, enmLevel, &CheckData);
     8577            kHlpAssertMsg(fRet == fRetCheck, ("fRet=%d fRetCheck=%d; %ls\n", fRet, fRetCheck, pwszFilename));
     8578            if (fRetCheck && fRet)
     8579            {
     8580# define ASSERT_FS_FIELD_EQUAL_W(pResult, pExpected, pszFilename, Field, szFmt) \
     8581    kHlpAssertMsg((pResult)->Field == (pExpected)->Field, (#Field ": " szFmt " , expected " szFmt "; %ls\n", (pResult)->Field, (pExpected)->Field, pwszFilename))
     8582                ASSERT_FS_FIELD_EQUAL_W(pData, &CheckData, pwszFilename, dwFileAttributes, "%#x");
     8583                ASSERT_FS_FIELD_EQUAL_W(pData, &CheckData, pwszFilename, nFileSizeHigh, "%#x");
     8584                ASSERT_FS_FIELD_EQUAL_W(pData, &CheckData, pwszFilename, nFileSizeLow, "%#x");
     8585                ASSERT_FS_FIELD_EQUAL_W(pData, &CheckData, pwszFilename, ftCreationTime.dwHighDateTime, "%#x");
     8586                ASSERT_FS_FIELD_EQUAL_W(pData, &CheckData, pwszFilename, ftCreationTime.dwLowDateTime, "%#x");
     8587                ASSERT_FS_FIELD_EQUAL_W(pData, &CheckData, pwszFilename, ftLastWriteTime.dwHighDateTime, "%#x");
     8588                ASSERT_FS_FIELD_EQUAL_W(pData, &CheckData, pwszFilename, ftLastWriteTime.dwLowDateTime, "%#x");
     8589            }
     8590            else
     8591                kHlpAssertMsg(dwErrSaved == GetLastError(), ("%u, expected %u; %ls\n", dwErrSaved, GetLastError(), pwszFilename));
     8592            SetLastError(dwErrSaved);
     8593        }
     8594#endif
     8595        KWFS_LOG(("GetFileAttributesExW(%ls,%d,) -> %d [cached]\n", pwszFilename, enmLevel, fRet));
    81418596        return fRet;
    81428597    }
     
    88619316             */
    88629317            PKWVIRTALLOC pTracker;
    8863             kHlpAssert(GetCurrentThreadId() == g_Sandbox.idMainThread);
    8864 
     9318
     9319            EnterCriticalSection(&g_Sandbox.VirtualAllocLock);
    88659320            pTracker = g_Sandbox.pVirtualAllocHead;
    88669321            while (   pTracker
    88679322                   && (KUPTR)pvMem - (KUPTR)pTracker->pvAlloc >= pTracker->cbAlloc)
    88689323                pTracker = pTracker->pNext;
     9324            LeaveCriticalSection(&g_Sandbox.VirtualAllocLock);
    88699325            if (!pTracker)
    88709326            {
     
    88769332                    pTracker->cbAlloc           = cb;
    88779333                    pTracker->idxPreAllocated   = idxPreAllocated;
     9334                    EnterCriticalSection(&g_Sandbox.VirtualAllocLock);
    88789335                    pTracker->pNext             = g_Sandbox.pVirtualAllocHead;
    88799336                    g_Sandbox.pVirtualAllocHead = pTracker;
     9337                    LeaveCriticalSection(&g_Sandbox.VirtualAllocLock);
    88809338                }
    88819339                SetLastError(dwErr);
     
    89009358        if (dwFreeType & MEM_RELEASE)
    89019359        {
    8902             PKWVIRTALLOC pTracker = g_Sandbox.pVirtualAllocHead;
     9360            PKWVIRTALLOC pTracker;
     9361            EnterCriticalSection(&g_Sandbox.VirtualAllocLock);
     9362            pTracker = g_Sandbox.pVirtualAllocHead;
    89039363            if (pTracker)
    89049364            {
     
    89229382                    {
    89239383                        kwSandboxResetFixedAllocation(pTracker->idxPreAllocated);
     9384                        LeaveCriticalSection(&g_Sandbox.VirtualAllocLock);
    89249385                        KW_LOG(("VirtualFree: pvAddr=%p cb=%p type=%#x -> TRUE [pre allocated #%u]\n",
    89259386                                pvAddr, cb, dwFreeType, pTracker->idxPreAllocated));
     
    89379398                        g_Sandbox.pVirtualAllocHead = pTracker;
    89389399                    }
     9400                    LeaveCriticalSection(&g_Sandbox.VirtualAllocLock);
    89399401                    KW_LOG(("VirtualFree: pvAddr=%p cb=%p type=%#x -> %d\n", pvAddr, cb, dwFreeType, fRc));
    89409402                    return fRc;
     
    89439405                KW_LOG(("VirtualFree: pvAddr=%p not found!\n", pvAddr));
    89449406            }
     9407            LeaveCriticalSection(&g_Sandbox.VirtualAllocLock);
    89459408        }
    89469409    }
     
    91889651    if (g_Sandbox.pTool->u.Sandboxed.enmHint == KWTOOLHINT_VISUAL_CPP_CL)
    91899652    {
     9653        /** @todo do generic caching of hash results.  Need SHA-1 and SHA-256 for
     9654         *        more recent compilers. */
    91909655        if (idAlg == CALG_MD5)
    91919656        {
     
    92229687                kwErrPrintf("CryptCreateHash: hKey=%p is not supported with CALG_MD5\n", hKey);
    92239688        }
    9224         else
    9225             kwErrPrintf("CryptCreateHash: idAlg=%#x is not supported\n", idAlg);
     9689        //else
     9690        //    kwErrPrintf("CryptCreateHash: idAlg=%#x is not supported\n", idAlg);
    92269691    }
    92279692
     
    93379802            else
    93389803                kwErrPrintf("CryptHashData: Hash is already finalized!!\n");
    9339             SetLastError(NTE_BAD_HASH);
     9804            SetLastError((DWORD)NTE_BAD_HASH);
    93409805            fRc = FALSE;
    93419806        }
     
    94479912                    default:
    94489913                        kwErrPrintf("CryptGetHashParam: Unknown dwParam=%#x\n", dwParam);
    9449                         SetLastError(NTE_BAD_TYPE);
     9914                        SetLastError((DWORD)NTE_BAD_TYPE);
    94509915                        return FALSE;
    94519916                }
     
    94859950            {
    94869951                kwErrPrintf("CryptGetHashParam: dwFlags is not zero: %#x!\n", dwFlags);
    9487                 SetLastError(NTE_BAD_FLAGS);
     9952                SetLastError((DWORD)NTE_BAD_FLAGS);
    94889953            }
    94899954        }
     
    94919956        {
    94929957            kwErrPrintf("CryptGetHashParam: Invalid cached hash handle!!\n");
    9493             SetLastError(NTE_BAD_HASH);
     9958            SetLastError((DWORD)NTE_BAD_HASH);
    94949959        }
    94959960        fRc = FALSE;
     
    991910384    KSIZE      cbLeft = cb;
    992010385    while (cbLeft-- > 0)
    9921         *pbDst++ = bFiller;
     10386        *pbDst++ = (KU8)bFiller;
    992210387    return pvDst;
    992310388}
     
    1004610511
    1004710512    { TUPLE("_beginthread"),                NULL,       (KUPTR)kwSandbox_msvcrt__beginthread },
    10048     { TUPLE("_beginthreadex"),              NULL,       (KUPTR)kwSandbox_msvcrt__beginthreadex },
     10513    { TUPLE("_beginthreadex"),              NULL,       (KUPTR)kwSandbox_msvcrt__beginthreadex, K_FALSE /*fOnlyExe*/, K_TRUE /*fCrtSlotArray*/ },
    1004910514    { TUPLE("_beginthreadex"),          "msvcr120.dll", (KUPTR)kwSandbox_msvcr120__beginthreadex }, /* higher priority last */
    1005010515
     
    1026210727
    1026310728
     10729#if 0
    1026410730/**
    1026510731 * Resets the KWMODULE::fVisited flag for _all_ known modules.
     
    1032610792    }
    1032710793}
     10794#else
     10795/**
     10796 * Used by kwSandboxExec to reset the state of the module tree.
     10797 */
     10798static void kwSandboxResetModuleState(void)
     10799{
     10800    PKWMODULE pMod = g_pModuleHead;
     10801    while (pMod)
     10802    {
     10803        if (!pMod->fNative)
     10804            pMod->u.Manual.enmState = K_MIN(pMod->u.Manual.enmReInitState, pMod->u.Manual.enmState);
     10805        /* Hack: Re-init mspdbXXX.dll when we want to use a different mspdbsrv.exe instance. */
     10806        else if (   pMod->fReInitOnMsPdbSrvEndpointChange
     10807                 && (   g_Sandbox.pTool->u.Sandboxed.enmHint == KWTOOLHINT_VISUAL_CPP_CL
     10808                     || g_Sandbox.pTool->u.Sandboxed.enmHint == KWTOOLHINT_VISUAL_CPP_LINK))
     10809        {
     10810            const char *pszValue = kwSandboxDoGetEnvA(&g_Sandbox, TUPLE("_MSPDBSRV_ENDPOINT_"));
     10811            if (pMod->fReInitOnMsPdbSrvEndpointChange == 1)
     10812            {
     10813                pMod->fReInitOnMsPdbSrvEndpointChange = 2;
     10814                pMod->pszMsPdbSrvEndpoint = pszValue ? kHlpStrDup(pszValue) : NULL;
     10815                KWLDR_LOG(("Not re-initing '%s': first time used (_MSPDBSRV_ENDPOINT_ is '%s')\n",
     10816                           pMod->pszPath, pszValue ? pszValue : "<null>"));
     10817            }
     10818            else if (   (pszValue == NULL && pMod->pszMsPdbSrvEndpoint == NULL)
     10819                     || (pszValue != NULL && pMod->pszMsPdbSrvEndpoint != NULL && kHlpStrComp(pszValue, pMod->pszMsPdbSrvEndpoint) == 0))
     10820                KWLDR_LOG(("Not re-initing '%s': _MSPDBSRV_ENDPOINT_ unchanged ('%s')\n",
     10821                           pMod->pszPath, pszValue ? pszValue : "<null>"));
     10822            else
     10823            {
     10824                KWLDR_LOG(("Re-initing '%s': _MSPDBSRV_ENDPOINT_ changed from '%s' to '%s'\n", pMod->pszPath,
     10825                           pMod->pszMsPdbSrvEndpoint ? pMod->pszMsPdbSrvEndpoint : "<null>", pszValue ? pszValue : "<null>"));
     10826                kHlpFree(pMod->pszMsPdbSrvEndpoint);
     10827                if (pszValue != NULL)
     10828                    pMod->pszMsPdbSrvEndpoint = kHlpStrDup(pszValue);
     10829                else
     10830                    pMod->pszMsPdbSrvEndpoint = NULL;
     10831                pMod->fNeedReInit = K_TRUE;
     10832            }
     10833        }
     10834
     10835        pMod = pMod->pNextList;
     10836    }
     10837}
     10838#endif
    1032810839
    1032910840static PPEB kwSandboxGetProcessEnvironmentBlock(void)
     
    1074011251
    1074111252    /* Free left behind VirtualAlloc leaks. */
     11253    EnterCriticalSection(&g_Sandbox.VirtualAllocLock);
    1074211254    pTracker = g_Sandbox.pVirtualAllocHead;
    1074311255    g_Sandbox.pVirtualAllocHead = NULL;
     11256    LeaveCriticalSection(&g_Sandbox.VirtualAllocLock);
    1074411257    while (pTracker)
    1074511258    {
     
    1091111424         * Do module initialization.
    1091211425         */
    10913         kwSandboxResetModuleVisited();
    10914         kwSandboxResetModuleState(pTool->u.Sandboxed.pExe);
     11426#if 0
     11427        //kwSandboxResetModuleVisited();
     11428        //kwSandboxResetModuleState(pTool->u.Sandboxed.pExe);
     11429#else
     11430        kwSandboxResetModuleState();
     11431#endif
    1091511432        rc = kwLdrModuleInitTree(pTool->u.Sandboxed.pExe);
    1091611433        if (rc == 0)
     
    1187712394     * Do the job.
    1187812395     */
     12396    rcExit = 0;
    1187912397    for (j = 0; j < cRepeats; j++)
    1188012398    {
     
    1201712535 * @param   pszAppend       The string to append.
    1201812536 */
    12019 static int kwFullTestVectorAppend(const char ***ppapszVector, int *pcEntries, char const *pszAppend)
    12020 {
    12021     unsigned cEntries = *pcEntries;
     12537static int kwFullTestVectorAppend(const char ***ppapszVector, KU32 *pcEntries, char const *pszAppend)
     12538{
     12539    KU32 cEntries = *pcEntries;
    1202212540    if (!(cEntries & 15))
    1202312541    {
     
    1239512913        return kwErrPrintfRc(3, "VirtualProtect(%p, %#x, PAGE_EXECUTE_READWRITE,NULL) failed: %u\n",
    1239612914                             g_abDefLdBuf, sizeof(g_abDefLdBuf), GetLastError());
     12915    InitializeCriticalSection(&g_Sandbox.VirtualAllocLock);
    1239712916
    1239812917#ifdef WITH_CONSOLE_OUTPUT_BUFFERING
     
    1251913038                    && uValue <= 5)
    1252013039                {
    12521                     DWORD dwClass, dwPriority;
     13040                    DWORD dwClass;
     13041                    int   dwPriority;
    1252213042                    switch (uValue)
    1252313043                    {
    1252413044                        case 1: dwClass = IDLE_PRIORITY_CLASS;         dwPriority = THREAD_PRIORITY_IDLE; break;
    1252513045                        case 2: dwClass = BELOW_NORMAL_PRIORITY_CLASS; dwPriority = THREAD_PRIORITY_BELOW_NORMAL; break;
     13046                        default:
    1252613047                        case 3: dwClass = NORMAL_PRIORITY_CLASS;       dwPriority = THREAD_PRIORITY_NORMAL; break;
    12527                         case 4: dwClass = HIGH_PRIORITY_CLASS;         dwPriority = 0xffffffff; break;
    12528                         case 5: dwClass = REALTIME_PRIORITY_CLASS;     dwPriority = 0xffffffff; break;
     13048                        case 4: dwClass = HIGH_PRIORITY_CLASS;         dwPriority = INT_MAX; break;
     13049                        case 5: dwClass = REALTIME_PRIORITY_CLASS;     dwPriority = INT_MAX; break;
    1252913050                    }
    1253013051                    SetPriorityClass(GetCurrentProcess(), dwClass);
    12531                     if (dwPriority != 0xffffffff)
     13052                    if (dwPriority != INT_MAX)
    1253213053                        SetThreadPriority(GetCurrentThread(), dwPriority);
    1253313054                }
     
    1269213213        if (g_fRestart)
    1269313214        {
     13215            DWORD cbIgnored = 1;
    1269413216            KU8 b;
    1269513217            FlushFileBuffers(hPipe);
    12696             ReadFile(hPipe, &b, 1, &cbMsg, NULL);
     13218            ReadFile(hPipe, &b, 1, &cbIgnored, NULL);
    1269713219        }
    1269813220
  • trunk/src/kWorker/kWorkerTlsXxxK.c

    r3042 r3361  
    5858 * Initialization data.
    5959 */
    60 static char const g_abDummy[TLS_SIZE] = {0x42};
     60//static char const g_abDummy[TLS_SIZE] = {0x42};
     61static char g_abDummy[TLS_SIZE] = {0};
    6162
    6263/**
     
    8889    if (dwReason == DLL_PROCESS_ATTACH)
    8990    {
    90         HMODULE hModExe = (HMODULE)(ULONG_PTR)KWORKER_BASE;
     91        //HMODULE hModExe = (HMODULE)(ULONG_PTR)KWORKER_BASE;
     92        HMODULE hModExe = GetModuleHandleW(NULL);
    9193        KWLDRTLSALLOCATIONHOOK *pfnHook = (KWLDRTLSALLOCATIONHOOK *)GetProcAddress(hModExe, "kwLdrTlsAllocationHook");
    9294        if (pfnHook)
Note: See TracChangeset for help on using the changeset viewer.