Ignore:
Timestamp:
Sep 15, 2016, 1:41:42 PM (9 years ago)
Author:
bird
Message:

fixes

File:
1 edited

Legend:

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

    r2915 r2916  
    3232*********************************************************************************************************************************/
    3333//#undef NDEBUG
     34//#define K_STRICT 1
     35//#define KW_LOG_ENABLED
     36
    3437#define PSAPI_VERSION 1
    3538#include <k/kHlp.h>
     
    7578#define WITH_CONSOLE_OUTPUT_BUFFERING
    7679
    77 
    78 /** String constant comma length.   */
    79 #define TUPLE(a_sz)                     a_sz, sizeof(a_sz) - 1
     80/** @def WITH_STD_OUT_ERR_BUFFERING
     81 * Enables buffering of standard output and standard error buffer as well as
     82 * removal of annoying source file echo by cl.exe. */
     83#define WITH_STD_OUT_ERR_BUFFERING
     84
     85/** @def WITH_LOG_FILE
     86 * Log to file instead of stderr. */
     87#define WITH_LOG_FILE
     88
     89#ifndef NDEBUG
     90# define KW_LOG_ENABLED
     91#endif
     92
    8093
    8194/** @def KW_LOG
    8295 * Generic logging.
    8396 * @param a     Argument list for kwDbgPrintf  */
    84 #ifndef NDEBUG
     97#ifdef KW_LOG_ENABLED
    8598# define KW_LOG(a) kwDbgPrintf a
    8699#else
     
    91104 * FS cache logging.
    92105 * @param a     Argument list for kwDbgPrintf  */
    93 #ifndef NDEBUG
     106#ifdef KW_LOG_ENABLED
    94107# define KWFS_LOG(a) kwDbgPrintf a
    95108#else
     
    97110#endif
    98111
     112/** @def KWOUT_LOG
     113 * Output related logging.
     114 * @param a     Argument list for kwDbgPrintf  */
     115#ifdef KW_LOG_ENABLED
     116# define KWOUT_LOG(a) kwDbgPrintf a
     117#else
     118# define KWOUT_LOG(a) do { } while (0)
     119#endif
     120
    99121/** @def KWCRYPT_LOG
    100122 * FS cache logging.
    101123 * @param a     Argument list for kwDbgPrintf  */
    102 #ifndef NDEBUG
     124#ifdef KW_LOG_ENABLED
    103125# define KWCRYPT_LOG(a) kwDbgPrintf a
    104126#else
     
    123145/** Marks unfinished code.  */
    124146#if 1
    125 # define KWFS_TODO()    do { kwErrPrintf("\nHit TODO on line %u in %s!\n", __LINE__, __FUNCTION__); __debugbreak(); } while (0)
     147# define KWFS_TODO()    do { kwErrPrintf("\nHit TODO on line %u in %s!\n", __LINE__, __FUNCTION__); fflush(stderr); __debugbreak(); } while (0)
    126148#else
    127 # define KWFS_TODO()    do { kwErrPrintf("\nHit TODO on line %u in %s!\n", __LINE__, __FUNCTION__); } while (0)
     149# define KWFS_TODO()    do { kwErrPrintf("\nHit TODO on line %u in %s!\n", __LINE__, __FUNCTION__); fflush(stderr); } while (0)
    128150#endif
    129151
     
    132154/** User data key for a cached file. */
    133155#define KW_DATA_KEY_CACHED_FILE         (~(KUPTR)65521)
     156
     157/** String constant comma length.   */
     158#define TUPLE(a_sz)                     a_sz, sizeof(a_sz) - 1
    134159
    135160
     
    356381 * Console line buffer or output full buffer.
    357382 */
    358 typedef struct KWCONSOLEOUTPUTLINE
     383typedef struct KWOUTPUTSTREAMBUF
    359384{
    360385    /** The main output handle. */
     
    366391     * boundraries when ever possible. */
    367392    KBOOL               fIsConsole;
    368     KU8                 abPadding[3];
     393    /** Compressed GetFileType result. */
     394    KU8                 fFileType;
     395    KU8                 abPadding[2];
    369396    union
    370397    {
     
    384411            /** Amount of pending output (in chars). */
    385412            KU32                cchBuf;
     413#ifdef WITH_STD_OUT_ERR_BUFFERING
    386414            /** The allocated buffer size (in chars).   */
    387415            KU32                cchBufAlloc;
    388416            /** Pending output. */
    389417            char               *pchBuf;
     418#endif
    390419        } Fully;
    391420    } u;
    392 } KWCONSOLEOUTPUTLINE;
     421} KWOUTPUTSTREAMBUF;
    393422/** Pointer to a console line buffer. */
    394 typedef KWCONSOLEOUTPUTLINE *PKWCONSOLEOUTPUTLINE;
     423typedef KWOUTPUTSTREAMBUF *PKWOUTPUTSTREAMBUF;
    395424
    396425/**
     
    423452    KWHANDLETYPE_FSOBJ_READ_CACHE,
    424453    KWHANDLETYPE_TEMP_FILE,
    425     KWHANDLETYPE_TEMP_FILE_MAPPING
    426     //KWHANDLETYPE_CONSOLE_CACHE
     454    KWHANDLETYPE_TEMP_FILE_MAPPING,
     455    KWHANDLETYPE_OUTPUT_BUF
    427456} KWHANDLETYPE;
    428457
     
    431460{
    432461    KWHANDLETYPE        enmType;
     462    /** Number of references   */
     463    KU32                cRefs;
    433464    /** The current file offset. */
    434465    KU32                offFile;
     
    445476        /** Temporary file handle or mapping handle. */
    446477        PKWFSTEMPFILE       pTempFile;
     478#ifdef WITH_CONSOLE_OUTPUT_BUFFERING
     479        /** Buffered output stream. */
     480        PKWOUTPUTSTREAMBUF  pOutBuf;
     481#endif
    447482    } u;
    448483} KWHANDLE;
     
    618653    /** Number of active handles in the table. */
    619654    KU32            cActiveHandles;
     655    /** Number of handles in the handle table that will not be freed.   */
     656    KU32            cFixedHandles;
     657    /** Total number of leaked handles. */
     658    KU32            cLeakedHandles;
    620659
    621660    /** Head of the list of temporary file. */
     
    636675    PKWEXITCALLACK  pExitCallbackHead;
    637676
    638     UNICODE_STRING SavedCommandLine;
     677    MY_UNICODE_STRING SavedCommandLine;
    639678
    640679#ifdef WITH_HASH_MD5_CACHE
     
    661700
    662701#ifdef WITH_CONSOLE_OUTPUT_BUFFERING
    663     /** Standard output (and whatever else) line buffer. */
    664     KWCONSOLEOUTPUTLINE StdOut;
    665     /** Standard error line buffer. */
    666     KWCONSOLEOUTPUTLINE StdErr;
     702    /** The internal standard output handle. */
     703    KWHANDLE            HandleStdOut;
     704    /** The internal standard error handle. */
     705    KWHANDLE            HandleStdErr;
     706    /** Standard output (and whatever else) buffer. */
     707    KWOUTPUTSTREAMBUF   StdOut;
     708    /** Standard error buffer. */
     709    KWOUTPUTSTREAMBUF   StdErr;
    667710    /** Combined buffer of completed lines. */
    668711    KWCONSOLEOUTPUT     Combined;
     
    749792static KU8          g_abDefLdBuf[16*1024*1024];
    750793
     794#ifdef WITH_LOG_FILE
     795/** Log file handle.   */
     796static HANDLE g_hLogFile = INVALID_HANDLE_VALUE;
     797#endif
    751798
    752799
     
    756803static FNKLDRMODGETIMPORT kwLdrModuleGetImportCallback;
    757804static int kwLdrModuleResolveAndLookup(const char *pszName, PKWMODULE pExe, PKWMODULE pImporter, PKWMODULE *ppMod);
    758 static KBOOL kwSandboxHandleTableEnter(PKWSANDBOX pSandbox, PKWHANDLE pHandle);
     805static KBOOL kwSandboxHandleTableEnter(PKWSANDBOX pSandbox, PKWHANDLE pHandle, HANDLE hHandle);
    759806#ifdef WITH_CONSOLE_OUTPUT_BUFFERING
    760 static void kwSandboxConsoleWriteA(PKWSANDBOX pSandbox, PKWCONSOLEOUTPUTLINE pLineBuf, const char *pchBuffer, KU32 cchToWrite);
     807static void kwSandboxConsoleWriteA(PKWSANDBOX pSandbox, PKWOUTPUTSTREAMBUF pLineBuf, const char *pchBuffer, KU32 cchToWrite);
    761808#endif
    762809
     
    773820    {
    774821        DWORD const dwSavedErr = GetLastError();
    775 
     822#ifdef WITH_LOG_FILE
     823        DWORD       dwIgnored;
     824        char        szTmp[2048];
     825        int         cchPrefix = _snprintf(szTmp, sizeof(szTmp), "%x:%x: ", GetCurrentProcessId(), GetCurrentThreadId());
     826        int         cch = vsnprintf(&szTmp[cchPrefix], sizeof(szTmp) - cchPrefix, pszFormat, va);
     827        if (cch < (int)sizeof(szTmp) - 1 - cchPrefix)
     828            cch += cchPrefix;
     829        else
     830        {
     831            cch = sizeof(szTmp) - 1;
     832            szTmp[cch] = '\0';
     833        }
     834
     835        if (g_hLogFile == INVALID_HANDLE_VALUE)
     836        {
     837            wchar_t wszFilename[128];
     838            _snwprintf(wszFilename, K_ELEMENTS(wszFilename), L"kWorker-%x-%x.log", GetTickCount(), GetCurrentProcessId());
     839            g_hLogFile = CreateFileW(wszFilename, GENERIC_WRITE, FILE_SHARE_READ, NULL /*pSecAttrs*/, CREATE_ALWAYS,
     840                                     FILE_ATTRIBUTE_NORMAL, NULL /*hTemplateFile*/);
     841        }
     842
     843        WriteFile(g_hLogFile, szTmp, cch, &dwIgnored, NULL /*pOverlapped*/);
     844#else
    776845        fprintf(stderr, "debug: ");
    777846        vfprintf(stderr, pszFormat, va);
     847#endif
    778848
    779849        SetLastError(dwSavedErr);
     
    42654335        {
    42664336            pHandle->enmType            = !fMapping ? KWHANDLETYPE_TEMP_FILE : KWHANDLETYPE_TEMP_FILE_MAPPING;
     4337            pHandle->cRefs              = 1;
    42674338            pHandle->offFile            = 0;
    42684339            pHandle->hHandle            = hFile;
    42694340            pHandle->dwDesiredAccess    = dwDesiredAccess;
    42704341            pHandle->u.pTempFile        = pTempFile;
    4271             if (kwSandboxHandleTableEnter(&g_Sandbox, pHandle))
     4342            if (kwSandboxHandleTableEnter(&g_Sandbox, pHandle, hFile))
    42724343            {
    42734344                pTempFile->cActiveHandles++;
     
    46854756                {
    46864757                    pHandle->enmType            = KWHANDLETYPE_FSOBJ_READ_CACHE;
     4758                    pHandle->cRefs              = 1;
    46874759                    pHandle->offFile            = 0;
    46884760                    pHandle->hHandle            = *phFile;
    46894761                    pHandle->dwDesiredAccess    = dwDesiredAccess;
    46904762                    pHandle->u.pCachedFile      = pCachedFile;
    4691                     if (kwSandboxHandleTableEnter(&g_Sandbox, pHandle))
     4763                    if (kwSandboxHandleTableEnter(&g_Sandbox, pHandle, pHandle->hHandle))
    46924764                        return K_TRUE;
    46934765
     
    47734845    }
    47744846
     4847    /*
     4848     * Okay, normal.
     4849     */
    47754850    hFile = CreateFileA(pszFilename, dwDesiredAccess, dwShareMode, pSecAttrs,
    47764851                        dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile);
     4852    if (hFile != INVALID_HANDLE_VALUE)
     4853    {
     4854        kHlpAssert(   KW_HANDLE_TO_INDEX(hFile) >= g_Sandbox.cHandles
     4855                   || g_Sandbox.papHandles[KW_HANDLE_TO_INDEX(hFile)] == NULL);
     4856    }
    47774857    KWFS_LOG(("CreateFileA(%s) -> %p\n", pszFilename, hFile));
    47784858    return hFile;
     
    48344914    else
    48354915        KWFS_LOG(("CreateFileW: incompatible disposition %u\n", dwCreationDisposition));
     4916
     4917    /*
     4918     * Okay, normal.
     4919     */
    48364920    hFile = CreateFileW(pwszFilename, dwDesiredAccess, dwShareMode, pSecAttrs,
    48374921                        dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile);
     4922    if (hFile != INVALID_HANDLE_VALUE)
     4923    {
     4924        kHlpAssert(   KW_HANDLE_TO_INDEX(hFile) >= g_Sandbox.cHandles
     4925                   || g_Sandbox.papHandles[KW_HANDLE_TO_INDEX(hFile)] == NULL);
     4926    }
    48384927    KWFS_LOG(("CreateFileW(%ls) -> %p\n", pwszFilename, hFile));
    48394928    return hFile;
     
    48624951                    cbFile = pHandle->u.pTempFile->cbFile;
    48634952                    break;
     4953#endif
    48644954                case KWHANDLETYPE_TEMP_FILE_MAPPING:
    4865 #endif
     4955                case KWHANDLETYPE_OUTPUT_BUF:
    48664956                default:
    48674957                    kHlpAssertFailed();
     
    49435033                    cbFile = pHandle->u.pTempFile->cbFile;
    49445034                    break;
     5035#endif
    49455036                case KWHANDLETYPE_TEMP_FILE_MAPPING:
    4946 #endif
     5037                case KWHANDLETYPE_OUTPUT_BUF:
    49475038                default:
    49485039                    kHlpAssertFailed();
     
    51005191                    return TRUE;
    51015192                }
     5193#endif /* WITH_TEMP_MEMORY_FILES */
    51025194
    51035195                case KWHANDLETYPE_TEMP_FILE_MAPPING:
    5104 #endif /* WITH_TEMP_MEMORY_FILES */
     5196                case KWHANDLETYPE_OUTPUT_BUF:
    51055197                default:
    51065198                    kHlpAssertFailed();
     
    51365228}
    51375229
    5138 #ifdef WITH_CONSOLE_OUTPUT_BUFFERING
     5230#ifdef WITH_STD_OUT_ERR_BUFFERING
    51395231
    51405232/**
     
    51795271 * @param   cchToWrite          How much to write.
    51805272 */
    5181 static void kwSandboxOutBufWrite(PKWSANDBOX pSandbox, PKWCONSOLEOUTPUTLINE pOutBuf, const char *pchBuffer, KU32 cchToWrite)
     5273static void kwSandboxOutBufWrite(PKWSANDBOX pSandbox, PKWOUTPUTSTREAMBUF pOutBuf, const char *pchBuffer, KU32 cchToWrite)
    51825274{
    51835275    if (pOutBuf->u.Fully.cchBufAlloc > 0)
     
    52235315        while (cchToWrite > 0)
    52245316        {
    5225             char const *pchNewLine = (char *)memchr(pchBuffer, '\n', cchToWrite);
     5317            char const *pchNewLine = (const char *)memchr(pchBuffer, '\n', cchToWrite);
    52265318            KU32        cchLine    = pchNewLine ? (KU32)(pchNewLine - pchBuffer) + 1 : cchToWrite;
    52275319            if (cchLine <= pOutBuf->u.Fully.cchBufAlloc - pOutBuf->u.Fully.cchBuf)
     
    52405332                     || pOutBuf->u.Fully.pchBuf[pOutBuf->u.Fully.cchBuf - 1] != '\n')
    52415333            {
     5334                KWOUT_LOG(("kwSandboxOutBufWrite: flushing %u bytes, writing %u bytes\n", pOutBuf->u.Fully.cchBuf, cchLine));
    52425335                if (pOutBuf->u.Fully.cchBuf > 0)
    52435336                {
     
    52525345            else
    52535346            {
     5347                KWOUT_LOG(("kwSandboxOutBufWrite: flushing %u bytes\n", pOutBuf->u.Fully.cchBuf));
    52545348                kwSandboxOutBufWriteIt(pOutBuf->hBackup, pOutBuf->u.Fully.pchBuf, pOutBuf->u.Fully.cchBuf);
    52555349                memcpy(&pOutBuf->u.Fully.pchBuf[0], pchBuffer, cchLine);
     
    52635357    }
    52645358}
    5265 #endif  /* WITH_CONSOLE_OUTPUT_BUFFERING */
     5359
     5360#endif  /* WITH_STD_OUT_ERR_BUFFERING */
    52665361
    52675362#ifdef WITH_TEMP_MEMORY_FILES
    5268 
    52695363static KBOOL kwFsTempFileEnsureSpace(PKWFSTEMPFILE pTempFile, KU32 offFile, KU32 cbNeeded)
    52705364{
     
    53215415    return K_FALSE;
    53225416}
    5323 
    5324 
     5417#endif /* WITH_TEMP_MEMORY_FILES */
     5418
     5419
     5420#if defined(WITH_TEMP_MEMORY_FILES) || defined(WITH_STD_OUT_ERR_BUFFERING)
    53255421/** Kernel32 - WriteFile */
    53265422static BOOL WINAPI kwSandbox_Kernel32_WriteFile(HANDLE hFile, LPCVOID pvBuffer, DWORD cbToWrite, LPDWORD pcbActuallyWritten,
     
    53365432            switch (pHandle->enmType)
    53375433            {
     5434# ifdef WITH_TEMP_MEMORY_FILES
    53385435                case KWHANDLETYPE_TEMP_FILE:
    53395436                {
     
    53905487                    return FALSE;
    53915488                }
     5489# endif
    53925490
    53935491                case KWHANDLETYPE_FSOBJ_READ_CACHE:
     
    53965494                    *pcbActuallyWritten = 0;
    53975495                    return FALSE;
     5496
     5497# if defined(WITH_STD_OUT_ERR_BUFFERING) || defined(WITH_CONSOLE_OUTPUT_BUFFERING)
     5498                /*
     5499                 * Standard output & error.
     5500                 */
     5501                case KWHANDLETYPE_OUTPUT_BUF:
     5502                {
     5503                    PKWOUTPUTSTREAMBUF pOutBuf = pHandle->u.pOutBuf;
     5504                    if (pOutBuf->fIsConsole)
     5505                    {
     5506                        kwSandboxConsoleWriteA(&g_Sandbox, pOutBuf, (const char *)pvBuffer, cbToWrite);
     5507                        KWOUT_LOG(("WriteFile(%p [console]) -> TRUE\n", hFile));
     5508                    }
     5509                    else
     5510                    {
     5511#  ifdef WITH_STD_OUT_ERR_BUFFERING
     5512                        kwSandboxOutBufWrite(&g_Sandbox, pOutBuf, (const char *)pvBuffer, cbToWrite);
     5513                        KWOUT_LOG(("WriteFile(%p [std%s], 's*.*', %#x) -> TRUE\n", hFile,
     5514                                   pOutBuf == &g_Sandbox.StdErr ? "err" : "out", cbToWrite, cbToWrite, pvBuffer, cbToWrite));
     5515#  else
     5516                        kHlpAssertFailed();
     5517#  endif
     5518                    }
     5519                    if (pcbActuallyWritten)
     5520                        *pcbActuallyWritten = cbToWrite;
     5521                    return TRUE;
     5522                }
     5523# endif
    53985524
    53995525                default:
     
    54075533    }
    54085534
    5409 #ifdef WITH_CONSOLE_OUTPUT_BUFFERING
    5410     /*
    5411      * Check for stdout and stderr.
    5412      */
    5413     if (   g_Sandbox.StdErr.hOutput == hFile
    5414         || g_Sandbox.StdOut.hOutput == hFile)
    5415     {
    5416         PKWCONSOLEOUTPUTLINE pLineBuf = g_Sandbox.StdErr.hOutput == hFile ? &g_Sandbox.StdErr : &g_Sandbox.StdOut;
    5417         if (pLineBuf->fIsConsole)
    5418         {
    5419             kwSandboxConsoleWriteA(&g_Sandbox, pLineBuf, (const char *)pvBuffer, cbToWrite);
    5420             KWFS_LOG(("WriteFile(console) -> TRUE\n", hFile));
    5421             return TRUE;
    5422         }
    5423         kwSandboxOutBufWrite(&g_Sandbox, pLineBuf, (const char *)pvBuffer, cbToWrite);
    5424         KWFS_LOG(("WriteFile(stdout/err) -> TRUE\n", hFile));
    5425         return TRUE;
    5426     }
    5427 #endif
    5428 
    5429     KWFS_LOG(("WriteFile(%p)\n", hFile));
     5535    KWFS_LOG(("WriteFile(%p,,%#x)\n", hFile, cbToWrite));
    54305536    return WriteFile(hFile, pvBuffer, cbToWrite, pcbActuallyWritten, pOverlapped);
    54315537}
     
    54515557}
    54525558
     5559#endif /* WITH_TEMP_MEMORY_FILES || WITH_STD_OUT_ERR_BUFFERING */
     5560
     5561#ifdef WITH_TEMP_MEMORY_FILES
    54535562
    54545563/** Kernel32 - SetEndOfFile; */
     
    54855594                    return FALSE;
    54865595
     5596                case KWHANDLETYPE_OUTPUT_BUF:
     5597                    kHlpAssertFailed();
     5598                    SetLastError(pHandle->u.pOutBuf->fIsConsole ? ERROR_INVALID_OPERATION : ERROR_ACCESS_DENIED);
     5599                    return FALSE;
     5600
    54875601                default:
    54885602                case KWHANDLETYPE_TEMP_FILE_MAPPING:
     
    55185632                    KWFS_LOG(("GetFileType(%p) -> FILE_TYPE_DISK [temp]\n", hFile));
    55195633                    return FILE_TYPE_DISK;
     5634
     5635                case KWHANDLETYPE_OUTPUT_BUF:
     5636                {
     5637                    PKWOUTPUTSTREAMBUF pOutBuf = pHandle->u.pOutBuf;
     5638                    DWORD fRet;
     5639                    if (pOutBuf->fFileType != KU8_MAX)
     5640                    {
     5641                        fRet = (pOutBuf->fFileType & 0xf) | ((pOutBuf->fFileType & (FILE_TYPE_REMOTE >> 8)) << 8);
     5642                        KWFS_LOG(("GetFileType(%p) -> %#x [outbuf]\n", hFile, fRet));
     5643                    }
     5644                    else
     5645                    {
     5646                        fRet = GetFileType(hFile);
     5647                        KWFS_LOG(("GetFileType(%p) -> %#x [outbuf, fallback]\n", hFile, fRet));
     5648                    }
     5649                    return fRet;
     5650                }
     5651
    55205652            }
    55215653        }
     
    55505682                    return pHandle->u.pTempFile->cbFile;
    55515683
     5684                case KWHANDLETYPE_OUTPUT_BUF:
     5685                    /* do default */
     5686                    break;
     5687
    55525688                default:
    55535689                    kHlpAssertFailed();
     
    55845720                    pcbFile->QuadPart = pHandle->u.pTempFile->cbFile;
    55855721                    return TRUE;
     5722
     5723                case KWHANDLETYPE_OUTPUT_BUF:
     5724                    /* do default */
     5725                    break;
    55865726
    55875727                default:
     
    56545794                case KWHANDLETYPE_FSOBJ_READ_CACHE:
    56555795                case KWHANDLETYPE_TEMP_FILE:
     5796                case KWHANDLETYPE_OUTPUT_BUF:
    56565797                    kHlpAssertFailed();
    5657                     SetLastError(ERROR_NOT_ENOUGH_MEMORY);
     5798                    SetLastError(ERROR_INVALID_OPERATION);
    56585799                    return NULL;
    56595800
     
    57495890/** @todo UnmapViewOfFileEx */
    57505891
    5751 
    57525892#endif /* WITH_TEMP_MEMORY_FILES */
     5893
     5894
     5895/** Kernel32 - DuplicateHandle */
     5896static BOOL WINAPI kwSandbox_Kernel32_DuplicateHandle(HANDLE hSrcProc, HANDLE hSrc, HANDLE hDstProc, PHANDLE phNew,
     5897                                                      DWORD dwDesiredAccess, BOOL fInheritHandle, DWORD dwOptions)
     5898{
     5899    BOOL fRet;
     5900
     5901    /*
     5902     * We must catch our handles being duplicated.
     5903     */
     5904    if (hSrcProc == GetCurrentProcess())
     5905    {
     5906        KUPTR const idxHandle = KW_HANDLE_TO_INDEX(hSrc);
     5907        kHlpAssert(GetCurrentThreadId() == g_Sandbox.idMainThread);
     5908        if (idxHandle < g_Sandbox.cHandles)
     5909        {
     5910            PKWHANDLE pHandle = g_Sandbox.papHandles[idxHandle];
     5911            if (pHandle)
     5912            {
     5913                fRet = DuplicateHandle(hSrcProc, hSrc, hDstProc, phNew, dwDesiredAccess, fInheritHandle, dwOptions);
     5914                if (fRet)
     5915                {
     5916                    if (kwSandboxHandleTableEnter(&g_Sandbox, pHandle, *phNew))
     5917                    {
     5918                        pHandle->cRefs++;
     5919                        KWFS_LOG(("DuplicateHandle(%p, %p, %p, , %#x, %d, %#x) -> TRUE, %p [intercepted handle] enmType=%d cRef=%d\n",
     5920                                  hSrcProc, hSrc, hDstProc, dwDesiredAccess, fInheritHandle, dwOptions, *phNew,
     5921                                  pHandle->enmType, pHandle->cRefs));
     5922                    }
     5923                    else
     5924                    {
     5925                        fRet = FALSE;
     5926                        SetLastError(ERROR_NOT_ENOUGH_MEMORY);
     5927                        KWFS_LOG(("DuplicateHandle(%p, %p, %p, , %#x, %d, %#x) -> !FALSE!, %p [intercepted handle] enmType=%d\n",
     5928                                  hSrcProc, hSrc, hDstProc, dwDesiredAccess, fInheritHandle, dwOptions, *phNew, pHandle->enmType));
     5929                    }
     5930                }
     5931                else
     5932                    KWFS_LOG(("DuplicateHandle(%p, %p, %p, , %#x, %d, %#x) -> FALSE [intercepted handle] enmType=%d\n",
     5933                              hSrcProc, hSrc, hDstProc, dwDesiredAccess, fInheritHandle, dwOptions, pHandle->enmType));
     5934                return fRet;
     5935            }
     5936        }
     5937    }
     5938
     5939    /*
     5940     * Not one of ours, just do what the caller asks and log it.
     5941     */
     5942    fRet = DuplicateHandle(hSrcProc, hSrc, hDstProc, phNew, dwDesiredAccess, fInheritHandle, dwOptions);
     5943    KWFS_LOG(("DuplicateHandle(%p, %p, %p, , %#x, %d, %#x) -> %d, %p\n", hSrcProc, hSrc, hDstProc, dwDesiredAccess,
     5944              fInheritHandle, dwOptions, fRet, *phNew));
     5945    return fRet;
     5946}
     5947
    57535948
    57545949/** Kernel32 - CloseHandle */
     
    57585953    KUPTR const idxHandle = KW_HANDLE_TO_INDEX(hObject);
    57595954    kHlpAssert(GetCurrentThreadId() == g_Sandbox.idMainThread);
    5760     if (   idxHandle < g_Sandbox.cHandles
    5761         && g_Sandbox.papHandles[idxHandle] != NULL)
    5762     {
    5763         fRet = CloseHandle(hObject);
    5764         if (fRet)
    5765         {
    5766             PKWHANDLE pHandle = g_Sandbox.papHandles[idxHandle];
    5767             g_Sandbox.papHandles[idxHandle] = NULL;
    5768             g_Sandbox.cActiveHandles--;
     5955    if (idxHandle < g_Sandbox.cHandles)
     5956    {
     5957        PKWHANDLE pHandle = g_Sandbox.papHandles[idxHandle];
     5958        if (pHandle)
     5959        {
     5960            /* Prevent the closing of the standard output and error handles. */
     5961            if (   pHandle->enmType != KWHANDLETYPE_OUTPUT_BUF
     5962                || idxHandle != KW_HANDLE_TO_INDEX(pHandle->hHandle))
     5963            {
     5964                fRet = CloseHandle(hObject);
     5965                if (fRet)
     5966                {
     5967                    PKWHANDLE pHandle = g_Sandbox.papHandles[idxHandle];
     5968                    g_Sandbox.papHandles[idxHandle] = NULL;
     5969                    g_Sandbox.cActiveHandles--;
     5970                    kHlpAssert(g_Sandbox.cActiveHandles >= g_Sandbox.cFixedHandles);
     5971                    if (--pHandle->cRefs == 0)
     5972                    {
    57695973#ifdef WITH_TEMP_MEMORY_FILES
    5770             if (pHandle->enmType == KWHANDLETYPE_TEMP_FILE)
    5771             {
    5772                 kHlpAssert(pHandle->u.pTempFile->cActiveHandles > 0);
    5773                 pHandle->u.pTempFile->cActiveHandles--;
    5774             }
     5974                        if (pHandle->enmType == KWHANDLETYPE_TEMP_FILE)
     5975                        {
     5976                            kHlpAssert(pHandle->u.pTempFile->cActiveHandles > 0);
     5977                            pHandle->u.pTempFile->cActiveHandles--;
     5978                        }
    57755979#endif
    5776             kHlpFree(pHandle);
    5777             KWFS_LOG(("CloseHandle(%p) -> TRUE [intercepted handle]\n", hObject));
    5778         }
    5779         else
    5780             KWFS_LOG(("CloseHandle(%p) -> FALSE [intercepted handle] err=%u!\n", hObject, GetLastError()));
    5781     }
    5782     else
    5783     {
    5784         KWFS_LOG(("CloseHandle(%p)\n", hObject));
    5785         fRet = CloseHandle(hObject);
    5786     }
     5980                        kHlpFree(pHandle);
     5981                        KWFS_LOG(("CloseHandle(%p) -> TRUE [intercepted handle, freed]\n", hObject));
     5982                    }
     5983                    else
     5984                        KWFS_LOG(("CloseHandle(%p) -> TRUE [intercepted handle, not freed]\n", hObject));
     5985                }
     5986                else
     5987                    KWFS_LOG(("CloseHandle(%p) -> FALSE [intercepted handle] err=%u!\n", hObject, GetLastError()));
     5988            }
     5989            else
     5990            {
     5991                KWFS_LOG(("CloseHandle(%p) -> TRUE [intercepted handle] Ignored closing of std%s!\n",
     5992                          hObject, hObject == g_Sandbox.StdErr.hOutput ? "err" : "out"));
     5993                fRet = TRUE;
     5994            }
     5995            return fRet;
     5996        }
     5997    }
     5998
     5999    fRet = CloseHandle(hObject);
     6000    KWFS_LOG(("CloseHandle(%p) -> %d\n", hObject, fRet));
    57876001    return fRet;
    57886002}
     
    59886202    if (pSandbox->Combined.cwcBuf > 0)
    59896203    {
     6204        KWOUT_LOG(("kwSandboxConsoleFlushCombined: %u wchars\n", pSandbox->Combined.cwcBuf));
    59906205        kwSandboxConsoleWriteIt(pSandbox, pSandbox->Combined.wszBuf, pSandbox->Combined.cwcBuf);
    59916206        pSandbox->Combined.cwcBuf = 0;
     
    60256240 * @param   pSandbox            The sandbox.
    60266241 * @param   pLineBuf            The line buffer.
    6027  */
    6028 static void kwSandboxConsoleFinalFlushLineBuf(PKWSANDBOX pSandbox, PKWCONSOLEOUTPUTLINE pLineBuf)
     6242 * @param   pszName             The line buffer name (for logging)
     6243 */
     6244static void kwSandboxConsoleFinalFlushLineBuf(PKWSANDBOX pSandbox, PKWOUTPUTSTREAMBUF pLineBuf, const char *pszName)
    60296245{
    60306246    if (pLineBuf->fIsConsole)
     
    60326248        if (pLineBuf->u.Con.cwcBuf > 0)
    60336249        {
     6250            KWOUT_LOG(("kwSandboxConsoleFinalFlushLineBuf: %s: %u wchars\n", pszName, pLineBuf->u.Con.cwcBuf));
     6251
    60346252            if (pLineBuf->u.Con.cwcBuf < pLineBuf->u.Con.cwcBufAlloc)
    60356253            {
     
    60456263        }
    60466264    }
     6265#ifdef WITH_STD_OUT_ERR_BUFFERING
    60476266    else if (pLineBuf->u.Fully.cchBuf > 0)
    60486267    {
     6268        KWOUT_LOG(("kwSandboxConsoleFinalFlushLineBuf: %s: %u bytes\n", pszName, pLineBuf->u.Fully.cchBuf));
     6269
    60496270        kwSandboxOutBufWriteIt(pLineBuf->hBackup, pLineBuf->u.Fully.pchBuf, pLineBuf->u.Fully.cchBuf);
    60506271        pLineBuf->u.Fully.cchBuf = 0;
    60516272    }
     6273#endif
    60526274}
    60536275
     
    60926314                    if (fOk)
    60936315                    {
     6316                        KWOUT_LOG(("kwSandboxConsoleFlushAll: Dropping '%*.*ls in combined console buffer\n",
     6317                                   pSandbox->Combined.cwcBuf, pSandbox->Combined.cwcBuf, pSandbox->Combined.wszBuf));
    60946318                        pSandbox->Combined.cwcBuf = 0;
    60956319                        return;
    60966320                    }
    60976321                }
    6098             }
    6099         }
     6322                KWOUT_LOG(("kwSandboxConsoleFlushAll: Unable to drop '%*.*ls in combined console buffer\n",
     6323                           pSandbox->Combined.cwcBuf, pSandbox->Combined.cwcBuf, pSandbox->Combined.wszBuf));
     6324            }
     6325        }
     6326#ifdef WITH_STD_OUT_ERR_BUFFERING
    61006327        /*
    6101          * Otherwise, it goes to standard error.
     6328         * Otherwise, it goes to standard output (redirected).
    61026329         */
    6103         else if (   pSandbox->StdOut.u.Fully.cchBuf == 0
    6104                  && pSandbox->StdErr.u.Fully.cchBuf >= 3)
    6105         {
    6106             char const *pchBuf = pSandbox->StdErr.u.Fully.pchBuf;
    6107             KI32        off    = pSandbox->StdErr.u.Fully.cchBuf - 1;
     6330        else if (   pSandbox->StdErr.u.Fully.cchBuf == 0
     6331                 && pSandbox->StdOut.u.Fully.cchBuf >= 3)
     6332        {
     6333            char const *pchBuf = pSandbox->StdOut.u.Fully.pchBuf;
     6334            KI32        off    = pSandbox->StdOut.u.Fully.cchBuf - 1;
    61086335            kHlpAssert(pSandbox->Combined.cFlushes == 0 && pSandbox->Combined.cwcBuf == 0); /* unused! */
    61096336
     
    61266353                if (fOk)
    61276354                {
    6128                     pSandbox->StdErr.u.Fully.cchBuf = 0;
     6355                    KWOUT_LOG(("kwSandboxConsoleFlushAll: Dropping '%*.*s in stdout buffer\n",
     6356                               pSandbox->StdOut.u.Fully.cchBuf, pSandbox->StdOut.u.Fully.cchBuf, pchBuf));
     6357                    pSandbox->StdOut.u.Fully.cchBuf = 0;
    61296358                    return;
    61306359                }
    61316360            }
    6132         }
     6361            KWOUT_LOG(("kwSandboxConsoleFlushAll: Unable to drop '%*.*s in stdout buffer\n",
     6362                       pSandbox->StdOut.u.Fully.cchBuf, pSandbox->StdOut.u.Fully.cchBuf, pchBuf));
     6363        }
     6364#endif
    61336365    }
    61346366
     
    61366368     * Flush the two line buffer, the the combined buffer.
    61376369     */
    6138     kwSandboxConsoleFinalFlushLineBuf(pSandbox, &pSandbox->StdErr);
    6139     kwSandboxConsoleFinalFlushLineBuf(pSandbox, &pSandbox->StdOut);
     6370    kwSandboxConsoleFinalFlushLineBuf(pSandbox, &pSandbox->StdErr, "StdErr");
     6371    kwSandboxConsoleFinalFlushLineBuf(pSandbox, &pSandbox->StdOut, "StdOut");
    61406372    kwSandboxConsoleFlushCombined(pSandbox);
    61416373}
     
    61506382 * @param   cwcToWrite          The number of wchar_t's in the buffer.
    61516383 */
    6152 static void kwSandboxConsoleWriteW(PKWSANDBOX pSandbox, PKWCONSOLEOUTPUTLINE pLineBuf, wchar_t const *pwcBuffer, KU32 cwcToWrite)
     6384static void kwSandboxConsoleWriteW(PKWSANDBOX pSandbox, PKWOUTPUTSTREAMBUF pLineBuf, wchar_t const *pwcBuffer, KU32 cwcToWrite)
    61536385{
    61546386    kHlpAssert(pLineBuf->fIsConsole);
     
    63166548 * @param   cchToWrite          How much to write.
    63176549 */
    6318 static void kwSandboxConsoleWriteA(PKWSANDBOX pSandbox, PKWCONSOLEOUTPUTLINE pLineBuf, const char *pchBuffer, KU32 cchToWrite)
     6550static void kwSandboxConsoleWriteA(PKWSANDBOX pSandbox, PKWOUTPUTSTREAMBUF pLineBuf, const char *pchBuffer, KU32 cchToWrite)
    63196551{
    63206552    /*
     
    63746606                                             PVOID pvReserved)
    63756607{
    6376     BOOL                    fRc;
    6377     PKWCONSOLEOUTPUTLINE    pLineBuf;
     6608    BOOL                fRc;
     6609    PKWOUTPUTSTREAMBUF  pLineBuf;
    63786610    kHlpAssert(GetCurrentThreadId() == g_Sandbox.idMainThread);
    63796611
     
    63866618        kwSandboxConsoleWriteA(&g_Sandbox, pLineBuf, (char const *)pvBuffer, cbToWrite);
    63876619
    6388         KWFS_LOG(("WriteConsoleA: %p, %p LB %#x (%*.*s), %p, %p -> TRUE [cached]\n",
    6389                   hConOutput, pvBuffer, cbToWrite, cbToWrite, cbToWrite, pvBuffer, pcbWritten, pvReserved));
     6620        KWOUT_LOG(("WriteConsoleA: %p, %p LB %#x (%*.*s), %p, %p -> TRUE [cached]\n",
     6621                   hConOutput, pvBuffer, cbToWrite, cbToWrite, cbToWrite, pvBuffer, pcbWritten, pvReserved));
    63906622        if (pcbWritten)
    63916623            *pcbWritten = cbToWrite;
     
    63956627    {
    63966628        fRc = WriteConsoleA(hConOutput, pvBuffer, cbToWrite, pcbWritten, pvReserved);
    6397         KWFS_LOG(("WriteConsoleA: %p, %p LB %#x (%*.*s), %p, %p -> %d !fallback!\n",
    6398                   hConOutput, pvBuffer, cbToWrite, cbToWrite, cbToWrite, pvBuffer, pcbWritten, pvReserved, fRc));
     6629        KWOUT_LOG(("WriteConsoleA: %p, %p LB %#x (%*.*s), %p, %p -> %d !fallback!\n",
     6630                   hConOutput, pvBuffer, cbToWrite, cbToWrite, cbToWrite, pvBuffer, pcbWritten, pvReserved, fRc));
    63996631    }
    64006632    return fRc;
     
    64066638                                             PVOID pvReserved)
    64076639{
    6408     BOOL                    fRc;
    6409     PKWCONSOLEOUTPUTLINE    pLineBuf;
     6640    BOOL                fRc;
     6641    PKWOUTPUTSTREAMBUF  pLineBuf;
    64106642    kHlpAssert(GetCurrentThreadId() == g_Sandbox.idMainThread);
    64116643
     
    64206652        kwSandboxConsoleWriteW(&g_Sandbox, pLineBuf, (wchar_t const *)pvBuffer, cwcToWrite);
    64216653
    6422         KWFS_LOG(("WriteConsoleW: %p, %p LB %#x (%*.*ls), %p, %p -> TRUE [cached]\n",
    6423                   hConOutput, pvBuffer, cwcToWrite, cwcToWrite, cwcToWrite, pvBuffer, pcwcWritten, pvReserved));
     6654        KWOUT_LOG(("WriteConsoleW: %p, %p LB %#x (%*.*ls), %p, %p -> TRUE [cached]\n",
     6655                   hConOutput, pvBuffer, cwcToWrite, cwcToWrite, cwcToWrite, pvBuffer, pcwcWritten, pvReserved));
    64246656        if (pcwcWritten)
    64256657            *pcwcWritten = cwcToWrite;
     
    64296661    {
    64306662        fRc = WriteConsoleW(hConOutput, pvBuffer, cwcToWrite, pcwcWritten, pvReserved);
    6431         KWFS_LOG(("WriteConsoleW: %p, %p LB %#x (%*.*ls), %p, %p -> %d !fallback!\n",
    6432                   hConOutput, pvBuffer, cwcToWrite, cwcToWrite, cwcToWrite, pvBuffer, pcwcWritten, pvReserved, fRc));
     6663        KWOUT_LOG(("WriteConsoleW: %p, %p LB %#x (%*.*ls), %p, %p -> %d !fallback!\n",
     6664                   hConOutput, pvBuffer, cwcToWrite, cwcToWrite, cwcToWrite, pvBuffer, pcwcWritten, pvReserved, fRc));
    64336665    }
    64346666    return fRc;
     
    71287360    { TUPLE("SetFilePointer"),              NULL,       (KUPTR)kwSandbox_Kernel32_SetFilePointer },
    71297361    { TUPLE("SetFilePointerEx"),            NULL,       (KUPTR)kwSandbox_Kernel32_SetFilePointerEx },
     7362    { TUPLE("DuplicateHandle"),             NULL,       (KUPTR)kwSandbox_Kernel32_DuplicateHandle },
    71307363    { TUPLE("CloseHandle"),                 NULL,       (KUPTR)kwSandbox_Kernel32_CloseHandle },
    71317364    { TUPLE("GetFileAttributesA"),          NULL,       (KUPTR)kwSandbox_Kernel32_GetFileAttributesA },
     
    72517484    { TUPLE("SetFilePointer"),              NULL,       (KUPTR)kwSandbox_Kernel32_SetFilePointer },
    72527485    { TUPLE("SetFilePointerEx"),            NULL,       (KUPTR)kwSandbox_Kernel32_SetFilePointerEx },
     7486    { TUPLE("DuplicateHandle"),             NULL,       (KUPTR)kwSandbox_Kernel32_DuplicateHandle },
    72537487    { TUPLE("CloseHandle"),                 NULL,       (KUPTR)kwSandbox_Kernel32_CloseHandle },
    72547488    { TUPLE("GetFileAttributesA"),          NULL,       (KUPTR)kwSandbox_Kernel32_GetFileAttributesA },
     
    74667700 * @param   pSandbox            The sandbox.
    74677701 * @param   pHandle             The handle.
    7468  */
    7469 static KBOOL kwSandboxHandleTableEnter(PKWSANDBOX pSandbox, PKWHANDLE pHandle)
    7470 {
    7471     KUPTR const idxHandle = KW_HANDLE_TO_INDEX(pHandle->hHandle);
     7702 * @param   hHandle             The handle value to enter it under (for the
     7703 *                              duplicate handle API).
     7704 */
     7705static KBOOL kwSandboxHandleTableEnter(PKWSANDBOX pSandbox, PKWHANDLE pHandle, HANDLE hHandle)
     7706{
     7707    KUPTR const idxHandle = KW_HANDLE_TO_INDEX(hHandle);
    74727708    kHlpAssertReturn(idxHandle < KW_HANDLE_MAX, K_FALSE);
    74737709
     
    75627798{
    75637799    PPEB pPeb = kwSandboxGetProcessEnvironmentBlock();
     7800    PMY_RTL_USER_PROCESS_PARAMETERS pProcParams = (PMY_RTL_USER_PROCESS_PARAMETERS)pPeb->ProcessParameters;
    75647801    wchar_t *pwcPool;
    75657802    KSIZE cbStrings;
     
    75777814#ifdef WITH_CONSOLE_OUTPUT_BUFFERING
    75787815    if (pSandbox->StdOut.fIsConsole)
    7579         pSandbox->StdOut.u.Con.cwcBuf = 0;
     7816        pSandbox->StdOut.u.Con.cwcBuf   = 0;
    75807817    else
    75817818        pSandbox->StdOut.u.Fully.cchBuf = 0;
    75827819    if (pSandbox->StdErr.fIsConsole)
    7583         pSandbox->StdErr.u.Con.cwcBuf = 0;
     7820        pSandbox->StdErr.u.Con.cwcBuf   = 0;
    75847821    else
    75857822        pSandbox->StdErr.u.Fully.cchBuf = 0;
    7586     pSandbox->Combined.cwcBuf = 0;
     7823    pSandbox->Combined.cwcBuf   = 0;
    75877824    pSandbox->Combined.cFlushes = 0;
    75887825#endif
     
    76207857    cwc = kwStrToUtf16(pSandbox->pszCmdLine, pSandbox->pwszCmdLine, cbStrings / sizeof(wchar_t));
    76217858
    7622     pSandbox->SavedCommandLine = pPeb->ProcessParameters->CommandLine;
    7623     pPeb->ProcessParameters->CommandLine.Buffer = pSandbox->pwszCmdLine;
    7624     pPeb->ProcessParameters->CommandLine.Length = (USHORT)cwc * sizeof(wchar_t);
     7859    pSandbox->SavedCommandLine = pProcParams->CommandLine;
     7860    pProcParams->CommandLine.Buffer = pSandbox->pwszCmdLine;
     7861    pProcParams->CommandLine.Length = (USHORT)cwc * sizeof(wchar_t);
    76257862
    76267863    /*
     
    76977934    PKWEXITCALLACK              pExitCallback;
    76987935
    7699 
    77007936    /*
    77017937     * First stuff that may cause code to run.
     
    77527988     * Then free resources associated with the sandbox run.
    77537989     */
     7990
     7991    /* Open handles, except fixed handles (stdout and stderr). */
     7992    if (pSandbox->cActiveHandles > pSandbox->cFixedHandles)
     7993    {
     7994        KU32 idxHandle = pSandbox->cHandles;
     7995        while (idxHandle-- > 0)
     7996            if (pSandbox->papHandles[idxHandle] == NULL)
     7997            { /* likely */ }
     7998            else
     7999            {
     8000                PKWHANDLE pHandle = pSandbox->papHandles[idxHandle];
     8001                if (   pHandle->enmType != KWHANDLETYPE_OUTPUT_BUF
     8002                    || idxHandle != KW_HANDLE_TO_INDEX(pHandle->hHandle) )
     8003                {
     8004                    pSandbox->papHandles[idxHandle] = NULL;
     8005                    pSandbox->cLeakedHandles++;
     8006
     8007                    switch (pHandle->enmType)
     8008                    {
     8009                        case KWHANDLETYPE_FSOBJ_READ_CACHE:
     8010                            KWFS_LOG(("Closing leaked read cache handle: %#x/%p cRefs=%d\n",
     8011                                      idxHandle, pHandle->hHandle, pHandle->cRefs));
     8012                            break;
     8013                        case KWHANDLETYPE_OUTPUT_BUF:
     8014                            KWFS_LOG(("Closing leaked output buf handle: %#x/%p cRefs=%d\n",
     8015                                      idxHandle, pHandle->hHandle, pHandle->cRefs));
     8016                            break;
     8017                        case KWHANDLETYPE_TEMP_FILE:
     8018                            KWFS_LOG(("Closing leaked temp file  handle: %#x/%p cRefs=%d\n",
     8019                                      idxHandle, pHandle->hHandle, pHandle->cRefs));
     8020                            pHandle->u.pTempFile->cActiveHandles--;
     8021                            break;
     8022                        case KWHANDLETYPE_TEMP_FILE_MAPPING:
     8023                            KWFS_LOG(("Closing leaked temp mapping handle: %#x/%p cRefs=%d\n",
     8024                                      idxHandle, pHandle->hHandle, pHandle->cRefs));
     8025                            pHandle->u.pTempFile->cActiveHandles--;
     8026                            break;
     8027                        default:
     8028                            kHlpAssertFailed();
     8029                    }
     8030                    if (--pHandle->cRefs == 0)
     8031                        kHlpFree(pHandle);
     8032                    if (--pSandbox->cActiveHandles == pSandbox->cFixedHandles)
     8033                        break;
     8034                }
     8035            }
     8036        kHlpAssert(pSandbox->cActiveHandles == pSandbox->cFixedHandles);
     8037    }
    77548038
    77558039#ifdef WITH_TEMP_MEMORY_FILES
     
    78318115    if (GetProcessMemoryInfo(GetCurrentProcess(), &MemInfo, sizeof(MemInfo)))
    78328116    {
     8117        /** @todo make the limit dynamic and user configurable. */
    78338118#if K_ARCH_BITS >= 64
    78348119        if (MemInfo.WorkingSetSize >= 512*1024*1024)
     
    78388123        {
    78398124            KW_LOG(("WorkingSetSize = %#x - > restart next time.\n", MemInfo.WorkingSetSize));
    7840             //fprintf(stderr, "WorkingSetSize = %#x - > restart next time.\n", MemInfo.WorkingSetSize);
    78418125            g_fRestart = K_TRUE;
    78428126        }
    78438127    }
    7844 }
    7845 
    7846 
     8128
     8129    /*
     8130     * The CRT has a max of 8192 handles, so we better restart after a while if
     8131     * someone is leaking handles or we risk running out of descriptors.
     8132     *
     8133     * Note! We only detect leaks for handles we intercept.  In the case of CL.EXE
     8134     *       doing _dup2(1, 2) (stderr ==> stdout), there isn't actually a leak.
     8135     */
     8136    if (pSandbox->cLeakedHandles > 6000)
     8137    {
     8138        KW_LOG(("LeakedHandles = %#x - > restart next time.\n", pSandbox->cLeakedHandles));
     8139        g_fRestart = K_TRUE;
     8140    }
     8141}
     8142
     8143
     8144/**
     8145 * Does essential cleanups and restoring, anything externally visible.
     8146 *
     8147 * All cleanups that aren't externally visible are postponed till after we've
     8148 * informed kmk of the result, so it can be done in the dead time between jobs.
     8149 *
     8150 * @param   pSandbox            The sandbox.
     8151 */
    78478152static void kwSandboxCleanup(PKWSANDBOX pSandbox)
    78488153{
     
    78518156     */
    78528157    PPEB pPeb = kwSandboxGetProcessEnvironmentBlock();
    7853     pPeb->ProcessParameters->CommandLine = pSandbox->SavedCommandLine;
    7854 
    7855     /*
    7856      * Kill all open handles.
    7857      */
    7858     if (pSandbox->cActiveHandles > 0)
    7859     {
    7860         KU32 i = pSandbox->cHandles;
    7861         while (i-- > 0)
    7862             if (pSandbox->papHandles[i] == NULL)
    7863             { /* likely */ }
    7864             else
    7865             {
    7866                 PKWHANDLE pHandle = pSandbox->papHandles[i];
    7867                 pSandbox->papHandles[i] = NULL;
    7868                 switch (pHandle->enmType)
    7869                 {
    7870                     case KWHANDLETYPE_FSOBJ_READ_CACHE:
    7871                         break;
    7872                     case KWHANDLETYPE_TEMP_FILE:
    7873                     case KWHANDLETYPE_TEMP_FILE_MAPPING:
    7874                         pHandle->u.pTempFile->cActiveHandles--;
    7875                         break;
    7876                     default:
    7877                         kHlpAssertFailed();
    7878                 }
    7879                 kHlpFree(pHandle);
    7880                 if (--pSandbox->cActiveHandles == 0)
    7881                     break;
    7882             }
    7883     }
     8158    PMY_RTL_USER_PROCESS_PARAMETERS pProcParams = (PMY_RTL_USER_PROCESS_PARAMETERS)pPeb->ProcessParameters;
     8159    pProcParams->CommandLine    = pSandbox->SavedCommandLine;
     8160    pProcParams->StandardOutput = pSandbox->StdOut.hOutput;
     8161    pProcParams->StandardError  = pSandbox->StdErr.hOutput; /* CL.EXE messes with this one. */
    78848162}
    78858163
     
    84558733    }
    84568734
     8735# ifdef WITH_LOG_FILE
     8736    if (g_hLogFile != INVALID_HANDLE_VALUE && g_hLogFile != NULL)
     8737        CloseHandle(g_hLogFile);
     8738# endif
    84578739    return rcExit;
    84588740}
     
    84758757    PPEB                            pPeb           = kwSandboxGetProcessEnvironmentBlock();
    84768758    PMY_RTL_USER_PROCESS_PARAMETERS pProcessParams = (PMY_RTL_USER_PROCESS_PARAMETERS)pPeb->ProcessParameters;
     8759    DWORD                           dwType;
    84778760#endif
    84788761
     
    85048787     * Get and duplicate the console handles.
    85058788     */
     8789    /* Standard output. */
    85068790    g_Sandbox.StdOut.hOutput = pProcessParams->StandardOutput;
    85078791    if (!DuplicateHandle(hCurProc, pProcessParams->StandardOutput, hCurProc, &g_Sandbox.StdOut.hBackup,
    85088792                         GENERIC_WRITE, FALSE /*fInherit*/, DUPLICATE_SAME_ACCESS))
    85098793        kHlpAssertFailedStmt(g_Sandbox.StdOut.hBackup = pProcessParams->StandardOutput);
    8510     g_Sandbox.StdOut.fIsConsole = GetFileType(g_Sandbox.StdOut.hOutput) == FILE_TYPE_CHAR;
    8511 
     8794    dwType = GetFileType(g_Sandbox.StdOut.hOutput);
     8795    g_Sandbox.StdOut.fIsConsole = dwType == FILE_TYPE_CHAR;
     8796    g_Sandbox.StdOut.fFileType  = (dwType & ~FILE_TYPE_REMOTE) < 0xf
     8797                                ? (KU8)((dwType & ~FILE_TYPE_REMOTE) | (dwType >> 8)) : KU8_MAX;
     8798    g_Sandbox.HandleStdOut.enmType         = KWHANDLETYPE_OUTPUT_BUF;
     8799    g_Sandbox.HandleStdOut.cRefs           = 0x10001;
     8800    g_Sandbox.HandleStdOut.dwDesiredAccess = GENERIC_WRITE;
     8801    g_Sandbox.HandleStdOut.u.pOutBuf       = &g_Sandbox.StdOut;
     8802    g_Sandbox.HandleStdOut.hHandle         = g_Sandbox.StdOut.hOutput;
     8803    if (g_Sandbox.StdOut.hOutput != INVALID_HANDLE_VALUE)
     8804    {
     8805        if (kwSandboxHandleTableEnter(&g_Sandbox, &g_Sandbox.HandleStdOut, g_Sandbox.StdOut.hOutput))
     8806            g_Sandbox.cFixedHandles++;
     8807        else
     8808            return kwErrPrintfRc(3, "kwSandboxHandleTableEnter failed for StdOut (%p)!\n", g_Sandbox.StdOut.hOutput);
     8809    }
     8810    KWOUT_LOG(("StdOut: hOutput=%p (%p) fIsConsole=%d dwType=%#x\n",
     8811               g_Sandbox.StdOut.hOutput, g_Sandbox.StdOut.hBackup, g_Sandbox.StdOut.fIsConsole, dwType));
     8812
     8813    /* Standard error. */
    85128814    g_Sandbox.StdErr.hOutput = pProcessParams->StandardError;
    85138815    if (!DuplicateHandle(hCurProc, pProcessParams->StandardError, hCurProc, &g_Sandbox.StdErr.hBackup,
    85148816                         GENERIC_WRITE, FALSE /*fInherit*/, DUPLICATE_SAME_ACCESS))
    85158817        kHlpAssertFailedStmt(g_Sandbox.StdErr.hBackup = pProcessParams->StandardError);
    8516     g_Sandbox.StdErr.fIsConsole = GetFileType(g_Sandbox.StdErr.hOutput) == FILE_TYPE_CHAR;
    8517 
     8818    dwType = GetFileType(g_Sandbox.StdErr.hOutput);
     8819    g_Sandbox.StdErr.fIsConsole = dwType == FILE_TYPE_CHAR;
     8820    g_Sandbox.StdErr.fFileType  = (dwType & ~FILE_TYPE_REMOTE) < 0xf
     8821                                ? (KU8)((dwType & ~FILE_TYPE_REMOTE) | (dwType >> 8)) : KU8_MAX;
     8822    g_Sandbox.HandleStdErr.enmType         = KWHANDLETYPE_OUTPUT_BUF;
     8823    g_Sandbox.HandleStdErr.cRefs           = 0x10001;
     8824    g_Sandbox.HandleStdErr.dwDesiredAccess = GENERIC_WRITE;
     8825    g_Sandbox.HandleStdErr.u.pOutBuf       = &g_Sandbox.StdErr;
     8826    g_Sandbox.HandleStdErr.hHandle         = g_Sandbox.StdErr.hOutput;
     8827    if (   g_Sandbox.StdErr.hOutput != INVALID_HANDLE_VALUE
     8828        && g_Sandbox.StdErr.hOutput != g_Sandbox.StdOut.hOutput)
     8829    {
     8830        if (kwSandboxHandleTableEnter(&g_Sandbox, &g_Sandbox.HandleStdErr, g_Sandbox.StdErr.hOutput))
     8831            g_Sandbox.cFixedHandles++;
     8832        else
     8833            return kwErrPrintfRc(3, "kwSandboxHandleTableEnter failed for StdErr (%p)!\n", g_Sandbox.StdErr.hOutput);
     8834    }
     8835    KWOUT_LOG(("StdErr: hOutput=%p (%p) fIsConsole=%d dwType=%#x\n",
     8836               g_Sandbox.StdErr.hOutput, g_Sandbox.StdErr.hBackup, g_Sandbox.StdErr.fIsConsole, dwType));
     8837
     8838    /* Combined console buffer. */
    85188839    if (g_Sandbox.StdErr.fIsConsole)
    85198840    {
     
    85318852        g_Sandbox.Combined.uCodepage = CP_ACP;
    85328853    }
    8533 #endif
     8854    KWOUT_LOG(("Combined: hOutput=%p uCodepage=%d\n", g_Sandbox.Combined.hOutput, g_Sandbox.Combined.uCodepage));
     8855#endif /* WITH_CONSOLE_OUTPUT_BUFFERING */
    85348856
    85358857
     
    86748996
    86758997        CloseHandle(hPipe);
     8998# ifdef WITH_LOG_FILE
     8999        if (g_hLogFile != INVALID_HANDLE_VALUE && g_hLogFile != NULL)
     9000            CloseHandle(g_hLogFile);
     9001# endif
    86769002        return rc > 0 ? 0 : 1;
    86779003    }
Note: See TracChangeset for help on using the changeset viewer.