Changeset 2861 in kBuild for trunk/src/lib/nt/kFsCache.c
- Timestamp:
- Sep 1, 2016 10:42:55 PM (9 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/lib/nt/kFsCache.c
r2859 r2861 160 160 161 161 /** 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 */ 168 static 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. 163 182 * 164 183 * @returns The string length in wchar_t units. … … 178 197 *puHash = uHash; 179 198 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 */ 209 static 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; 180 218 } 181 219 … … 2351 2389 2352 2390 /** 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. 2354 2393 * 2355 2394 * This will first try the hash table. If not in the hash table, the file … … 2364 2403 * NULL if not a path we care to cache. 2365 2404 * @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. 2367 2408 * @param penmError Where to return details as to why the lookup 2368 2409 * failed. 2369 2410 */ 2370 PKFSOBJ kFsCacheLookupA(PKFSCACHE pCache, const char *pszPath, KFSLOOKUPERROR *penmError) 2411 static PKFSOBJ kFsCacheLookupHashedA(PKFSCACHE pCache, const char *pchPath, KU32 cchPath, KU32 uHashPath, 2412 KFSLOOKUPERROR *penmError) 2371 2413 { 2372 2414 /* 2373 2415 * Do hash table lookup of the path. 2374 2416 */ 2375 KU32 uHashPath;2376 KU32 cchPath = (KU32)kFsCacheStrHashEx(pszPath, &uHashPath);2377 2417 KU32 idxHashTab = uHashPath % K_ELEMENTS(pCache->apAnsiPaths); 2378 2418 PKFSHASHA pHashEntry = pCache->apAnsiPaths[idxHashTab]; … … 2384 2424 if ( pHashEntry->uHashPath == uHashPath 2385 2425 && pHashEntry->cchPath == cchPath 2386 && kHlpMemComp(pHashEntry->pszPath, p szPath, cchPath) == 0)2426 && kHlpMemComp(pHashEntry->pszPath, pchPath, cchPath) == 0) 2387 2427 { 2388 2428 if ( pHashEntry->uCacheGen == KFSOBJ_CACHE_GEN_IGNORE … … 2392 2432 pCache->cLookups++; 2393 2433 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)); 2395 2435 *penmError = pHashEntry->enmError; 2396 2436 if (pHashEntry->pFsObj) … … 2415 2455 /* Is absolute without any '..' bits? */ 2416 2456 if ( cchPath >= 3 2417 && ( ( p szPath[1] == ':' /* Drive letter */2418 && IS_SLASH(p szPath[2])2419 && IS_ALPHA(p szPath[0]) )2420 || ( IS_SLASH(p szPath[0]) /* UNC */2421 && IS_SLASH(p szPath[1]) ) )2422 && !kFsCacheHasDotDotA(p szPath, cchPath) )2423 { 2424 pFsObj = kFsCacheLookupAbsoluteA(pCache, p szPath, 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); 2425 2465 fAbsolute = K_TRUE; 2426 2466 } 2427 2467 else 2428 2468 { 2429 pFsObj = kFsCacheLookupSlowA(pCache, p szPath, cchPath, penmError);2469 pFsObj = kFsCacheLookupSlowA(pCache, pchPath, cchPath, penmError); 2430 2470 fAbsolute = K_FALSE; 2431 2471 } … … 2434 2474 && *penmError != KFSLOOKUPERROR_PATH_TOO_LONG) 2435 2475 || *penmError == KFSLOOKUPERROR_UNSUPPORTED ) 2436 kFsCacheCreatePathHashTabEntryA(pCache, pFsObj, p szPath, cchPath, uHashPath, idxHashTab, fAbsolute, *penmError);2476 kFsCacheCreatePathHashTabEntryA(pCache, pFsObj, pchPath, cchPath, uHashPath, idxHashTab, fAbsolute, *penmError); 2437 2477 2438 2478 pCache->cLookups++; … … 2448 2488 2449 2489 /** 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. 2451 2492 * 2452 2493 * This will first try the hash table. If not in the hash table, the file … … 2457 2498 * point. 2458 2499 * 2459 * @returns Reference to object corresponding to @a p szPath on success, this2500 * @returns Reference to object corresponding to @a pwcPath on success, this 2460 2501 * must be released by kFsCacheObjRelease. 2461 2502 * NULL if not a path we care to cache. 2462 2503 * @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. 2464 2507 * @param penmError Where to return details as to why the lookup 2465 2508 * failed. 2466 2509 */ 2467 PKFSOBJ kFsCacheLookupW(PKFSCACHE pCache, const wchar_t *pwszPath, KFSLOOKUPERROR *penmError) 2510 static PKFSOBJ kFsCacheLookupHashedW(PKFSCACHE pCache, const wchar_t *pwcPath, KU32 cwcPath, KU32 uHashPath, 2511 KFSLOOKUPERROR *penmError) 2468 2512 { 2469 2513 /* 2470 2514 * Do hash table lookup of the path. 2471 2515 */ 2472 KU32 uHashPath;2473 KU32 cwcPath = (KU32)kFsCacheUtf16HashEx(pwszPath, &uHashPath);2474 2516 KU32 idxHashTab = uHashPath % K_ELEMENTS(pCache->apAnsiPaths); 2475 2517 PKFSHASHW pHashEntry = pCache->apUtf16Paths[idxHashTab]; … … 2481 2523 if ( pHashEntry->uHashPath == uHashPath 2482 2524 && pHashEntry->cwcPath == cwcPath 2483 && kHlpMemComp(pHashEntry->pwszPath, pw szPath, cwcPath) == 0)2525 && kHlpMemComp(pHashEntry->pwszPath, pwcPath, cwcPath) == 0) 2484 2526 { 2485 2527 if ( pHashEntry->uCacheGen == KFSOBJ_CACHE_GEN_IGNORE … … 2489 2531 pCache->cLookups++; 2490 2532 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)); 2492 2534 *penmError = pHashEntry->enmError; 2493 2535 if (pHashEntry->pFsObj) … … 2512 2554 /* Is absolute without any '..' bits? */ 2513 2555 if ( cwcPath >= 3 2514 && ( ( pw szPath[1] == ':' /* Drive letter */2515 && IS_SLASH(pw szPath[2])2516 && IS_ALPHA(pw szPath[0]) )2517 || ( IS_SLASH(pw szPath[0]) /* UNC */2518 && IS_SLASH(pw szPath[1]) ) )2519 && !kFsCacheHasDotDotW(pw szPath, cwcPath) )2520 { 2521 pFsObj = kFsCacheLookupAbsoluteW(pCache, pw szPath, 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); 2522 2564 fAbsolute = K_TRUE; 2523 2565 } 2524 2566 else 2525 2567 { 2526 pFsObj = kFsCacheLookupSlowW(pCache, pw szPath, cwcPath, penmError);2568 pFsObj = kFsCacheLookupSlowW(pCache, pwcPath, cwcPath, penmError); 2527 2569 fAbsolute = K_FALSE; 2528 2570 } … … 2531 2573 && *penmError != KFSLOOKUPERROR_PATH_TOO_LONG) 2532 2574 || *penmError == KFSLOOKUPERROR_UNSUPPORTED ) 2533 kFsCacheCreatePathHashTabEntryW(pCache, pFsObj, pw szPath, cwcPath, uHashPath, idxHashTab, fAbsolute, *penmError);2575 kFsCacheCreatePathHashTabEntryW(pCache, pFsObj, pwcPath, cwcPath, uHashPath, idxHashTab, fAbsolute, *penmError); 2534 2576 2535 2577 pCache->cLookups++; … … 2541 2583 *penmError = KFSLOOKUPERROR_PATH_TOO_LONG; 2542 2584 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 */ 2607 PKFSOBJ 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 */ 2633 PKFSOBJ 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 */ 2661 PKFSOBJ 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 */ 2687 PKFSOBJ kFsCacheLookupWithLengthW(PKFSCACHE pCache, const wchar_t *pwcPath, KSIZE cwcPath, KFSLOOKUPERROR *penmError) 2688 { 2689 return kFsCacheLookupHashedW(pCache, pwcPath, (KU32)cwcPath, kFsCacheUtf16HashN(pwcPath, cwcPath), penmError); 2543 2690 } 2544 2691 … … 3005 3152 3006 3153 #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 */ 3169 KBOOL 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 } 3007 3233 3008 3234
Note:
See TracChangeset
for help on using the changeset viewer.