Changeset 2876 in kBuild
- Timestamp:
- Sep 5, 2016 10:10:23 AM (9 years ago)
- Location:
- trunk/src
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/kWorker/kWorker.c
r2874 r2876 195 195 PKWDYNLOAD pNext; 196 196 197 /** The normalized path to the image. */198 const char *pszPath;199 /** The module name (within pszPath). */200 const char *pszModName;201 /** UTF-16 version of pszPath. */202 const wchar_t *pwszPath;203 /** The hash of the path. */204 KU32 uHashPath;205 206 197 /** The module handle we present to the application. 207 198 * This is the LoadLibraryEx return value for special modules and the … … 211 202 /** The module for non-special resource stuff, NULL if special. */ 212 203 PKWMODULE pMod; 204 205 /** The length of the LoadLibary filename. */ 206 KSIZE cchRequest; 207 /** The LoadLibrary filename. */ 208 char szRequest[1]; 213 209 } KWDYNLOAD; 214 210 … … 381 377 struct 382 378 { 379 /** The main entry point. */ 380 KUPTR uMainAddr; 383 381 /** The executable. */ 384 382 PKWMODULE pExe; … … 386 384 * These will be kept loaded till the tool is destroyed (if we ever do that). */ 387 385 PKWDYNLOAD pDynLoadHead; 386 /** Module array sorted by hOurMod. */ 387 PKWMODULE *papModules; 388 /** Number of entries in papModules. */ 389 KU32 cModules; 390 388 391 /** Tool hint (for hacks and such). */ 389 392 KWTOOLHINT enmHint; … … 1655 1658 KSIZE const cchName = kHlpStrLen(pszName); 1656 1659 char szPath[1024]; 1660 char *psz; 1657 1661 PKWMODULE pMod = NULL; 1662 KBOOL fNeedSuffix = *kHlpGetExt(pszName) == '\0' && kHlpGetFilename(pszName) == pszName; 1663 KSIZE cchSuffix = fNeedSuffix ? 4 : 0; 1658 1664 1659 1665 … … 1661 1667 if (pMod == NULL && pImporter != NULL) 1662 1668 { 1663 if (pImporter->offFilename + cchName >= sizeof(szPath))1669 if (pImporter->offFilename + cchName + cchSuffix >= sizeof(szPath)) 1664 1670 return KERR_BUFFER_OVERFLOW; 1665 kHlpMemCopy(kHlpMemPCopy(szPath, pImporter->pszPath, pImporter->offFilename), pszName, cchName + 1); 1671 1672 psz = (char *)kHlpMemPCopy(kHlpMemPCopy(szPath, pImporter->pszPath, pImporter->offFilename), pszName, cchName + 1); 1673 if (fNeedSuffix) 1674 kHlpMemCopy(psz - 1, ".dll", sizeof(".dll")); 1666 1675 pMod = kwLdrModuleTryLoadDll(szPath, KWLOCATION_IMPORTER_DIR, pExe); 1667 1676 } … … 1670 1679 if (pMod == NULL && pExe != NULL && pExe != pImporter) 1671 1680 { 1672 if (pExe->offFilename + cchName >= sizeof(szPath))1681 if (pExe->offFilename + cchName + cchSuffix >= sizeof(szPath)) 1673 1682 return KERR_BUFFER_OVERFLOW; 1674 kHlpMemCopy(kHlpMemPCopy(szPath, pExe->pszPath, pExe->offFilename), pszName, cchName + 1); 1683 psz = (char *)kHlpMemPCopy(kHlpMemPCopy(szPath, pExe->pszPath, pExe->offFilename), pszName, cchName + 1); 1684 if (fNeedSuffix) 1685 kHlpMemCopy(psz - 1, ".dll", sizeof(".dll")); 1675 1686 pMod = kwLdrModuleTryLoadDll(szPath, KWLOCATION_EXE_DIR, pExe); 1676 1687 } … … 1681 1692 UINT cchDir = GetSystemDirectoryA(szPath, sizeof(szPath)); 1682 1693 if ( cchDir <= 2 1683 || cchDir + 1 + cchName >= sizeof(szPath))1694 || cchDir + 1 + cchName + cchSuffix >= sizeof(szPath)) 1684 1695 return KERR_BUFFER_OVERFLOW; 1685 1696 szPath[cchDir++] = '\\'; 1686 kHlpMemCopy(&szPath[cchDir], pszName, cchName + 1); 1697 psz = (char *)kHlpMemPCopy(&szPath[cchDir], pszName, cchName + 1); 1698 if (fNeedSuffix) 1699 kHlpMemCopy(psz - 1, ".dll", sizeof(".dll")); 1687 1700 pMod = kwLdrModuleTryLoadDll(szPath, KWLOCATION_SYSTEM32, pExe); 1688 1701 } … … 1769 1782 1770 1783 1784 /** 1785 * Looks up a module handle for a tool. 1786 * 1787 * @returns Referenced loader module on success, NULL on if not found. 1788 * @param pTool The tool. 1789 * @param hmod The module handle. 1790 */ 1791 static PKWMODULE kwToolLocateModuleByHandle(PKWTOOL pTool, HMODULE hmod) 1792 { 1793 KUPTR const uHMod = (KUPTR)hmod; 1794 PKWMODULE *papMods; 1795 KU32 iEnd; 1796 KU32 i; 1797 PKWDYNLOAD pDynLoad; 1798 1799 /* The executable. */ 1800 if ( hmod == NULL 1801 || pTool->u.Sandboxed.pExe->hOurMod == hmod) 1802 return kwLdrModuleRetain(pTool->u.Sandboxed.pExe); 1803 1804 /* 1805 * Binary lookup using the module table. 1806 */ 1807 papMods = pTool->u.Sandboxed.papModules; 1808 iEnd = pTool->u.Sandboxed.cModules; 1809 if (iEnd) 1810 { 1811 KU32 iStart = 0; 1812 i = iEnd / 2; 1813 for (;;) 1814 { 1815 KUPTR const uHModThis = (KUPTR)papMods[i]->hOurMod; 1816 if (uHMod < uHModThis) 1817 { 1818 iEnd = i--; 1819 if (iStart <= i) 1820 { } 1821 else 1822 break; 1823 } 1824 else if (uHMod != uHModThis) 1825 { 1826 iStart = ++i; 1827 if (i < iEnd) 1828 { } 1829 else 1830 break; 1831 } 1832 else 1833 return kwLdrModuleRetain(papMods[i]); 1834 1835 i = iStart + (iEnd - iStart) / 2; 1836 } 1837 1838 #ifndef NDEBUG 1839 iStart = pTool->u.Sandboxed.cModules; 1840 while (--iStart > 0) 1841 kHlpAssert((KUPTR)papMods[iStart]->hOurMod != uHMod); 1842 kHlpAssert(i == 0 || (KUPTR)papMods[i - 1]->hOurMod < uHMod); 1843 kHlpAssert(i == pTool->u.Sandboxed.cModules || (KUPTR)papMods[i]->hOurMod > uHMod); 1844 #endif 1845 } 1846 1847 /* 1848 * Dynamically loaded images. 1849 */ 1850 for (pDynLoad = pTool->u.Sandboxed.pDynLoadHead; pDynLoad != NULL; pDynLoad = pDynLoad->pNext) 1851 if (pDynLoad->hmod == hmod) 1852 { 1853 if (pDynLoad->pMod) 1854 return kwLdrModuleRetain(pDynLoad->pMod); 1855 KWFS_TODO(); 1856 return NULL; 1857 } 1858 1859 return NULL; 1860 } 1861 1862 /** 1863 * Adds the given module to the tool import table. 1864 * 1865 * @returns 0 on success, non-zero on failure. 1866 * @param pTool The tool. 1867 * @param pMod The module. 1868 */ 1869 static int kwToolAddModule(PKWTOOL pTool, PKWMODULE pMod) 1870 { 1871 /* 1872 * Binary lookup. Locating the right slot for it, return if already there. 1873 */ 1874 KUPTR const uHMod = (KUPTR)pMod->hOurMod; 1875 PKWMODULE *papMods = pTool->u.Sandboxed.papModules; 1876 KU32 iEnd = pTool->u.Sandboxed.cModules; 1877 KU32 i; 1878 if (iEnd) 1879 { 1880 KU32 iStart = 0; 1881 i = iEnd / 2; 1882 for (;;) 1883 { 1884 KUPTR const uHModThis = (KUPTR)papMods[i]->hOurMod; 1885 if (uHMod < uHModThis) 1886 { 1887 iEnd = i; 1888 if (iStart < i) 1889 { } 1890 else 1891 break; 1892 } 1893 else if (uHMod != uHModThis) 1894 { 1895 iStart = ++i; 1896 if (i < iEnd) 1897 { } 1898 else 1899 break; 1900 } 1901 else 1902 { 1903 /* Already there in the table. */ 1904 return 0; 1905 } 1906 1907 i = iStart + (iEnd - iStart) / 2; 1908 } 1909 #ifndef NDEBUG 1910 iStart = pTool->u.Sandboxed.cModules; 1911 while (--iStart > 0) 1912 { 1913 kHlpAssert(papMods[iStart] != pMod); 1914 kHlpAssert((KUPTR)papMods[iStart]->hOurMod != uHMod); 1915 } 1916 kHlpAssert(i == 0 || (KUPTR)papMods[i - 1]->hOurMod < uHMod); 1917 kHlpAssert(i == pTool->u.Sandboxed.cModules || (KUPTR)papMods[i]->hOurMod > uHMod); 1918 #endif 1919 } 1920 else 1921 i = 0; 1922 1923 /* 1924 * Grow the table? 1925 */ 1926 if ((pTool->u.Sandboxed.cModules % 16) == 0) 1927 { 1928 void *pvNew = kHlpRealloc(papMods, sizeof(papMods[0]) * (pTool->u.Sandboxed.cModules + 16)); 1929 if (!pvNew) 1930 return KERR_NO_MEMORY; 1931 pTool->u.Sandboxed.papModules = papMods = (PKWMODULE *)pvNew; 1932 } 1933 1934 /* Insert it. */ 1935 if (i != pTool->u.Sandboxed.cModules) 1936 kHlpMemMove(&papMods[i + 1], &papMods[i], (pTool->u.Sandboxed.cModules - i) * sizeof(papMods[0])); 1937 papMods[i] = kwLdrModuleRetain(pMod); 1938 pTool->u.Sandboxed.cModules++; 1939 KW_LOG(("kwToolAddModule: %u modules after adding %p=%s\n", pTool->u.Sandboxed.cModules, uHMod, pMod->pszPath)); 1940 return 0; 1941 } 1942 1943 1944 /** 1945 * Adds the given module and all its imports to the 1946 * 1947 * @returns 0 on success, non-zero on failure. 1948 * @param pTool The tool. 1949 * @param pMod The module. 1950 */ 1951 static int kwToolAddModuleAndImports(PKWTOOL pTool, PKWMODULE pMod) 1952 { 1953 int rc = kwToolAddModule(pTool, pMod); 1954 if (!pMod->fNative && rc == 0) 1955 { 1956 KSIZE iImp = pMod->u.Manual.cImpMods; 1957 while (iImp-- > 0) 1958 { 1959 rc = kwToolAddModuleAndImports(pTool, pMod->u.Manual.apImpMods[iImp]); 1960 if (rc == 0) 1961 { } 1962 else 1963 break; 1964 } 1965 } 1966 return 0; 1967 } 1771 1968 1772 1969 … … 1800 1997 pTool->enmType = KWTOOLTYPE_SANDBOXED; 1801 1998 pTool->u.Sandboxed.pExe = kwLdrModuleCreateNonNative(pTool->pszPath, kwStrHash(pTool->pszPath), K_TRUE /*fExe*/, NULL); 1802 if (!pTool->u.Sandboxed.pExe) 1999 if (pTool->u.Sandboxed.pExe) 2000 { 2001 int rc = kwLdrModuleQueryMainEntrypoint(pTool->u.Sandboxed.pExe, &pTool->u.Sandboxed.uMainAddr); 2002 if (rc == 0) 2003 { 2004 if (kHlpStrICompAscii(pToolFsObj->pszName, "cl.exe") == 0) 2005 pTool->u.Sandboxed.enmHint = KWTOOLHINT_VISUAL_CPP_CL; 2006 else 2007 pTool->u.Sandboxed.enmHint = KWTOOLHINT_NONE; 2008 kwToolAddModuleAndImports(pTool, pTool->u.Sandboxed.pExe); 2009 } 2010 else 2011 { 2012 kwErrPrintf("Failed to get entrypoint for '%s': %u\n", pTool->pszPath, rc); 2013 kwLdrModuleRelease(pTool->u.Sandboxed.pExe); 2014 pTool->u.Sandboxed.pExe = NULL; 2015 pTool->enmType = KWTOOLTYPE_EXEC; 2016 } 2017 } 2018 else 1803 2019 pTool->enmType = KWTOOLTYPE_EXEC; 1804 else if (kHlpStrICompAscii(pToolFsObj->pszName, "cl.exe") == 0)1805 pTool->u.Sandboxed.enmHint = KWTOOLHINT_VISUAL_CPP_CL;1806 else1807 pTool->u.Sandboxed.enmHint = KWTOOLHINT_NONE;1808 2020 1809 2021 kFsCacheObjRelease(g_pFsCache, pToolFsObj); … … 2005 2217 */ 2006 2218 2007 /** ExitProcess replacement. */2008 static void WINAPI kwSandbox _Kernel32_ExitProcess(UINTuExitCode)2219 /** Common worker for ExitProcess(), exit() and friends. */ 2220 static void WINAPI kwSandboxDoExit(int uExitCode) 2009 2221 { 2010 2222 if (g_Sandbox.idMainThread == GetCurrentThreadId()) … … 2026 2238 2027 2239 /** ExitProcess replacement. */ 2240 static void WINAPI kwSandbox_Kernel32_ExitProcess(UINT uExitCode) 2241 { 2242 KW_LOG(("kwSandbox_Kernel32_ExitProcess: %u\n", uExitCode)); 2243 kwSandboxDoExit((int)uExitCode); 2244 } 2245 2246 2247 /** ExitProcess replacement. */ 2028 2248 static BOOL WINAPI kwSandbox_Kernel32_TerminateProcess(HANDLE hProcess, UINT uExitCode) 2029 2249 { 2030 2250 if (hProcess == GetCurrentProcess()) 2031 kwSandbox _Kernel32_ExitProcess(uExitCode);2251 kwSandboxDoExit(uExitCode); 2032 2252 KWFS_TODO(); 2033 2253 return TerminateProcess(hProcess, uExitCode); … … 2039 2259 { 2040 2260 KW_LOG(("kwSandbox_msvcrt_exit: %d\n", rcExitCode)); 2041 kwSandbox _Kernel32_ExitProcess(rcExitCode);2261 kwSandboxDoExit(rcExitCode); 2042 2262 } 2043 2263 … … 2048 2268 /* Quick. */ 2049 2269 KW_LOG(("kwSandbox_msvcrt__exit %d\n", rcExitCode)); 2050 kwSandbox _Kernel32_ExitProcess(rcExitCode);2270 kwSandboxDoExit(rcExitCode); 2051 2271 } 2052 2272 … … 2056 2276 { 2057 2277 KW_LOG(("kwSandbox_msvcrt__cexit: %d\n", rcExitCode)); 2058 kwSandbox _Kernel32_ExitProcess(rcExitCode);2278 kwSandboxDoExit(rcExitCode); 2059 2279 } 2060 2280 … … 2064 2284 { 2065 2285 KW_LOG(("kwSandbox_msvcrt__c_exit: %d\n", rcExitCode)); 2066 kwSandbox _Kernel32_ExitProcess(rcExitCode);2286 kwSandboxDoExit(rcExitCode); 2067 2287 } 2068 2288 … … 2072 2292 { 2073 2293 KW_LOG(("\nRuntime error #%u!\n", iMsgNo)); 2074 kwSandbox _Kernel32_ExitProcess(255);2294 kwSandboxDoExit(255); 2075 2295 } 2076 2296 … … 2080 2300 { 2081 2301 KW_LOG(("\nRuntime - terminate!\n")); 2082 kwSandbox _Kernel32_ExitProcess(254);2302 kwSandboxDoExit(254); 2083 2303 } 2084 2304 … … 2408 2628 * Kernel32 - LoadLibraryExA() worker that loads resource files and such. 2409 2629 */ 2410 static HMODULE WINAPI kwSandbox_Kernel32_LoadLibraryExA_Resource(LPCSTR pszFilename, HANDLE hFile, DWORD fFlags) 2630 static HMODULE WINAPI kwSandbox_Kernel32_LoadLibraryExA_Resource(PKWDYNLOAD pDynLoad, DWORD fFlags) 2631 { 2632 /* Load it first. */ 2633 HMODULE hmod = LoadLibraryExA(pDynLoad->szRequest, NULL /*hFile*/, fFlags); 2634 if (hmod) 2635 { 2636 pDynLoad->hmod = hmod; 2637 pDynLoad->pMod = NULL; /* indicates special */ 2638 2639 pDynLoad->pNext = g_Sandbox.pTool->u.Sandboxed.pDynLoadHead; 2640 g_Sandbox.pTool->u.Sandboxed.pDynLoadHead = pDynLoad; 2641 KW_LOG(("LoadLibraryExA(%s,,[resource]) -> %p\n", pDynLoad->szRequest, pDynLoad->hmod)); 2642 } 2643 else 2644 kHlpFree(pDynLoad); 2645 return hmod; 2646 } 2647 2648 2649 /** 2650 * Kernel32 - LoadLibraryExA() worker that deals with the api-ms-xxx modules. 2651 */ 2652 static HMODULE WINAPI kwSandbox_Kernel32_LoadLibraryExA_VirtualApiModule(PKWDYNLOAD pDynLoad, DWORD fFlags) 2411 2653 { 2412 2654 HMODULE hmod; 2413 PKW DYNLOAD pDynLoad;2655 PKWMODULE pMod; 2414 2656 KU32 uHashPath; 2415 char szNormPath[4096]; 2416 2417 /* Normalize the path. */ 2418 int rc = kwPathNormalize(pszFilename, szNormPath, sizeof(szNormPath)); 2419 if (rc != 0) 2420 { 2421 KWFS_TODO(); 2422 return LoadLibraryExA(pszFilename, hFile, fFlags); 2423 } 2424 2425 /* Try look it up. */ 2426 uHashPath = kwStrHash(szNormPath); 2427 for (pDynLoad = g_Sandbox.pTool->u.Sandboxed.pDynLoadHead; pDynLoad != NULL; pDynLoad = pDynLoad->pNext) 2428 if ( pDynLoad->uHashPath == uHashPath 2429 && kHlpStrComp(pDynLoad->pszPath, szNormPath) == 0) 2430 { 2431 if (pDynLoad->pMod == NULL) 2432 return pDynLoad->hmod; 2433 KWFS_TODO(); 2434 } 2435 2436 /* Then try load it. */ 2437 hmod = LoadLibraryExA(szNormPath, hFile, fFlags); 2438 if (hmod) 2439 { 2440 KSIZE cbNormPath = kHlpStrLen(szNormPath) + 1; 2441 pDynLoad = (PKWDYNLOAD)kHlpAlloc(sizeof(*pDynLoad) + cbNormPath + cbNormPath * 2 * sizeof(wchar_t)); 2442 if (pDynLoad) 2443 { 2444 pDynLoad->pszPath = (char *)kHlpMemCopy(pDynLoad + 1, szNormPath, cbNormPath); 2445 pDynLoad->pwszPath = (wchar_t *)(pDynLoad->pszPath + cbNormPath + (cbNormPath & 1)); 2446 kwStrToUtf16(pDynLoad->pszPath, (wchar_t *)pDynLoad->pwszPath, cbNormPath * 2); 2447 pDynLoad->pszModName = kHlpGetFilename(pDynLoad->pszPath); 2448 pDynLoad->uHashPath = uHashPath; 2449 pDynLoad->pMod = NULL; /* indicates special */ 2450 pDynLoad->hmod = hmod; 2451 2452 pDynLoad->pNext = g_Sandbox.pTool->u.Sandboxed.pDynLoadHead; 2453 g_Sandbox.pTool->u.Sandboxed.pDynLoadHead = pDynLoad; 2454 } 2455 else 2456 KWFS_TODO(); 2457 } 2458 return hmod; 2459 } 2460 2461 2462 /** 2463 * Kernel32 - LoadLibraryExA() worker that deals with the api-ms-xxx modules. 2464 */ 2465 static HMODULE WINAPI kwSandbox_Kernel32_LoadLibraryExA_VirtualApiModule(LPCSTR pszFilename, HANDLE hFile, DWORD fFlags) 2466 { 2467 HMODULE hmod; 2468 PKWDYNLOAD pDynLoad; 2469 KU32 uHashPath; 2657 KSIZE idxHash; 2470 2658 char szNormPath[256]; 2471 KSIZE cbFilename = kHlpStrLen(pszFilename) + 1; 2472 2473 /* Lower case it. */ 2659 KSIZE cbFilename = kHlpStrLen(pDynLoad->szRequest) + 1; 2660 2661 /* 2662 * Lower case it. 2663 */ 2474 2664 if (cbFilename <= sizeof(szNormPath)) 2475 2665 { 2476 kHlpMemCopy(szNormPath, p szFilename, cbFilename);2666 kHlpMemCopy(szNormPath, pDynLoad->szRequest, cbFilename); 2477 2667 _strlwr(szNormPath); 2478 2668 } … … 2483 2673 } 2484 2674 2485 /* Try look it up. */ 2675 /* 2676 * Check if it has already been loaded so we don't create an unnecessary 2677 * loader module for it. 2678 */ 2486 2679 uHashPath = kwStrHash(szNormPath); 2487 for (pDynLoad = g_Sandbox.pTool->u.Sandboxed.pDynLoadHead; pDynLoad != NULL; pDynLoad = pDynLoad->pNext) 2488 if ( pDynLoad->uHashPath == uHashPath 2489 && kHlpStrComp(pDynLoad->pszPath, szNormPath) == 0) 2490 { 2491 if (pDynLoad->pMod != NULL) 2680 idxHash = uHashPath % K_ELEMENTS(g_apModules); 2681 pMod = g_apModules[idxHash]; 2682 if (pMod) 2683 { 2684 do 2685 { 2686 if ( pMod->uHashPath == uHashPath 2687 && kHlpStrComp(pMod->pszPath, szNormPath) == 0) 2688 { 2689 pDynLoad->pMod = kwLdrModuleRetain(pMod); 2690 pDynLoad->hmod = pMod->hOurMod; 2691 2692 pDynLoad->pNext = g_Sandbox.pTool->u.Sandboxed.pDynLoadHead; 2693 g_Sandbox.pTool->u.Sandboxed.pDynLoadHead = pDynLoad; 2694 KW_LOG(("LoadLibraryExA(%s,,) -> %p [already loaded]\n", pDynLoad->szRequest, pDynLoad->hmod)); 2492 2695 return pDynLoad->hmod; 2493 KWFS_TODO(); 2494 } 2495 2496 /* Then try load it and make a kLdr module for it. */ 2497 hmod = LoadLibraryExA(szNormPath, hFile, fFlags); 2696 } 2697 pMod = pMod->pNext; 2698 } while (pMod); 2699 } 2700 2701 2702 /* 2703 * Try load it and make a kLdr module for it. 2704 */ 2705 hmod = LoadLibraryExA(szNormPath, NULL /*hFile*/, fFlags); 2498 2706 if (hmod) 2499 2707 { … … 2506 2714 if (pMod) 2507 2715 { 2716 kwToolAddModuleAndImports(g_Sandbox.pTool, pMod); 2717 2508 2718 pDynLoad = (PKWDYNLOAD)kHlpAlloc(sizeof(*pDynLoad) + cbFilename + cbFilename * sizeof(wchar_t)); 2509 2719 if (pDynLoad) 2510 2720 { 2511 pDynLoad->pwszPath = (wchar_t *)(pDynLoad + 1); 2512 kwStrToUtf16(szNormPath, (wchar_t *)pDynLoad->pwszPath, cbFilename); 2513 pDynLoad->pszPath = (char *)kHlpMemCopy((char *)&pDynLoad->pwszPath[cbFilename], szNormPath, cbFilename); 2514 pDynLoad->pszModName = pDynLoad->pszPath; 2515 pDynLoad->uHashPath = uHashPath; 2516 pDynLoad->pMod = pMod; 2517 pDynLoad->hmod = hmod; 2721 pDynLoad->pMod = pMod; 2722 pDynLoad->hmod = hmod; 2518 2723 2519 2724 pDynLoad->pNext = g_Sandbox.pTool->u.Sandboxed.pDynLoadHead; 2520 2725 g_Sandbox.pTool->u.Sandboxed.pDynLoadHead = pDynLoad; 2726 KW_LOG(("LoadLibraryExA(%s,,) -> %p\n", pDynLoad->szRequest, pDynLoad->hmod)); 2521 2727 return hmod; 2522 2728 } … … 2530 2736 KWFS_TODO(); 2531 2737 } 2738 kHlpFree(pDynLoad); 2532 2739 return hmod; 2533 2740 } … … 2537 2744 static HMODULE WINAPI kwSandbox_Kernel32_LoadLibraryExA(LPCSTR pszFilename, HANDLE hFile, DWORD fFlags) 2538 2745 { 2746 KSIZE cchFilename = kHlpStrLen(pszFilename); 2539 2747 PKWDYNLOAD pDynLoad; 2540 2748 PKWMODULE pMod; 2541 2749 int rc; 2542 2750 2543 if ( (fFlags & LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE) 2544 || (hFile != NULL && hFile != INVALID_HANDLE_VALUE) ) 2751 /* 2752 * Deal with a couple of extremely unlikely special cases right away. 2753 */ 2754 if ( !(fFlags & LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE) 2755 && (hFile == NULL || hFile == INVALID_HANDLE_VALUE) ) 2756 { /* likely */ } 2757 else 2545 2758 { 2546 2759 KWFS_TODO(); 2547 2760 return LoadLibraryExA(pszFilename, hFile, fFlags); 2761 } 2762 2763 /* 2764 * Check if we've already got a dynload entry for this one. 2765 */ 2766 for (pDynLoad = g_Sandbox.pTool->u.Sandboxed.pDynLoadHead; pDynLoad; pDynLoad = pDynLoad->pNext) 2767 if ( pDynLoad->cchRequest == cchFilename 2768 && kHlpMemComp(pDynLoad->szRequest, pszFilename, cchFilename) == 0) 2769 { 2770 if (pDynLoad->pMod) 2771 rc = kwLdrModuleInitTree(pDynLoad->pMod); 2772 else 2773 rc = 0; 2774 if (rc == 0) 2775 { 2776 KW_LOG(("LoadLibraryExA(%s,,) -> %p [cached]\n", pszFilename, pDynLoad->hmod)); 2777 return pDynLoad->hmod; 2778 } 2779 SetLastError(ERROR_DLL_INIT_FAILED); 2780 return NULL; 2781 } 2782 2783 /* 2784 * Allocate a dynload entry for the request. 2785 */ 2786 pDynLoad = (PKWDYNLOAD)kHlpAlloc(sizeof(*pDynLoad) + cchFilename + 1); 2787 if (pDynLoad) 2788 { 2789 pDynLoad->cchRequest = cchFilename; 2790 kHlpMemCopy(pDynLoad->szRequest, pszFilename, cchFilename + 1); 2791 } 2792 else 2793 { 2794 KW_LOG(("LoadLibraryExA: Out of memory!\n")); 2795 SetLastError(ERROR_NOT_ENOUGH_MEMORY); 2796 return NULL; 2548 2797 } 2549 2798 … … 2554 2803 | LOAD_LIBRARY_AS_DATAFILE 2555 2804 | LOAD_LIBRARY_AS_IMAGE_RESOURCE) ) 2556 { 2557 /* currently, only deal with those that has a path. */ 2558 if (kHlpIsFilenameOnly(pszFilename)) 2559 { 2560 KWFS_TODO(); 2561 return LoadLibraryExA(pszFilename, hFile, fFlags); 2562 } 2563 2564 return kwSandbox_Kernel32_LoadLibraryExA_Resource(pszFilename, hFile, fFlags); 2565 } 2805 return kwSandbox_Kernel32_LoadLibraryExA_Resource(pDynLoad, fFlags); 2806 2807 /* 2808 * Special case: api-ms-win-core-synch-l1-2-0 and friends (32-bit yasm, built with VS2015). 2809 */ 2810 if ( strnicmp(pszFilename, TUPLE("api-ms-")) == 0 2811 && kHlpIsFilenameOnly(pszFilename)) 2812 return kwSandbox_Kernel32_LoadLibraryExA_VirtualApiModule(pDynLoad, fFlags); 2566 2813 2567 2814 /* … … 2571 2818 if (!kHlpIsFilenameOnly(pszFilename)) 2572 2819 pMod = kwLdrModuleTryLoadDll(pszFilename, KWLOCATION_UNKNOWN, g_Sandbox.pTool->u.Sandboxed.pExe); 2573 /* Special case: api-ms-win-core-synch-l1-2-0 and friends (32-bit yasm, built with VS2015). */2574 else if (strnicmp(pszFilename, TUPLE("api-ms-")) == 0)2575 return kwSandbox_Kernel32_LoadLibraryExA_VirtualApiModule(pszFilename, hFile, fFlags);2576 2820 else 2577 2821 { 2578 KWFS_TODO();2579 2822 rc = kwLdrModuleResolveAndLookup(pszFilename, g_Sandbox.pTool->u.Sandboxed.pExe, NULL /*pImporter*/, &pMod); 2580 2823 if (rc != 0) 2581 2824 pMod = NULL; 2582 2825 } 2583 if (!pMod) 2826 if (pMod) 2827 { 2828 /* Enter it into the tool module table and dynamic link request cache. */ 2829 kwToolAddModuleAndImports(g_Sandbox.pTool, pMod); 2830 2831 pDynLoad->pMod = pMod; 2832 pDynLoad->hmod = pMod->hOurMod; 2833 2834 pDynLoad->pNext = g_Sandbox.pTool->u.Sandboxed.pDynLoadHead; 2835 g_Sandbox.pTool->u.Sandboxed.pDynLoadHead = pDynLoad; 2836 2837 /* 2838 * Make sure it's initialized (need to link it first since DllMain may 2839 * use loader APIs). 2840 */ 2841 rc = kwLdrModuleInitTree(pMod); 2842 if (rc == 0) 2843 { 2844 KW_LOG(("LoadLibraryExA(%s,,) -> %p\n", pszFilename, pDynLoad->hmod)); 2845 return pDynLoad->hmod; 2846 } 2847 2848 SetLastError(ERROR_DLL_INIT_FAILED); 2849 } 2850 else 2584 2851 { 2585 2852 KWFS_TODO(); 2853 kHlpFree(pDynLoad); 2586 2854 SetLastError(ERROR_MOD_NOT_FOUND); 2587 return NULL; 2588 } 2589 2590 /* 2591 * Make sure it's initialized. 2592 */ 2593 rc = kwLdrModuleInitTree(pMod); 2594 if (rc == 0) 2595 { 2596 /* 2597 * Create an dynamic loading entry for it. 2598 */ 2599 pDynLoad = (PKWDYNLOAD)kHlpAlloc(sizeof(*pDynLoad)); 2600 if (pDynLoad) 2601 { 2602 pDynLoad->pszPath = pMod->pszPath; 2603 pDynLoad->pwszPath = pMod->pwszPath; 2604 pDynLoad->pszModName = kHlpGetFilename(pDynLoad->pszPath); 2605 pDynLoad->uHashPath = pMod->uHashPath; 2606 pDynLoad->pMod = pMod; 2607 pDynLoad->hmod = pMod->hOurMod; 2608 2609 pDynLoad->pNext = g_Sandbox.pTool->u.Sandboxed.pDynLoadHead; 2610 g_Sandbox.pTool->u.Sandboxed.pDynLoadHead = pDynLoad; 2611 2612 return pDynLoad->hmod; 2613 } 2614 } 2615 2616 KWFS_TODO(); 2617 SetLastError(ERROR_NOT_ENOUGH_MEMORY); 2618 kwLdrModuleRelease(pMod); 2855 } 2619 2856 return NULL; 2620 2857 } … … 2722 2959 2723 2960 2724 static PKWMODULE kwSandboxLocateModuleByHandle(PKWSANDBOX pSandbox, HMODULE hmod)2725 {2726 PKWDYNLOAD pDynLoad;2727 2728 /* The executable. */2729 if ( hmod == NULL2730 || pSandbox->pTool->u.Sandboxed.pExe->hOurMod == hmod)2731 return kwLdrModuleRetain(pSandbox->pTool->u.Sandboxed.pExe);2732 2733 /* Dynamically loaded images. */2734 for (pDynLoad = pSandbox->pTool->u.Sandboxed.pDynLoadHead; pDynLoad != NULL; pDynLoad = pDynLoad->pNext)2735 if (pDynLoad->hmod == hmod)2736 {2737 if (pDynLoad->pMod)2738 return kwLdrModuleRetain(pDynLoad->pMod);2739 KWFS_TODO();2740 return NULL;2741 }2742 2743 return NULL;2744 }2745 2746 2747 2961 /** Used to debug dynamically resolved procedures. */ 2748 2962 static UINT WINAPI kwSandbox_BreakIntoDebugger(void *pv1, void *pv2, void *pv3, void *pv4) … … 2761 2975 * Try locate the module. 2762 2976 */ 2763 PKWMODULE pMod = kw SandboxLocateModuleByHandle(&g_Sandbox, hmod);2977 PKWMODULE pMod = kwToolLocateModuleByHandle(g_Sandbox.pTool, hmod); 2764 2978 if (pMod) 2765 2979 { … … 2807 3021 static DWORD WINAPI kwSandbox_Kernel32_GetModuleFileNameA(HMODULE hmod, LPSTR pszFilename, DWORD cbFilename) 2808 3022 { 2809 PKWMODULE pMod = kw SandboxLocateModuleByHandle(&g_Sandbox, hmod);3023 PKWMODULE pMod = kwToolLocateModuleByHandle(g_Sandbox.pTool, hmod); 2810 3024 if (pMod != NULL) 2811 3025 { … … 2822 3036 static DWORD WINAPI kwSandbox_Kernel32_GetModuleFileNameW(HMODULE hmod, LPWSTR pwszFilename, DWORD cbFilename) 2823 3037 { 2824 PKWMODULE pMod = kw SandboxLocateModuleByHandle(&g_Sandbox, hmod);3038 PKWMODULE pMod = kwToolLocateModuleByHandle(g_Sandbox.pTool, hmod); 2825 3039 if (pMod) 2826 3040 { … … 5100 5314 * Call the main function. 5101 5315 */ 5102 KUPTR uAddrMain;5103 rc = kwLdrModuleQueryMainEntrypoint(pTool->u.Sandboxed.pExe, &uAddrMain);5104 if (rc == 0)5105 {5106 5316 #if K_ARCH == K_ARCH_AMD64 5107 5317 int (*pfnWin64Entrypoint)(void *pvPeb, void *, void *, void *); 5108 5318 #elif K_ARCH == K_ARCH_X86_32 5109 5319 int (__cdecl *pfnWin32Entrypoint)(void *pvPeb); 5110 5320 #else 5111 5321 # error "Port me!" 5112 5322 #endif 5113 5323 5114 5115 5116 5117 5118 5324 /* Save the NT TIB first (should do that here, not in some other function). */ 5325 PNT_TIB pTib = (PNT_TIB)NtCurrentTeb(); 5326 pSandbox->TibMainThread = *pTib; 5327 5328 /* Make the call in a guarded fashion. */ 5119 5329 #if K_ARCH == K_ARCH_AMD64 5120 /* AMD64 */ 5121 *(KUPTR *)&pfnWin64Entrypoint = uAddrMain; 5122 __try 5330 /* AMD64 */ 5331 *(KUPTR *)&pfnWin64Entrypoint = pTool->u.Sandboxed.uMainAddr; 5332 __try 5333 { 5334 pSandbox->pOutXcptListHead = pTib->ExceptionList; 5335 if (setjmp(pSandbox->JmpBuf) == 0) 5123 5336 { 5124 pSandbox->pOutXcptListHead = pTib->ExceptionList; 5125 if (setjmp(pSandbox->JmpBuf) == 0) 5126 { 5127 *(KU64*)(pSandbox->JmpBuf) = 0; /** @todo find other way to prevent longjmp from doing unwind! */ 5128 pSandbox->fRunning = K_TRUE; 5129 rcExit = pfnWin64Entrypoint(kwSandboxGetProcessEnvironmentBlock(), NULL, NULL, NULL); 5130 pSandbox->fRunning = K_FALSE; 5131 } 5132 else 5133 rcExit = pSandbox->rcExitCode; 5337 *(KU64*)(pSandbox->JmpBuf) = 0; /** @todo find other way to prevent longjmp from doing unwind! */ 5338 pSandbox->fRunning = K_TRUE; 5339 rcExit = pfnWin64Entrypoint(kwSandboxGetProcessEnvironmentBlock(), NULL, NULL, NULL); 5340 pSandbox->fRunning = K_FALSE; 5134 5341 } 5342 else 5343 rcExit = pSandbox->rcExitCode; 5344 } 5135 5345 #elif K_ARCH == K_ARCH_X86_32 5136 /* x86 (see _tmainCRTStartup) */ 5137 *(KUPTR *)&pfnWin32Entrypoint = uAddrMain; 5138 __try 5346 /* x86 (see _tmainCRTStartup) */ 5347 *(KUPTR *)&pfnWin32Entrypoint = pTool->u.Sandboxed.uMainAddr; 5348 __try 5349 { 5350 pSandbox->pOutXcptListHead = pTib->ExceptionList; 5351 if (setjmp(pSandbox->JmpBuf) == 0) 5139 5352 { 5140 pSandbox->pOutXcptListHead = pTib->ExceptionList; 5141 if (setjmp(pSandbox->JmpBuf) == 0) 5142 { 5143 //*(KU64*)(pSandbox->JmpBuf) = 0; /** @todo find other way to prevent longjmp from doing unwind! */ 5144 pSandbox->fRunning = K_TRUE; 5145 rcExit = pfnWin32Entrypoint(kwSandboxGetProcessEnvironmentBlock()); 5146 pSandbox->fRunning = K_FALSE; 5147 } 5148 else 5149 rcExit = pSandbox->rcExitCode; 5353 //*(KU64*)(pSandbox->JmpBuf) = 0; /** @todo find other way to prevent longjmp from doing unwind! */ 5354 pSandbox->fRunning = K_TRUE; 5355 rcExit = pfnWin32Entrypoint(kwSandboxGetProcessEnvironmentBlock()); 5356 pSandbox->fRunning = K_FALSE; 5150 5357 } 5358 else 5359 rcExit = pSandbox->rcExitCode; 5360 } 5151 5361 #endif 5152 __except (EXCEPTION_EXECUTE_HANDLER) 5153 { 5154 rcExit = 512; 5155 } 5156 pSandbox->fRunning = K_FALSE; 5157 5158 /* Now, restore the NT TIB. */ 5159 *pTib = pSandbox->TibMainThread; 5160 } 5161 else 5162 rcExit = 42 + 5; 5362 __except (EXCEPTION_EXECUTE_HANDLER) 5363 { 5364 rcExit = 512; 5365 } 5366 pSandbox->fRunning = K_FALSE; 5367 5368 /* Now, restore the NT TIB. */ 5369 *pTib = pSandbox->TibMainThread; 5163 5370 } 5164 5371 else … … 5331 5538 5332 5539 /* Environment variable count. */ 5333 if ( sizeof(KU32) < cbMsg)5540 if (cbMsg > sizeof(KU32)) 5334 5541 { 5335 5542 KU32 cEnvVars; … … 5354 5561 else 5355 5562 { 5356 if ( cbTmp == cbMsg 5357 && i + 1 == cEnvVars) 5358 cbMsg = 0; 5359 else 5360 cbMsg = KSIZE_MAX; 5563 cbMsg = 0; 5361 5564 break; 5362 5565 } 5363 5566 } 5364 5567 papszEnvVars[cEnvVars] = 0; 5365 if (cbMsg != KSIZE_MAX)5568 if (cbMsg >= sizeof(KU8)) 5366 5569 { 5570 KBOOL fWatcomBrainDamange = *pszMsg++; 5571 cbMsg--; 5367 5572 if (cbMsg == 0) 5368 5573 { 5369 KBOOL fWatcomBrainDamange = K_FALSE; /** @todo fix fWatcomBrainDamange */5370 5574 /* 5371 5575 * The next step. … … 5504 5708 const char *pszCwd = getcwd(szCwd, sizeof(szCwd)); 5505 5709 KU32 cEnvVars; 5710 KBOOL fWatcomBrainDamange = K_FALSE; 5506 5711 5507 5712 /* … … 5529 5734 } 5530 5735 5736 /* Optional watcom flag directory change. */ 5737 if ( i < argc 5738 && ( strcmp(argv[i], "--wcc-brain-damage") == 0 5739 || strcmp(argv[i], "--watcom-brain-damage") == 0) ) 5740 { 5741 fWatcomBrainDamange = K_TRUE; 5742 i++; 5743 } 5744 5531 5745 /* Check for '--'. */ 5532 5746 if (i >= argc) … … 5554 5768 { 5555 5769 rcExit = kSubmitHandleJobUnpacked(argv[i], pszCwd, 5556 argc - i, &argv[i], K_FALSE /* fWatcomBrainDamange*/,5770 argc - i, &argv[i], fWatcomBrainDamange, 5557 5771 cEnvVars, environ); 5772 KW_LOG(("rcExit=%d\n", rcExit)); 5558 5773 } 5559 5774 -
trunk/src/kmk/kmkbuiltin/kSubmit.c
r2875 r2876 569 569 * 570 570 * @returns Pointer to the message. 571 * @param pszExecutable The executable to run. 572 * @param papszArgs The argument vector. 573 * @param papszEnvVars The environment vector. 574 * @param pszCwd The current directory. 575 * @param pcbMsg Where to return the message length. 571 * @param pszExecutable The executable to run. 572 * @param papszArgs The argument vector. 573 * @param papszEnvVars The environment vector. 574 * @param pszCwd The current directory. 575 * @param fWatcomBrainDamage The wcc/wcc386 workaround. 576 * @param pcbMsg Where to return the message length. 576 577 */ 577 578 static void *kSubmitComposeJobMessage(const char *pszExecutable, char **papszArgs, char **papszEnvVars, 578 const char *pszCwd, uint32_t *pcbMsg)579 const char *pszCwd, int fWatcomBrainDamage, uint32_t *pcbMsg) 579 580 { 580 581 size_t cbTmp; … … 610 611 cEnvVars = i; 611 612 613 cbMsg += 1; 612 614 613 615 /* … … 649 651 } 650 652 assert(i == cEnvVars); 653 654 *pbCursor++ = fWatcomBrainDamage != 0; 651 655 652 656 assert(pbCursor - pbMsg == (size_t)cbMsg); … … 1544 1548 { 1545 1549 uint32_t cbMsg; 1546 void *pvMsg = kSubmitComposeJobMessage(pszExecutable, &argv[iArg], papszEnv, szCwd, &cbMsg); 1550 void *pvMsg = kSubmitComposeJobMessage(pszExecutable, &argv[iArg], papszEnv, szCwd, 1551 fWatcomBrainDamage, &cbMsg); 1547 1552 PWORKERINSTANCE pWorker = kSubmitSelectWorkSpawnNewIfNecessary(cBitsWorker, cVerbosity); 1548 1553 if (pWorker)
Note:
See TracChangeset
for help on using the changeset viewer.