Ignore:
Timestamp:
Aug 19, 2016, 11:15:32 PM (9 years ago)
Author:
bird
Message:

kWorker: Got cl.exe (2010) going. ~20 faster on a medium 220 lined C++ file.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/kWorker/kWorker.c

    r2831 r2832  
    3939extern void nt_fullpath(const char *pszPath, char *pszFull, size_t cchFull);
    4040#include <Windows.h>
     41#include <winternl.h>
    4142
    4243
     
    4950    KWLOCATION_EXE_DIR,
    5051    KWLOCATION_IMPORTER_DIR,
    51     KWLOCATION_SYSTEM32
     52    KWLOCATION_SYSTEM32,
     53    KWLOCATION_UNKNOWN_NATIVE,
     54    KWLOCATION_UNKNOWN,
    5255} KWLOCATION;
    5356
     
    7376    /** Number of references. */
    7477    KU32                cRefs;
     78    /** UTF-16 version of pszPath. */
     79    const wchar_t      *pwszPath;
    7580    /** The offset of the filename in pszPath. */
    7681    KU16                offFilename;
     
    8186    /** Loader module handle. */
    8287    PKLDRMOD            pLdrMod;
     88    /** The windows module handle. */
     89    HMODULE             hOurMod;
    8390
    8491    union
     
    106113} KWMODULE;
    107114
     115
     116typedef struct KWDYNLOAD *PKWDYNLOAD;
     117typedef struct KWDYNLOAD
     118{
     119    /** Pointer to the next in the list. */
     120    PKWDYNLOAD          pNext;
     121
     122    /** The normalized path to the image. */
     123    const char         *pszPath;
     124    /** The module name (within pszPath). */
     125    const char         *pszModName;
     126    /** UTF-16 version of pszPath. */
     127    const wchar_t      *pwszPath;
     128    /** The hash of the path. */
     129    KU32                uHashPath;
     130
     131    /** The module handle we present to the application.
     132     * This is the LoadLibraryEx return value for special modules and the
     133     * KWMODULE.hOurMod value for the others. */
     134    HMODULE             hmod;
     135
     136    /** The module for non-special resource stuff, NULL if special. */
     137    PKWMODULE           pMod;
     138} KWDYNLOAD;
     139
     140
    108141typedef enum KWTOOLTYPE
    109142{
     
    126159    /** The kind of tool. */
    127160    KWTOOLTYPE          enmType;
     161    /** UTF-16 version of pszPath. */
     162    wchar_t const      *pwszPath;
    128163
    129164    union
     
    133168            /** The executable. */
    134169            PKWMODULE   pExe;
     170            /** List of dynamically loaded modules.
     171             * These will be kept loaded till the tool is destroyed (if we ever do that). */
     172            PKWDYNLOAD  pDynLoadHead;
    135173        } Sandboxed;
    136174    } u;
     
    147185    /** The thread ID of the main thread (owner of JmpBuf). */
    148186    DWORD       idMainThread;
     187    /** Copy of the NT TIB of the main thread. */
     188    NT_TIB      TibMainThread;
    149189    /** The exit code in case of longjmp.   */
    150190    int         rcExitCode;
    151191
    152 
     192    /** The command line.   */
     193    const char *pszCmdLine;
     194    /** The UTF-16 command line. */
     195    wchar_t    *pwszCmdLine;
     196    /** Number of arguments in papszArgs. */
     197    int         cArgs;
     198    /** The argument vector. */
     199    char      **papszArgs;
     200    /** The argument vector. */
     201    wchar_t   **papwszArgs;
     202
     203    /** The _pgmptr msvcrt variable.  */
     204    char       *pgmptr;
     205    /** The _wpgmptr msvcrt variable. */
     206    wchar_t    *wpgmptr;
     207
     208    /** The _initenv msvcrt variable. */
     209    char      **initenv;
     210    /** The _winitenv msvcrt variable. */
     211    wchar_t   **winitenv;
     212
     213    /** The _environ msvcrt variable. */
     214    char      **environ;
     215    /** The _wenviron msvcrt variable. */
     216    wchar_t   **wenviron;
     217
     218
     219    UNICODE_STRING  SavedCommandLine;
    153220} KWSANDBOX;
    154221
     
    162229    /** The module name (optional). */
    163230    const char *pszModule;
    164     /** The replacement function. */
     231    /** The replacement function or data address. */
    165232    KUPTR       pfnReplacement;
    166233} KWREPLACEMENTFUNCTION;
    167234typedef KWREPLACEMENTFUNCTION const *PCKWREPLACEMENTFUNCTION;
    168235
     236#if 0
     237/** Replacement function entry. */
     238typedef struct KWREPLACEMENTDATA
     239{
     240    /** The function name. */
     241    const char *pszFunction;
     242    /** The length of the function name. */
     243    KSIZE       cchFunction;
     244    /** The module name (optional). */
     245    const char *pszModule;
     246    /** Function providing the replacement. */
     247    KUPTR     (*pfnMakeReplacement)(PKWMODULE pMod, const char *pchSymbol, KSIZE cchSymbol);
     248} KWREPLACEMENTDATA;
     249typedef KWREPLACEMENTDATA const *PCKWREPLACEMENTDATA;
     250#endif
     251
    169252
    170253/*********************************************************************************************************************************
    171254*   Global Variables                                                                                                             *
    172255*********************************************************************************************************************************/
    173 /** The currently active sandbox. */
    174 static PKWSANDBOX   g_pSandbox;
     256/** The sandbox data. */
     257static KWSANDBOX    g_Sandbox;
    175258
    176259/** Module hash table. */
     
    179262/** Tool hash table. */
    180263static PKWTOOL      g_apTools[63];
     264
     265static int          g_cVerbose = 2;
     266
     267/* Further down. */
     268extern KWREPLACEMENTFUNCTION const g_aSandboxReplacements[];
     269extern KU32                  const g_cSandboxReplacements;
    181270
    182271/** Create a larget BSS blob that with help of /IMAGEBASE:0x10000 should
     
    186275static KU8          g_abDefLdBuf[16*1024*1024];
    187276
    188 /* Further down. */
    189 extern KWREPLACEMENTFUNCTION const g_aSandboxReplacements[];
    190 extern KU32                  const g_cSandboxReplacements;
    191277
    192278
     
    196282static FNKLDRMODGETIMPORT kwLdrModuleGetImportCallback;
    197283static int kwLdrModuleResolveAndLookup(const char *pszName, PKWMODULE pExe, PKWMODULE pImporter, PKWMODULE *ppMod);
     284
     285
     286
     287/**
     288 * Debug printing.
     289 * @param   pszFormat           Debug format string.
     290 * @param   ...                 Format argument.
     291 */
     292static void kwDbgPrintfV(const char *pszFormat, va_list va)
     293{
     294    if (g_cVerbose >= 2)
     295    {
     296        fprintf(stderr, "debug: ");
     297        vfprintf(stderr, pszFormat, va);
     298    }
     299}
     300
     301
     302/**
     303 * Debug printing.
     304 * @param   pszFormat           Debug format string.
     305 * @param   ...                 Format argument.
     306 */
     307static void kwDbgPrintf(const char *pszFormat, ...)
     308{
     309    if (g_cVerbose >= 2)
     310    {
     311        va_list va;
     312        va_start(va, pszFormat);
     313        kwDbgPrintfV(pszFormat, va);
     314        va_end(va);
     315    }
     316}
     317
     318
     319/**
     320 * Debugger printing.
     321 * @param   pszFormat           Debug format string.
     322 * @param   ...                 Format argument.
     323 */
     324static void kwDebuggerPrintfV(const char *pszFormat, va_list va)
     325{
     326    if (IsDebuggerPresent())
     327    {
     328        char szTmp[2048];
     329        _vsnprintf(szTmp, sizeof(szTmp), pszFormat, va);
     330        OutputDebugStringA(szTmp);
     331    }
     332}
     333
     334
     335/**
     336 * Debugger printing.
     337 * @param   pszFormat           Debug format string.
     338 * @param   ...                 Format argument.
     339 */
     340static void kwDebuggerPrintf(const char *pszFormat, ...)
     341{
     342    va_list va;
     343    va_start(va, pszFormat);
     344    kwDebuggerPrintfV(pszFormat, va);
     345    va_end(va);
     346}
     347
     348
     349
     350/**
     351 * Error printing.
     352 * @param   pszFormat           Message format string.
     353 * @param   ...                 Format argument.
     354 */
     355static void kwErrPrintfV(const char *pszFormat, va_list va)
     356{
     357    fprintf(stderr, "error: ");
     358    vfprintf(stderr, pszFormat, va);
     359}
     360
     361
     362/**
     363 * Error printing.
     364 * @param   pszFormat           Message format string.
     365 * @param   ...                 Format argument.
     366 */
     367static void kwErrPrintf(const char *pszFormat, ...)
     368{
     369    va_list va;
     370    va_start(va, pszFormat);
     371    kwErrPrintfV(pszFormat, va);
     372    va_end(va);
     373}
    198374
    199375
     
    247423}
    248424
     425
     426
     427/**
     428 * Converts the given string to unicode.
     429 *
     430 * @returns Length of the resulting string in wchar_t's.
     431 * @param   pszSrc              The source string.
     432 * @param   pwszDst             The destination buffer.
     433 * @param   cwcDst              The size of the destination buffer in wchar_t's.
     434 */
     435static size_t kwStrToUtf16(const char *pszSrc, wchar_t *pwszDst, size_t cwcDst)
     436{
     437    /* Just to the quick ASCII stuff for now. correct ansi code page stuff later some time.  */
     438    size_t offDst = 0;
     439    while (offDst < cwcDst)
     440    {
     441        char ch = *pszSrc++;
     442        pwszDst[offDst++] = ch;
     443        if (!ch)
     444            return offDst - 1;
     445        kHlpAssert((unsigned)ch < 127);
     446    }
     447
     448    pwszDst[offDst - 1] = '\0';
     449    return offDst;
     450}
     451
     452
     453/**
     454 * Converts the given UTF-16 to a normal string.
     455 *
     456 * @returns Length of the resulting string.
     457 * @param   pwszSrc             The source UTF-16 string.
     458 * @param   pszDst              The destination buffer.
     459 * @param   cbDst               The size of the destination buffer in bytes.
     460 */
     461static size_t kwUtf16ToStr(const wchar_t *pwszSrc, char *pszDst, size_t cbDst)
     462{
     463    /* Just to the quick ASCII stuff for now. correct ansi code page stuff later some time.  */
     464    size_t offDst = 0;
     465    while (offDst < cbDst)
     466    {
     467        wchar_t wc = *pwszSrc++;
     468        pszDst[offDst++] = (char)wc;
     469        if (!wc)
     470            return offDst - 1;
     471        kHlpAssert((unsigned)wc < 127);
     472    }
     473
     474    pszDst[offDst - 1] = '\0';
     475    return offDst;
     476}
     477
     478
     479
     480/** UTF-16 string length.  */
     481static KSIZE kwUtf16Len(wchar_t const *pwsz)
     482{
     483    KSIZE cwc = 0;
     484    while (*pwsz != '\0')
     485        cwc++, pwsz++;
     486    return cwc;
     487}
     488
     489/**
     490 * Copy out the UTF-16 string following the convension of GetModuleFileName
     491 */
     492static DWORD kwUtf16CopyStyle1(wchar_t const *pwszSrc, wchar_t *pwszDst, KSIZE cwcDst)
     493{
     494    KSIZE cwcSrc = kwUtf16Len(pwszSrc);
     495    if (cwcSrc + 1 <= cwcDst)
     496    {
     497        kHlpMemCopy(pwszDst, pwszSrc, (cwcSrc + 1) * sizeof(wchar_t));
     498        return (DWORD)cwcSrc;
     499    }
     500    if (cwcDst > 0)
     501    {
     502        size_t cwcDstTmp = cwcDst - 1;
     503        pwszDst[cwcDstTmp] = '\0';
     504        if (cwcDstTmp > 0)
     505            kHlpMemCopy(pwszDst, pwszSrc, cwcDstTmp);
     506    }
     507    SetLastError(ERROR_INSUFFICIENT_BUFFER);
     508    return (DWORD)cwcDst;
     509}
     510
     511
     512/**
     513 * Copy out the ANSI string following the convension of GetModuleFileName
     514 */
     515static DWORD kwStrCopyStyle1(char const *pszSrc, char *pszDst, KSIZE cbDst)
     516{
     517    KSIZE cchSrc = kHlpStrLen(pszSrc);
     518    if (cchSrc + 1 <= cbDst)
     519    {
     520        kHlpMemCopy(pszDst, pszSrc, cchSrc + 1);
     521        return (DWORD)cchSrc;
     522    }
     523    if (cbDst > 0)
     524    {
     525        size_t cbDstTmp = cbDst - 1;
     526        pszDst[cbDstTmp] = '\0';
     527        if (cbDstTmp > 0)
     528            kHlpMemCopy(pszDst, pszSrc, cbDstTmp);
     529    }
     530    SetLastError(ERROR_INSUFFICIENT_BUFFER);
     531    return (DWORD)cbDst;
     532}
    249533
    250534
     
    356640         */
    357641        KSIZE     cbPath = kHlpStrLen(pszPath) + 1;
    358         PKWMODULE pMod   = (PKWMODULE)kHlpAllocZ(sizeof(*pMod) + cbPath);
     642        PKWMODULE pMod   = (PKWMODULE)kHlpAllocZ(sizeof(*pMod) + cbPath + 1 + cbPath * 2 * sizeof(wchar_t));
    359643        if (pMod)
    360644        {
    361645            pMod->pszPath       = (char *)kHlpMemCopy(pMod + 1, pszPath, cbPath);
     646            pMod->pwszPath      = (wchar_t *)(pMod->pszPath + cbPath + (cbPath & 1));
     647            kwStrToUtf16(pMod->pszPath, (wchar_t *)pMod->pwszPath, cbPath * 2);
    362648            pMod->uHashPath     = uHashPath;
    363649            pMod->cRefs         = 1;
     
    366652            pMod->fNative       = K_TRUE;
    367653            pMod->pLdrMod       = pLdrMod;
     654            pMod->hOurMod       = (HMODULE)(KUPTR)pLdrMod->aSegments[0].MapAddress;
     655            kwDbgPrintf("New module: %p LB %#010x %s (native)\n",
     656                        (KUPTR)pMod->pLdrMod->aSegments[0].MapAddress, kLdrModSize(pMod->pLdrMod), pMod->pszPath);
    368657            return kwLdrModuleLink(pMod);
    369658        }
     
    424713                 */
    425714                KSIZE     cbPath = kHlpStrLen(pszPath) + 1;
    426                 PKWMODULE pMod   = (PKWMODULE)kHlpAllocZ(sizeof(*pMod) + cbPath + sizeof(pMod) * cImports);
     715                PKWMODULE pMod   = (PKWMODULE)kHlpAllocZ(sizeof(*pMod)
     716                                                         + sizeof(pMod) * cImports
     717                                                         + cbPath
     718                                                         + cbPath * 2 * sizeof(wchar_t));
    427719                if (pMod)
    428720                {
     
    431723                    pMod->cRefs         = 1;
    432724                    pMod->offFilename   = (KU16)(kHlpGetFilename(pszPath) - pszPath);
     725                    pMod->uHashPath     = uHashPath;
    433726                    pMod->fExe          = fExe;
    434727                    pMod->fNative       = K_FALSE;
     
    436729                    pMod->u.Manual.cImpMods = (KU32)cImports;
    437730                    pMod->pszPath       = (char *)kHlpMemCopy(&pMod->u.Manual.apImpMods[cImports + 1], pszPath, cbPath);
     731                    pMod->pwszPath      = (wchar_t *)(pMod->pszPath + cbPath + (cbPath & 1));
     732                    kwStrToUtf16(pMod->pszPath, (wchar_t *)pMod->pwszPath, cbPath * 2);
    438733
    439734                    /*
     
    459754                             * Link the module (unless it's an executable image) and process the imports.
    460755                             */
     756                            pMod->hOurMod = (HMODULE)pMod->u.Manual.pvLoad;
    461757                            if (!fExe)
    462758                                kwLdrModuleLink(pMod);
     759                            kwDbgPrintf("New module: %p LB %#010x %s (kLdr)\n",
     760                                        pMod->u.Manual.pvLoad, pMod->u.Manual.cbImage, pMod->pszPath);
     761                            kwDebuggerPrintf("TODO: .reload /f %s=%p\n", pMod->pszPath, pMod->u.Manual.pvLoad);
    463762
    464763                            for (iImp = 0; iImp < cImports; iImp++)
     
    489788                            kwLdrModuleRelease(pMod);
    490789                            return NULL;
    491 
    492                             //kHlpPageFree(pMod->u.Manual.pvCopy, pMod->u.Manual.cbImage);
    493790                        }
     791
    494792                        kHlpPageFree(pMod->u.Manual.pvLoad, pMod->u.Manual.cbImage);
     793                        kwErrPrintf("Failed to allocate %#x bytes\n", pMod->u.Manual.cbImage);
    495794                    }
     795                    else if (fFixed)
     796                        kwErrPrintf("Failed to allocate %#x bytes at %p\n",
     797                                    pMod->u.Manual.cbImage, (void *)(KUPTR)pLdrMod->aSegments[0].LinkAddress);
     798                    else
     799                        kwErrPrintf("Failed to allocate %#x bytes\n", pMod->u.Manual.cbImage);
    496800                }
    497801            }
     
    499803        kLdrModClose(pLdrMod);
    500804    }
     805    else
     806        kwErrPrintf("kLdrOpen failed with %#x (%d) for %s\n", rc, rc, pszPath);
    501807    return NULL;
    502808}
     
    532838                    || kHlpStrICompAscii(g_aSandboxReplacements[i].pszModule, &pImpMod->pszPath[pImpMod->offFilename]) == 0)
    533839                {
    534                     printf("replacing %s!%s\n", &pImpMod->pszPath[pImpMod->offFilename], g_aSandboxReplacements[i].pszFunction);
     840                    kwDbgPrintf("replacing %s!%s\n", &pImpMod->pszPath[pImpMod->offFilename], g_aSandboxReplacements[i].pszFunction);
    535841                    *puValue = g_aSandboxReplacements[i].pfnReplacement;
    536842                }
     
    538844    }
    539845
    540     printf("iImport=%u (%s) %*.*s rc=%d\n", iImport, &pImpMod->pszPath[pImpMod->offFilename], cchSymbol, cchSymbol, pchSymbol, rc);
     846    //printf("iImport=%u (%s) %*.*s rc=%d\n", iImport, &pImpMod->pszPath[pImpMod->offFilename], cchSymbol, cchSymbol, pchSymbol, rc);
    541847    return rc;
    542848
     
    568874    if (enmLocation == KWLOCATION_SYSTEM32)
    569875        return K_TRUE;
     876    if (enmLocation == KWLOCATION_UNKNOWN_NATIVE)
     877        return K_TRUE;
    570878    return kHlpStrICompAscii(pszFilename, "msvcrt.dll") == 0
    571         || kHlpStrNICompAscii(pszFilename, "msvc", 4)   == 0;
     879        || kHlpStrNICompAscii(pszFilename, "msvc", 4)   == 0
     880        || kHlpStrNICompAscii(pszFilename, "msdis", 5)  == 0
     881        || kHlpStrNICompAscii(pszFilename, "mspdb", 5)  == 0;
    572882}
    573883
     
    6981008
    6991009
     1010/**
     1011 * Does module initialization starting at @a pMod.
     1012 *
     1013 * This is initially used on the executable.  Later it is used by the
     1014 * LoadLibrary interceptor.
     1015 *
     1016 * @returns 0 on success, error on failure.
     1017 * @param   pMod                The module to initialize.
     1018 */
     1019static int kwLdrModuleInitTree(PKWMODULE pMod)
     1020{
     1021    int rc = 0;
     1022    if (!pMod->fNative)
     1023    {
     1024        /* Need to copy bits? */
     1025        if (pMod->u.Manual.enmState == KWMODSTATE_NEEDS_BITS)
     1026        {
     1027            kHlpMemCopy(pMod->u.Manual.pvLoad, pMod->u.Manual.pvCopy, pMod->u.Manual.cbImage);
     1028            pMod->u.Manual.enmState = KWMODSTATE_NEEDS_INIT;
     1029        }
     1030
     1031        if (pMod->u.Manual.enmState == KWMODSTATE_NEEDS_INIT)
     1032        {
     1033            /* Must do imports first, but mark our module as being initialized to avoid
     1034               endless recursion should there be a dependency loop. */
     1035            KSIZE iImp;
     1036            pMod->u.Manual.enmState = KWMODSTATE_BEING_INITED;
     1037
     1038            for (iImp = 0; iImp < pMod->u.Manual.cImpMods; iImp++)
     1039            {
     1040                rc = kwLdrModuleInitTree(pMod->u.Manual.apImpMods[iImp]);
     1041                if (rc != 0)
     1042                    return rc;
     1043            }
     1044
     1045            rc = kLdrModCallInit(pMod->pLdrMod, pMod->u.Manual.pvLoad, (KUPTR)pMod->u.Manual.pvLoad);
     1046            if (rc == 0)
     1047                pMod->u.Manual.enmState = KWMODSTATE_READY;
     1048            else
     1049                pMod->u.Manual.enmState = KWMODSTATE_INIT_FAILED;
     1050        }
     1051    }
     1052    return rc;
     1053}
     1054
     1055
     1056
    7001057
    7011058/**
     
    7101067{
    7111068    KSIZE   cbTool = kHlpStrLen(pszTool) + 1;
    712     PKWTOOL pTool  = (PKWTOOL)kHlpAllocZ(sizeof(*pTool) + cbTool);
     1069    PKWTOOL pTool  = (PKWTOOL)kHlpAllocZ(sizeof(*pTool) + cbTool + 1 + cbTool * 2 * sizeof(wchar_t));
    7131070    if (pTool)
    7141071    {
    7151072        pTool->pszPath   = (char *)kHlpMemCopy(pTool + 1, pszTool, cbTool);
     1073        pTool->pwszPath  = (wchar_t *)(pTool->pszPath + cbTool + (cbTool & 1));
     1074        kwStrToUtf16(pTool->pszPath, (wchar_t *)pTool->pwszPath, cbTool * 2);
    7161075        pTool->uHashPath = uHashPath;
    7171076        pTool->enmType   = KWTOOLTYPE_SANDBOXED;
     
    7691128
    7701129
     1130/**
     1131 * Parses the argument string passed in as pszSrc.
     1132 *
     1133 * @returns size of the processed arguments.
     1134 * @param   pszSrc  Pointer to the commandline that's to be parsed.
     1135 * @param   pcArgs  Where to return the number of arguments.
     1136 * @param   argv    Pointer to argument vector to put argument pointers in. NULL allowed.
     1137 * @param   pchPool Pointer to memory pchPool to put the arguments into. NULL allowed.
     1138 *
     1139 * @remarks Lifted from startuphacks-win.c
     1140 */
     1141static int parse_args(const char *pszSrc, int *pcArgs, char **argv, char *pchPool)
     1142{
     1143    int   bs;
     1144    char  chQuote;
     1145    char *pfFlags;
     1146    int   cbArgs;
     1147    int   cArgs;
     1148
     1149#define PUTC(c) do { ++cbArgs; if (pchPool != NULL) *pchPool++ = (c); } while (0)
     1150#define PUTV    do { ++cArgs;  if (argv != NULL) *argv++ = pchPool; } while (0)
     1151#define WHITE(c) ((c) == ' ' || (c) == '\t')
     1152
     1153#define _ARG_DQUOTE   0x01          /* Argument quoted (")                  */
     1154#define _ARG_RESPONSE 0x02          /* Argument read from response file     */
     1155#define _ARG_WILDCARD 0x04          /* Argument expanded from wildcard      */
     1156#define _ARG_ENV      0x08          /* Argument from environment            */
     1157#define _ARG_NONZERO  0x80          /* Always set, to avoid end of string   */
     1158
     1159    cArgs  = 0;
     1160    cbArgs = 0;
     1161
     1162#if 0
     1163    /* argv[0] */
     1164    PUTC((char)_ARG_NONZERO);
     1165    PUTV;
     1166    for (;;)
     1167    {
     1168        PUTC(*pszSrc);
     1169        if (*pszSrc == 0)
     1170            break;
     1171        ++pszSrc;
     1172    }
     1173    ++pszSrc;
     1174#endif
     1175
     1176    for (;;)
     1177    {
     1178        while (WHITE(*pszSrc))
     1179            ++pszSrc;
     1180        if (*pszSrc == 0)
     1181            break;
     1182        pfFlags = pchPool;
     1183        PUTC((char)_ARG_NONZERO);
     1184        PUTV;
     1185        bs = 0; chQuote = 0;
     1186        for (;;)
     1187        {
     1188            if (!chQuote ? (*pszSrc == '"' /*|| *pszSrc == '\''*/) : *pszSrc == chQuote)
     1189            {
     1190                while (bs >= 2)
     1191                {
     1192                    PUTC('\\');
     1193                    bs -= 2;
     1194                }
     1195                if (bs & 1)
     1196                    PUTC(*pszSrc);
     1197                else
     1198                {
     1199                    chQuote = chQuote ? 0 : *pszSrc;
     1200                    if (pfFlags != NULL)
     1201                        *pfFlags |= _ARG_DQUOTE;
     1202                }
     1203                bs = 0;
     1204            }
     1205            else if (*pszSrc == '\\')
     1206                ++bs;
     1207            else
     1208            {
     1209                while (bs != 0)
     1210                {
     1211                    PUTC('\\');
     1212                    --bs;
     1213                }
     1214                if (*pszSrc == 0 || (WHITE(*pszSrc) && !chQuote))
     1215                    break;
     1216                PUTC(*pszSrc);
     1217            }
     1218            ++pszSrc;
     1219        }
     1220        PUTC(0);
     1221    }
     1222
     1223    *pcArgs = cArgs;
     1224    return cbArgs;
     1225}
     1226
     1227
     1228
     1229
    7711230/*
    7721231 *
    773  * Kernel32 API replacements.
    774  * Kernel32 API replacements.
    775  * Kernel32 API replacements.
     1232 * Process and thread related APIs.
     1233 * Process and thread related APIs.
     1234 * Process and thread related APIs.
    7761235 *
    7771236 */
     
    7801239static void WINAPI kwSandbox_Kernel32_ExitProcess(UINT uExitCode)
    7811240{
    782     if (g_pSandbox->idMainThread == GetCurrentThreadId())
    783     {
    784         g_pSandbox->rcExitCode = (int)uExitCode;
    785         longjmp(g_pSandbox->JmpBuf, 1);
    786     }
    787     __debugbreak();
    788 }
     1241    if (g_Sandbox.idMainThread == GetCurrentThreadId())
     1242    {
     1243        PNT_TIB pTib = (PNT_TIB)NtCurrentTeb();
     1244
     1245        g_Sandbox.rcExitCode = (int)uExitCode;
     1246
     1247        /* Before we jump, restore the TIB as we're not interested in any
     1248           exception chain stuff installed by the sandboxed executable. */
     1249        *pTib = g_Sandbox.TibMainThread;
     1250
     1251        longjmp(g_Sandbox.JmpBuf, 1);
     1252    }
     1253    __debugbreak();
     1254}
     1255
    7891256
    7901257/** ExitProcess replacement.  */
     
    7931260    if (hProcess == GetCurrentProcess())
    7941261        kwSandbox_Kernel32_ExitProcess(uExitCode);
    795 __debugbreak();
     1262    __debugbreak();
    7961263    return TerminateProcess(hProcess, uExitCode);
    7971264}
    7981265
    799 
    800 
    801 /*
    802  *
    803  * MS Visual C++ CRT replacements.
    804  * MS Visual C++ CRT replacements.
    805  * MS Visual C++ CRT replacements.
    806  *
    807  */
    8081266
    8091267/** Normal CRT exit(). */
    8101268static void __cdecl kwSandbox_msvcrt_exit(int rcExitCode)
    8111269{
    812     fprintf(stderr, "kwSandbox_msvcrt_exit\n");
     1270    kwDbgPrintf("kwSandbox_msvcrt_exit: %d\n", rcExitCode);
    8131271    kwSandbox_Kernel32_ExitProcess(rcExitCode);
    8141272}
     
    8191277{
    8201278    /* Quick. */
    821     fprintf(stderr, "kwSandbox_msvcrt__exit\n");
     1279    kwDbgPrintf("kwSandbox_msvcrt__exit %d\n", rcExitCode);
    8221280    kwSandbox_Kernel32_ExitProcess(rcExitCode);
    8231281}
     
    8271285static void __cdecl kwSandbox_msvcrt__cexit(int rcExitCode)
    8281286{
    829     fprintf(stderr, "kwSandbox_msvcrt__cexit\n");
     1287    kwDbgPrintf("kwSandbox_msvcrt__cexit: %d\n", rcExitCode);
    8301288    kwSandbox_Kernel32_ExitProcess(rcExitCode);
    8311289}
     
    8351293static void __cdecl kwSandbox_msvcrt__c_exit(int rcExitCode)
    8361294{
    837     fprintf(stderr, "kwSandbox_msvcrt__c_exit\n");
     1295    kwDbgPrintf("kwSandbox_msvcrt__c_exit: %d\n", rcExitCode);
    8381296    kwSandbox_Kernel32_ExitProcess(rcExitCode);
    8391297}
    8401298
    8411299
    842 /** Runtime error and exit. */
     1300/** Runtime error and exit _amsg_exit(). */
    8431301static void __cdecl kwSandbox_msvcrt__amsg_exit(int iMsgNo)
    8441302{
    845     fprintf(stderr, "\nRuntime error #%u!\n", iMsgNo);
     1303    kwDbgPrintf("\nRuntime error #%u!\n", iMsgNo);
    8461304    kwSandbox_Kernel32_ExitProcess(255);
    8471305}
     
    8501308/** The CRT internal __getmainargs() API. */
    8511309static int __cdecl kwSandbox_msvcrt___getmainargs(int *pargc, char ***pargv, char ***penvp,
    852                                                   int dowildcard, /*_startupinfo*/ void *startinfo)
    853 {
     1310                                                  int dowildcard, int const *piNewMode)
     1311{
     1312    *pargc = g_Sandbox.cArgs;
     1313    *pargv = g_Sandbox.papszArgs;
     1314    *penvp = g_Sandbox.environ;
     1315
    8541316    /** @todo startinfo points at a newmode (setmode) value.   */
    855 
    856     *pargc = 2;
    857     *pargv = (char **)kHlpAllocZ(sizeof(char *) * 3);
    858     (*pargv)[0] = "nasm.exe";
    859     (*pargv)[1] = "-h";
    860     *penvp = (char **)kHlpAllocZ(sizeof(char *) * 1);
    8611317    return 0;
    8621318}
    8631319
    8641320
     1321/** The CRT internal __wgetmainargs() API. */
     1322static int __cdecl kwSandbox_msvcrt___wgetmainargs(int *pargc, wchar_t ***pargv, wchar_t ***penvp,
     1323                                                   int dowildcard, int const *piNewMode)
     1324{
     1325    *pargc = g_Sandbox.cArgs;
     1326    *pargv = g_Sandbox.papwszArgs;
     1327    *penvp = g_Sandbox.wenviron;
     1328
     1329    /** @todo startinfo points at a newmode (setmode) value.   */
     1330    return 0;
     1331}
     1332
     1333
     1334
     1335/** Kernel32 - GetCommandLineA()  */
     1336static LPCSTR /*LPSTR*/ WINAPI kwSandbox_Kernel32_GetCommandLineA(VOID)
     1337{
     1338    return g_Sandbox.pszCmdLine;
     1339}
     1340
     1341
     1342/** Kernel32 - GetCommandLineW()  */
     1343static LPCWSTR /*LPWSTR*/ WINAPI kwSandbox_Kernel32_GetCommandLineW(VOID)
     1344{
     1345    return g_Sandbox.pwszCmdLine;
     1346}
     1347
     1348
     1349/** Kernel32 - GetStartupInfoA()  */
     1350static VOID WINAPI kwSandbox_Kernel32_GetStartupInfoA(LPSTARTUPINFOA pStartupInfo)
     1351{
     1352    __debugbreak();
     1353}
     1354
     1355
     1356/** Kernel32 - GetStartupInfoW()  */
     1357static VOID WINAPI kwSandbox_Kernel32_GetStartupInfoW(LPSTARTUPINFOW lpStartupInfo)
     1358{
     1359    __debugbreak();
     1360}
     1361
     1362
     1363/** CRT - __p___argc().  */
     1364static int * __cdecl kwSandbox_msvcrt___p___argc(void)
     1365{
     1366    return &g_Sandbox.cArgs;
     1367}
     1368
     1369
     1370/** CRT - __p___argv().  */
     1371static char *** __cdecl kwSandbox_msvcrt___p___argv(void)
     1372{
     1373    return &g_Sandbox.papszArgs;
     1374}
     1375
     1376
     1377/** CRT - __p___sargv().  */
     1378static wchar_t *** __cdecl kwSandbox_msvcrt___p___wargv(void)
     1379{
     1380    return &g_Sandbox.papwszArgs;
     1381}
     1382
     1383
     1384/** CRT - __p__acmdln().  */
     1385static char ** __cdecl kwSandbox_msvcrt___p__acmdln(void)
     1386{
     1387    return (char **)&g_Sandbox.pszCmdLine;
     1388}
     1389
     1390
     1391/** CRT - __p__acmdln().  */
     1392static wchar_t ** __cdecl kwSandbox_msvcrt___p__wcmdln(void)
     1393{
     1394    return &g_Sandbox.pwszCmdLine;
     1395}
     1396
     1397
     1398/** CRT - __p__pgmptr().  */
     1399static char ** __cdecl kwSandbox_msvcrt___p__pgmptr(void)
     1400{
     1401    return &g_Sandbox.pgmptr;
     1402}
     1403
     1404
     1405/** CRT - __p__wpgmptr().  */
     1406static wchar_t ** __cdecl kwSandbox_msvcrt___p__wpgmptr(void)
     1407{
     1408    return &g_Sandbox.wpgmptr;
     1409}
     1410
     1411
     1412/** CRT - _get_pgmptr().  */
     1413static errno_t __cdecl kwSandbox_msvcrt__get_pgmptr(char **ppszValue)
     1414{
     1415    *ppszValue = g_Sandbox.pgmptr;
     1416    return 0;
     1417}
     1418
     1419
     1420/** CRT - _get_wpgmptr().  */
     1421static errno_t __cdecl kwSandbox_msvcrt__get_wpgmptr(wchar_t **ppwszValue)
     1422{
     1423    *ppwszValue = g_Sandbox.wpgmptr;
     1424    return 0;
     1425}
     1426
     1427/** Just in case. */
     1428static void kwSandbox_msvcrt__wincmdln(void)
     1429{
     1430    __debugbreak();
     1431}
     1432
     1433
     1434/** Just in case. */
     1435static void kwSandbox_msvcrt__wwincmdln(void)
     1436{
     1437    __debugbreak();
     1438}
     1439
     1440/** CreateThread interceptor. */
     1441static HANDLE WINAPI kwSandbox_Kernel32_CreateThread(LPSECURITY_ATTRIBUTES pSecAttr, SIZE_T cbStack,
     1442                                                     PTHREAD_START_ROUTINE pfnThreadProc, PVOID pvUser,
     1443                                                     DWORD fFlags, PDWORD pidThread)
     1444{
     1445    __debugbreak();
     1446    return NULL;
     1447}
     1448
     1449
     1450/** _beginthread - create a new thread. */
     1451static uintptr_t __cdecl kwSandbox_msvcrt__beginthread(void (__cdecl *pfnThreadProc)(void *), unsigned cbStack, void *pvUser)
     1452{
     1453    __debugbreak();
     1454    return 0;
     1455}
     1456
     1457
     1458/** _beginthreadex - create a new thread. */
     1459static uintptr_t __cdecl kwSandbox_msvcrt__beginthreadex(void *pvSecAttr, unsigned cbStack,
     1460                                                         unsigned (__stdcall *pfnThreadProc)(void *), void *pvUser,
     1461                                                         unsigned fCreate, unsigned *pidThread)
     1462{
     1463    __debugbreak();
     1464    return 0;
     1465}
     1466
     1467
     1468/*
     1469 *
     1470 * Environment related APIs.
     1471 * Environment related APIs.
     1472 * Environment related APIs.
     1473 *
     1474 */
     1475
     1476/** Kernel32 - GetEnvironmentVariableA()  */
     1477static DWORD WINAPI kwSandbox_Kernel32_GetEnvironmentVariableA(LPCSTR pwszVar, LPSTR pszValue, DWORD cbValue)
     1478{
     1479    __debugbreak();
     1480    return 0;
     1481}
     1482
     1483
     1484/** Kernel32 - GetEnvironmentVariableW()  */
     1485static DWORD WINAPI kwSandbox_Kernel32_GetEnvironmentVariableW(LPCWSTR pwszVar, LPWSTR pwszValue, DWORD cbValue)
     1486{
     1487    kwDbgPrintf("GetEnvironmentVariableW: '%ls'\n", pwszVar);
     1488    //__debugbreak();
     1489    //SetLastError(ERROR_ENVVAR_NOT_FOUND);
     1490    //return 0;
     1491    return GetEnvironmentVariableW(pwszVar, pwszValue, cbValue);
     1492}
     1493
     1494
     1495/** Kernel32 - SetEnvironmentVariableA()  */
     1496static BOOL WINAPI kwSandbox_Kernel32_SetEnvironmentVariableA(LPCSTR pszVar, LPCSTR pszValue)
     1497{
     1498    __debugbreak();
     1499    return FALSE;
     1500}
     1501
     1502
     1503/** Kernel32 - SetEnvironmentVariableW()  */
     1504static BOOL WINAPI kwSandbox_Kernel32_SetEnvironmentVariableW(LPCWSTR pwszVar, LPCWSTR pwszValue)
     1505{
     1506    kwDbgPrintf("SetEnvironmentVariableW: '%ls' = '%ls'\n", pwszVar, pwszValue);
     1507    return SetEnvironmentVariableW(pwszVar, pwszValue);
     1508    //__debugbreak();
     1509    //return FALSE;
     1510}
     1511
     1512
     1513/** Kernel32 - ExpandEnvironmentStringsA()  */
     1514static DWORD WINAPI kwSandbox_Kernel32_ExpandEnvironmentStringsA(LPCSTR pszSrc, LPSTR pwszDst, DWORD cbDst)
     1515{
     1516    __debugbreak();
     1517    return 0;
     1518}
     1519
     1520
     1521/** Kernel32 - ExpandEnvironmentStringsW()  */
     1522static DWORD WINAPI kwSandbox_Kernel32_ExpandEnvironmentStringsW(LPCWSTR pwszSrc, LPWSTR pwszDst, DWORD cbDst)
     1523{
     1524    __debugbreak();
     1525    return 0;
     1526}
     1527
     1528
     1529/** CRT - _putenv(). */
     1530static int __cdecl kwSandbox_msvcrt__putenv(const char *pszVarEqualValue)
     1531{
     1532    __debugbreak();
     1533    return 0;
     1534}
     1535
     1536
     1537/** CRT - _wputenv(). */
     1538static int __cdecl kwSandbox_msvcrt__wputenv(const wchar_t *pwszVarEqualValue)
     1539{
     1540    __debugbreak();
     1541    return 0;
     1542}
     1543
     1544
     1545/** CRT - _putenv_s(). */
     1546static errno_t __cdecl kwSandbox_msvcrt__putenv_s(const char *pszVar, const char *pszValue)
     1547{
     1548    __debugbreak();
     1549    return 0;
     1550}
     1551
     1552
     1553/** CRT - _wputenv_s(). */
     1554static errno_t __cdecl kwSandbox_msvcrt__wputenv_s(const wchar_t *pwszVar, const wchar_t *pwszValue)
     1555{
     1556    kwDbgPrintf("_wputenv_s: '%ls' = '%ls'\n", pwszVar, pwszValue);
     1557    //__debugbreak();
     1558    return SetEnvironmentVariableW(pwszVar, pwszValue) ? 0 : -1;
     1559}
     1560
     1561
     1562/** CRT - get pointer to the __initenv variable (initial environment).   */
     1563static char *** __cdecl kwSandbox_msvcrt___p___initenv(void)
     1564{
     1565    return &g_Sandbox.initenv;
     1566}
     1567
     1568
     1569/** CRT - get pointer to the __winitenv variable (initial environment).   */
     1570static wchar_t *** __cdecl kwSandbox_msvcrt___p___winitenv(void)
     1571{
     1572    return &g_Sandbox.winitenv;
     1573}
     1574
     1575
     1576/** CRT - get pointer to the _environ variable (current environment).   */
     1577static char *** __cdecl kwSandbox_msvcrt___p__environ(void)
     1578{
     1579    return &g_Sandbox.environ;
     1580}
     1581
     1582
     1583/** CRT - get pointer to the _wenviron variable (current environment).   */
     1584static wchar_t *** __cdecl kwSandbox_msvcrt___p__wenviron(void)
     1585{
     1586    return &g_Sandbox.wenviron;
     1587}
     1588
     1589
     1590/** CRT - get the _environ variable (current environment).
     1591 * @remarks Not documented or prototyped?  */
     1592static KUPTR /*void*/ __cdecl kwSandbox_msvcrt__get_environ(char ***ppapszEnviron)
     1593{
     1594    __debugbreak(); /** @todo check the callers expecations! */
     1595    *ppapszEnviron = g_Sandbox.environ;
     1596    return 0;
     1597}
     1598
     1599
     1600/** CRT - get the _wenviron variable (current environment).
     1601 * @remarks Not documented or prototyped? */
     1602static KUPTR /*void*/ __cdecl kwSandbox_msvcrt__get_wenviron(wchar_t ***ppapwszEnviron)
     1603{
     1604    __debugbreak(); /** @todo check the callers expecations! */
     1605    *ppapwszEnviron = g_Sandbox.wenviron;
     1606    return 0;
     1607}
     1608
     1609
     1610
     1611/*
     1612 *
     1613 * Loader related APIs
     1614 * Loader related APIs
     1615 * Loader related APIs
     1616 *
     1617 */
     1618
     1619
     1620/** Kernel32 - LoadLibraryExA()   */
     1621static HMODULE WINAPI kwSandbox_Kernel32_LoadLibraryExA(LPCSTR pszFilename, HANDLE hFile, DWORD fFlags)
     1622{
     1623    PKWDYNLOAD  pDynLoad;
     1624    PKWMODULE   pMod;
     1625    int         rc;
     1626
     1627    if (   (fFlags & LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE)
     1628        || (hFile != NULL && hFile != INVALID_HANDLE_VALUE) )
     1629    {
     1630        __debugbreak();
     1631        return LoadLibraryExA(pszFilename, hFile, fFlags);
     1632    }
     1633
     1634    /*
     1635     * Deal with resource / data DLLs.
     1636     */
     1637    if (fFlags & (  DONT_RESOLVE_DLL_REFERENCES
     1638                  | LOAD_LIBRARY_AS_DATAFILE
     1639                  | LOAD_LIBRARY_AS_IMAGE_RESOURCE) )
     1640    {
     1641        HMODULE hmod;
     1642        char    szNormPath[4096];
     1643        KU32    uHashPath;
     1644
     1645        /* currently, only deal with those that has a path. */
     1646        if (kHlpIsFilenameOnly(pszFilename))
     1647        {
     1648            __debugbreak();
     1649            return LoadLibraryExA(pszFilename, hFile, fFlags);
     1650        }
     1651
     1652        /* Normalize the path. */
     1653        rc = kwPathNormalize(pszFilename, szNormPath, sizeof(szNormPath));
     1654        if (rc != 0)
     1655        {
     1656            __debugbreak();
     1657            return LoadLibraryExA(pszFilename, hFile, fFlags);
     1658        }
     1659
     1660        /* Try look it up. */
     1661        uHashPath = kwStrHash(szNormPath);
     1662        for (pDynLoad = g_Sandbox.pTool->u.Sandboxed.pDynLoadHead; pDynLoad != NULL; pDynLoad = pDynLoad->pNext)
     1663            if (   pDynLoad->uHashPath == uHashPath
     1664                && kHlpStrComp(pDynLoad->pszPath, szNormPath) == 0)
     1665            {
     1666                if (pDynLoad->pMod == NULL)
     1667                    return pDynLoad->hmod;
     1668                __debugbreak();
     1669            }
     1670
     1671        /* Then try load it. */
     1672        hmod = LoadLibraryExA(szNormPath, hFile, fFlags);
     1673        if (hmod)
     1674        {
     1675            KSIZE cbNormPath = kHlpStrLen(szNormPath) + 1;
     1676            pDynLoad = (PKWDYNLOAD)kHlpAlloc(sizeof(*pDynLoad) + cbNormPath + cbNormPath * 2 * sizeof(wchar_t));
     1677            if (pDynLoad)
     1678            {
     1679                pDynLoad->pszPath           = (char *)kHlpMemCopy(pDynLoad + 1, szNormPath, cbNormPath);
     1680                pDynLoad->pwszPath          = (wchar_t *)(pDynLoad->pszPath + cbNormPath + (cbNormPath & 1));
     1681                kwStrToUtf16(pDynLoad->pszPath, (wchar_t *)pDynLoad->pwszPath, cbNormPath * 2);
     1682                pDynLoad->pszModName        = kHlpGetFilename(pDynLoad->pszPath);
     1683                pDynLoad->uHashPath         = uHashPath;
     1684                pDynLoad->pMod              = NULL; /* indicates special  */
     1685                pDynLoad->hmod              = hmod;
     1686
     1687                pDynLoad->pNext = g_Sandbox.pTool->u.Sandboxed.pDynLoadHead;
     1688                g_Sandbox.pTool->u.Sandboxed.pDynLoadHead = pDynLoad;
     1689            }
     1690            else
     1691                __debugbreak();
     1692        }
     1693        return hmod;
     1694    }
     1695
     1696    /*
     1697     * Normal library loading.
     1698     * We start by being very lazy and reusing the code for resolving imports.
     1699     */
     1700    if (!kHlpIsFilenameOnly(pszFilename))
     1701        pMod = kwLdrModuleTryLoadDll(pszFilename, KWLOCATION_UNKNOWN, g_Sandbox.pTool->u.Sandboxed.pExe);
     1702    else
     1703    {
     1704__debugbreak();
     1705        rc = kwLdrModuleResolveAndLookup(pszFilename, g_Sandbox.pTool->u.Sandboxed.pExe, NULL /*pImporter*/, &pMod);
     1706        if (rc != 0)
     1707            pMod = NULL;
     1708    }
     1709    if (!pMod)
     1710    {
     1711        __debugbreak();
     1712        SetLastError(ERROR_MOD_NOT_FOUND);
     1713        return NULL;
     1714    }
     1715
     1716    /*
     1717     * Make sure it's initialized.
     1718     */
     1719    rc = kwLdrModuleInitTree(pMod);
     1720    if (rc == 0)
     1721    {
     1722        /*
     1723         * Create an dynamic loading entry for it.
     1724         */
     1725        pDynLoad = (PKWDYNLOAD)kHlpAlloc(sizeof(*pDynLoad));
     1726        if (pDynLoad)
     1727        {
     1728            pDynLoad->pszPath           = pMod->pszPath;
     1729            pDynLoad->pwszPath          = pMod->pwszPath;
     1730            pDynLoad->pszModName        = kHlpGetFilename(pDynLoad->pszPath);
     1731            pDynLoad->uHashPath         = pMod->uHashPath;
     1732            pDynLoad->pMod              = pMod;
     1733            pDynLoad->hmod              = pMod->hOurMod;
     1734
     1735            pDynLoad->pNext = g_Sandbox.pTool->u.Sandboxed.pDynLoadHead;
     1736            g_Sandbox.pTool->u.Sandboxed.pDynLoadHead = pDynLoad;
     1737
     1738            return pDynLoad->hmod;
     1739        }
     1740    }
     1741
     1742    __debugbreak();
     1743    SetLastError(ERROR_NOT_ENOUGH_MEMORY);
     1744    kwLdrModuleRelease(pMod);
     1745    return NULL;
     1746}
     1747
     1748
     1749/** Kernel32 - LoadLibraryExW()   */
     1750static HMODULE WINAPI kwSandbox_Kernel32_LoadLibraryExW(LPCWSTR pwszFilename, HANDLE hFile, DWORD fFlags)
     1751{
     1752    char szTmp[4096];
     1753    KSIZE cchTmp = kwUtf16ToStr(pwszFilename, szTmp, sizeof(szTmp));
     1754    if (cchTmp < sizeof(szTmp))
     1755        return kwSandbox_Kernel32_LoadLibraryExA(szTmp, hFile, fFlags);
     1756
     1757    __debugbreak();
     1758    SetLastError(ERROR_FILENAME_EXCED_RANGE);
     1759    return NULL;
     1760}
     1761
     1762/** Kernel32 - LoadLibraryA()   */
     1763static HMODULE WINAPI kwSandbox_Kernel32_LoadLibraryA(LPCSTR pszFilename)
     1764{
     1765    return kwSandbox_Kernel32_LoadLibraryExA(pszFilename, NULL /*hFile*/, 0 /*fFlags*/);
     1766}
     1767
     1768
     1769/** Kernel32 - LoadLibraryW()   */
     1770static HMODULE WINAPI kwSandbox_Kernel32_LoadLibraryW(LPCWSTR pwszFilename)
     1771{
     1772    char szTmp[4096];
     1773    KSIZE cchTmp = kwUtf16ToStr(pwszFilename, szTmp, sizeof(szTmp));
     1774    if (cchTmp < sizeof(szTmp))
     1775        return kwSandbox_Kernel32_LoadLibraryExA(szTmp, NULL /*hFile*/, 0 /*fFlags*/);
     1776    __debugbreak();
     1777    SetLastError(ERROR_FILENAME_EXCED_RANGE);
     1778    return NULL;
     1779}
     1780
     1781
     1782/** Kernel32 - FreeLibrary()   */
     1783static BOOL WINAPI kwSandbox_Kernel32_FreeLibrary(HMODULE hmod)
     1784{
     1785    /* Ignored, we like to keep everything loaded. */
     1786    return TRUE;
     1787}
     1788
     1789
     1790/** Kernel32 - GetModuleHandleA()   */
     1791static HMODULE WINAPI kwSandbox_Kernel32_GetModuleHandleA(LPCSTR pszModule)
     1792{
     1793    if (pszModule == NULL)
     1794        return (HMODULE)g_Sandbox.pTool->u.Sandboxed.pExe->hOurMod;
     1795    __debugbreak();
     1796    return NULL;
     1797}
     1798
     1799
     1800/** Kernel32 - GetModuleHandleW()   */
     1801static HMODULE WINAPI kwSandbox_Kernel32_GetModuleHandleW(LPCWSTR pwszModule)
     1802{
     1803    if (pwszModule == NULL)
     1804        return (HMODULE)g_Sandbox.pTool->u.Sandboxed.pExe->hOurMod;
     1805    __debugbreak();
     1806    return NULL;
     1807}
     1808
     1809
     1810static PKWMODULE kwSandboxLocateModuleByHandle(PKWSANDBOX pSandbox, HMODULE hmod)
     1811{
     1812    PKWDYNLOAD pDynLoad;
     1813
     1814    /* The executable. */
     1815    if (   hmod == NULL
     1816        || pSandbox->pTool->u.Sandboxed.pExe->hOurMod == hmod)
     1817        return kwLdrModuleRetain(pSandbox->pTool->u.Sandboxed.pExe);
     1818
     1819    /* Dynamically loaded images. */
     1820    for (pDynLoad = pSandbox->pTool->u.Sandboxed.pDynLoadHead; pDynLoad != NULL; pDynLoad = pDynLoad->pNext)
     1821        if (pDynLoad->hmod == hmod)
     1822        {
     1823            if (pDynLoad->pMod)
     1824                return kwLdrModuleRetain(pDynLoad->pMod);
     1825            __debugbreak();
     1826            return NULL;
     1827        }
     1828
     1829    return NULL;
     1830}
     1831
     1832
     1833/** Used to debug dynamically resolved procedures. */
     1834static UINT WINAPI kwSandbox_BreakIntoDebugger(void *pv1, void *pv2, void *pv3, void *pv4)
     1835{
     1836    __debugbreak();
     1837    return -1;
     1838}
     1839
     1840
     1841/** Kernel32 - GetProcAddress()   */
     1842static FARPROC WINAPI kwSandbox_Kernel32_GetProcAddress(HMODULE hmod, LPCSTR pszProc)
     1843{
     1844    /*
     1845     * Try locate the module.
     1846     */
     1847    PKWMODULE pMod = kwSandboxLocateModuleByHandle(&g_Sandbox, hmod);
     1848    if (pMod)
     1849    {
     1850        KLDRADDR uValue;
     1851        int rc = kLdrModQuerySymbol(pMod->pLdrMod,
     1852                                    pMod->fNative ? NULL : pMod->u.Manual.pvBits,
     1853                                    pMod->fNative ? KLDRMOD_BASEADDRESS_MAP : (KUPTR)pMod->u.Manual.pvLoad,
     1854                                    KU32_MAX /*iSymbol*/,
     1855                                    pszProc,
     1856                                    strlen(pszProc),
     1857                                    NULL /*pszVersion*/,
     1858                                    NULL /*pfnGetForwarder*/, NULL /*pvUser*/,
     1859                                    &uValue,
     1860                                    NULL /*pfKind*/);
     1861        if (rc == 0)
     1862        {
     1863            static int s_cDbgGets = 0;
     1864            s_cDbgGets++;
     1865            kwDbgPrintf("GetProcAddress(%s, %s) -> %p [%d]\n", pMod->pszPath, pszProc, (KUPTR)uValue, s_cDbgGets);
     1866            kwLdrModuleRelease(pMod);
     1867            //if (s_cGets >= 3)
     1868            //    return (FARPROC)kwSandbox_BreakIntoDebugger;
     1869            return (FARPROC)(KUPTR)uValue;
     1870        }
     1871
     1872        __debugbreak();
     1873        SetLastError(ERROR_PROC_NOT_FOUND);
     1874        kwLdrModuleRelease(pMod);
     1875        return NULL;
     1876    }
     1877
     1878    __debugbreak();
     1879    return GetProcAddress(hmod, pszProc);
     1880}
     1881
     1882
     1883/** Kernel32 - GetModuleFileNameA()   */
     1884static DWORD WINAPI kwSandbox_Kernel32_GetModuleFileNameA(HMODULE hmod, LPSTR pszFilename, DWORD cbFilename)
     1885{
     1886    PKWMODULE pMod = kwSandboxLocateModuleByHandle(&g_Sandbox, hmod);
     1887    if (pMod != NULL)
     1888    {
     1889        DWORD cbRet = kwStrCopyStyle1(pMod->pszPath, pszFilename, cbFilename);
     1890        kwLdrModuleRelease(pMod);
     1891        return cbRet;
     1892    }
     1893    __debugbreak();
     1894    return 0;
     1895}
     1896
     1897
     1898/** Kernel32 - GetModuleFileNameW()   */
     1899static DWORD WINAPI kwSandbox_Kernel32_GetModuleFileNameW(HMODULE hmod, LPWSTR pwszFilename, DWORD cbFilename)
     1900{
     1901    PKWMODULE pMod = kwSandboxLocateModuleByHandle(&g_Sandbox, hmod);
     1902    if (pMod)
     1903    {
     1904        DWORD cwcRet = kwUtf16CopyStyle1(pMod->pwszPath, pwszFilename, cbFilename);
     1905        kwLdrModuleRelease(pMod);
     1906        return cwcRet;
     1907    }
     1908
     1909    __debugbreak();
     1910    return 0;
     1911}
     1912
     1913
     1914
    8651915/**
    8661916 * Functions that needs replacing for sandboxed execution.
     
    8691919{
    8701920#define TUPLE(a_sz) a_sz, sizeof(a_sz) - 1
    871     { TUPLE("ExitProcess"),            NULL,       (KUPTR)kwSandbox_Kernel32_ExitProcess },
    872     { TUPLE("TerminateProcess"),       NULL,       (KUPTR)kwSandbox_Kernel32_TerminateProcess },
    873     { TUPLE("exit"),                   NULL,       (KUPTR)kwSandbox_msvcrt_exit },
    874     { TUPLE("_exit"),                  NULL,       (KUPTR)kwSandbox_msvcrt__exit },
    875     { TUPLE("_cexit"),                 NULL,       (KUPTR)kwSandbox_msvcrt__cexit },
    876     { TUPLE("_c_exit"),                NULL,       (KUPTR)kwSandbox_msvcrt__c_exit },
    877     { TUPLE("_amsg_exit"),             NULL,       (KUPTR)kwSandbox_msvcrt__amsg_exit },
    878     { TUPLE("__getmainargs"),          NULL,       (KUPTR)kwSandbox_msvcrt___getmainargs},
     1921    /*
     1922     * Kernel32.dll and friends.
     1923     */
     1924    { TUPLE("ExitProcess"),                 NULL,       (KUPTR)kwSandbox_Kernel32_ExitProcess },
     1925    { TUPLE("TerminateProcess"),            NULL,       (KUPTR)kwSandbox_Kernel32_TerminateProcess },
     1926
     1927    { TUPLE("LoadLibraryA"),                NULL,       (KUPTR)kwSandbox_Kernel32_LoadLibraryA },
     1928    { TUPLE("LoadLibraryW"),                NULL,       (KUPTR)kwSandbox_Kernel32_LoadLibraryW },
     1929    { TUPLE("LoadLibraryExA"),              NULL,       (KUPTR)kwSandbox_Kernel32_LoadLibraryExA },
     1930    { TUPLE("LoadLibraryExW"),              NULL,       (KUPTR)kwSandbox_Kernel32_LoadLibraryExW },
     1931    { TUPLE("FreeLibrary"),                 NULL,       (KUPTR)kwSandbox_Kernel32_FreeLibrary },
     1932    { TUPLE("GetModuleHandleA"),            NULL,       (KUPTR)kwSandbox_Kernel32_GetModuleHandleA },
     1933    { TUPLE("GetModuleHandleW"),            NULL,       (KUPTR)kwSandbox_Kernel32_GetModuleHandleW },
     1934    { TUPLE("GetProcAddress"),              NULL,       (KUPTR)kwSandbox_Kernel32_GetProcAddress },
     1935    { TUPLE("GetModuleFileNameA"),          NULL,       (KUPTR)kwSandbox_Kernel32_GetModuleFileNameA },
     1936    { TUPLE("GetModuleFileNameW"),          NULL,       (KUPTR)kwSandbox_Kernel32_GetModuleFileNameW },
     1937
     1938    { TUPLE("GetCommandLineA"),             NULL,       (KUPTR)kwSandbox_Kernel32_GetCommandLineA },
     1939    { TUPLE("GetCommandLineW"),             NULL,       (KUPTR)kwSandbox_Kernel32_GetCommandLineW },
     1940    { TUPLE("GetStartupInfoA"),             NULL,       (KUPTR)kwSandbox_Kernel32_GetStartupInfoA },
     1941    { TUPLE("GetStartupInfoW"),             NULL,       (KUPTR)kwSandbox_Kernel32_GetStartupInfoW },
     1942
     1943    { TUPLE("CreateThread"),                NULL,       (KUPTR)kwSandbox_Kernel32_CreateThread },
     1944
     1945    { TUPLE("GetEnvironmentVariableA"),     NULL,       (KUPTR)kwSandbox_Kernel32_GetEnvironmentVariableA },
     1946    { TUPLE("GetEnvironmentVariableW"),     NULL,       (KUPTR)kwSandbox_Kernel32_GetEnvironmentVariableW },
     1947    { TUPLE("SetEnvironmentVariableA"),     NULL,       (KUPTR)kwSandbox_Kernel32_SetEnvironmentVariableA },
     1948    { TUPLE("SetEnvironmentVariableW"),     NULL,       (KUPTR)kwSandbox_Kernel32_SetEnvironmentVariableW },
     1949    { TUPLE("ExpandEnvironmentStringsA"),   NULL,       (KUPTR)kwSandbox_Kernel32_ExpandEnvironmentStringsA },
     1950    { TUPLE("ExpandEnvironmentStringsW"),   NULL,       (KUPTR)kwSandbox_Kernel32_ExpandEnvironmentStringsW },
     1951
     1952    /*
     1953     * MS Visual C++ CRTs.
     1954     */
     1955    { TUPLE("exit"),                        NULL,       (KUPTR)kwSandbox_msvcrt_exit },
     1956    { TUPLE("_exit"),                       NULL,       (KUPTR)kwSandbox_msvcrt__exit },
     1957    { TUPLE("_cexit"),                      NULL,       (KUPTR)kwSandbox_msvcrt__cexit },
     1958    { TUPLE("_c_exit"),                     NULL,       (KUPTR)kwSandbox_msvcrt__c_exit },
     1959    { TUPLE("_amsg_exit"),                  NULL,       (KUPTR)kwSandbox_msvcrt__amsg_exit },
     1960
     1961    { TUPLE("_beginthread"),                NULL,       (KUPTR)kwSandbox_msvcrt__beginthread },
     1962    { TUPLE("_beginthreadex"),              NULL,       (KUPTR)kwSandbox_msvcrt__beginthreadex },
     1963
     1964    { TUPLE("__argc"),                      NULL,       (KUPTR)&g_Sandbox.cArgs },
     1965    { TUPLE("__argv"),                      NULL,       (KUPTR)&g_Sandbox.papszArgs },
     1966    { TUPLE("__wargv"),                     NULL,       (KUPTR)&g_Sandbox.papwszArgs },
     1967    { TUPLE("__p___argc"),                  NULL,       (KUPTR)kwSandbox_msvcrt___p___argc },
     1968    { TUPLE("__p___argv"),                  NULL,       (KUPTR)kwSandbox_msvcrt___p___argv },
     1969    { TUPLE("__p___wargv"),                 NULL,       (KUPTR)kwSandbox_msvcrt___p___wargv },
     1970    { TUPLE("_acmdln"),                     NULL,       (KUPTR)&g_Sandbox.pszCmdLine },
     1971    { TUPLE("_wcmdln"),                     NULL,       (KUPTR)&g_Sandbox.pwszCmdLine },
     1972    { TUPLE("__p__acmdln"),                 NULL,       (KUPTR)kwSandbox_msvcrt___p__acmdln },
     1973    { TUPLE("__p__wcmdln"),                 NULL,       (KUPTR)kwSandbox_msvcrt___p__wcmdln },
     1974    { TUPLE("_pgmptr"),                     NULL,       (KUPTR)&g_Sandbox.pgmptr  },
     1975    { TUPLE("_wpgmptr"),                    NULL,       (KUPTR)&g_Sandbox.wpgmptr },
     1976    { TUPLE("_get_pgmptr"),                 NULL,       (KUPTR)kwSandbox_msvcrt__get_pgmptr },
     1977    { TUPLE("_get_wpgmptr"),                NULL,       (KUPTR)kwSandbox_msvcrt__get_wpgmptr },
     1978    { TUPLE("__p__pgmptr"),                 NULL,       (KUPTR)kwSandbox_msvcrt___p__pgmptr },
     1979    { TUPLE("__p__wpgmptr"),                NULL,       (KUPTR)kwSandbox_msvcrt___p__wpgmptr },
     1980    { TUPLE("_wincmdln"),                   NULL,       (KUPTR)kwSandbox_msvcrt__wincmdln },
     1981    { TUPLE("_wwincmdln"),                  NULL,       (KUPTR)kwSandbox_msvcrt__wwincmdln },
     1982    { TUPLE("__getmainargs"),               NULL,       (KUPTR)kwSandbox_msvcrt___getmainargs},
     1983    { TUPLE("__wgetmainargs"),              NULL,       (KUPTR)kwSandbox_msvcrt___wgetmainargs},
     1984
     1985    { TUPLE("_putenv"),                     NULL,       (KUPTR)kwSandbox_msvcrt__putenv},
     1986    { TUPLE("_wputenv"),                    NULL,       (KUPTR)kwSandbox_msvcrt__wputenv},
     1987    { TUPLE("_putenv_s"),                   NULL,       (KUPTR)kwSandbox_msvcrt__putenv_s},
     1988    { TUPLE("_wputenv_s"),                  NULL,       (KUPTR)kwSandbox_msvcrt__wputenv_s},
     1989    { TUPLE("__initenv"),                   NULL,       (KUPTR)&g_Sandbox.initenv },
     1990    { TUPLE("__winitenv"),                  NULL,       (KUPTR)&g_Sandbox.winitenv },
     1991    { TUPLE("__p___initenv"),               NULL,       (KUPTR)kwSandbox_msvcrt___p___initenv},
     1992    { TUPLE("__p___winitenv"),              NULL,       (KUPTR)kwSandbox_msvcrt___p___winitenv},
     1993    { TUPLE("_environ"),                    NULL,       (KUPTR)&g_Sandbox.environ },
     1994    { TUPLE("_wenviron"),                   NULL,       (KUPTR)&g_Sandbox.wenviron },
     1995    { TUPLE("_get_environ"),                NULL,       (KUPTR)kwSandbox_msvcrt__get_environ },
     1996    { TUPLE("_get_wenviron"),               NULL,       (KUPTR)kwSandbox_msvcrt__get_wenviron },
     1997    { TUPLE("__p__environ"),                NULL,       (KUPTR)kwSandbox_msvcrt___p__environ },
     1998    { TUPLE("__p__wenviron"),               NULL,       (KUPTR)kwSandbox_msvcrt___p__wenviron },
     1999    /// @todo terminate
    8792000};
    8802001/** Number of entries in g_aReplacements. */
     
    9022023}
    9032024
    904 
    905 /**
    906  * Does module initialization starting at @a pMod.
    907  *
    908  * This is initially used on the executable.  Later it is used by the
    909  * LoadLibrary interceptor.
    910  *
    911  * @returns 0 on success, error on failure.
    912  * @param   pMod                The module to initialize.
    913  */
    914 static int kwSandboxInitModuleTree(PKWMODULE pMod)
    915 {
    916     int rc = 0;
    917     if (!pMod->fNative)
    918     {
    919         /* Need to copy bits? */
    920         if (pMod->u.Manual.enmState == KWMODSTATE_NEEDS_BITS)
    921         {
    922             kHlpMemCopy(pMod->u.Manual.pvLoad, pMod->u.Manual.pvCopy, pMod->u.Manual.cbImage);
    923             pMod->u.Manual.enmState = KWMODSTATE_NEEDS_INIT;
    924         }
    925 
    926         if (pMod->u.Manual.enmState == KWMODSTATE_NEEDS_INIT)
    927         {
    928             /* Must do imports first, but mark our module as being initialized to avoid
    929                endless recursion should there be a dependency loop. */
    930             KSIZE iImp;
    931             pMod->u.Manual.enmState = KWMODSTATE_BEING_INITED;
    932 
    933             for (iImp = 0; iImp < pMod->u.Manual.cImpMods; iImp++)
    934             {
    935                 rc = kwSandboxInitModuleTree(pMod->u.Manual.apImpMods[iImp]);
    936                 if (rc != 0)
    937                     return rc;
    938             }
    939 
    940             rc = kLdrModCallInit(pMod->pLdrMod, pMod->u.Manual.pvLoad, (KUPTR)pMod->u.Manual.pvLoad);
    941             if (rc == 0)
    942                 pMod->u.Manual.enmState = KWMODSTATE_READY;
    943             else
    944                 pMod->u.Manual.enmState = KWMODSTATE_INIT_FAILED;
    945         }
    946     }
    947     return rc;
    948 }
    949 
    950 
    951 static void *kwSandboxGetProcessEnvironmentBlock(void)
     2025static PPEB kwSandboxGetProcessEnvironmentBlock(void)
    9522026{
    9532027#if K_ARCH == K_ARCH_X86_32
    954     return (void *)__readfsdword(0x030 /* offset of ProcessEnvironmentBlock in TEB */);
     2028    return (PPEB)__readfsdword(0x030 /* offset of ProcessEnvironmentBlock in TEB */);
    9552029#elif K_ARCH == K_ARCH_AMD64
    956     return (void *)__readgsqword(0x060 /* offset of ProcessEnvironmentBlock in TEB */);
     2030    return (PPEB)__readgsqword(0x060 /* offset of ProcessEnvironmentBlock in TEB */);
    9572031#else
    9582032# error "Port me!"
     
    9612035
    9622036
     2037
     2038
     2039static int kwSandboxInit(PKWSANDBOX pSandbox, PKWTOOL pTool, const char *pszCmdLine)
     2040{
     2041    PPEB pPeb = kwSandboxGetProcessEnvironmentBlock();
     2042    wchar_t *pwcPool;
     2043    KSIZE cbStrings;
     2044    KSIZE cwc;
     2045    int i;
     2046
     2047    /* Simple stuff. */
     2048    g_Sandbox.rcExitCode    = 256;
     2049    g_Sandbox.pTool         = pTool;
     2050    g_Sandbox.idMainThread  = GetCurrentThreadId();
     2051    g_Sandbox.TibMainThread = *(PNT_TIB)NtCurrentTeb();
     2052    g_Sandbox.pszCmdLine    = pszCmdLine;
     2053    g_Sandbox.pgmptr        = (char *)pTool->pszPath;
     2054    g_Sandbox.wpgmptr       = (wchar_t *)pTool->pwszPath;
     2055
     2056    /*
     2057     * Convert the command line to argc and argv.
     2058     */
     2059    cbStrings = parse_args(pszCmdLine, &pSandbox->cArgs, NULL /*papszArgs*/, NULL /*pchPool*/);
     2060    pSandbox->papszArgs = (char **)kHlpAlloc(sizeof(char *) * (pSandbox->cArgs + 2) + cbStrings);
     2061    if (!pSandbox->papszArgs)
     2062        return KERR_NO_MEMORY;
     2063    parse_args(pSandbox->pszCmdLine, &pSandbox->cArgs, pSandbox->papszArgs, (char *)&pSandbox->papszArgs[pSandbox->cArgs + 2]);
     2064    pSandbox->papszArgs[pSandbox->cArgs + 0] = NULL;
     2065    pSandbox->papszArgs[pSandbox->cArgs + 1] = NULL;
     2066
     2067    /*
     2068     * Convert command line and argv to UTF-16.
     2069     * We assume each ANSI char requires a surrogate pair in the UTF-16 variant.
     2070     */
     2071    pSandbox->papwszArgs = (wchar_t **)kHlpAlloc(sizeof(wchar_t *) * (pSandbox->cArgs + 2) + cbStrings * 2 * sizeof(wchar_t));
     2072    if (!pSandbox->papwszArgs)
     2073        return KERR_NO_MEMORY;
     2074    pwcPool = (wchar_t *)&pSandbox->papwszArgs[pSandbox->cArgs + 2];
     2075    for (i = 0; i < pSandbox->cArgs; i++)
     2076    {
     2077        *pwcPool++ = pSandbox->papszArgs[i][-1]; /* flags */
     2078        pSandbox->papwszArgs[i] = pwcPool;
     2079        pwcPool += kwStrToUtf16(pSandbox->papszArgs[i], pwcPool, (strlen(pSandbox->papszArgs[i]) + 1) * 2);
     2080        pwcPool++;
     2081    }
     2082    pSandbox->papwszArgs[pSandbox->cArgs + 0] = NULL;
     2083    pSandbox->papwszArgs[pSandbox->cArgs + 1] = NULL;
     2084
     2085    /*
     2086     * Convert the commandline string to UTF-16, same pessimistic approach as above.
     2087     */
     2088    cbStrings = (kHlpStrLen(pSandbox->pszCmdLine) + 1) * 2 * sizeof(wchar_t);
     2089    pSandbox->pwszCmdLine = kHlpAlloc(cbStrings);
     2090    if (!pSandbox->pwszCmdLine)
     2091        return KERR_NO_MEMORY;
     2092    cwc = kwStrToUtf16(pSandbox->pszCmdLine, pSandbox->pwszCmdLine, cbStrings / sizeof(wchar_t));
     2093
     2094    pSandbox->SavedCommandLine = pPeb->ProcessParameters->CommandLine;
     2095    pPeb->ProcessParameters->CommandLine.Buffer = pSandbox->pwszCmdLine;
     2096    pPeb->ProcessParameters->CommandLine.Length = (USHORT)cwc * sizeof(wchar_t);
     2097
     2098    return 0;
     2099}
     2100
     2101
     2102static void kwSandboxCleanup(PKWSANDBOX pSandbox)
     2103{
     2104    PPEB pPeb = kwSandboxGetProcessEnvironmentBlock();
     2105    pPeb->ProcessParameters->CommandLine = pSandbox->SavedCommandLine;
     2106    /** @todo lots more to do here!   */
     2107}
     2108
     2109
    9632110static int kwSandboxExec(PKWTOOL pTool, const char *pszCmdLine, int *prcExitCode)
    9642111{
    9652112    int rc;
    966     KWSANDBOX Sandbox;
     2113
     2114    *prcExitCode            = 256;
     2115kwDbgPrintf("GetCommandLineA: '%s'\n", GetCommandLineA());
    9672116
    9682117    /*
    9692118     * Initialize the sandbox environment.
    9702119     */
    971     Sandbox.pTool = pTool;
    972     Sandbox.rcExitCode = *prcExitCode = 256;
    973     Sandbox.idMainThread = GetCurrentThreadId();
    974     g_pSandbox = &Sandbox;
    975 
    976     /*
    977      * Do module initialization.
    978      */
    979     kwSandboxResetModuleState(pTool->u.Sandboxed.pExe);
    980     rc = kwSandboxInitModuleTree(pTool->u.Sandboxed.pExe);
     2120    rc = kwSandboxInit(&g_Sandbox, pTool, pszCmdLine);
    9812121    if (rc == 0)
    9822122    {
     2123
    9832124        /*
    984          * Call the main function.
     2125         * Do module initialization.
    9852126         */
    986         KUPTR uAddrMain;
    987         rc = kwLdrModuleQueryMainEntrypoint(pTool->u.Sandboxed.pExe, &uAddrMain);
     2127        kwSandboxResetModuleState(pTool->u.Sandboxed.pExe);
     2128        rc = kwLdrModuleInitTree(pTool->u.Sandboxed.pExe);
    9882129        if (rc == 0)
    9892130        {
    990             int rcExitCode;
    991             int (*pfnWin64Entrypoint)(void *pvPeb, void *, void *, void *);
    992             *(KUPTR *)&pfnWin64Entrypoint = uAddrMain;
     2131            /*
     2132             * Call the main function.
     2133             */
     2134            KUPTR uAddrMain;
     2135            rc = kwLdrModuleQueryMainEntrypoint(pTool->u.Sandboxed.pExe, &uAddrMain);
     2136            if (rc == 0)
     2137            {
     2138                int rcExitCode;
     2139                int (*pfnWin64Entrypoint)(void *pvPeb, void *, void *, void *);
     2140                *(KUPTR *)&pfnWin64Entrypoint = uAddrMain;
    9932141
    9942142                __try
    9952143                {
    996                     if (setjmp(Sandbox.JmpBuf) == 0)
     2144                    if (setjmp(g_Sandbox.JmpBuf) == 0)
    9972145                    {
    998                         *(KU64*)(Sandbox.JmpBuf) = 0; /** @todo find other way to prevent longjmp from doing unwind! */
    999                         rcExitCode = pfnWin64Entrypoint(kwSandboxGetProcessEnvironmentBlock, NULL, NULL, NULL);
     2146#if K_ARCH == K_ARCH_AMD64
     2147                        *(KU64*)(g_Sandbox.JmpBuf) = 0; /** @todo find other way to prevent longjmp from doing unwind! */
     2148#else
     2149# error "Port me!"
     2150#endif
     2151                        rcExitCode = pfnWin64Entrypoint(kwSandboxGetProcessEnvironmentBlock(), NULL, NULL, NULL);
    10002152                    }
    10012153                    else
    1002                         rcExitCode = Sandbox.rcExitCode;
     2154                        rcExitCode = g_Sandbox.rcExitCode;
    10032155                }
    10042156                __except (EXCEPTION_EXECUTE_HANDLER)
     
    10062158                    rcExitCode = 512;
    10072159                }
    1008             *prcExitCode = rcExitCode;
     2160                *prcExitCode = rcExitCode;
     2161
     2162                /*
     2163                 * Restore the TIB and later some other stuff.
     2164                 */
     2165                *(PNT_TIB)NtCurrentTeb() = g_Sandbox.TibMainThread;
     2166            }
    10092167        }
    10102168    }
     2169
    10112170    return rc;
    10122171}
     
    10202179    {
    10212180        int rc;
    1022         int rcExitExit;
     2181        int rcExitCode;
    10232182        switch (pTool->enmType)
    10242183        {
    10252184            case KWTOOLTYPE_SANDBOXED:
    1026                 rc = kwSandboxExec(pTool, pszCmdLine, &rcExitExit);
     2185                kwDbgPrintf("Sandboxing tool %s\n", pTool->pszPath);
     2186                rc = kwSandboxExec(pTool, pszCmdLine, &rcExitCode);
     2187                break;
     2188
     2189            case KWTOOLTYPE_WATCOM:
     2190                kwDbgPrintf("TODO: Watcom style tool %s\n", pTool->pszPath);
     2191                rc = rcExitCode = 2;
     2192                break;
     2193
     2194            case KWTOOLTYPE_EXEC:
     2195                kwDbgPrintf("TODO: Direct exec tool %s\n", pTool->pszPath);
     2196                rc = rcExitCode = 2;
    10272197                break;
    10282198
    10292199            default:
    10302200                kHlpAssertFailed();
    1031             case KWTOOLTYPE_WATCOM:
    1032             case KWTOOLTYPE_EXEC:
    1033                 rc = 2;
     2201                rc = rcExitCode = 2;
    10342202                break;
    10352203        }
     2204        kwDbgPrintf("rcExitCode=%d (rc=%d)\n", rcExitCode, rc);
    10362205    }
    10372206    else
     
    10432212int main(int argc, char **argv)
    10442213{
    1045     int rc = kwExecCmdLine(argv[1], argv[2]);
    1046     rc = kwExecCmdLine(argv[1], argv[2]);
     2214    int i;
     2215    int rc;
     2216    argv[2] = "\"E:/vbox/svn/trunk/tools/win.x86/vcc/v10sp1/bin/amd64/cl.exe\" -c -c -TP -nologo -Zi -Zi -Zl -GR- -EHsc -GF -Zc:wchar_t- -Oy- -MT -W4 -Wall -wd4065 -wd4996 -wd4127 -wd4706 -wd4201 -wd4214 -wd4510 -wd4512 -wd4610 -wd4514 -wd4820 -wd4365 -wd4987 -wd4710 -wd4061 -wd4986 -wd4191 -wd4574 -wd4917 -wd4711 -wd4611 -wd4571 -wd4324 -wd4505 -wd4263 -wd4264 -wd4738 -wd4242 -wd4244 -WX -RTCsu -IE:/vbox/svn/trunk/tools/win.x86/vcc/v10sp1/include -IE:/vbox/svn/trunk/tools/win.x86/vcc/v10sp1/atlmfc/include -IE:/vbox/svn/trunk/tools/win.x86/sdk/v7.1/Include -IE:/vbox/svn/trunk/include -IE:/vbox/svn/trunk/out/win.amd64/debug -IE:/vbox/svn/trunk/tools/win.x86/vcc/v10sp1/include -IE:/vbox/svn/trunk/tools/win.x86/vcc/v10sp1/atlmfc/include -DVBOX -DVBOX_WITH_64_BITS_GUESTS -DVBOX_WITH_REM -DVBOX_WITH_RAW_MODE -DDEBUG -DDEBUG_bird -DDEBUG_USERNAME=bird -DRT_OS_WINDOWS -D__WIN__ -DRT_ARCH_AMD64 -D__AMD64__ -D__WIN64__ -DVBOX_WITH_DEBUGGER -DRT_LOCK_STRICT -DRT_LOCK_STRICT_ORDER -DIN_RING3 -DLOG_DISABLED -DIN_BLD_PROG -D_CRT_SECURE_NO_DEPRECATE -FdE:/vbox/svn/trunk/out/win.amd64/debug/obj/VBoxBs2Linker/VBoxBs2Linker-obj.pdb -FD -FoE:/vbox/svn/trunk/out/win.amd64/debug/obj/VBoxBs2Linker/VBoxBs2Linker.obj E:\\vbox\\svn\\trunk\\src\\VBox\\ValidationKit\\bootsectors\\VBoxBs2Linker.cpp";
     2217    //rc = kwExecCmdLine(argv[1], argv[2]);
     2218    //rc = kwExecCmdLine(argv[1], argv[2]);
     2219// run 2: 34/1024 = 0x0 (0.033203125)
     2220// run 1: 37/1024 = 0x0 (0.0361328125)
     2221// kmk 1: 44/1024 = 0x0 (0.04296875)
     2222// cmd 1: 48/1024 = 0x0 (0.046875)
     2223    g_cVerbose = 0;
     2224    for (i = 0; i < 1024 && rc == 0; i++)
     2225        rc = kwExecCmdLine(argv[1], argv[2]);
    10472226    return rc;
    10482227}
Note: See TracChangeset for help on using the changeset viewer.