Changeset 2941 in kBuild for trunk/src/kWorker
- Timestamp:
- Sep 19, 2016 8:01:17 PM (8 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/kWorker/kWorker.c
r2940 r2941 491 491 KWHANDLETYPE_INVALID = 0, 492 492 KWHANDLETYPE_FSOBJ_READ_CACHE, 493 KWHANDLETYPE_FSOBJ_READ_CACHE_MAPPING, 493 494 KWHANDLETYPE_TEMP_FILE, 494 495 KWHANDLETYPE_TEMP_FILE_MAPPING, … … 523 524 } KWHANDLE; 524 525 typedef KWHANDLE *PKWHANDLE; 526 527 /** 528 * Tracking one of our memory mappings. 529 */ 530 typedef struct KWMEMMAPPING 531 { 532 /** Number of references. */ 533 KU32 cRefs; 534 /** The mapping type (KWHANDLETYPE_FSOBJ_READ_CACHE_MAPPING or 535 * KWHANDLETYPE_TEMP_FILE_MAPPING). */ 536 KWHANDLETYPE enmType; 537 /** The mapping address. */ 538 PVOID pvMapping; 539 /** Type specific data. */ 540 union 541 { 542 /** The file system object. */ 543 PKFSWCACHEDFILE pCachedFile; 544 /** Temporary file handle or mapping handle. */ 545 PKWFSTEMPFILE pTempFile; 546 } u; 547 } KWMEMMAPPING; 548 /** Pointer to a memory mapping tracker. */ 549 typedef KWMEMMAPPING *PKWMEMMAPPING; 525 550 526 551 … … 697 722 /** Total number of leaked handles. */ 698 723 KU32 cLeakedHandles; 724 725 /** Number of active memory mappings in paMemMappings. */ 726 KU32 cMemMappings; 727 /** The allocated size of paMemMappings. */ 728 KU32 cMemMappingsAlloc; 729 /** Memory mappings (MapViewOfFile / UnmapViewOfFile). */ 730 PKWMEMMAPPING paMemMappings; 699 731 700 732 /** Head of the list of temporary file. */ … … 5044 5076 5045 5077 /** 5078 * Kernel32 - Common code for kwFsObjCacheCreateFile and CreateFileMappingW/A. 5079 */ 5080 static KBOOL kwFsObjCacheCreateFileHandle(PKFSWCACHEDFILE pCachedFile, DWORD dwDesiredAccess, BOOL fInheritHandle, 5081 KBOOL fIsFileHandle, HANDLE *phFile) 5082 { 5083 HANDLE hProcSelf = GetCurrentProcess(); 5084 if (DuplicateHandle(hProcSelf, pCachedFile->hCached, 5085 hProcSelf, phFile, 5086 dwDesiredAccess, fInheritHandle, 5087 0 /*dwOptions*/)) 5088 { 5089 /* 5090 * Create handle table entry for the duplicate handle. 5091 */ 5092 PKWHANDLE pHandle = (PKWHANDLE)kHlpAlloc(sizeof(*pHandle)); 5093 if (pHandle) 5094 { 5095 pHandle->enmType = fIsFileHandle ? KWHANDLETYPE_FSOBJ_READ_CACHE : KWHANDLETYPE_FSOBJ_READ_CACHE_MAPPING; 5096 pHandle->cRefs = 1; 5097 pHandle->offFile = 0; 5098 pHandle->hHandle = *phFile; 5099 pHandle->dwDesiredAccess = dwDesiredAccess; 5100 pHandle->u.pCachedFile = pCachedFile; 5101 if (kwSandboxHandleTableEnter(&g_Sandbox, pHandle, pHandle->hHandle)) 5102 return K_TRUE; 5103 5104 kHlpFree(pHandle); 5105 } 5106 else 5107 KWFS_LOG(("Out of memory for handle!\n")); 5108 5109 CloseHandle(*phFile); 5110 *phFile = INVALID_HANDLE_VALUE; 5111 } 5112 else 5113 KWFS_LOG(("DuplicateHandle failed! err=%u\n", GetLastError())); 5114 return K_FALSE; 5115 } 5116 5117 5118 /** 5046 5119 * Kernel32 - Common code for CreateFileW and CreateFileA. 5047 5120 */ … … 5049 5122 { 5050 5123 *phFile = INVALID_HANDLE_VALUE; 5051 kHlpAssert(pFsObj->fHaveStats);5052 5124 5053 5125 /* … … 5057 5129 { 5058 5130 PKFSWCACHEDFILE pCachedFile = (PKFSWCACHEDFILE)kFsCacheObjGetUserData(g_pFsCache, pFsObj, KW_DATA_KEY_CACHED_FILE); 5131 kHlpAssert(pFsObj->fHaveStats); 5059 5132 if ( pCachedFile != NULL 5060 5133 || (pCachedFile = kwFsObjCacheNewFile(pFsObj)) != NULL) 5061 5134 { 5062 HANDLE hProcSelf = GetCurrentProcess(); 5063 if (DuplicateHandle(hProcSelf, pCachedFile->hCached, 5064 hProcSelf, phFile, 5065 dwDesiredAccess, fInheritHandle, 5066 0 /*dwOptions*/)) 5067 { 5068 /* 5069 * Create handle table entry for the duplicate handle. 5070 */ 5071 PKWHANDLE pHandle = (PKWHANDLE)kHlpAlloc(sizeof(*pHandle)); 5072 if (pHandle) 5073 { 5074 pHandle->enmType = KWHANDLETYPE_FSOBJ_READ_CACHE; 5075 pHandle->cRefs = 1; 5076 pHandle->offFile = 0; 5077 pHandle->hHandle = *phFile; 5078 pHandle->dwDesiredAccess = dwDesiredAccess; 5079 pHandle->u.pCachedFile = pCachedFile; 5080 if (kwSandboxHandleTableEnter(&g_Sandbox, pHandle, pHandle->hHandle)) 5081 return K_TRUE; 5082 5083 kHlpFree(pHandle); 5084 } 5085 else 5086 KWFS_LOG(("Out of memory for handle!\n")); 5087 5088 CloseHandle(*phFile); 5089 *phFile = INVALID_HANDLE_VALUE; 5090 } 5091 else 5092 KWFS_LOG(("DuplicateHandle failed! err=%u\n", GetLastError())); 5135 if (kwFsObjCacheCreateFileHandle(pCachedFile, dwDesiredAccess, fInheritHandle, K_TRUE /*fIsFileHandle*/, phFile)) 5136 return K_TRUE; 5093 5137 } 5094 5138 } … … 6091 6135 6092 6136 6093 /** Kernel32 - CreateFileMapping */6137 /** Kernel32 - CreateFileMappingW */ 6094 6138 static HANDLE WINAPI kwSandbox_Kernel32_CreateFileMappingW(HANDLE hFile, LPSECURITY_ATTRIBUTES pSecAttrs, 6095 6139 DWORD fProtect, DWORD dwMaximumSizeHigh, … … 6126 6170 } 6127 6171 6172 /* moc.exe benefits from this. */ 6173 case KWHANDLETYPE_FSOBJ_READ_CACHE: 6174 { 6175 PKFSWCACHEDFILE pCachedFile = pHandle->u.pCachedFile; 6176 if ( ( fProtect == PAGE_READONLY 6177 || fProtect == PAGE_EXECUTE_READ) 6178 && dwMaximumSizeHigh == 0 6179 && ( dwMaximumSizeLow == 0 6180 || dwMaximumSizeLow == pCachedFile->cbCached) 6181 && pwszName == NULL) 6182 { 6183 if (kwFsObjCacheCreateFileHandle(pCachedFile, GENERIC_READ, FALSE /*fInheritHandle*/, 6184 K_FALSE /*fIsFileHandle*/, &hMapping)) 6185 { /* likely */ } 6186 else 6187 hMapping = NULL; 6188 KWFS_LOG(("CreateFileMappingW(%p, %u) -> %p [temp]\n", hFile, fProtect, hMapping)); 6189 return hMapping; 6190 } 6191 kHlpAssertMsgFailed(("fProtect=%#x cb=%#x'%08x name=%p\n", 6192 fProtect, dwMaximumSizeHigh, dwMaximumSizeLow, pwszName)); 6193 SetLastError(ERROR_ACCESS_DENIED); 6194 return INVALID_HANDLE_VALUE; 6195 6196 6197 } 6198 6128 6199 /** @todo read cached memory mapped files too for moc. */ 6129 6200 } … … 6137 6208 } 6138 6209 6210 6139 6211 /** Kernel32 - MapViewOfFile */ 6140 6212 static PVOID WINAPI kwSandbox_Kernel32_MapViewOfFile(HANDLE hSection, DWORD dwDesiredAccess, … … 6149 6221 if (pHandle != NULL) 6150 6222 { 6223 KU32 idxMapping; 6224 6225 /* 6226 * Ensure one free entry in the mapping tracking table first, 6227 * since this is common to both temporary and cached files. 6228 */ 6229 if (g_Sandbox.cMemMappings + 1 <= g_Sandbox.cMemMappingsAlloc) 6230 { /* likely */ } 6231 else 6232 { 6233 void *pvNew; 6234 KU32 cNew = g_Sandbox.cMemMappingsAlloc; 6235 if (cNew) 6236 cNew *= 2; 6237 else 6238 cNew = 32; 6239 pvNew = kHlpRealloc(g_Sandbox.paMemMappings, cNew * sizeof(g_Sandbox.paMemMappings)); 6240 if (pvNew) 6241 g_Sandbox.paMemMappings = (PKWMEMMAPPING)pvNew; 6242 else 6243 { 6244 kwErrPrintf("Failed to grow paMemMappings from %#x to %#x!\n", g_Sandbox.cMemMappingsAlloc, cNew); 6245 SetLastError(ERROR_NOT_ENOUGH_MEMORY); 6246 return NULL; 6247 } 6248 g_Sandbox.cMemMappingsAlloc = cNew; 6249 } 6250 6251 /* 6252 * Type specific work. 6253 */ 6151 6254 switch (pHandle->enmType) 6152 6255 { … … 6154 6257 case KWHANDLETYPE_TEMP_FILE: 6155 6258 case KWHANDLETYPE_OUTPUT_BUF: 6259 default: 6156 6260 kHlpAssertFailed(); 6157 6261 SetLastError(ERROR_INVALID_OPERATION); … … 6206 6310 kHlpAssert(pTempFile->cMappings == 1); 6207 6311 6208 KWFS_LOG(("CreateFileMappingW(%p) -> %p [temp]\n", hSection, pTempFile->paSegs[0].pbData)); 6209 return pTempFile->paSegs[0].pbData; 6312 pvRet = pTempFile->paSegs[0].pbData; 6313 KWFS_LOG(("CreateFileMappingW(%p) -> %p [temp]\n", hSection, pvRet)); 6314 break; 6210 6315 } 6211 6316 … … 6215 6320 return NULL; 6216 6321 } 6217 } 6322 6323 /* 6324 * This is simple in comparison to the above temporary file code. 6325 */ 6326 case KWHANDLETYPE_FSOBJ_READ_CACHE_MAPPING: 6327 { 6328 PKFSWCACHEDFILE pCachedFile = pHandle->u.pCachedFile; 6329 if ( dwDesiredAccess == FILE_MAP_READ 6330 && offFileHigh == 0 6331 && offFileLow == 0 6332 && (cbToMap == 0 || cbToMap == pCachedFile->cbCached) ) 6333 { 6334 pvRet = pCachedFile->pbCached; 6335 KWFS_LOG(("CreateFileMappingW(%p) -> %p [cached]\n", hSection, pvRet)); 6336 break; 6337 } 6338 kHlpAssertMsgFailed(("dwDesiredAccess=%#x offFile=%#x'%08x cbToMap=%#x (cbFile=%#x)\n", 6339 dwDesiredAccess, offFileHigh, offFileLow, cbToMap, pCachedFile->cbCached)); 6340 SetLastError(ERROR_NOT_ENOUGH_MEMORY); 6341 return NULL; 6342 } 6343 } 6344 6345 /* 6346 * Insert into the mapping tracking table. This is common 6347 * and we should only get here with a non-NULL pvRet. 6348 * 6349 * Note! We could look for duplicates and do ref counting, but it's 6350 * easier to just append for now. 6351 */ 6352 kHlpAssert(pvRet != NULL); 6353 idxMapping = g_Sandbox.cMemMappings; 6354 kHlpAssert(idxMapping < g_Sandbox.cMemMappingsAlloc); 6355 6356 g_Sandbox.paMemMappings[idxMapping].cRefs = 1; 6357 g_Sandbox.paMemMappings[idxMapping].pvMapping = pvRet; 6358 g_Sandbox.paMemMappings[idxMapping].enmType = pHandle->enmType; 6359 g_Sandbox.paMemMappings[idxMapping].u.pCachedFile = pHandle->u.pCachedFile; 6360 g_Sandbox.cMemMappings++; 6361 6362 return pvRet; 6218 6363 } 6219 6364 } … … 6230 6375 static BOOL WINAPI kwSandbox_Kernel32_UnmapViewOfFile(LPCVOID pvBase) 6231 6376 { 6232 /* Is this one of our temporary mappings? */ 6233 PKWFSTEMPFILE pCur = g_Sandbox.pTempFileHead; 6377 /* 6378 * Consult the memory mapping tracker. 6379 */ 6380 PKWMEMMAPPING paMemMappings = g_Sandbox.paMemMappings; 6381 KU32 idxMapping = g_Sandbox.cMemMappings; 6234 6382 kHlpAssert(GetCurrentThreadId() == g_Sandbox.idMainThread); 6235 while (pCur) 6236 { 6237 if ( pCur->cMappings > 0 6238 && pCur->paSegs[0].pbData == (KU8 *)pvBase) 6239 { 6240 pCur->cMappings--; 6241 KWFS_LOG(("UnmapViewOfFile(%p) -> TRUE [temp]\n", pvBase)); 6383 while (idxMapping-- > 0) 6384 if (paMemMappings[idxMapping].pvMapping == pvBase) 6385 { 6386 /* Type specific stuff. */ 6387 if (paMemMappings[idxMapping].enmType == KWHANDLETYPE_TEMP_FILE_MAPPING) 6388 { 6389 KWFS_LOG(("UnmapViewOfFile(%p) -> TRUE [temp]\n", pvBase)); 6390 paMemMappings[idxMapping].u.pTempFile->cMappings--; 6391 } 6392 else 6393 KWFS_LOG(("UnmapViewOfFile(%p) -> TRUE [cached]\n", pvBase)); 6394 6395 /* Deref and probably free it. */ 6396 if (--paMemMappings[idxMapping].cRefs == 0) 6397 { 6398 g_Sandbox.cMemMappings--; 6399 if (idxMapping != g_Sandbox.cMemMappings) 6400 paMemMappings[idxMapping] = paMemMappings[g_Sandbox.cMemMappings]; 6401 } 6242 6402 return TRUE; 6243 6403 } 6244 pCur = pCur->pNext;6245 }6246 6404 6247 6405 KWFS_LOG(("UnmapViewOfFile(%p)\n", pvBase)); … … 8591 8749 idxHandle, pHandle->hHandle, pHandle->cRefs)); 8592 8750 break; 8751 case KWHANDLETYPE_FSOBJ_READ_CACHE_MAPPING: 8752 KWFS_LOG(("Closing leaked read mapping handle: %#x/%p cRefs=%d\n", 8753 idxHandle, pHandle->hHandle, pHandle->cRefs)); 8754 break; 8593 8755 case KWHANDLETYPE_OUTPUT_BUF: 8594 8756 KWFS_LOG(("Closing leaked output buf handle: %#x/%p cRefs=%d\n", … … 8617 8779 } 8618 8780 8781 /* Reset memory mappings - This assumes none of the DLLs keeps any of our mappings open! */ 8782 g_Sandbox.cMemMappings = 0; 8783 8619 8784 #ifdef WITH_TEMP_MEMORY_FILES 8620 8785 /* The temporary files aren't externally visible, they're all in memory. */ … … 8814 8979 { 8815 8980 kwErrPrintf("Caught exception %#x!\n", GetExceptionCode()); 8981 #ifdef WITH_HISTORY 8982 { 8983 KU32 cPrinted = 0; 8984 while (cPrinted++ < 5) 8985 { 8986 KU32 idx = (g_iHistoryNext + K_ELEMENTS(g_apszHistory) - cPrinted) % K_ELEMENTS(g_apszHistory); 8987 if (g_apszHistory[idx]) 8988 kwErrPrintf("cmd[%d]: %s\n", 1 - cPrinted, g_apszHistory[idx]); 8989 } 8990 } 8991 #endif 8816 8992 rcExit = 512; 8817 8993 }
Note:
See TracChangeset
for help on using the changeset viewer.