VirtualBox

Changeset 2834 in kBuild


Ignore:
Timestamp:
Aug 23, 2016 12:53:11 AM (9 years ago)
Author:
bird
Message:

kWorker: Next step, speed up header file opening by handle duplication.

File:
1 edited

Legend:

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

    r2833 r2834  
    7272# define KWFS_LOG(a) do { } while (0)
    7373#endif
     74
     75/** Converts a windows handle to a handle table index.
     76 * @note We currently just mask off the 31th bit, and do no shifting or anything
     77 *     else to create an index of the handle.
     78 * @todo consider shifting by 2 or 3. */
     79#define KW_HANDLE_TO_INDEX(a_hHandle)   ((KUPTR)(a_hHandle) & ~(KUPTR)KU32_C(0x8000000))
     80/** Maximum handle value we can deal with.   */
     81#define KW_HANDLE_MAX                   0x20000
    7482
    7583
     
    249257
    250258
     259/** Handle type.   */
     260typedef enum KWHANDLETYPE
     261{
     262    KWHANDLETYPE_INVALID = 0,
     263    KWHANDLETYPE_FSOBJ_READ_CACHE
     264    //KWHANDLETYPE_TEMP_FILE_CACHE,
     265    //KWHANDLETYPE_CONSOLE_CACHE
     266} KWHANDLETYPE;
     267
     268/** Handle data. */
     269typedef struct KWHANDLE
     270{
     271    KWHANDLETYPE        enmType;
     272    /** The current file offset. */
     273    KU32                offFile;
     274    /** The handle. */
     275    HANDLE              hHandle;
     276
     277    /** Type specific data. */
     278    union
     279    {
     280        /** The file system object.   */
     281        PKWFSOBJ            pFsObj;
     282    } u;
     283} KWHANDLE;
     284typedef KWHANDLE *PKWHANDLE;
     285
     286
    251287typedef enum KWTOOLTYPE
    252288{
     
    326362    wchar_t   **wenviron;
    327363
     364
     365    /** Handle table. */
     366    PKWHANDLE      *papHandles;
     367    /** Size of the handle table. */
     368    KU32            cHandles;
     369    /** Number of active handles in the table. */
     370    KU32            cActiveHandles;
    328371
    329372    UNICODE_STRING  SavedCommandLine;
     
    439482static int kwLdrModuleResolveAndLookup(const char *pszName, PKWMODULE pExe, PKWMODULE pImporter, PKWMODULE *ppMod);
    440483static PKWFSOBJ kwFsLookupA(const char *pszPath);
     484static KBOOL kwSandboxHandleTableEnter(PKWSANDBOX pSandbox, PKWHANDLE pHandle);
    441485
    442486
     
    29172961
    29182962
     2963static KBOOL kwFsObjCacheFileCommon(PKWFSOBJ pFsObj, HANDLE hFile)
     2964{
     2965    LARGE_INTEGER cbFile;
     2966    if (GetFileSizeEx(hFile, &cbFile))
     2967    {
     2968        if (   cbFile.QuadPart >= 0
     2969            && cbFile.QuadPart < 16*1024*1024)
     2970        {
     2971            KU32 cbCache = (KU32)cbFile.QuadPart;
     2972            KU8 *pbCache = (KU8 *)kHlpAlloc(cbCache);
     2973            if (pbCache)
     2974            {
     2975                if (ReadFile(hFile, pbCache, cbCache, NULL, NULL))
     2976                {
     2977                    LARGE_INTEGER offZero;
     2978                    offZero.QuadPart = 0;
     2979                    if (SetFilePointerEx(hFile, offZero, NULL /*poffNew*/, FILE_BEGIN))
     2980                    {
     2981                        pFsObj->hCached  = hFile;
     2982                        pFsObj->cbCached = cbCache;
     2983                        pFsObj->pbCached = pbCache;
     2984                        return K_TRUE;
     2985                    }
     2986                    else
     2987                        KWFS_LOG(("Failed to seek to start of cached file! err=%u\n", GetLastError()));
     2988                }
     2989                else
     2990                    KWFS_LOG(("Failed to read %#x bytes into cache! err=%u\n", cbCache, GetLastError()));
     2991                kHlpFree(pbCache);
     2992            }
     2993            else
     2994                KWFS_LOG(("Failed to allocate %#x bytes for cache!\n", cbCache));
     2995        }
     2996        else
     2997            KWFS_LOG(("File to big to cache! %#llx\n", cbFile.QuadPart));
     2998    }
     2999    else
     3000        KWFS_LOG(("File to get file size! err=%u\n", GetLastError()));
     3001    CloseHandle(hFile);
     3002    return K_FALSE;
     3003}
     3004
     3005
     3006static KBOOL kwFsObjCacheFileA(PKWFSOBJ pFsObj, const char *pszFilename)
     3007{
     3008    HANDLE hFile;
     3009    kHlpAssert(pFsObj->hCached == INVALID_HANDLE_VALUE);
     3010
     3011    hFile = CreateFileA(pszFilename, GENERIC_READ, FILE_SHARE_READ, NULL /*pSecAttrs*/,
     3012                        FILE_OPEN_IF, FILE_ATTRIBUTE_NORMAL, NULL /*hTemplateFile*/);
     3013    if (hFile != INVALID_HANDLE_VALUE)
     3014        return kwFsObjCacheFileCommon(pFsObj, hFile);
     3015    return K_FALSE;
     3016}
     3017
     3018
     3019static KBOOL kwFsObjCacheFileW(PKWFSOBJ pFsObj, const wchar_t *pwszFilename)
     3020{
     3021    HANDLE hFile;
     3022    kHlpAssert(pFsObj->hCached == INVALID_HANDLE_VALUE);
     3023
     3024    hFile = CreateFileW(pwszFilename, GENERIC_READ, FILE_SHARE_READ, NULL /*pSecAttrs*/,
     3025                        FILE_OPEN_IF, FILE_ATTRIBUTE_NORMAL, NULL /*hTemplateFile*/);
     3026    if (hFile != INVALID_HANDLE_VALUE)
     3027        return kwFsObjCacheFileCommon(pFsObj, hFile);
     3028    return K_FALSE;
     3029}
     3030
     3031
     3032/** Kernel32 - Common code for CreateFileW and CreateFileA.   */
     3033static KBOOL kwFsObjCacheCreateFile(PKWFSOBJ pFsObj, DWORD dwDesiredAccess, BOOL fInheritHandle,
     3034                                    const char *pszFilename, const wchar_t *pwszFilename, HANDLE *phFile)
     3035{
     3036    *phFile = INVALID_HANDLE_VALUE;
     3037
     3038    /*
     3039     * At the moment we only handle existing files.
     3040     */
     3041    if (!(pFsObj->fAttribs & (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_DEVICE))) /* also checks invalid */
     3042    {
     3043        if (   pFsObj->hCached != INVALID_HANDLE_VALUE
     3044            || (pwszFilename != NULL && kwFsObjCacheFileW(pFsObj, pwszFilename))
     3045            || (pszFilename  != NULL && kwFsObjCacheFileA(pFsObj, pszFilename)) )
     3046        {
     3047            HANDLE hProcSelf = GetCurrentProcess();
     3048            if (DuplicateHandle(hProcSelf, pFsObj->hCached,
     3049                                hProcSelf, phFile,
     3050                                dwDesiredAccess, fInheritHandle,
     3051                                0 /*dwOptions*/))
     3052            {
     3053                /*
     3054                 * Create handle table entry for the duplicate handle.
     3055                 */
     3056                PKWHANDLE pHandle = (PKWHANDLE)kHlpAlloc(sizeof(*pHandle));
     3057                if (pHandle)
     3058                {
     3059                    pHandle->enmType  = KWHANDLETYPE_FSOBJ_READ_CACHE;
     3060                    pHandle->offFile  = 0;
     3061                    pHandle->hHandle  = *phFile;
     3062                    pHandle->u.pFsObj = pFsObj;
     3063                    if (kwSandboxHandleTableEnter(&g_Sandbox, pHandle))
     3064                        return K_TRUE;
     3065
     3066                    kHlpFree(pHandle);
     3067                }
     3068                else
     3069                    KWFS_LOG(("Out of memory for handle!\n"));
     3070
     3071                CloseHandle(*phFile);
     3072                *phFile = INVALID_HANDLE_VALUE;
     3073            }
     3074            else
     3075                KWFS_LOG(("DuplicateHandle failed! err=%u\n", GetLastError()));
     3076        }
     3077    }
     3078    /** @todo Deal with non-existing files if it becomes necessary (it's not for VS2010). */
     3079
     3080    /* Do fallback, please. */
     3081    return K_FALSE;
     3082}
     3083
    29193084/** Kernel32 - CreateFileA */
    29203085static HANDLE WINAPI kwSandbox_Kernel32_CreateFileA(LPCSTR pszFilename, DWORD dwDesiredAccess, DWORD dwShareMode,
     
    29233088{
    29243089    HANDLE hFile;
    2925     if (dwCreationDisposition == FILE_OPEN)
     3090    if (dwCreationDisposition == FILE_OPEN_IF)
    29263091    {
    29273092        if (   dwDesiredAccess == GENERIC_READ
     
    29313096            {
    29323097                if (   !pSecAttrs
    2933                     || (   pSecAttrs->bInheritHandle == FALSE
    2934                         && pSecAttrs->nLength == 0) ) /** @todo This one might not make a lot of sense... */
     3098                    || (   pSecAttrs->nLength == sizeof(*pSecAttrs)
     3099                        && pSecAttrs->lpSecurityDescriptor == NULL ) )
    29353100                {
    29363101                    const char *pszExt = kHlpGetExt(pszFilename);
    29373102                    if (kwFsIsCachableExtensionA(pszExt, K_FALSE /*fAttrQuery*/))
    29383103                    {
    2939                         /** @todo later.   */
     3104                        PKWFSOBJ pFsObj = kwFsLookupA(pszFilename);
     3105                        if (pFsObj)
     3106                        {
     3107                            if (kwFsObjCacheCreateFile(pFsObj, dwDesiredAccess, pSecAttrs && pSecAttrs->bInheritHandle,
     3108                                                       pszFilename, NULL /*pwszFilename*/, &hFile))
     3109                            {
     3110                                KWFS_LOG(("CreateFileA(%s) -> %p [cached]\n", pszFilename, hFile));
     3111                                return hFile;
     3112                            }
     3113                        }
     3114
     3115                        /* fallback */
    29403116                        hFile = CreateFileA(pszFilename, dwDesiredAccess, dwShareMode, pSecAttrs,
    29413117                                            dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile);
    2942                         KWFS_LOG(("CreateFileA(%s) - cachable -> %p\n", pszFilename, hFile));
     3118                        KWFS_LOG(("CreateFileA(%s) -> %p (err=%u) [fallback]\n", pszFilename, hFile, GetLastError()));
    29433119                        return hFile;
    29443120                    }
     
    29613137{
    29623138    HANDLE hFile;
    2963     if (dwCreationDisposition == FILE_OPEN)
     3139    if (dwCreationDisposition == FILE_OPEN_IF)
    29643140    {
    29653141        if (   dwDesiredAccess == GENERIC_READ
     
    29693145            {
    29703146                if (   !pSecAttrs
    2971                     || (   pSecAttrs->bInheritHandle == FALSE
    2972                         && pSecAttrs->nLength == 0) ) /** @todo This one might not make a lot of sense... */
     3147                    || (   pSecAttrs->nLength == sizeof(*pSecAttrs)
     3148                        && pSecAttrs->lpSecurityDescriptor == NULL ) )
    29733149                {
    29743150                    if (kwFsIsCachablePathExtensionW(pwszFilename, K_FALSE /*fAttrQuery*/))
    29753151                    {
    2976                         /** @todo later.   */
    2977 
    2978                         hFile = CreateFileW(pwszFilename, dwDesiredAccess, dwShareMode, pSecAttrs,
    2979                                             dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile);
    2980 
    2981                         KWFS_LOG(("CreateFileW(%ls) - cachable -> %p\n", pwszFilename, hFile));
    2982                         return hFile;
     3152                        /** @todo rewrite to pure UTF-16. */
     3153                        char szTmp[2048];
     3154                        KSIZE cch = kwUtf16ToStr(pwszFilename, szTmp, sizeof(szTmp));
     3155                        if (cch < sizeof(szTmp))
     3156                            return kwSandbox_Kernel32_CreateFileA(szTmp, dwDesiredAccess, dwShareMode, pSecAttrs,
     3157                                                                  dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile);
    29833158                    }
    29843159                }
     3160                else
     3161                    KWFS_LOG(("CreateFileW: incompatible security attributes (nLength=%#x pDesc=%p)\n",
     3162                              pSecAttrs->nLength, pSecAttrs->lpSecurityDescriptor));
    29853163            }
    2986         }
    2987     }
     3164            else
     3165                KWFS_LOG(("CreateFileW: incompatible sharing mode %#x\n", dwShareMode));
     3166        }
     3167        else
     3168            KWFS_LOG(("CreateFileW: incompatible desired access %#x\n", dwDesiredAccess));
     3169    }
     3170    else
     3171        KWFS_LOG(("CreateFileW: incompatible disposition %u\n", dwCreationDisposition));
    29883172    hFile = CreateFileW(pwszFilename, dwDesiredAccess, dwShareMode, pSecAttrs,
    29893173                        dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile);
     
    30223206static BOOL WINAPI kwSandbox_Kernel32_CloseHandle(HANDLE hObject)
    30233207{
    3024     KWFS_LOG(("CloseHandle(%p)\n", hObject));
    3025     return CloseHandle(hObject);
     3208    BOOL        fRet;
     3209    KUPTR const idxHandle = KW_HANDLE_TO_INDEX(hObject);
     3210    if (   idxHandle < g_Sandbox.cHandles
     3211        && g_Sandbox.papHandles[idxHandle] != NULL)
     3212    {
     3213        fRet = CloseHandle(hObject);
     3214        if (fRet)
     3215        {
     3216            PKWHANDLE pHandle = g_Sandbox.papHandles[idxHandle];
     3217            g_Sandbox.papHandles[idxHandle] = NULL;
     3218            g_Sandbox.cActiveHandles--;
     3219            kHlpFree(pHandle);
     3220            KWFS_LOG(("CloseHandle(%p) -> TRUE [intercepted handle]\n", hObject));
     3221        }
     3222        else
     3223            KWFS_LOG(("CloseHandle(%p) -> FALSE [intercepted handle] err=%u!\n", hObject, GetLastError()));
     3224    }
     3225    else
     3226    {
     3227        KWFS_LOG(("CloseHandle(%p)\n", hObject));
     3228        fRet = CloseHandle(hObject);
     3229    }
     3230    return fRet;
    30263231}
    30273232
     
    32093414#endif
    32103415
    3211 #if 0
    32123416    { TUPLE("CreateFileA"),                 NULL,       (KUPTR)kwSandbox_Kernel32_CreateFileA },
    32133417    { TUPLE("CreateFileW"),                 NULL,       (KUPTR)kwSandbox_Kernel32_CreateFileW },
     3418#if 0
    32143419    { TUPLE("ReadFile"),                    NULL,       (KUPTR)kwSandbox_Kernel32_ReadFile },
    32153420    { TUPLE("SetFilePointer"),              NULL,       (KUPTR)kwSandbox_Kernel32_SetFilePointer },
    32163421    { TUPLE("SetFilePointerEx"),            NULL,       (KUPTR)kwSandbox_Kernel32_SetFilePointerEx },
     3422#endif
    32173423    { TUPLE("CloseHandle"),                 NULL,       (KUPTR)kwSandbox_Kernel32_CloseHandle },
    3218 #endif
    32193424    { TUPLE("GetFileAttributesA"),          NULL,       (KUPTR)kwSandbox_Kernel32_GetFileAttributesA },
    32203425    { TUPLE("GetFileAttributesW"),          NULL,       (KUPTR)kwSandbox_Kernel32_GetFileAttributesW },
     
    32713476}
    32723477
     3478
     3479/**
     3480 * Enters the given handle into the handle table.
     3481 *
     3482 * @returns K_TRUE on success, K_FALSE on failure.
     3483 * @param   pSandbox            The sandbox.
     3484 * @param   pHandle             The handle.
     3485 */
     3486static KBOOL kwSandboxHandleTableEnter(PKWSANDBOX pSandbox, PKWHANDLE pHandle)
     3487{
     3488    KUPTR const idxHandle = KW_HANDLE_TO_INDEX(pHandle->hHandle);
     3489    kHlpAssertReturn(idxHandle < KW_HANDLE_MAX, K_FALSE);
     3490
     3491    /*
     3492     * Grow handle table.
     3493     */
     3494    if (idxHandle >= pSandbox->cHandles)
     3495    {
     3496        void *pvNew;
     3497        KU32  cHandles = pSandbox->cHandles ? pSandbox->cHandles * 2 : 32;
     3498        while (cHandles <= idxHandle)
     3499            cHandles *= 2;
     3500        pvNew = kHlpRealloc(pSandbox->papHandles, cHandles * sizeof(pSandbox->papHandles[0]));
     3501        if (!pvNew)
     3502        {
     3503            KW_LOG(("Out of memory growing handle table to %u handles\n", cHandles));
     3504            return K_FALSE;
     3505        }
     3506        pSandbox->papHandles = (PKWHANDLE *)pvNew;
     3507        kHlpMemSet(&pSandbox->papHandles[pSandbox->cHandles], 0,
     3508                   (cHandles - pSandbox->cHandles) * sizeof(pSandbox->papHandles[0]));
     3509        pSandbox->cHandles = cHandles;
     3510    }
     3511
     3512    /*
     3513     * Check that the entry is unused then insert it.
     3514     */
     3515    kHlpAssertReturn(pSandbox->papHandles[idxHandle] == NULL, K_FALSE);
     3516    pSandbox->papHandles[idxHandle] = pHandle;
     3517    pSandbox->cActiveHandles++;
     3518    return K_TRUE;
     3519}
    32733520
    32743521
     
    34543701    int i;
    34553702    argv[2] = "\"E:/vbox/svn/trunk/tools/win.x86/vcc/v10sp1/bin/amd64/cl.exe\" -c -c -TP -nologo -Zi -Zi -Zl -GR- -EHsc -GF -Zc:wchar_t- -Oy- -MT -W4 -Wall -wd4065 -wd4996 -wd4127 -wd4706 -wd4201 -wd4214 -wd4510 -wd4512 -wd4610 -wd4514 -wd4820 -wd4365 -wd4987 -wd4710 -wd4061 -wd4986 -wd4191 -wd4574 -wd4917 -wd4711 -wd4611 -wd4571 -wd4324 -wd4505 -wd4263 -wd4264 -wd4738 -wd4242 -wd4244 -WX -RTCsu -IE:/vbox/svn/trunk/tools/win.x86/vcc/v10sp1/include -IE:/vbox/svn/trunk/tools/win.x86/vcc/v10sp1/atlmfc/include -IE:/vbox/svn/trunk/tools/win.x86/sdk/v7.1/Include -IE:/vbox/svn/trunk/include -IE:/vbox/svn/trunk/out/win.amd64/debug -IE:/vbox/svn/trunk/tools/win.x86/vcc/v10sp1/include -IE:/vbox/svn/trunk/tools/win.x86/vcc/v10sp1/atlmfc/include -DVBOX -DVBOX_WITH_64_BITS_GUESTS -DVBOX_WITH_REM -DVBOX_WITH_RAW_MODE -DDEBUG -DDEBUG_bird -DDEBUG_USERNAME=bird -DRT_OS_WINDOWS -D__WIN__ -DRT_ARCH_AMD64 -D__AMD64__ -D__WIN64__ -DVBOX_WITH_DEBUGGER -DRT_LOCK_STRICT -DRT_LOCK_STRICT_ORDER -DIN_RING3 -DLOG_DISABLED -DIN_BLD_PROG -D_CRT_SECURE_NO_DEPRECATE -FdE:/vbox/svn/trunk/out/win.amd64/debug/obj/VBoxBs2Linker/VBoxBs2Linker-obj.pdb -FD -FoE:/vbox/svn/trunk/out/win.amd64/debug/obj/VBoxBs2Linker/VBoxBs2Linker.obj E:\\vbox\\svn\\trunk\\src\\VBox\\ValidationKit\\bootsectors\\VBoxBs2Linker.cpp";
    3456 #if 0
     3703#if 1
    34573704    rc = kwExecCmdLine(argv[1], argv[2]);
    3458     rc = kwExecCmdLine(argv[1], argv[2]);
     3705    //rc = kwExecCmdLine(argv[1], argv[2]);
    34593706    K_NOREF(i);
    34603707#else
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