Changeset 2900 for trunk/src/kWorker/kWorker.c
- Timestamp:
- Sep 9, 2016, 4:42:06 PM (9 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/kWorker/kWorker.c
r2898 r2900 69 69 * they are included. */ 70 70 #define WITH_HASH_MD5_CACHE 71 72 /** @def WITH_CONSOLE_OUTPUT_BUFFERING 73 * Enables buffering of all console output as well as removal of annoying 74 * source file echo by cl.exe. */ 75 #define WITH_CONSOLE_OUTPUT_BUFFERING 71 76 72 77 … … 276 281 typedef KFSWCACHEDFILE *PKFSWCACHEDFILE; 277 282 278 279 283 #ifdef WITH_HASH_MD5_CACHE 284 280 285 /** Pointer to a MD5 hash instance. */ 281 286 typedef struct KWHASHMD5 *PKWHASHMD5; … … 307 312 /** Magic value for KWHASHMD5::uMagic (Les McCann). */ 308 313 # define KWHASHMD5_MAGIC KUPTR_C(0x19350923) 314 309 315 #endif /* WITH_HASH_MD5_CACHE */ 310 311 316 #ifdef WITH_TEMP_MEMORY_FILES 312 317 313 318 typedef struct KWFSTEMPFILESEG *PKWFSTEMPFILESEG; … … 345 350 } KWFSTEMPFILE; 346 351 352 #endif /* WITH_TEMP_MEMORY_FILES */ 353 #ifdef WITH_CONSOLE_OUTPUT_BUFFERING 354 355 /** 356 * Console line buffer. 357 */ 358 typedef struct KWCONSOLEOUTPUTLINE 359 { 360 /** The main output handle. */ 361 HANDLE hOutput; 362 /** Our backup handle. */ 363 HANDLE hBackup; 364 /** Set if this is a console handle. */ 365 KBOOL fIsConsole; 366 /** Amount of pending console output in wchar_t's. */ 367 KU32 cwcBuf; 368 /** The allocated buffer size. */ 369 KU32 cwcBufAlloc; 370 /** Pending console output. */ 371 wchar_t *pwcBuf; 372 } KWCONSOLEOUTPUTLINE; 373 /** Pointer to a console line buffer. */ 374 typedef KWCONSOLEOUTPUTLINE *PKWCONSOLEOUTPUTLINE; 375 376 /** 377 * Combined console buffer of complete lines. 378 */ 379 typedef struct KWCONSOLEOUTPUT 380 { 381 /** The console output handle. 382 * INVALID_HANDLE_VALUE if we haven't got a console and shouldn't be doing any 383 * combined output buffering. */ 384 HANDLE hOutput; 385 /** The current code page for the console. */ 386 KU32 uCodepage; 387 /** Amount of pending console output in wchar_t's. */ 388 KU32 cwcBuf; 389 /** Number of times we've flushed it in any way (for cl.exe hack). */ 390 KU32 cFlushes; 391 /** Pending console output. */ 392 wchar_t wszBuf[8192]; 393 } KWCONSOLEOUTPUT; 394 /** Pointer to a combined console buffer. */ 395 typedef KWCONSOLEOUTPUT *PKWCONSOLEOUTPUT; 396 397 #endif /* WITH_CONSOLE_OUTPUT_BUFFERING */ 347 398 348 399 /** Handle type. */ … … 554 605 } LastHashRead; 555 606 #endif 607 608 #ifdef WITH_CONSOLE_OUTPUT_BUFFERING 609 /** Standard output (and whatever else) line buffer. */ 610 KWCONSOLEOUTPUTLINE StdOut; 611 /** Standard error line buffer. */ 612 KWCONSOLEOUTPUTLINE StdErr; 613 /** Combined buffer of completed lines. */ 614 KWCONSOLEOUTPUT Combined; 615 #endif 556 616 } KWSANDBOX; 557 617 … … 640 700 static int kwLdrModuleResolveAndLookup(const char *pszName, PKWMODULE pExe, PKWMODULE pImporter, PKWMODULE *ppMod); 641 701 static KBOOL kwSandboxHandleTableEnter(PKWSANDBOX pSandbox, PKWHANDLE pHandle); 702 #ifdef WITH_CONSOLE_OUTPUT_BUFFERING 703 static void kwSandboxConsoleWriteA(PKWSANDBOX pSandbox, PKWCONSOLEOUTPUTLINE pLineBuf, const char *pchBuffer, KU32 cchToWrite); 704 #endif 642 705 643 706 … … 5013 5076 } 5014 5077 5078 #ifdef WITH_CONSOLE_OUTPUT_BUFFERING 5079 /* 5080 * Check for stdout and stderr. 5081 */ 5082 if ( g_Sandbox.StdErr.hOutput == hFile 5083 || g_Sandbox.StdOut.hOutput == hFile) 5084 { 5085 PKWCONSOLEOUTPUTLINE pLineBuf = g_Sandbox.StdErr.hOutput == hFile ? &g_Sandbox.StdErr : &g_Sandbox.StdOut; 5086 if (pLineBuf->fIsConsole) 5087 { 5088 kwSandboxConsoleWriteA(&g_Sandbox, pLineBuf, (const char *)pvBuffer, cbToWrite); 5089 KWFS_LOG(("WriteFile(console) -> TRUE\n", hFile)); 5090 return TRUE; 5091 } 5092 } 5093 #endif 5094 5015 5095 KWFS_LOG(("WriteFile(%p)\n", hFile)); 5016 5096 return WriteFile(hFile, pvBuffer, cbToWrite, pcbActuallyWritten, pOverlapped); … … 5499 5579 } 5500 5580 #endif /* WITH_TEMP_MEMORY_FILES */ 5581 5582 5583 5584 #ifdef WITH_CONSOLE_OUTPUT_BUFFERING 5585 5586 /* 5587 * 5588 * Console output buffering. 5589 * Console output buffering. 5590 * Console output buffering. 5591 * 5592 */ 5593 5594 5595 /** 5596 * Write a wide char string to the console. 5597 * 5598 * @param pSandbox The sandbox which output buffer to flush. 5599 */ 5600 static void kwSandboxConsoleWriteIt(PKWSANDBOX pSandbox, wchar_t const *pwcBuf, KU32 cwcToWrite) 5601 { 5602 if (cwcToWrite > 0) 5603 { 5604 DWORD cwcWritten = 0; 5605 if (WriteConsoleW(pSandbox->Combined.hOutput, pwcBuf, cwcToWrite, &cwcWritten, NULL)) 5606 { 5607 if (cwcWritten == cwcToWrite) 5608 { /* likely */ } 5609 else 5610 { 5611 DWORD off = 0; 5612 do 5613 { 5614 off += cwcWritten; 5615 cwcWritten = 0; 5616 } 5617 while ( off < cwcToWrite 5618 && WriteConsoleW(pSandbox->Combined.hOutput, &pwcBuf[off], cwcToWrite - off, &cwcWritten, NULL)); 5619 kHlpAssert(off == cwcWritten); 5620 } 5621 } 5622 else 5623 kHlpAssertFailed(); 5624 pSandbox->Combined.cFlushes++; 5625 } 5626 } 5627 5628 5629 /** 5630 * Flushes the combined console output buffer. 5631 * 5632 * @param pSandbox The sandbox which output buffer to flush. 5633 */ 5634 static void kwSandboxConsoleFlushCombined(PKWSANDBOX pSandbox) 5635 { 5636 if (pSandbox->Combined.cwcBuf > 0) 5637 { 5638 kwSandboxConsoleWriteIt(pSandbox, pSandbox->Combined.wszBuf, pSandbox->Combined.cwcBuf); 5639 pSandbox->Combined.cwcBuf = 0; 5640 } 5641 } 5642 5643 5644 /** 5645 * For handling combined buffer overflow cases line by line. 5646 * 5647 * @param pSandbox The sandbox. 5648 * @param pwcBuf What to add to the combined buffer. Usually a 5649 * line, unless we're really low on buffer space. 5650 * @param cwcBuf The length of what to add. 5651 * @param fBrokenLine Whether this is a broken line. 5652 */ 5653 static void kwSandboxConsoleAddToCombined(PKWSANDBOX pSandbox, wchar_t const *pwcBuf, KU32 cwcBuf, KBOOL fBrokenLine) 5654 { 5655 if (fBrokenLine) 5656 kwSandboxConsoleFlushCombined(pSandbox); 5657 if (pSandbox->Combined.cwcBuf + cwcBuf > K_ELEMENTS(pSandbox->Combined.wszBuf)) 5658 { 5659 kwSandboxConsoleFlushCombined(pSandbox); 5660 kwSandboxConsoleWriteIt(pSandbox, pwcBuf, cwcBuf); 5661 } 5662 else 5663 { 5664 memcpy(&pSandbox->Combined.wszBuf[pSandbox->Combined.cwcBuf], pwcBuf, cwcBuf * sizeof(wchar_t)); 5665 pSandbox->Combined.cwcBuf += cwcBuf; 5666 } 5667 } 5668 5669 5670 /** 5671 * Called to final flush a line buffer via the combined buffer (if applicable). 5672 * 5673 * @param pSandbox The sandbox. 5674 * @param pLineBuf The line buffer. 5675 */ 5676 static void kwSandboxConsoleFinalFlushLineBuf(PKWSANDBOX pSandbox, PKWCONSOLEOUTPUTLINE pLineBuf) 5677 { 5678 if (pLineBuf->cwcBuf > 0) 5679 { 5680 if (pLineBuf->fIsConsole) 5681 { 5682 if (pLineBuf->cwcBuf < pLineBuf->cwcBufAlloc) 5683 { 5684 pLineBuf->pwcBuf[pLineBuf->cwcBuf++] = '\n'; 5685 kwSandboxConsoleAddToCombined(pSandbox, pLineBuf->pwcBuf, pLineBuf->cwcBuf, K_FALSE /*fBrokenLine*/); 5686 } 5687 else 5688 { 5689 kwSandboxConsoleAddToCombined(pSandbox, pLineBuf->pwcBuf, pLineBuf->cwcBuf, K_TRUE /*fBrokenLine*/); 5690 kwSandboxConsoleAddToCombined(pSandbox, L"\n", 1, K_TRUE /*fBrokenLine*/); 5691 } 5692 pLineBuf->cwcBuf = 0; 5693 } 5694 else 5695 { 5696 kHlpAssertFailed(); 5697 } 5698 } 5699 } 5700 5701 5702 /** 5703 * Called at the end of sandboxed execution to flush both stream buffers. 5704 * 5705 * @param pSandbox The sandbox. 5706 */ 5707 static void kwSandboxConsoleFlushAll(PKWSANDBOX pSandbox) 5708 { 5709 /* 5710 * First do the cl.exe source file supression trick, if applicable. 5711 */ 5712 if ( pSandbox->Combined.cwcBuf >= 3 5713 && pSandbox->StdOut.cwcBuf == 0 5714 && pSandbox->StdErr.cwcBuf == 0 5715 && pSandbox->Combined.cFlushes == 0 5716 && pSandbox->pTool->u.Sandboxed.enmHint == KWTOOLHINT_VISUAL_CPP_CL) 5717 { 5718 KI32 off = pSandbox->Combined.cwcBuf - 1; 5719 if (pSandbox->Combined.wszBuf[off] == '\n') 5720 { 5721 KBOOL fOk = K_TRUE; 5722 while (off-- > 0) 5723 { 5724 wchar_t const wc = pSandbox->Combined.wszBuf[off]; 5725 if (iswalnum(wc) || wc == '.' || wc == ' ' || wc == '_' || wc == '-') 5726 { /* likely */ } 5727 else 5728 { 5729 fOk = K_FALSE; 5730 break; 5731 } 5732 } 5733 if (fOk) 5734 { 5735 pSandbox->Combined.cwcBuf = 0; 5736 return; 5737 } 5738 } 5739 } 5740 5741 /* 5742 * Flush the two line buffer, the the combined buffer. 5743 */ 5744 kwSandboxConsoleFinalFlushLineBuf(pSandbox, &pSandbox->StdErr); 5745 kwSandboxConsoleFinalFlushLineBuf(pSandbox, &pSandbox->StdOut); 5746 kwSandboxConsoleFlushCombined(pSandbox); 5747 } 5748 5749 5750 /** 5751 * Writes a string to the given output stream. 5752 * 5753 * @param pSandbox The sandbox. 5754 * @param pLineBuf The line buffer for the output stream. 5755 * @param pwcBuffer The buffer to write. 5756 * @param cwcToWrite The number of wchar_t's in the buffer. 5757 */ 5758 static void kwSandboxConsoleWriteW(PKWSANDBOX pSandbox, PKWCONSOLEOUTPUTLINE pLineBuf, wchar_t const *pwcBuffer, KU32 cwcToWrite) 5759 { 5760 if (cwcToWrite > 0) 5761 { 5762 /* 5763 * First, find the start of the last incomplete line so we can figure 5764 * out how much line buffering we need to do. 5765 */ 5766 KU32 cchLastIncompleteLine; 5767 KU32 offLastIncompleteLine = cwcToWrite; 5768 while ( offLastIncompleteLine > 0 5769 && pwcBuffer[offLastIncompleteLine - 1] != '\n') 5770 offLastIncompleteLine--; 5771 cchLastIncompleteLine = cwcToWrite - offLastIncompleteLine; 5772 5773 /* Was there anything to line buffer? */ 5774 if (offLastIncompleteLine < cwcToWrite) 5775 { 5776 /* Need to grow the line buffer? */ 5777 KU32 cwcNeeded = offLastIncompleteLine != 0 ? offLastIncompleteLine : cchLastIncompleteLine + pLineBuf->cwcBuf; 5778 if (cwcNeeded > pLineBuf->cwcBufAlloc) 5779 { 5780 void *pvNew; 5781 KU32 cwcNew = !pLineBuf->cwcBufAlloc ? 1024 : pLineBuf->cwcBufAlloc * 2; 5782 while (cwcNew < cwcNeeded) 5783 cwcNew *= 2; 5784 pvNew = kHlpRealloc(pLineBuf->pwcBuf, cwcNew * sizeof(wchar_t)); 5785 if (pvNew) 5786 { 5787 pLineBuf->pwcBuf = (wchar_t *)pvNew; 5788 pLineBuf->cwcBufAlloc = cwcNew; 5789 } 5790 else 5791 { 5792 pvNew = kHlpRealloc(pLineBuf->pwcBuf, cwcNeeded * sizeof(wchar_t)); 5793 if (pvNew) 5794 { 5795 pLineBuf->pwcBuf = (wchar_t *)pvNew; 5796 pLineBuf->cwcBufAlloc = cwcNeeded; 5797 } 5798 else 5799 { 5800 /* This isn't perfect, but it will have to do for now. */ 5801 if (pLineBuf->cwcBuf > 0) 5802 { 5803 kwSandboxConsoleAddToCombined(pSandbox, pLineBuf->pwcBuf, pLineBuf->cwcBuf, K_TRUE /*fBrokenLine*/); 5804 pLineBuf->cwcBuf = 0; 5805 } 5806 kwSandboxConsoleAddToCombined(pSandbox, pwcBuffer, cwcToWrite, K_TRUE /*fBrokenLine*/); 5807 return; 5808 } 5809 } 5810 } 5811 5812 /* 5813 * Handle the case where we only add to the line buffer. 5814 */ 5815 if (offLastIncompleteLine == 0) 5816 { 5817 memcpy(&pLineBuf->pwcBuf[pLineBuf->cwcBuf], pwcBuffer, cwcToWrite * sizeof(wchar_t)); 5818 pLineBuf->cwcBuf += cwcToWrite; 5819 return; 5820 } 5821 } 5822 5823 /* 5824 * If there is sufficient combined buffer to handle this request, this are rather simple. 5825 */ 5826 if (pLineBuf->cwcBuf + cchLastIncompleteLine <= K_ELEMENTS(pSandbox->Combined.wszBuf)) 5827 { 5828 if (pLineBuf->cwcBuf > 0) 5829 { 5830 memcpy(&pSandbox->Combined.wszBuf[pSandbox->Combined.cwcBuf], 5831 pLineBuf->pwcBuf, pLineBuf->cwcBuf * sizeof(wchar_t)); 5832 pSandbox->Combined.cwcBuf += pLineBuf->cwcBuf; 5833 pLineBuf->cwcBuf = 0; 5834 } 5835 5836 memcpy(&pSandbox->Combined.wszBuf[pSandbox->Combined.cwcBuf], 5837 pwcBuffer, offLastIncompleteLine * sizeof(wchar_t)); 5838 pSandbox->Combined.cwcBuf += offLastIncompleteLine; 5839 } 5840 else 5841 { 5842 /* 5843 * Do line-by-line processing of the input, flusing the combined buffer 5844 * when it becomes necessary. We may have to write lines 5845 */ 5846 KU32 off = 0; 5847 KU32 offNextLine = 0; 5848 5849 /* If there is buffered chars, we handle the first line outside the 5850 main loop. We must try our best outputting it as a complete line. */ 5851 if (pLineBuf->cwcBuf > 0) 5852 { 5853 while (offNextLine < cwcToWrite && pwcBuffer[offNextLine] != '\n') 5854 offNextLine++; 5855 offNextLine++; 5856 kHlpAssert(offNextLine <= offLastIncompleteLine); 5857 5858 if (pLineBuf->cwcBuf + offNextLine + pSandbox->Combined.cwcBuf <= K_ELEMENTS(pSandbox->Combined.wszBuf)) 5859 { 5860 memcpy(&pSandbox->Combined.wszBuf[pSandbox->Combined.cwcBuf], 5861 pLineBuf->pwcBuf, pLineBuf->cwcBuf * sizeof(wchar_t)); 5862 pSandbox->Combined.cwcBuf += pLineBuf->cwcBuf; 5863 pLineBuf->cwcBuf = 0; 5864 5865 memcpy(&pSandbox->Combined.wszBuf[pSandbox->Combined.cwcBuf], pwcBuffer, offNextLine * sizeof(wchar_t)); 5866 pSandbox->Combined.cwcBuf += offNextLine; 5867 } 5868 else 5869 { 5870 KU32 cwcLeft = pLineBuf->cwcBufAlloc - pLineBuf->cwcBuf; 5871 if (cwcLeft > 0) 5872 { 5873 KU32 cwcCopy = K_MIN(cwcLeft, offNextLine); 5874 memcpy(&pLineBuf->pwcBuf[pLineBuf->cwcBuf], pwcBuffer, cwcCopy * sizeof(wchar_t)); 5875 pLineBuf->cwcBuf += cwcCopy; 5876 off += cwcCopy; 5877 } 5878 if (pLineBuf->cwcBuf > 0) 5879 { 5880 kwSandboxConsoleAddToCombined(pSandbox, pLineBuf->pwcBuf, pLineBuf->cwcBuf, K_TRUE /*fBrokenLine*/); 5881 pLineBuf->cwcBuf = 0; 5882 } 5883 if (off < offNextLine) 5884 kwSandboxConsoleAddToCombined(pSandbox, &pwcBuffer[off], offNextLine - off, K_TRUE /*fBrokenLine*/); 5885 } 5886 off = offNextLine; 5887 } 5888 5889 /* Deal with the remaining lines */ 5890 while (off < offLastIncompleteLine) 5891 { 5892 while (offNextLine < offLastIncompleteLine && pwcBuffer[offNextLine] != '\n') 5893 offNextLine++; 5894 offNextLine++; 5895 kHlpAssert(offNextLine <= offLastIncompleteLine); 5896 kwSandboxConsoleAddToCombined(pSandbox, &pwcBuffer[off], offNextLine - off, K_FALSE /*fBrokenLine*/); 5897 off = offNextLine; 5898 } 5899 } 5900 5901 /* 5902 * Buffer any remaining incomplete line chars. 5903 */ 5904 if (offLastIncompleteLine < cwcToWrite) 5905 { 5906 memcpy(&pLineBuf->pwcBuf, &pwcBuffer[offLastIncompleteLine], cchLastIncompleteLine * sizeof(wchar_t)); 5907 pLineBuf->cwcBuf = cchLastIncompleteLine; 5908 } 5909 } 5910 } 5911 5912 5913 /** 5914 * Worker for WriteConsoleA and WriteFile. 5915 * 5916 * @param pSandbox The sandbox. 5917 * @param pLineBuf The line buffer. 5918 * @param pchBuffer What to write. 5919 * @param cchToWrite How much to write. 5920 */ 5921 static void kwSandboxConsoleWriteA(PKWSANDBOX pSandbox, PKWCONSOLEOUTPUTLINE pLineBuf, const char *pchBuffer, KU32 cchToWrite) 5922 { 5923 /* 5924 * Convert it to wide char and use the 'W' to do the work. 5925 */ 5926 int cwcRet; 5927 KU32 cwcBuf = cchToWrite * 2 + 1; 5928 wchar_t *pwcBufFree = NULL; 5929 wchar_t *pwcBuf; 5930 5931 if (cwcBuf <= 4096) 5932 pwcBuf = alloca(cwcBuf * sizeof(wchar_t)); 5933 else 5934 pwcBuf = pwcBufFree = kHlpAlloc(cwcBuf * sizeof(wchar_t)); 5935 5936 cwcRet = MultiByteToWideChar(pSandbox->Combined.uCodepage, 0/*dwFlags*/, pchBuffer, cchToWrite, pwcBuf, cwcBuf); 5937 if (cwcRet > 0) 5938 kwSandboxConsoleWriteW(pSandbox, pLineBuf, pwcBuf, cwcRet); 5939 else 5940 { 5941 DWORD cchWritten; 5942 kHlpAssertFailed(); 5943 5944 /* Flush the line buffer and combined buffer before calling WriteConsoleA. */ 5945 if (pLineBuf->cwcBuf > 0) 5946 { 5947 kwSandboxConsoleAddToCombined(pSandbox, pLineBuf->pwcBuf, pLineBuf->cwcBuf, K_TRUE /*fBroken*/); 5948 pLineBuf->cwcBuf = 0; 5949 } 5950 kwSandboxConsoleFlushCombined(pSandbox); 5951 5952 if (WriteConsoleA(pLineBuf->hBackup, pchBuffer, cchToWrite, &cchWritten, NULL /*pvReserved*/)) 5953 { 5954 if (cchWritten >= cchToWrite) 5955 { /* likely */ } 5956 else 5957 { 5958 KU32 off = 0; 5959 do 5960 { 5961 off += cchWritten; 5962 cchWritten = 0; 5963 } while ( off < cchToWrite 5964 && WriteConsoleA(pLineBuf->hBackup, &pchBuffer[off], cchToWrite - off, &cchWritten, NULL)); 5965 } 5966 } 5967 } 5968 5969 if (pwcBufFree) 5970 kHlpFree(pwcBufFree); 5971 } 5972 5973 5974 /** Kernel32 - WriteConsoleA */ 5975 BOOL WINAPI kwSandbox_Kernel32_WriteConsoleA(HANDLE hConOutput, CONST VOID *pvBuffer, DWORD cbToWrite, PDWORD pcbWritten, 5976 PVOID pvReserved) 5977 { 5978 BOOL fRc; 5979 PKWCONSOLEOUTPUTLINE pLineBuf; 5980 5981 if (hConOutput == g_Sandbox.StdErr.hOutput) 5982 pLineBuf = &g_Sandbox.StdErr; 5983 else 5984 pLineBuf = &g_Sandbox.StdOut; 5985 if (pLineBuf->fIsConsole) 5986 { 5987 kwSandboxConsoleWriteA(&g_Sandbox, pLineBuf, (char const *)pvBuffer, cbToWrite); 5988 5989 KWFS_LOG(("WriteConsoleA: %p, %p LB %#x (%*.*s), %p, %p -> TRUE [cached]\n", 5990 hConOutput, pvBuffer, cbToWrite, cbToWrite, cbToWrite, pvBuffer, pcbWritten, pvReserved)); 5991 if (pcbWritten) 5992 *pcbWritten = cbToWrite; 5993 fRc = TRUE; 5994 } 5995 else 5996 { 5997 fRc = WriteConsoleA(hConOutput, pvBuffer, cbToWrite, pcbWritten, pvReserved); 5998 KWFS_LOG(("WriteConsoleA: %p, %p LB %#x (%*.*s), %p, %p -> %d !fallback!\n", 5999 hConOutput, pvBuffer, cbToWrite, cbToWrite, cbToWrite, pvBuffer, pcbWritten, pvReserved, fRc)); 6000 } 6001 return fRc; 6002 } 6003 6004 6005 /** Kernel32 - WriteConsoleW */ 6006 BOOL WINAPI kwSandbox_Kernel32_WriteConsoleW(HANDLE hConOutput, CONST VOID *pvBuffer, DWORD cwcToWrite, PDWORD pcwcWritten, 6007 PVOID pvReserved) 6008 { 6009 BOOL fRc; 6010 PKWCONSOLEOUTPUTLINE pLineBuf; 6011 6012 if (hConOutput == g_Sandbox.StdErr.hOutput) 6013 pLineBuf = &g_Sandbox.StdErr; 6014 else 6015 pLineBuf = &g_Sandbox.StdOut; 6016 if (pLineBuf->fIsConsole) 6017 { 6018 kwSandboxConsoleWriteW(&g_Sandbox, pLineBuf, (wchar_t const *)pvBuffer, cwcToWrite); 6019 6020 KWFS_LOG(("WriteConsoleW: %p, %p LB %#x (%*.*ls), %p, %p -> TRUE [cached]\n", 6021 hConOutput, pvBuffer, cwcToWrite, cwcToWrite, cwcToWrite, pvBuffer, pcwcWritten, pvReserved)); 6022 if (pcwcWritten) 6023 *pcwcWritten = cwcToWrite; 6024 fRc = TRUE; 6025 } 6026 else 6027 { 6028 fRc = WriteConsoleW(hConOutput, pvBuffer, cwcToWrite, pcwcWritten, pvReserved); 6029 KWFS_LOG(("WriteConsoleW: %p, %p LB %#x (%*.*ls), %p, %p -> %d !fallback!\n", 6030 hConOutput, pvBuffer, cwcToWrite, cwcToWrite, cwcToWrite, pvBuffer, pcwcWritten, pvReserved, fRc)); 6031 } 6032 return fRc; 6033 } 6034 6035 #endif /* WITH_CONSOLE_OUTPUT_BUFFERING */ 5501 6036 5502 6037 … … 6127 6662 #endif 6128 6663 6664 { TUPLE("WriteConsoleA"), NULL, (KUPTR)kwSandbox_Kernel32_WriteConsoleA }, 6665 { TUPLE("WriteConsoleW"), NULL, (KUPTR)kwSandbox_Kernel32_WriteConsoleW }, 6666 6129 6667 { TUPLE("VirtualAlloc"), NULL, (KUPTR)kwSandbox_Kernel32_VirtualAlloc }, 6130 6668 { TUPLE("VirtualFree"), NULL, (KUPTR)kwSandbox_Kernel32_VirtualFree }, … … 6241 6779 { TUPLE("SetConsoleCtrlHandler"), NULL, (KUPTR)kwSandbox_Kernel32_SetConsoleCtrlHandler }, 6242 6780 6781 { TUPLE("WriteConsoleA"), NULL, (KUPTR)kwSandbox_Kernel32_WriteConsoleA }, 6782 { TUPLE("WriteConsoleW"), NULL, (KUPTR)kwSandbox_Kernel32_WriteConsoleW }, 6783 6243 6784 #ifdef WITH_HASH_MD5_CACHE 6244 6785 { TUPLE("CryptCreateHash"), NULL, (KUPTR)kwSandbox_Advapi32_CryptCreateHash }, … … 6553 7094 pSandbox->pgmptr = (char *)pTool->pszPath; 6554 7095 pSandbox->wpgmptr = (wchar_t *)pTool->pwszPath; 7096 #ifdef WITH_CONSOLE_OUTPUT_BUFFERING 7097 pSandbox->StdOut.cwcBuf = 0; 7098 pSandbox->StdErr.cwcBuf = 0; 7099 pSandbox->Combined.cwcBuf = 0; 7100 pSandbox->Combined.cFlushes = 0; 7101 #endif 6555 7102 pSandbox->cArgs = cArgs; 6556 7103 pSandbox->papszArgs = (char **)papszArgs; … … 6885 7432 rcExit = 42 + 4; 6886 7433 6887 /* Clean up essential bits only, the rest is done after we've replied to kmk. */ 7434 /* 7435 * Flush and clean up the essential bits only, postpone whatever we 7436 * can till after we've replied to kmk. 7437 */ 7438 #ifdef WITH_CONSOLE_OUTPUT_BUFFERING 7439 kwSandboxConsoleFlushAll(&g_Sandbox); 7440 #endif 6888 7441 kwSandboxCleanup(&g_Sandbox); 6889 7442 } … … 7376 7929 PVOID pvVecXcptHandler = AddVectoredExceptionHandler(0 /*called last*/, kwSandboxVecXcptEmulateChained); 7377 7930 #endif 7931 #ifdef WITH_CONSOLE_OUTPUT_BUFFERING 7932 HANDLE hCurProc = GetCurrentProcess(); 7933 PPEB pPeb = kwSandboxGetProcessEnvironmentBlock(); 7934 PMY_RTL_USER_PROCESS_PARAMETERS pProcessParams = (PMY_RTL_USER_PROCESS_PARAMETERS)pPeb->ProcessParameters; 7935 #endif 7378 7936 7379 7937 /* … … 7399 7957 if (pszTmp && *pszTmp != '\0') 7400 7958 kFsCacheSetupCustomRevisionForTree(g_pFsCache, kFsCacheLookupA(g_pFsCache, pszTmp, &enmIgnored)); 7959 7960 #ifdef WITH_CONSOLE_OUTPUT_BUFFERING 7961 /* 7962 * Get and duplicate the console handles. 7963 */ 7964 g_Sandbox.StdOut.hOutput = pProcessParams->StandardOutput; 7965 if (!DuplicateHandle(hCurProc, pProcessParams->StandardOutput, hCurProc, &g_Sandbox.StdOut.hBackup, 7966 GENERIC_WRITE, FALSE /*fInherit*/, DUPLICATE_SAME_ACCESS)) 7967 kHlpAssertFailedStmt(g_Sandbox.StdOut.hBackup = pProcessParams->StandardOutput); 7968 g_Sandbox.StdOut.fIsConsole = GetFileType(g_Sandbox.StdOut.hOutput) == FILE_TYPE_CHAR; 7969 7970 g_Sandbox.StdErr.hOutput = pProcessParams->StandardError; 7971 if (!DuplicateHandle(hCurProc, pProcessParams->StandardError, hCurProc, &g_Sandbox.StdErr.hBackup, 7972 GENERIC_WRITE, FALSE /*fInherit*/, DUPLICATE_SAME_ACCESS)) 7973 kHlpAssertFailedStmt(g_Sandbox.StdErr.hBackup = pProcessParams->StandardError); 7974 g_Sandbox.StdErr.fIsConsole = GetFileType(g_Sandbox.StdErr.hOutput) == FILE_TYPE_CHAR; 7975 7976 if (g_Sandbox.StdErr.fIsConsole) 7977 { 7978 g_Sandbox.Combined.hOutput = g_Sandbox.StdErr.hBackup; 7979 g_Sandbox.Combined.uCodepage = GetConsoleCP(); 7980 } 7981 else if (g_Sandbox.StdOut.fIsConsole) 7982 { 7983 g_Sandbox.Combined.hOutput = g_Sandbox.StdOut.hBackup; 7984 g_Sandbox.Combined.uCodepage = GetConsoleCP(); 7985 } 7986 else 7987 { 7988 g_Sandbox.Combined.hOutput = INVALID_HANDLE_VALUE; 7989 g_Sandbox.Combined.uCodepage = CP_ACP; 7990 } 7991 #endif 7992 7401 7993 7402 7994 /*
Note:
See TracChangeset
for help on using the changeset viewer.