- Timestamp:
- Sep 15, 2016, 1:41:42 PM (9 years ago)
- Location:
- trunk/src
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/kWorker/kWorker.c
r2915 r2916 32 32 *********************************************************************************************************************************/ 33 33 //#undef NDEBUG 34 //#define K_STRICT 1 35 //#define KW_LOG_ENABLED 36 34 37 #define PSAPI_VERSION 1 35 38 #include <k/kHlp.h> … … 75 78 #define WITH_CONSOLE_OUTPUT_BUFFERING 76 79 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 80 93 81 94 /** @def KW_LOG 82 95 * Generic logging. 83 96 * @param a Argument list for kwDbgPrintf */ 84 #if ndef NDEBUG97 #ifdef KW_LOG_ENABLED 85 98 # define KW_LOG(a) kwDbgPrintf a 86 99 #else … … 91 104 * FS cache logging. 92 105 * @param a Argument list for kwDbgPrintf */ 93 #if ndef NDEBUG106 #ifdef KW_LOG_ENABLED 94 107 # define KWFS_LOG(a) kwDbgPrintf a 95 108 #else … … 97 110 #endif 98 111 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 99 121 /** @def KWCRYPT_LOG 100 122 * FS cache logging. 101 123 * @param a Argument list for kwDbgPrintf */ 102 #if ndef NDEBUG124 #ifdef KW_LOG_ENABLED 103 125 # define KWCRYPT_LOG(a) kwDbgPrintf a 104 126 #else … … 123 145 /** Marks unfinished code. */ 124 146 #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) 126 148 #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) 128 150 #endif 129 151 … … 132 154 /** User data key for a cached file. */ 133 155 #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 134 159 135 160 … … 356 381 * Console line buffer or output full buffer. 357 382 */ 358 typedef struct KW CONSOLEOUTPUTLINE383 typedef struct KWOUTPUTSTREAMBUF 359 384 { 360 385 /** The main output handle. */ … … 366 391 * boundraries when ever possible. */ 367 392 KBOOL fIsConsole; 368 KU8 abPadding[3]; 393 /** Compressed GetFileType result. */ 394 KU8 fFileType; 395 KU8 abPadding[2]; 369 396 union 370 397 { … … 384 411 /** Amount of pending output (in chars). */ 385 412 KU32 cchBuf; 413 #ifdef WITH_STD_OUT_ERR_BUFFERING 386 414 /** The allocated buffer size (in chars). */ 387 415 KU32 cchBufAlloc; 388 416 /** Pending output. */ 389 417 char *pchBuf; 418 #endif 390 419 } Fully; 391 420 } u; 392 } KW CONSOLEOUTPUTLINE;421 } KWOUTPUTSTREAMBUF; 393 422 /** Pointer to a console line buffer. */ 394 typedef KW CONSOLEOUTPUTLINE *PKWCONSOLEOUTPUTLINE;423 typedef KWOUTPUTSTREAMBUF *PKWOUTPUTSTREAMBUF; 395 424 396 425 /** … … 423 452 KWHANDLETYPE_FSOBJ_READ_CACHE, 424 453 KWHANDLETYPE_TEMP_FILE, 425 KWHANDLETYPE_TEMP_FILE_MAPPING 426 //KWHANDLETYPE_CONSOLE_CACHE454 KWHANDLETYPE_TEMP_FILE_MAPPING, 455 KWHANDLETYPE_OUTPUT_BUF 427 456 } KWHANDLETYPE; 428 457 … … 431 460 { 432 461 KWHANDLETYPE enmType; 462 /** Number of references */ 463 KU32 cRefs; 433 464 /** The current file offset. */ 434 465 KU32 offFile; … … 445 476 /** Temporary file handle or mapping handle. */ 446 477 PKWFSTEMPFILE pTempFile; 478 #ifdef WITH_CONSOLE_OUTPUT_BUFFERING 479 /** Buffered output stream. */ 480 PKWOUTPUTSTREAMBUF pOutBuf; 481 #endif 447 482 } u; 448 483 } KWHANDLE; … … 618 653 /** Number of active handles in the table. */ 619 654 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; 620 659 621 660 /** Head of the list of temporary file. */ … … 636 675 PKWEXITCALLACK pExitCallbackHead; 637 676 638 UNICODE_STRINGSavedCommandLine;677 MY_UNICODE_STRING SavedCommandLine; 639 678 640 679 #ifdef WITH_HASH_MD5_CACHE … … 661 700 662 701 #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; 667 710 /** Combined buffer of completed lines. */ 668 711 KWCONSOLEOUTPUT Combined; … … 749 792 static KU8 g_abDefLdBuf[16*1024*1024]; 750 793 794 #ifdef WITH_LOG_FILE 795 /** Log file handle. */ 796 static HANDLE g_hLogFile = INVALID_HANDLE_VALUE; 797 #endif 751 798 752 799 … … 756 803 static FNKLDRMODGETIMPORT kwLdrModuleGetImportCallback; 757 804 static int kwLdrModuleResolveAndLookup(const char *pszName, PKWMODULE pExe, PKWMODULE pImporter, PKWMODULE *ppMod); 758 static KBOOL kwSandboxHandleTableEnter(PKWSANDBOX pSandbox, PKWHANDLE pHandle );805 static KBOOL kwSandboxHandleTableEnter(PKWSANDBOX pSandbox, PKWHANDLE pHandle, HANDLE hHandle); 759 806 #ifdef WITH_CONSOLE_OUTPUT_BUFFERING 760 static void kwSandboxConsoleWriteA(PKWSANDBOX pSandbox, PKW CONSOLEOUTPUTLINEpLineBuf, const char *pchBuffer, KU32 cchToWrite);807 static void kwSandboxConsoleWriteA(PKWSANDBOX pSandbox, PKWOUTPUTSTREAMBUF pLineBuf, const char *pchBuffer, KU32 cchToWrite); 761 808 #endif 762 809 … … 773 820 { 774 821 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 776 845 fprintf(stderr, "debug: "); 777 846 vfprintf(stderr, pszFormat, va); 847 #endif 778 848 779 849 SetLastError(dwSavedErr); … … 4265 4335 { 4266 4336 pHandle->enmType = !fMapping ? KWHANDLETYPE_TEMP_FILE : KWHANDLETYPE_TEMP_FILE_MAPPING; 4337 pHandle->cRefs = 1; 4267 4338 pHandle->offFile = 0; 4268 4339 pHandle->hHandle = hFile; 4269 4340 pHandle->dwDesiredAccess = dwDesiredAccess; 4270 4341 pHandle->u.pTempFile = pTempFile; 4271 if (kwSandboxHandleTableEnter(&g_Sandbox, pHandle ))4342 if (kwSandboxHandleTableEnter(&g_Sandbox, pHandle, hFile)) 4272 4343 { 4273 4344 pTempFile->cActiveHandles++; … … 4685 4756 { 4686 4757 pHandle->enmType = KWHANDLETYPE_FSOBJ_READ_CACHE; 4758 pHandle->cRefs = 1; 4687 4759 pHandle->offFile = 0; 4688 4760 pHandle->hHandle = *phFile; 4689 4761 pHandle->dwDesiredAccess = dwDesiredAccess; 4690 4762 pHandle->u.pCachedFile = pCachedFile; 4691 if (kwSandboxHandleTableEnter(&g_Sandbox, pHandle ))4763 if (kwSandboxHandleTableEnter(&g_Sandbox, pHandle, pHandle->hHandle)) 4692 4764 return K_TRUE; 4693 4765 … … 4773 4845 } 4774 4846 4847 /* 4848 * Okay, normal. 4849 */ 4775 4850 hFile = CreateFileA(pszFilename, dwDesiredAccess, dwShareMode, pSecAttrs, 4776 4851 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 } 4777 4857 KWFS_LOG(("CreateFileA(%s) -> %p\n", pszFilename, hFile)); 4778 4858 return hFile; … … 4834 4914 else 4835 4915 KWFS_LOG(("CreateFileW: incompatible disposition %u\n", dwCreationDisposition)); 4916 4917 /* 4918 * Okay, normal. 4919 */ 4836 4920 hFile = CreateFileW(pwszFilename, dwDesiredAccess, dwShareMode, pSecAttrs, 4837 4921 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 } 4838 4927 KWFS_LOG(("CreateFileW(%ls) -> %p\n", pwszFilename, hFile)); 4839 4928 return hFile; … … 4862 4951 cbFile = pHandle->u.pTempFile->cbFile; 4863 4952 break; 4953 #endif 4864 4954 case KWHANDLETYPE_TEMP_FILE_MAPPING: 4865 #endif 4955 case KWHANDLETYPE_OUTPUT_BUF: 4866 4956 default: 4867 4957 kHlpAssertFailed(); … … 4943 5033 cbFile = pHandle->u.pTempFile->cbFile; 4944 5034 break; 5035 #endif 4945 5036 case KWHANDLETYPE_TEMP_FILE_MAPPING: 4946 #endif 5037 case KWHANDLETYPE_OUTPUT_BUF: 4947 5038 default: 4948 5039 kHlpAssertFailed(); … … 5100 5191 return TRUE; 5101 5192 } 5193 #endif /* WITH_TEMP_MEMORY_FILES */ 5102 5194 5103 5195 case KWHANDLETYPE_TEMP_FILE_MAPPING: 5104 #endif /* WITH_TEMP_MEMORY_FILES */ 5196 case KWHANDLETYPE_OUTPUT_BUF: 5105 5197 default: 5106 5198 kHlpAssertFailed(); … … 5136 5228 } 5137 5229 5138 #ifdef WITH_ CONSOLE_OUTPUT_BUFFERING5230 #ifdef WITH_STD_OUT_ERR_BUFFERING 5139 5231 5140 5232 /** … … 5179 5271 * @param cchToWrite How much to write. 5180 5272 */ 5181 static void kwSandboxOutBufWrite(PKWSANDBOX pSandbox, PKW CONSOLEOUTPUTLINEpOutBuf, const char *pchBuffer, KU32 cchToWrite)5273 static void kwSandboxOutBufWrite(PKWSANDBOX pSandbox, PKWOUTPUTSTREAMBUF pOutBuf, const char *pchBuffer, KU32 cchToWrite) 5182 5274 { 5183 5275 if (pOutBuf->u.Fully.cchBufAlloc > 0) … … 5223 5315 while (cchToWrite > 0) 5224 5316 { 5225 char const *pchNewLine = (c har *)memchr(pchBuffer, '\n', cchToWrite);5317 char const *pchNewLine = (const char *)memchr(pchBuffer, '\n', cchToWrite); 5226 5318 KU32 cchLine = pchNewLine ? (KU32)(pchNewLine - pchBuffer) + 1 : cchToWrite; 5227 5319 if (cchLine <= pOutBuf->u.Fully.cchBufAlloc - pOutBuf->u.Fully.cchBuf) … … 5240 5332 || pOutBuf->u.Fully.pchBuf[pOutBuf->u.Fully.cchBuf - 1] != '\n') 5241 5333 { 5334 KWOUT_LOG(("kwSandboxOutBufWrite: flushing %u bytes, writing %u bytes\n", pOutBuf->u.Fully.cchBuf, cchLine)); 5242 5335 if (pOutBuf->u.Fully.cchBuf > 0) 5243 5336 { … … 5252 5345 else 5253 5346 { 5347 KWOUT_LOG(("kwSandboxOutBufWrite: flushing %u bytes\n", pOutBuf->u.Fully.cchBuf)); 5254 5348 kwSandboxOutBufWriteIt(pOutBuf->hBackup, pOutBuf->u.Fully.pchBuf, pOutBuf->u.Fully.cchBuf); 5255 5349 memcpy(&pOutBuf->u.Fully.pchBuf[0], pchBuffer, cchLine); … … 5263 5357 } 5264 5358 } 5265 #endif /* WITH_CONSOLE_OUTPUT_BUFFERING */ 5359 5360 #endif /* WITH_STD_OUT_ERR_BUFFERING */ 5266 5361 5267 5362 #ifdef WITH_TEMP_MEMORY_FILES 5268 5269 5363 static KBOOL kwFsTempFileEnsureSpace(PKWFSTEMPFILE pTempFile, KU32 offFile, KU32 cbNeeded) 5270 5364 { … … 5321 5415 return K_FALSE; 5322 5416 } 5323 5324 5417 #endif /* WITH_TEMP_MEMORY_FILES */ 5418 5419 5420 #if defined(WITH_TEMP_MEMORY_FILES) || defined(WITH_STD_OUT_ERR_BUFFERING) 5325 5421 /** Kernel32 - WriteFile */ 5326 5422 static BOOL WINAPI kwSandbox_Kernel32_WriteFile(HANDLE hFile, LPCVOID pvBuffer, DWORD cbToWrite, LPDWORD pcbActuallyWritten, … … 5336 5432 switch (pHandle->enmType) 5337 5433 { 5434 # ifdef WITH_TEMP_MEMORY_FILES 5338 5435 case KWHANDLETYPE_TEMP_FILE: 5339 5436 { … … 5390 5487 return FALSE; 5391 5488 } 5489 # endif 5392 5490 5393 5491 case KWHANDLETYPE_FSOBJ_READ_CACHE: … … 5396 5494 *pcbActuallyWritten = 0; 5397 5495 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 5398 5524 5399 5525 default: … … 5407 5533 } 5408 5534 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)); 5430 5536 return WriteFile(hFile, pvBuffer, cbToWrite, pcbActuallyWritten, pOverlapped); 5431 5537 } … … 5451 5557 } 5452 5558 5559 #endif /* WITH_TEMP_MEMORY_FILES || WITH_STD_OUT_ERR_BUFFERING */ 5560 5561 #ifdef WITH_TEMP_MEMORY_FILES 5453 5562 5454 5563 /** Kernel32 - SetEndOfFile; */ … … 5485 5594 return FALSE; 5486 5595 5596 case KWHANDLETYPE_OUTPUT_BUF: 5597 kHlpAssertFailed(); 5598 SetLastError(pHandle->u.pOutBuf->fIsConsole ? ERROR_INVALID_OPERATION : ERROR_ACCESS_DENIED); 5599 return FALSE; 5600 5487 5601 default: 5488 5602 case KWHANDLETYPE_TEMP_FILE_MAPPING: … … 5518 5632 KWFS_LOG(("GetFileType(%p) -> FILE_TYPE_DISK [temp]\n", hFile)); 5519 5633 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 5520 5652 } 5521 5653 } … … 5550 5682 return pHandle->u.pTempFile->cbFile; 5551 5683 5684 case KWHANDLETYPE_OUTPUT_BUF: 5685 /* do default */ 5686 break; 5687 5552 5688 default: 5553 5689 kHlpAssertFailed(); … … 5584 5720 pcbFile->QuadPart = pHandle->u.pTempFile->cbFile; 5585 5721 return TRUE; 5722 5723 case KWHANDLETYPE_OUTPUT_BUF: 5724 /* do default */ 5725 break; 5586 5726 5587 5727 default: … … 5654 5794 case KWHANDLETYPE_FSOBJ_READ_CACHE: 5655 5795 case KWHANDLETYPE_TEMP_FILE: 5796 case KWHANDLETYPE_OUTPUT_BUF: 5656 5797 kHlpAssertFailed(); 5657 SetLastError(ERROR_ NOT_ENOUGH_MEMORY);5798 SetLastError(ERROR_INVALID_OPERATION); 5658 5799 return NULL; 5659 5800 … … 5749 5890 /** @todo UnmapViewOfFileEx */ 5750 5891 5751 5752 5892 #endif /* WITH_TEMP_MEMORY_FILES */ 5893 5894 5895 /** Kernel32 - DuplicateHandle */ 5896 static 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 5753 5948 5754 5949 /** Kernel32 - CloseHandle */ … … 5758 5953 KUPTR const idxHandle = KW_HANDLE_TO_INDEX(hObject); 5759 5954 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 { 5769 5973 #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 } 5775 5979 #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)); 5787 6001 return fRet; 5788 6002 } … … 5988 6202 if (pSandbox->Combined.cwcBuf > 0) 5989 6203 { 6204 KWOUT_LOG(("kwSandboxConsoleFlushCombined: %u wchars\n", pSandbox->Combined.cwcBuf)); 5990 6205 kwSandboxConsoleWriteIt(pSandbox, pSandbox->Combined.wszBuf, pSandbox->Combined.cwcBuf); 5991 6206 pSandbox->Combined.cwcBuf = 0; … … 6025 6240 * @param pSandbox The sandbox. 6026 6241 * @param pLineBuf The line buffer. 6027 */ 6028 static void kwSandboxConsoleFinalFlushLineBuf(PKWSANDBOX pSandbox, PKWCONSOLEOUTPUTLINE pLineBuf) 6242 * @param pszName The line buffer name (for logging) 6243 */ 6244 static void kwSandboxConsoleFinalFlushLineBuf(PKWSANDBOX pSandbox, PKWOUTPUTSTREAMBUF pLineBuf, const char *pszName) 6029 6245 { 6030 6246 if (pLineBuf->fIsConsole) … … 6032 6248 if (pLineBuf->u.Con.cwcBuf > 0) 6033 6249 { 6250 KWOUT_LOG(("kwSandboxConsoleFinalFlushLineBuf: %s: %u wchars\n", pszName, pLineBuf->u.Con.cwcBuf)); 6251 6034 6252 if (pLineBuf->u.Con.cwcBuf < pLineBuf->u.Con.cwcBufAlloc) 6035 6253 { … … 6045 6263 } 6046 6264 } 6265 #ifdef WITH_STD_OUT_ERR_BUFFERING 6047 6266 else if (pLineBuf->u.Fully.cchBuf > 0) 6048 6267 { 6268 KWOUT_LOG(("kwSandboxConsoleFinalFlushLineBuf: %s: %u bytes\n", pszName, pLineBuf->u.Fully.cchBuf)); 6269 6049 6270 kwSandboxOutBufWriteIt(pLineBuf->hBackup, pLineBuf->u.Fully.pchBuf, pLineBuf->u.Fully.cchBuf); 6050 6271 pLineBuf->u.Fully.cchBuf = 0; 6051 6272 } 6273 #endif 6052 6274 } 6053 6275 … … 6092 6314 if (fOk) 6093 6315 { 6316 KWOUT_LOG(("kwSandboxConsoleFlushAll: Dropping '%*.*ls in combined console buffer\n", 6317 pSandbox->Combined.cwcBuf, pSandbox->Combined.cwcBuf, pSandbox->Combined.wszBuf)); 6094 6318 pSandbox->Combined.cwcBuf = 0; 6095 6319 return; 6096 6320 } 6097 6321 } 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 6100 6327 /* 6101 * Otherwise, it goes to standard error.6328 * Otherwise, it goes to standard output (redirected). 6102 6329 */ 6103 else if ( pSandbox->Std Out.u.Fully.cchBuf == 06104 && pSandbox->Std Err.u.Fully.cchBuf >= 3)6105 { 6106 char const *pchBuf = pSandbox->Std Err.u.Fully.pchBuf;6107 KI32 off = pSandbox->Std Err.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; 6108 6335 kHlpAssert(pSandbox->Combined.cFlushes == 0 && pSandbox->Combined.cwcBuf == 0); /* unused! */ 6109 6336 … … 6126 6353 if (fOk) 6127 6354 { 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; 6129 6358 return; 6130 6359 } 6131 6360 } 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 6133 6365 } 6134 6366 … … 6136 6368 * Flush the two line buffer, the the combined buffer. 6137 6369 */ 6138 kwSandboxConsoleFinalFlushLineBuf(pSandbox, &pSandbox->StdErr );6139 kwSandboxConsoleFinalFlushLineBuf(pSandbox, &pSandbox->StdOut );6370 kwSandboxConsoleFinalFlushLineBuf(pSandbox, &pSandbox->StdErr, "StdErr"); 6371 kwSandboxConsoleFinalFlushLineBuf(pSandbox, &pSandbox->StdOut, "StdOut"); 6140 6372 kwSandboxConsoleFlushCombined(pSandbox); 6141 6373 } … … 6150 6382 * @param cwcToWrite The number of wchar_t's in the buffer. 6151 6383 */ 6152 static void kwSandboxConsoleWriteW(PKWSANDBOX pSandbox, PKW CONSOLEOUTPUTLINEpLineBuf, wchar_t const *pwcBuffer, KU32 cwcToWrite)6384 static void kwSandboxConsoleWriteW(PKWSANDBOX pSandbox, PKWOUTPUTSTREAMBUF pLineBuf, wchar_t const *pwcBuffer, KU32 cwcToWrite) 6153 6385 { 6154 6386 kHlpAssert(pLineBuf->fIsConsole); … … 6316 6548 * @param cchToWrite How much to write. 6317 6549 */ 6318 static void kwSandboxConsoleWriteA(PKWSANDBOX pSandbox, PKW CONSOLEOUTPUTLINEpLineBuf, const char *pchBuffer, KU32 cchToWrite)6550 static void kwSandboxConsoleWriteA(PKWSANDBOX pSandbox, PKWOUTPUTSTREAMBUF pLineBuf, const char *pchBuffer, KU32 cchToWrite) 6319 6551 { 6320 6552 /* … … 6374 6606 PVOID pvReserved) 6375 6607 { 6376 BOOL 6377 PKW CONSOLEOUTPUTLINEpLineBuf;6608 BOOL fRc; 6609 PKWOUTPUTSTREAMBUF pLineBuf; 6378 6610 kHlpAssert(GetCurrentThreadId() == g_Sandbox.idMainThread); 6379 6611 … … 6386 6618 kwSandboxConsoleWriteA(&g_Sandbox, pLineBuf, (char const *)pvBuffer, cbToWrite); 6387 6619 6388 KW FS_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)); 6390 6622 if (pcbWritten) 6391 6623 *pcbWritten = cbToWrite; … … 6395 6627 { 6396 6628 fRc = WriteConsoleA(hConOutput, pvBuffer, cbToWrite, pcbWritten, pvReserved); 6397 KW FS_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)); 6399 6631 } 6400 6632 return fRc; … … 6406 6638 PVOID pvReserved) 6407 6639 { 6408 BOOL 6409 PKW CONSOLEOUTPUTLINEpLineBuf;6640 BOOL fRc; 6641 PKWOUTPUTSTREAMBUF pLineBuf; 6410 6642 kHlpAssert(GetCurrentThreadId() == g_Sandbox.idMainThread); 6411 6643 … … 6420 6652 kwSandboxConsoleWriteW(&g_Sandbox, pLineBuf, (wchar_t const *)pvBuffer, cwcToWrite); 6421 6653 6422 KW FS_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)); 6424 6656 if (pcwcWritten) 6425 6657 *pcwcWritten = cwcToWrite; … … 6429 6661 { 6430 6662 fRc = WriteConsoleW(hConOutput, pvBuffer, cwcToWrite, pcwcWritten, pvReserved); 6431 KW FS_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)); 6433 6665 } 6434 6666 return fRc; … … 7128 7360 { TUPLE("SetFilePointer"), NULL, (KUPTR)kwSandbox_Kernel32_SetFilePointer }, 7129 7361 { TUPLE("SetFilePointerEx"), NULL, (KUPTR)kwSandbox_Kernel32_SetFilePointerEx }, 7362 { TUPLE("DuplicateHandle"), NULL, (KUPTR)kwSandbox_Kernel32_DuplicateHandle }, 7130 7363 { TUPLE("CloseHandle"), NULL, (KUPTR)kwSandbox_Kernel32_CloseHandle }, 7131 7364 { TUPLE("GetFileAttributesA"), NULL, (KUPTR)kwSandbox_Kernel32_GetFileAttributesA }, … … 7251 7484 { TUPLE("SetFilePointer"), NULL, (KUPTR)kwSandbox_Kernel32_SetFilePointer }, 7252 7485 { TUPLE("SetFilePointerEx"), NULL, (KUPTR)kwSandbox_Kernel32_SetFilePointerEx }, 7486 { TUPLE("DuplicateHandle"), NULL, (KUPTR)kwSandbox_Kernel32_DuplicateHandle }, 7253 7487 { TUPLE("CloseHandle"), NULL, (KUPTR)kwSandbox_Kernel32_CloseHandle }, 7254 7488 { TUPLE("GetFileAttributesA"), NULL, (KUPTR)kwSandbox_Kernel32_GetFileAttributesA }, … … 7466 7700 * @param pSandbox The sandbox. 7467 7701 * @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 */ 7705 static KBOOL kwSandboxHandleTableEnter(PKWSANDBOX pSandbox, PKWHANDLE pHandle, HANDLE hHandle) 7706 { 7707 KUPTR const idxHandle = KW_HANDLE_TO_INDEX(hHandle); 7472 7708 kHlpAssertReturn(idxHandle < KW_HANDLE_MAX, K_FALSE); 7473 7709 … … 7562 7798 { 7563 7799 PPEB pPeb = kwSandboxGetProcessEnvironmentBlock(); 7800 PMY_RTL_USER_PROCESS_PARAMETERS pProcParams = (PMY_RTL_USER_PROCESS_PARAMETERS)pPeb->ProcessParameters; 7564 7801 wchar_t *pwcPool; 7565 7802 KSIZE cbStrings; … … 7577 7814 #ifdef WITH_CONSOLE_OUTPUT_BUFFERING 7578 7815 if (pSandbox->StdOut.fIsConsole) 7579 pSandbox->StdOut.u.Con.cwcBuf = 0;7816 pSandbox->StdOut.u.Con.cwcBuf = 0; 7580 7817 else 7581 7818 pSandbox->StdOut.u.Fully.cchBuf = 0; 7582 7819 if (pSandbox->StdErr.fIsConsole) 7583 pSandbox->StdErr.u.Con.cwcBuf = 0;7820 pSandbox->StdErr.u.Con.cwcBuf = 0; 7584 7821 else 7585 7822 pSandbox->StdErr.u.Fully.cchBuf = 0; 7586 pSandbox->Combined.cwcBuf = 0;7823 pSandbox->Combined.cwcBuf = 0; 7587 7824 pSandbox->Combined.cFlushes = 0; 7588 7825 #endif … … 7620 7857 cwc = kwStrToUtf16(pSandbox->pszCmdLine, pSandbox->pwszCmdLine, cbStrings / sizeof(wchar_t)); 7621 7858 7622 pSandbox->SavedCommandLine = pP eb->ProcessParameters->CommandLine;7623 pP eb->ProcessParameters->CommandLine.Buffer = pSandbox->pwszCmdLine;7624 pP eb->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); 7625 7862 7626 7863 /* … … 7697 7934 PKWEXITCALLACK pExitCallback; 7698 7935 7699 7700 7936 /* 7701 7937 * First stuff that may cause code to run. … … 7752 7988 * Then free resources associated with the sandbox run. 7753 7989 */ 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 } 7754 8038 7755 8039 #ifdef WITH_TEMP_MEMORY_FILES … … 7831 8115 if (GetProcessMemoryInfo(GetCurrentProcess(), &MemInfo, sizeof(MemInfo))) 7832 8116 { 8117 /** @todo make the limit dynamic and user configurable. */ 7833 8118 #if K_ARCH_BITS >= 64 7834 8119 if (MemInfo.WorkingSetSize >= 512*1024*1024) … … 7838 8123 { 7839 8124 KW_LOG(("WorkingSetSize = %#x - > restart next time.\n", MemInfo.WorkingSetSize)); 7840 //fprintf(stderr, "WorkingSetSize = %#x - > restart next time.\n", MemInfo.WorkingSetSize);7841 8125 g_fRestart = K_TRUE; 7842 8126 } 7843 8127 } 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 */ 7847 8152 static void kwSandboxCleanup(PKWSANDBOX pSandbox) 7848 8153 { … … 7851 8156 */ 7852 8157 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. */ 7884 8162 } 7885 8163 … … 8455 8733 } 8456 8734 8735 # ifdef WITH_LOG_FILE 8736 if (g_hLogFile != INVALID_HANDLE_VALUE && g_hLogFile != NULL) 8737 CloseHandle(g_hLogFile); 8738 # endif 8457 8739 return rcExit; 8458 8740 } … … 8475 8757 PPEB pPeb = kwSandboxGetProcessEnvironmentBlock(); 8476 8758 PMY_RTL_USER_PROCESS_PARAMETERS pProcessParams = (PMY_RTL_USER_PROCESS_PARAMETERS)pPeb->ProcessParameters; 8759 DWORD dwType; 8477 8760 #endif 8478 8761 … … 8504 8787 * Get and duplicate the console handles. 8505 8788 */ 8789 /* Standard output. */ 8506 8790 g_Sandbox.StdOut.hOutput = pProcessParams->StandardOutput; 8507 8791 if (!DuplicateHandle(hCurProc, pProcessParams->StandardOutput, hCurProc, &g_Sandbox.StdOut.hBackup, 8508 8792 GENERIC_WRITE, FALSE /*fInherit*/, DUPLICATE_SAME_ACCESS)) 8509 8793 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. */ 8512 8814 g_Sandbox.StdErr.hOutput = pProcessParams->StandardError; 8513 8815 if (!DuplicateHandle(hCurProc, pProcessParams->StandardError, hCurProc, &g_Sandbox.StdErr.hBackup, 8514 8816 GENERIC_WRITE, FALSE /*fInherit*/, DUPLICATE_SAME_ACCESS)) 8515 8817 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. */ 8518 8839 if (g_Sandbox.StdErr.fIsConsole) 8519 8840 { … … 8531 8852 g_Sandbox.Combined.uCodepage = CP_ACP; 8532 8853 } 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 */ 8534 8856 8535 8857 … … 8674 8996 8675 8997 CloseHandle(hPipe); 8998 # ifdef WITH_LOG_FILE 8999 if (g_hLogFile != INVALID_HANDLE_VALUE && g_hLogFile != NULL) 9000 CloseHandle(g_hLogFile); 9001 # endif 8676 9002 return rc > 0 ? 0 : 1; 8677 9003 } -
trunk/src/kmk/kmkbuiltin/redirect.c
r2912 r2916 387 387 int aFdTries[32]; 388 388 int cTries; 389 int fdOpened; 390 391 #ifdef KBUILD_OS_WINDOWS 392 if (strcmp(pszFilename, "/dev/null") == 0) 393 pszFilename = "nul"; 394 #endif 389 395 390 396 /* Open it first. */ 391 intfdOpened = open(pszFilename, fOpen | fNoInherit, fMode);397 fdOpened = open(pszFilename, fOpen | fNoInherit, fMode); 392 398 if (fdOpened < 0) 393 return err( 9, "open(%s,%#x,) failed", pszFilename, fOpen);399 return err(-1, "open(%s,%#x,) failed", pszFilename, fOpen); 394 400 395 401 /* Check for conflicts. */ … … 434 440 else 435 441 { 436 err( 9, "open(%s,%#x,) #%u failed", pszFilename, cTries + 1, fOpen);442 err(-1, "open(%s,%#x,) #%u failed", pszFilename, cTries + 1, fOpen); 437 443 break; 438 444 } … … 444 450 */ 445 451 if (fdOpened >= 0) 446 errx( 9, "failed to find a conflict free file descriptor for '%s'!", pszFilename);452 errx(-1, "failed to find a conflict free file descriptor for '%s'!", pszFilename); 447 453 448 454 while (cTries-- > 0) … … 1580 1586 #endif 1581 1587 } 1588 else 1589 rcExit = 9; 1582 1590 } 1583 1591 } -
trunk/src/kmk/main.c
r2914 r2916 920 920 921 921 #ifdef WINDOWS32 922 # ifndef KMK 922 923 /* 923 924 * HANDLE runtime exceptions by avoiding a requestor on the GUI. Capture … … 994 995 #endif 995 996 } 997 # endif /* !KMK */ 996 998 997 999 /* … … 1381 1383 1382 1384 # ifndef ELECTRIC_HEAP /* Drop this because it prevents JIT debugging. */ 1385 # ifndef KMK /* Don't want none of this crap. */ 1383 1386 SetUnhandledExceptionFilter(handle_runtime_exceptions); 1387 # endif 1384 1388 # endif /* !ELECTRIC_HEAP */ 1385 1389
Note:
See TracChangeset
for help on using the changeset viewer.