VirtualBox

Changeset 2861 in kBuild for trunk/src/lib/nt/kFsCache.c


Ignore:
Timestamp:
Sep 1, 2016 10:42:55 PM (9 years ago)
Author:
bird
Message:

Updates

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/lib/nt/kFsCache.c

    r2859 r2861  
    160160
    161161/**
    162  * Hashes a string.
     162 * Hashes a substring.
     163 *
     164 * @returns 32-bit substring hash.
     165 * @param   pchString           Pointer to the substring (not terminated).
     166 * @param   cchString           The length of the substring.
     167 */
     168static KU32 kFsCacheStrHashN(const char *pszString, KSIZE cchString)
     169{
     170    KU32 uHash = 0;
     171    while (cchString-- > 0)
     172    {
     173        KU32 uChar = (unsigned char)*pszString++;
     174        uHash = uChar + (uHash << 6) + (uHash << 16) - uHash;
     175    }
     176    return uHash;
     177}
     178
     179
     180/**
     181 * Hashes a UTF-16 string.
    163182 *
    164183 * @returns The string length in wchar_t units.
     
    178197    *puHash = uHash;
    179198    return pwszString - pwszStart;
     199}
     200
     201
     202/**
     203 * Hashes a UTF-16 substring.
     204 *
     205 * @returns 32-bit substring hash.
     206 * @param   pwcString           Pointer to the substring (not terminated).
     207 * @param   cchString           The length of the substring (in wchar_t's).
     208 */
     209static KU32 kFsCacheUtf16HashN(const wchar_t *pwcString, KSIZE cwcString)
     210{
     211    KU32 uHash = 0;
     212    while (cwcString-- > 0)
     213    {
     214        KU32 uChar = *pwcString++;
     215        uHash = uChar + (uHash << 6) + (uHash << 16) - uHash;
     216    }
     217    return uHash;
    180218}
    181219
     
    23512389
    23522390/**
    2353  * Looks up a KFSOBJ for the given ANSI path.
     2391 * Internal lookup worker that looks up a KFSOBJ for the given ANSI path with
     2392 * length and hash.
    23542393 *
    23552394 * This will first try the hash table.  If not in the hash table, the file
     
    23642403 *          NULL if not a path we care to cache.
    23652404 * @param   pCache              The cache.
    2366  * @param   pszPath             The path to lookup.
     2405 * @param   pchPath             The path to lookup.
     2406 * @param   cchPath             The path length.
     2407 * @param   uHashPath           The hash of the path.
    23672408 * @param   penmError           Where to return details as to why the lookup
    23682409 *                              failed.
    23692410 */
    2370 PKFSOBJ kFsCacheLookupA(PKFSCACHE pCache, const char *pszPath, KFSLOOKUPERROR *penmError)
     2411static PKFSOBJ kFsCacheLookupHashedA(PKFSCACHE pCache, const char *pchPath, KU32 cchPath, KU32 uHashPath,
     2412                                     KFSLOOKUPERROR *penmError)
    23712413{
    23722414    /*
    23732415     * Do hash table lookup of the path.
    23742416     */
    2375     KU32        uHashPath;
    2376     KU32        cchPath    = (KU32)kFsCacheStrHashEx(pszPath, &uHashPath);
    23772417    KU32        idxHashTab = uHashPath % K_ELEMENTS(pCache->apAnsiPaths);
    23782418    PKFSHASHA   pHashEntry = pCache->apAnsiPaths[idxHashTab];
     
    23842424            if (   pHashEntry->uHashPath == uHashPath
    23852425                && pHashEntry->cchPath   == cchPath
    2386                 && kHlpMemComp(pHashEntry->pszPath, pszPath, cchPath) == 0)
     2426                && kHlpMemComp(pHashEntry->pszPath, pchPath, cchPath) == 0)
    23872427            {
    23882428                if (   pHashEntry->uCacheGen == KFSOBJ_CACHE_GEN_IGNORE
     
    23922432                    pCache->cLookups++;
    23932433                    pCache->cPathHashHits++;
    2394                     KFSCACHE_LOG(("kFsCacheLookupA(%s) - hit %p\n", pszPath, pHashEntry->pFsObj));
     2434                    KFSCACHE_LOG(("kFsCacheLookupA(%*.*s) - hit %p\n", cchPath, cchPath, pchPath, pHashEntry->pFsObj));
    23952435                    *penmError = pHashEntry->enmError;
    23962436                    if (pHashEntry->pFsObj)
     
    24152455        /* Is absolute without any '..' bits? */
    24162456        if (   cchPath >= 3
    2417             && (   (   pszPath[1] == ':'    /* Drive letter */
    2418                     && IS_SLASH(pszPath[2])
    2419                     && IS_ALPHA(pszPath[0]) )
    2420                 || (   IS_SLASH(pszPath[0]) /* UNC */
    2421                     && IS_SLASH(pszPath[1]) ) )
    2422             && !kFsCacheHasDotDotA(pszPath, cchPath) )
    2423         {
    2424             pFsObj = kFsCacheLookupAbsoluteA(pCache, pszPath, cchPath, penmError);
     2457            && (   (   pchPath[1] == ':'    /* Drive letter */
     2458                    && IS_SLASH(pchPath[2])
     2459                    && IS_ALPHA(pchPath[0]) )
     2460                || (   IS_SLASH(pchPath[0]) /* UNC */
     2461                    && IS_SLASH(pchPath[1]) ) )
     2462            && !kFsCacheHasDotDotA(pchPath, cchPath) )
     2463        {
     2464            pFsObj = kFsCacheLookupAbsoluteA(pCache, pchPath, cchPath, penmError);
    24252465            fAbsolute = K_TRUE;
    24262466        }
    24272467        else
    24282468        {
    2429             pFsObj = kFsCacheLookupSlowA(pCache, pszPath, cchPath, penmError);
     2469            pFsObj = kFsCacheLookupSlowA(pCache, pchPath, cchPath, penmError);
    24302470            fAbsolute = K_FALSE;
    24312471        }
     
    24342474                && *penmError != KFSLOOKUPERROR_PATH_TOO_LONG)
    24352475            || *penmError == KFSLOOKUPERROR_UNSUPPORTED )
    2436             kFsCacheCreatePathHashTabEntryA(pCache, pFsObj, pszPath, cchPath, uHashPath, idxHashTab, fAbsolute, *penmError);
     2476            kFsCacheCreatePathHashTabEntryA(pCache, pFsObj, pchPath, cchPath, uHashPath, idxHashTab, fAbsolute, *penmError);
    24372477
    24382478        pCache->cLookups++;
     
    24482488
    24492489/**
    2450  * Looks up a KFSOBJ for the given UTF-16 path.
     2490 * Internal lookup worker that looks up a KFSOBJ for the given UTF-16 path with
     2491 * length and hash.
    24512492 *
    24522493 * This will first try the hash table.  If not in the hash table, the file
     
    24572498 * point.
    24582499 *
    2459  * @returns Reference to object corresponding to @a pszPath on success, this
     2500 * @returns Reference to object corresponding to @a pwcPath on success, this
    24602501 *          must be released by kFsCacheObjRelease.
    24612502 *          NULL if not a path we care to cache.
    24622503 * @param   pCache              The cache.
    2463  * @param   pwszPath            The path to lookup.
     2504 * @param   pwcPath             The path to lookup.
     2505 * @param   cwcPath             The length of the path (in wchar_t's).
     2506 * @param   uHashPath           The hash of the path.
    24642507 * @param   penmError           Where to return details as to why the lookup
    24652508 *                              failed.
    24662509 */
    2467 PKFSOBJ kFsCacheLookupW(PKFSCACHE pCache, const wchar_t *pwszPath, KFSLOOKUPERROR *penmError)
     2510static PKFSOBJ kFsCacheLookupHashedW(PKFSCACHE pCache, const wchar_t *pwcPath, KU32 cwcPath, KU32 uHashPath,
     2511                                     KFSLOOKUPERROR *penmError)
    24682512{
    24692513    /*
    24702514     * Do hash table lookup of the path.
    24712515     */
    2472     KU32        uHashPath;
    2473     KU32        cwcPath    = (KU32)kFsCacheUtf16HashEx(pwszPath, &uHashPath);
    24742516    KU32        idxHashTab = uHashPath % K_ELEMENTS(pCache->apAnsiPaths);
    24752517    PKFSHASHW   pHashEntry = pCache->apUtf16Paths[idxHashTab];
     
    24812523            if (   pHashEntry->uHashPath == uHashPath
    24822524                && pHashEntry->cwcPath   == cwcPath
    2483                 && kHlpMemComp(pHashEntry->pwszPath, pwszPath, cwcPath) == 0)
     2525                && kHlpMemComp(pHashEntry->pwszPath, pwcPath, cwcPath) == 0)
    24842526            {
    24852527                if (   pHashEntry->uCacheGen == KFSOBJ_CACHE_GEN_IGNORE
     
    24892531                    pCache->cLookups++;
    24902532                    pCache->cPathHashHits++;
    2491                     KFSCACHE_LOG(("kFsCacheLookupW(%ls) - hit %p\n", pwszPath, pHashEntry->pFsObj));
     2533                    KFSCACHE_LOG(("kFsCacheLookupW(%*.*ls) - hit %p\n", cwcPath, cwcPath, pwcPath, pHashEntry->pFsObj));
    24922534                    *penmError = pHashEntry->enmError;
    24932535                    if (pHashEntry->pFsObj)
     
    25122554        /* Is absolute without any '..' bits? */
    25132555        if (   cwcPath >= 3
    2514             && (   (   pwszPath[1] == ':'    /* Drive letter */
    2515                     && IS_SLASH(pwszPath[2])
    2516                     && IS_ALPHA(pwszPath[0]) )
    2517                 || (   IS_SLASH(pwszPath[0]) /* UNC */
    2518                     && IS_SLASH(pwszPath[1]) ) )
    2519             && !kFsCacheHasDotDotW(pwszPath, cwcPath) )
    2520         {
    2521             pFsObj = kFsCacheLookupAbsoluteW(pCache, pwszPath, cwcPath, penmError);
     2556            && (   (   pwcPath[1] == ':'    /* Drive letter */
     2557                    && IS_SLASH(pwcPath[2])
     2558                    && IS_ALPHA(pwcPath[0]) )
     2559                || (   IS_SLASH(pwcPath[0]) /* UNC */
     2560                    && IS_SLASH(pwcPath[1]) ) )
     2561            && !kFsCacheHasDotDotW(pwcPath, cwcPath) )
     2562        {
     2563            pFsObj = kFsCacheLookupAbsoluteW(pCache, pwcPath, cwcPath, penmError);
    25222564            fAbsolute = K_TRUE;
    25232565        }
    25242566        else
    25252567        {
    2526             pFsObj = kFsCacheLookupSlowW(pCache, pwszPath, cwcPath, penmError);
     2568            pFsObj = kFsCacheLookupSlowW(pCache, pwcPath, cwcPath, penmError);
    25272569            fAbsolute = K_FALSE;
    25282570        }
     
    25312573                && *penmError != KFSLOOKUPERROR_PATH_TOO_LONG)
    25322574            || *penmError == KFSLOOKUPERROR_UNSUPPORTED )
    2533             kFsCacheCreatePathHashTabEntryW(pCache, pFsObj, pwszPath, cwcPath, uHashPath, idxHashTab, fAbsolute, *penmError);
     2575            kFsCacheCreatePathHashTabEntryW(pCache, pFsObj, pwcPath, cwcPath, uHashPath, idxHashTab, fAbsolute, *penmError);
    25342576
    25352577        pCache->cLookups++;
     
    25412583    *penmError = KFSLOOKUPERROR_PATH_TOO_LONG;
    25422584    return NULL;
     2585}
     2586
     2587
     2588
     2589/**
     2590 * Looks up a KFSOBJ for the given ANSI path.
     2591 *
     2592 * This will first try the hash table.  If not in the hash table, the file
     2593 * system cache tree is walked, missing bits filled in and finally a hash table
     2594 * entry is created.
     2595 *
     2596 * Only drive letter paths are cachable.  We don't do any UNC paths at this
     2597 * point.
     2598 *
     2599 * @returns Reference to object corresponding to @a pszPath on success, this
     2600 *          must be released by kFsCacheObjRelease.
     2601 *          NULL if not a path we care to cache.
     2602 * @param   pCache              The cache.
     2603 * @param   pszPath             The path to lookup.
     2604 * @param   penmError           Where to return details as to why the lookup
     2605 *                              failed.
     2606 */
     2607PKFSOBJ kFsCacheLookupA(PKFSCACHE pCache, const char *pszPath, KFSLOOKUPERROR *penmError)
     2608{
     2609    KU32 uHashPath;
     2610    KU32 cchPath = (KU32)kFsCacheStrHashEx(pszPath, &uHashPath);
     2611    return kFsCacheLookupHashedA(pCache, pszPath, cchPath, uHashPath, penmError);
     2612}
     2613
     2614
     2615/**
     2616 * Looks up a KFSOBJ for the given UTF-16 path.
     2617 *
     2618 * This will first try the hash table.  If not in the hash table, the file
     2619 * system cache tree is walked, missing bits filled in and finally a hash table
     2620 * entry is created.
     2621 *
     2622 * Only drive letter paths are cachable.  We don't do any UNC paths at this
     2623 * point.
     2624 *
     2625 * @returns Reference to object corresponding to @a pwszPath on success, this
     2626 *          must be released by kFsCacheObjRelease.
     2627 *          NULL if not a path we care to cache.
     2628 * @param   pCache              The cache.
     2629 * @param   pwszPath            The path to lookup.
     2630 * @param   penmError           Where to return details as to why the lookup
     2631 *                              failed.
     2632 */
     2633PKFSOBJ kFsCacheLookupW(PKFSCACHE pCache, const wchar_t *pwszPath, KFSLOOKUPERROR *penmError)
     2634{
     2635    KU32 uHashPath;
     2636    KU32 cwcPath = (KU32)kFsCacheUtf16HashEx(pwszPath, &uHashPath);
     2637    return kFsCacheLookupHashedW(pCache, pwszPath, cwcPath, uHashPath, penmError);
     2638}
     2639
     2640
     2641/**
     2642 * Looks up a KFSOBJ for the given ANSI path.
     2643 *
     2644 * This will first try the hash table.  If not in the hash table, the file
     2645 * system cache tree is walked, missing bits filled in and finally a hash table
     2646 * entry is created.
     2647 *
     2648 * Only drive letter paths are cachable.  We don't do any UNC paths at this
     2649 * point.
     2650 *
     2651 * @returns Reference to object corresponding to @a pchPath on success, this
     2652 *          must be released by kFsCacheObjRelease.
     2653 *          NULL if not a path we care to cache.
     2654 * @param   pCache              The cache.
     2655 * @param   pchPath             The path to lookup (does not need to be nul
     2656 *                              terminated).
     2657 * @param   cchPath             The path length.
     2658 * @param   penmError           Where to return details as to why the lookup
     2659 *                              failed.
     2660 */
     2661PKFSOBJ kFsCacheLookupWithLengthA(PKFSCACHE pCache, const char *pchPath, KSIZE cchPath, KFSLOOKUPERROR *penmError)
     2662{
     2663    return kFsCacheLookupHashedA(pCache, pchPath, (KU32)cchPath, kFsCacheStrHashN(pchPath, cchPath), penmError);
     2664}
     2665
     2666
     2667/**
     2668 * Looks up a KFSOBJ for the given UTF-16 path.
     2669 *
     2670 * This will first try the hash table.  If not in the hash table, the file
     2671 * system cache tree is walked, missing bits filled in and finally a hash table
     2672 * entry is created.
     2673 *
     2674 * Only drive letter paths are cachable.  We don't do any UNC paths at this
     2675 * point.
     2676 *
     2677 * @returns Reference to object corresponding to @a pwchPath on success, this
     2678 *          must be released by kFsCacheObjRelease.
     2679 *          NULL if not a path we care to cache.
     2680 * @param   pCache              The cache.
     2681 * @param   pwcPath             The path to lookup (does not need to be nul
     2682 *                              terminated).
     2683 * @param   cwcPath             The path length (in wchar_t's).
     2684 * @param   penmError           Where to return details as to why the lookup
     2685 *                              failed.
     2686 */
     2687PKFSOBJ kFsCacheLookupWithLengthW(PKFSCACHE pCache, const wchar_t *pwcPath, KSIZE cwcPath, KFSLOOKUPERROR *penmError)
     2688{
     2689    return kFsCacheLookupHashedW(pCache, pwcPath, (KU32)cwcPath, kFsCacheUtf16HashN(pwcPath, cwcPath), penmError);
    25432690}
    25442691
     
    30053152
    30063153#endif /* KFSCACHE_CFG_SHORT_NAMES */
     3154
     3155
     3156
     3157/**
     3158 * Read the specified bits from the files into the given buffer, simple version.
     3159 *
     3160 * @returns K_TRUE on success (all requested bytes read),
     3161 *          K_FALSE on any kind of failure.
     3162 *
     3163 * @param   pCache              The cache.
     3164 * @param   pFileObj            The file object.
     3165 * @param   offStart            Where to start reading.
     3166 * @param   pvBuf               Where to store what we read.
     3167 * @param   cbToRead            How much to read (exact).
     3168 */
     3169KBOOL kFsCacheFileSimpleOpenReadClose(PKFSCACHE pCache, PKFSOBJ pFileObj, KU64 offStart, void *pvBuf, KSIZE cbToRead)
     3170{
     3171    /*
     3172     * Open the file relative to the parent directory.
     3173     */
     3174    MY_NTSTATUS             rcNt;
     3175    HANDLE                  hFile;
     3176    MY_IO_STATUS_BLOCK      Ios;
     3177    MY_OBJECT_ATTRIBUTES    ObjAttr;
     3178    MY_UNICODE_STRING       UniStr;
     3179
     3180    kHlpAssertReturn(pFileObj->bObjType == KFSOBJ_TYPE_FILE, K_FALSE);
     3181    kHlpAssert(pFileObj->pParent);
     3182    kHlpAssertReturn(pFileObj->pParent->hDir != INVALID_HANDLE_VALUE, K_FALSE);
     3183    kHlpAssertReturn(offStart == 0, K_FALSE); /** @todo when needed */
     3184
     3185    Ios.Information = -1;
     3186    Ios.u.Status    = -1;
     3187
     3188    UniStr.Buffer        = (wchar_t *)pFileObj->pwszName;
     3189    UniStr.Length        = (USHORT)(pFileObj->cwcName * sizeof(wchar_t));
     3190    UniStr.MaximumLength = UniStr.Length + sizeof(wchar_t);
     3191
     3192    MyInitializeObjectAttributes(&ObjAttr, &UniStr, OBJ_CASE_INSENSITIVE, pFileObj->pParent->hDir, NULL /*pSecAttr*/);
     3193
     3194    rcNt = g_pfnNtCreateFile(&hFile,
     3195                             GENERIC_READ | SYNCHRONIZE,
     3196                             &ObjAttr,
     3197                             &Ios,
     3198                             NULL, /*cbFileInitialAlloc */
     3199                             FILE_ATTRIBUTE_NORMAL,
     3200                             FILE_SHARE_READ,
     3201                             FILE_OPEN,
     3202                             FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT,
     3203                             NULL, /*pEaBuffer*/
     3204                             0);   /*cbEaBuffer*/
     3205    if (MY_NT_SUCCESS(rcNt))
     3206    {
     3207        LARGE_INTEGER offFile;
     3208        offFile.QuadPart = offStart;
     3209
     3210        Ios.Information = -1;
     3211        Ios.u.Status    = -1;
     3212        rcNt = g_pfnNtReadFile(hFile, NULL /*hEvent*/, NULL /*pfnApcComplete*/, NULL /*pvApcCtx*/, &Ios,
     3213                               pvBuf, (KU32)cbToRead, !offStart ? &offFile : NULL, NULL /*puKey*/);
     3214        if (MY_NT_SUCCESS(rcNt))
     3215            rcNt = Ios.u.Status;
     3216        if (MY_NT_SUCCESS(rcNt))
     3217        {
     3218            if (Ios.Information == cbToRead)
     3219            {
     3220                g_pfnNtClose(hFile);
     3221                return K_TRUE;
     3222            }
     3223            KFSCACHE_LOG(("Error reading %#x bytes from '%ls': Information=%p\n", pFileObj->pwszName, Ios.Information));
     3224        }
     3225        else
     3226            KFSCACHE_LOG(("Error reading %#x bytes from '%ls': %#x\n", pFileObj->pwszName, rcNt));
     3227        g_pfnNtClose(hFile);
     3228    }
     3229    else
     3230        KFSCACHE_LOG(("Error opening '%ls' for caching: %#x\n", pFileObj->pwszName, rcNt));
     3231    return K_FALSE;
     3232}
    30073233
    30083234
Note: See TracChangeset for help on using the changeset viewer.

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