VirtualBox

Changeset 2941 in kBuild for trunk/src/kWorker


Ignore:
Timestamp:
Sep 19, 2016 8:01:17 PM (8 years ago)
Author:
bird
Message:

kWorker: More moc work - mainly related to mapping read cached files.

File:
1 edited

Legend:

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

    r2940 r2941  
    491491    KWHANDLETYPE_INVALID = 0,
    492492    KWHANDLETYPE_FSOBJ_READ_CACHE,
     493    KWHANDLETYPE_FSOBJ_READ_CACHE_MAPPING,
    493494    KWHANDLETYPE_TEMP_FILE,
    494495    KWHANDLETYPE_TEMP_FILE_MAPPING,
     
    523524} KWHANDLE;
    524525typedef KWHANDLE *PKWHANDLE;
     526
     527/**
     528 * Tracking one of our memory mappings.
     529 */
     530typedef 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. */
     549typedef KWMEMMAPPING *PKWMEMMAPPING;
    525550
    526551
     
    697722    /** Total number of leaked handles. */
    698723    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;
    699731
    700732    /** Head of the list of temporary file. */
     
    50445076
    50455077/**
     5078 * Kernel32 - Common code for kwFsObjCacheCreateFile and CreateFileMappingW/A.
     5079 */
     5080static 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/**
    50465119 * Kernel32 - Common code for CreateFileW and CreateFileA.
    50475120 */
     
    50495122{
    50505123    *phFile = INVALID_HANDLE_VALUE;
    5051     kHlpAssert(pFsObj->fHaveStats);
    50525124
    50535125    /*
     
    50575129    {
    50585130        PKFSWCACHEDFILE pCachedFile = (PKFSWCACHEDFILE)kFsCacheObjGetUserData(g_pFsCache, pFsObj, KW_DATA_KEY_CACHED_FILE);
     5131        kHlpAssert(pFsObj->fHaveStats);
    50595132        if (   pCachedFile != NULL
    50605133            || (pCachedFile = kwFsObjCacheNewFile(pFsObj)) != NULL)
    50615134        {
    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;
    50935137        }
    50945138    }
     
    60916135
    60926136
    6093 /** Kernel32 - CreateFileMapping  */
     6137/** Kernel32 - CreateFileMappingW  */
    60946138static HANDLE WINAPI kwSandbox_Kernel32_CreateFileMappingW(HANDLE hFile, LPSECURITY_ATTRIBUTES pSecAttrs,
    60956139                                                           DWORD fProtect, DWORD dwMaximumSizeHigh,
     
    61266170                }
    61276171
     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
    61286199                /** @todo read cached memory mapped files too for moc.   */
    61296200            }
     
    61376208}
    61386209
     6210
    61396211/** Kernel32 - MapViewOfFile  */
    61406212static PVOID WINAPI kwSandbox_Kernel32_MapViewOfFile(HANDLE hSection, DWORD dwDesiredAccess,
     
    61496221        if (pHandle != NULL)
    61506222        {
     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             */
    61516254            switch (pHandle->enmType)
    61526255            {
     
    61546257                case KWHANDLETYPE_TEMP_FILE:
    61556258                case KWHANDLETYPE_OUTPUT_BUF:
     6259                default:
    61566260                    kHlpAssertFailed();
    61576261                    SetLastError(ERROR_INVALID_OPERATION);
     
    62066310                        kHlpAssert(pTempFile->cMappings == 1);
    62076311
    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;
    62106315                    }
    62116316
     
    62156320                    return NULL;
    62166321                }
    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;
    62186363        }
    62196364    }
     
    62306375static BOOL WINAPI kwSandbox_Kernel32_UnmapViewOfFile(LPCVOID pvBase)
    62316376{
    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;
    62346382    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            }
    62426402            return TRUE;
    62436403        }
    6244         pCur = pCur->pNext;
    6245     }
    62466404
    62476405    KWFS_LOG(("UnmapViewOfFile(%p)\n", pvBase));
     
    85918749                                      idxHandle, pHandle->hHandle, pHandle->cRefs));
    85928750                            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;
    85938755                        case KWHANDLETYPE_OUTPUT_BUF:
    85948756                            KWFS_LOG(("Closing leaked output buf handle: %#x/%p cRefs=%d\n",
     
    86178779    }
    86188780
     8781    /* Reset memory mappings - This assumes none of the DLLs keeps any of our mappings open! */
     8782    g_Sandbox.cMemMappings = 0;
     8783
    86198784#ifdef WITH_TEMP_MEMORY_FILES
    86208785    /* The temporary files aren't externally visible, they're all in memory. */
     
    88148979            {
    88158980                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
    88168992                rcExit = 512;
    88178993            }
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette