Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1330 lines
34 KiB

  1. /*++
  2. Copyright (c) 1994 Microsoft Corporation
  3. Module Name:
  4. cachapia.cxx
  5. Abstract:
  6. contains the ANSI version of cache mangemant APIs.
  7. Author:
  8. Madan Appiah (madana) 12-Dec-1994
  9. Environment:
  10. User Mode - Win32
  11. Revision History:
  12. --*/
  13. #include <cache.hxx>
  14. /*-----------------------------------------------------------------------------
  15. CreateContainer
  16. ----------------------------------------------------------------------------*/
  17. URLCACHEAPI_(BOOL) CreateUrlCacheContainerA(
  18. IN LPCSTR Name,
  19. IN LPCSTR CachePrefix,
  20. IN LPCSTR CachePath,
  21. IN DWORD KBCacheLimit,
  22. IN DWORD dwContainerType,
  23. IN DWORD dwOptions,
  24. IN OUT LPVOID pvBuffer,
  25. IN OUT LPDWORD cbBuffer
  26. )
  27. {
  28. ENTER_CACHE_API ((DBG_API, Bool, "CreateUrlCacheContainerA", "%q, %q, %q, %d, %d, %d, %#x, %#x",
  29. Name, CachePrefix, CachePath, KBCacheLimit, dwContainerType, dwOptions, pvBuffer, cbBuffer));
  30. DWORD Error;
  31. // Initialize globals
  32. if (!InitGlobals())
  33. {
  34. Error = ERROR_INTERNET_INTERNAL_ERROR;
  35. goto Cleanup;
  36. }
  37. Error = GlobalUrlContainers->CreateContainer(
  38. Name,
  39. CachePrefix,
  40. CachePath,
  41. KBCacheLimit,
  42. dwOptions);
  43. LEAVE_CACHE_API();
  44. }
  45. URLCACHEAPI_(BOOL) DeleteUrlCacheContainerA(
  46. IN LPCSTR Name,
  47. IN DWORD dwOptions)
  48. {
  49. ENTER_CACHE_API ((DBG_API, Bool, "DeleteContainerA", "%q, %d", Name, dwOptions));
  50. DWORD Error;
  51. // Initialize globals
  52. if (!InitGlobals())
  53. {
  54. Error = ERROR_INTERNET_INTERNAL_ERROR;
  55. goto Cleanup;
  56. }
  57. Error = GlobalUrlContainers->DeleteContainer(
  58. Name,
  59. 0
  60. );
  61. LEAVE_CACHE_API();
  62. }
  63. URLCACHEAPI_(HANDLE) FindFirstUrlCacheContainerA(
  64. IN OUT LPDWORD pdwModified,
  65. OUT LPINTERNET_CACHE_CONTAINER_INFOA lpContainerInfo,
  66. IN OUT LPDWORD lpdwContainerInfoBufferSize,
  67. IN DWORD dwOptions
  68. )
  69. {
  70. ENTER_CACHE_API ((DBG_API, Bool, "FindFirstContainerA",
  71. "%#x, %#x, %#x, %#x",
  72. pdwModified,
  73. lpContainerInfo,
  74. lpdwContainerInfoBufferSize,
  75. dwOptions
  76. ));
  77. DWORD Error;
  78. HANDLE hFind = NULL;
  79. // Initialize globals.
  80. if (!InitGlobals())
  81. {
  82. Error = ERROR_INTERNET_INTERNAL_ERROR;
  83. goto Cleanup;
  84. }
  85. hFind = GlobalUrlContainers->FindFirstContainer(pdwModified,
  86. lpContainerInfo, lpdwContainerInfoBufferSize, dwOptions);
  87. if (hFind)
  88. Error = ERROR_SUCCESS;
  89. else
  90. {
  91. Error = GetLastError();
  92. // BUGBUG: Free hFind?
  93. // does the free take NULL?
  94. }
  95. Cleanup:
  96. if( Error != ERROR_SUCCESS )
  97. {
  98. SetLastError( Error );
  99. DEBUG_ERROR(API, Error);
  100. }
  101. DEBUG_LEAVE_API (hFind);
  102. return hFind;
  103. }
  104. URLCACHEAPI_(BOOL) FindNextUrlCacheContainerA(
  105. IN HANDLE hFind,
  106. OUT LPINTERNET_CACHE_CONTAINER_INFOA lpContainerInfo,
  107. IN OUT LPDWORD lpdwContainerInfoBufferSize
  108. )
  109. {
  110. ENTER_CACHE_API ((DBG_API, Bool, "FindNextContainerA",
  111. "%#x, %#x, %#x",
  112. hFind,
  113. lpContainerInfo,
  114. lpdwContainerInfoBufferSize
  115. ));
  116. DWORD Error;
  117. DWORD i;
  118. // Initialize globals.
  119. if (!InitGlobals())
  120. {
  121. Error = ERROR_INTERNET_INTERNAL_ERROR;
  122. goto Cleanup;
  123. }
  124. if (GlobalUrlContainers->FindNextContainer(hFind,
  125. lpContainerInfo, lpdwContainerInfoBufferSize))
  126. Error = ERROR_SUCCESS;
  127. else
  128. Error = GetLastError();
  129. LEAVE_CACHE_API();
  130. }
  131. #define GZIPHACK 8624
  132. URLCACHEAPI_(BOOL) CreateUrlCacheEntryA(
  133. IN LPCSTR lpszUrlName,
  134. IN DWORD dwExpectedFileSize,
  135. IN LPCSTR lpszFileExtension,
  136. OUT LPSTR lpszFileName,
  137. IN DWORD dwReserved
  138. )
  139. /*++
  140. Routine Description:
  141. This function creates a temperary file in the cache storage. This call
  142. is called by the application when it receives a url file from a
  143. server. When the receive is completed it caches this file to url cache
  144. management, which will move the file to permanent cache file. The idea
  145. is the cache file is written only once directly into the cache store.
  146. Arguments:
  147. lpszUrlName : name of the url file (unused now).
  148. lpszFileExtension: File extension for the saved data file
  149. dwExpectedFileSize : expected size of the incoming file. If it is unknown
  150. this value is set to null.
  151. lpszFileName : pointer to a buffer that receives the full path name of
  152. the the temp file.
  153. dwReserved : reserved for future use.
  154. Return Value:
  155. Windows Error Code.
  156. --*/
  157. {
  158. ENTER_CACHE_API ((DBG_API, Bool, "CreateUrlCacheEntryA", "%q, %q, %d, %q, %#x",
  159. lpszUrlName, lpszFileExtension, dwExpectedFileSize, lpszFileName, dwReserved));
  160. DWORD Error;
  161. //
  162. // validate parameters.
  163. //
  164. if( IsBadUrl( lpszUrlName ) || IsBadWriteFileName( lpszFileName ) ) {
  165. Error = ERROR_INVALID_PARAMETER;
  166. goto Cleanup;
  167. }
  168. // Initialize globals
  169. if (!InitGlobals())
  170. {
  171. Error = ERROR_INTERNET_INTERNAL_ERROR;
  172. goto Cleanup;
  173. }
  174. // Null first char in lpszFileName cues CreateUniqueFile
  175. // to generate a file name from scratch. Otherwise,
  176. // an attempt will be made to generate the filename
  177. // using the contents of the buffer.
  178. if(dwReserved != GZIPHACK)
  179. {
  180. *lpszFileName = '\0';
  181. }
  182. Error = GlobalUrlContainers->CreateUniqueFile(
  183. lpszUrlName,
  184. dwExpectedFileSize,
  185. lpszFileExtension,
  186. lpszFileName,
  187. NULL
  188. );
  189. LEAVE_CACHE_API();
  190. }
  191. URLCACHEAPI_(BOOL) CommitUrlCacheEntryA(
  192. IN LPCSTR lpszUrlName,
  193. IN LPCSTR lpszLocalFileName,
  194. IN FILETIME ExpireTime,
  195. IN FILETIME LastModifiedTime,
  196. IN DWORD CacheEntryType,
  197. IN LPBYTE lpHeaderInfo,
  198. IN DWORD dwHeaderSize,
  199. IN LPCSTR lpszFileExtension,
  200. IN LPCSTR lpszOriginalUrl
  201. )
  202. /*++
  203. Routine Description:
  204. This API caches a specified URL in the internet service cache
  205. storage. It creates a database entry of the URL info and moves the
  206. URL file to cache storage.
  207. Arguments:
  208. lpszUrlName : name of the URL that is cached.
  209. lpszLocalFileName : name of the local file where the URL data is
  210. stored. This file will be moved to an another file in cache storage, so
  211. this name is invalid after this api successfully returns. The
  212. name should include full path.
  213. ExpireTime : Expire time (GMT) of the file being cached. If it is
  214. unknown set it to zero.
  215. LastModifiedTime : Last modified time of this file. if this value is
  216. zero, current time is set as the last modified time.
  217. CacheEntryType : type of this new entry.
  218. lpHeaderInfo : if this pointer is non-NULL, it stores the HeaderInfo
  219. data as part of the URL entry in the memory mapped file, otherwise
  220. the app may store it else where. The size of the header info is
  221. specified by the HeaderSize parameter.
  222. dwHeaderSize : size of the header info associated with this URL, this
  223. can be non-zero even if the HeaderInfo specified above is NULL.
  224. lpszFileExtension : file extension used to create this file.
  225. dwReserved : reserved for future use.
  226. Return Value:
  227. Windows Error code.
  228. --*/
  229. {
  230. ENTER_CACHE_API ((DBG_API, Bool, "CommitUrlCacheEntryA",
  231. "%q, %q, <expires>, <last-mod>, %d, %#x, %d, %q, %q",
  232. lpszUrlName,
  233. lpszLocalFileName,
  234. CacheEntryType,
  235. lpHeaderInfo,
  236. dwHeaderSize,
  237. lpszFileExtension,
  238. lpszOriginalUrl
  239. ));
  240. DWORD Error;
  241. // validate parameters.
  242. if( IsBadUrl( lpszUrlName ) ||
  243. ( lpszLocalFileName ? IsBadReadFileName( lpszLocalFileName ) : FALSE ) )
  244. {
  245. Error = ERROR_INVALID_PARAMETER;
  246. goto Cleanup;
  247. }
  248. if( lpHeaderInfo != NULL )
  249. {
  250. if( IsBadReadPtr(lpHeaderInfo, dwHeaderSize) )
  251. {
  252. Error = ERROR_INVALID_PARAMETER;
  253. goto Cleanup;
  254. }
  255. }
  256. if( lpszFileExtension != NULL )
  257. {
  258. if( IsBadReadPtr(lpszFileExtension, 3) )
  259. {
  260. Error = ERROR_INVALID_PARAMETER;
  261. goto Cleanup;
  262. }
  263. }
  264. FILETIME ftPostCheck;
  265. ftPostCheck.dwLowDateTime = 0;
  266. ftPostCheck.dwHighDateTime = 0;
  267. // Record args in structure.
  268. AddUrlArg Args;
  269. memset(&Args, 0, sizeof(Args));
  270. Args.pszUrl = lpszUrlName;
  271. Args.pszFilePath = lpszLocalFileName;
  272. Args.dwFileSize = 0;
  273. Args.qwExpires = FT2LL(ExpireTime);
  274. Args.qwLastMod = FT2LL(LastModifiedTime);
  275. Args.qwPostCheck = FT2LL(ftPostCheck);
  276. Args.ftCreate = LastModifiedTime;
  277. Args.dwEntryType = CacheEntryType;
  278. Args.pbHeaders = (LPSTR)lpHeaderInfo;
  279. Args.cbHeaders = dwHeaderSize;
  280. Args.pszFileExt = lpszFileExtension;
  281. Args.pszRedirect = lpszOriginalUrl ? (LPSTR) lpszOriginalUrl : NULL;
  282. Args.fImage = FALSE;
  283. Error = UrlCacheCommitFile(&Args);
  284. LEAVE_CACHE_API();
  285. }
  286. URLCACHEAPI_(BOOL) RetrieveUrlCacheEntryFileA(
  287. IN LPCSTR lpszUrlName,
  288. OUT LPCACHE_ENTRY_INFOA lpCacheEntryInfo,
  289. IN OUT LPDWORD lpdwCacheEntryInfoBufferSize,
  290. IN DWORD dwReserved
  291. )
  292. /*++
  293. Routine Description:
  294. This API retrieves the specified URL file. When the file is retrieved
  295. it also checked out to the user to use. The user has to call
  296. UnlockUrlFile when he/she finished using it.
  297. Arguments:
  298. lpszUrlName : name of the URL that is being retrieved.
  299. lpCacheEntryInfo : pointer to the url info structure that receives the url
  300. info.
  301. lpdwCacheEntryInfoBufferSize : pointer to a location where length of
  302. the above buffer is passed in. On return, this contains the length
  303. of the above buffer that is fulled in.
  304. dwReserved : reserved for future use.
  305. Return Value:
  306. Windows Error code.
  307. --*/
  308. {
  309. ENTER_CACHE_API ((DBG_API, Bool, "RetrieveUrlCacheEntryFileA","%q, %#x, %#x, %#x",
  310. lpszUrlName, lpCacheEntryInfo, lpdwCacheEntryInfoBufferSize, dwReserved));
  311. DWORD Error;
  312. // validate parameters.
  313. if( IsBadUrl( lpszUrlName ) ||
  314. IsBadWriteUrlInfo(
  315. lpCacheEntryInfo,
  316. *lpdwCacheEntryInfoBufferSize) ) {
  317. Error = ERROR_INVALID_PARAMETER;
  318. goto Cleanup;
  319. }
  320. if (!InitGlobals())
  321. {
  322. Error = ERROR_INTERNET_INTERNAL_ERROR;
  323. goto Cleanup;
  324. }
  325. Error = GlobalUrlContainers->RetrieveUrl(
  326. lpszUrlName,
  327. (lpCacheEntryInfo ? &lpCacheEntryInfo : NULL),
  328. lpdwCacheEntryInfoBufferSize,
  329. LOOKUP_URL_CREATE,
  330. RETRIEVE_WITH_CHECKS);
  331. LEAVE_CACHE_API();
  332. }
  333. URLCACHEAPI_(HANDLE) RetrieveUrlCacheEntryStreamA(
  334. IN LPCSTR lpszUrlName,
  335. OUT LPCACHE_ENTRY_INFOA lpCacheEntryInfo,
  336. IN OUT LPDWORD lpdwCacheEntryInfoBufferSize,
  337. IN BOOL fRandomRead,
  338. IN DWORD dwReserved
  339. )
  340. /*++
  341. Routine Description:
  342. This API retrieves the specified URL file. When the file is retrieved
  343. it also checked out to the user to use. The user has to call
  344. UnlockUrlFile when he/she finished using it.
  345. Arguments:
  346. lpszUrlName : name of the URL that is being retrieved.
  347. lpCacheEntryInfo : pointer to the url info structure that receives the url
  348. info.
  349. lpdwCacheEntryInfoBufferSize : pointer to a location where length of
  350. the above buffer is passed in. On return, this contains the length
  351. of the above buffer that is fulled in.
  352. fRandomRead : if this flag is set to TRUE, then stream is open for
  353. random access.
  354. dwReserved: must pass 0
  355. Return Value:
  356. Windows Error code.
  357. --*/
  358. {
  359. ENTER_CACHE_API ((DBG_API, Handle, "RetrieveUrlCacheEntryStreamA",
  360. "%q, %#x, %#x, %d, %#x",
  361. lpszUrlName,
  362. lpCacheEntryInfo,
  363. lpdwCacheEntryInfoBufferSize,
  364. fRandomRead,
  365. dwReserved
  366. ));
  367. BOOL fLocked = FALSE;
  368. HANDLE hStream = NULL;
  369. HANDLE hFile = INVALID_HANDLE_VALUE;
  370. DWORD Error, dwFileSize;
  371. // Validate parameters.
  372. if( IsBadUrl( lpszUrlName )
  373. || IsBadWriteUrlInfo(lpCacheEntryInfo, *lpdwCacheEntryInfoBufferSize))
  374. {
  375. Error = ERROR_INVALID_PARAMETER;
  376. goto Cleanup;
  377. }
  378. // Initialize globals.
  379. if (!InitGlobals())
  380. {
  381. Error = ERROR_INTERNET_INTERNAL_ERROR;
  382. goto Cleanup;
  383. }
  384. Error = GlobalUrlContainers->RetrieveUrl
  385. (lpszUrlName, &lpCacheEntryInfo, lpdwCacheEntryInfoBufferSize,
  386. LOOKUP_URL_NOCREATE, RETRIEVE_WITHOUT_CHECKS);
  387. if( Error != ERROR_SUCCESS )
  388. goto Cleanup;
  389. fLocked = TRUE;
  390. // Allocate a stream handle.
  391. CACHE_STREAM_CONTEXT_HANDLE* pStream;
  392. LOCK_CACHE();
  393. hStream = HandleMgr.Alloc (sizeof(CACHE_STREAM_CONTEXT_HANDLE));
  394. if (hStream)
  395. {
  396. pStream = (CACHE_STREAM_CONTEXT_HANDLE*) HandleMgr.Map (hStream);
  397. INET_ASSERT (pStream);
  398. }
  399. UNLOCK_CACHE();
  400. if (!hStream)
  401. {
  402. Error = ERROR_NOT_ENOUGH_MEMORY;
  403. goto Cleanup;
  404. }
  405. // Open the file.
  406. hFile = CreateFile
  407. (
  408. lpCacheEntryInfo->lpszLocalFileName,
  409. GENERIC_READ,
  410. FILE_SHARE_READ,
  411. NULL,
  412. OPEN_EXISTING,
  413. FILE_ATTRIBUTE_NORMAL |
  414. (fRandomRead ? FILE_FLAG_RANDOM_ACCESS : FILE_FLAG_SEQUENTIAL_SCAN),
  415. // improves file read (cache) performance?
  416. NULL
  417. );
  418. if( hFile == INVALID_HANDLE_VALUE )
  419. {
  420. Error = GetLastError();
  421. goto Cleanup;
  422. }
  423. dwFileSize = GetFileSize(hFile, NULL);
  424. if (dwFileSize != lpCacheEntryInfo->dwSizeLow)
  425. {
  426. Error = (dwFileSize==0xFFFFFFFF) ? GetLastError() : ERROR_INVALID_DATA;
  427. goto Cleanup;
  428. }
  429. pStream->FileHandle = hFile;
  430. // Copy URL name storage.
  431. pStream->SourceUrlName = NewString(lpszUrlName);
  432. if( !pStream->SourceUrlName)
  433. {
  434. Error = ERROR_NOT_ENOUGH_MEMORY;
  435. goto Cleanup;
  436. }
  437. Error = ERROR_SUCCESS;
  438. Cleanup:
  439. if( Error != ERROR_SUCCESS )
  440. {
  441. if (hStream)
  442. {
  443. HandleMgr.Free (hStream);
  444. hStream = NULL;
  445. }
  446. if (hFile)
  447. CloseHandle (hFile);
  448. if (fLocked)
  449. GlobalUrlContainers->UnlockUrl(lpszUrlName);
  450. SetLastError (Error);
  451. DEBUG_ERROR(API, Error);
  452. }
  453. DEBUG_LEAVE_API (hStream);
  454. return hStream;
  455. }
  456. URLCACHEAPI_(BOOL) GetUrlCacheEntryInfoA(
  457. IN LPCSTR lpszUrlName,
  458. OUT LPCACHE_ENTRY_INFOA lpCacheEntryInfo,
  459. IN OUT LPDWORD lpdwCacheEntryInfoBufferSize
  460. )
  461. /*++
  462. Routine Description:
  463. This function retrieves the specified cache entry info.
  464. Arguments:
  465. lpszUrlName : name of the url file (unused now).
  466. lpCacheEntryInfo : pointer to the url info structure that receives the url
  467. info.
  468. lpdwCacheEntryInfoBufferSize : pointer to a location where length of
  469. the above buffer is passed in. On return, this contains the length
  470. of the above buffer that is fulled in.
  471. Return Value:
  472. Windows Error Code.
  473. --*/
  474. {
  475. ENTER_CACHE_API ((DBG_API, Bool, "GetUrlCacheEntryInfoA", "%q, %#x, %#x",
  476. lpszUrlName, lpCacheEntryInfo, lpdwCacheEntryInfoBufferSize));
  477. DWORD Error;
  478. // Validate parameters.
  479. if( IsBadUrl( lpszUrlName ) ||
  480. (lpCacheEntryInfo && !lpdwCacheEntryInfoBufferSize) ||
  481. (lpCacheEntryInfo && lpdwCacheEntryInfoBufferSize && IsBadWriteUrlInfo(
  482. lpCacheEntryInfo,
  483. *lpdwCacheEntryInfoBufferSize) ) )
  484. {
  485. Error = ERROR_INVALID_PARAMETER;
  486. goto Cleanup;
  487. }
  488. // Initialize globals.
  489. if (!InitGlobals())
  490. {
  491. Error = ERROR_INTERNET_INTERNAL_ERROR;
  492. goto Cleanup;
  493. }
  494. Error = GlobalUrlContainers->GetUrlInfo(
  495. lpszUrlName,
  496. lpCacheEntryInfo,
  497. lpdwCacheEntryInfoBufferSize,
  498. LOOKUP_URL_NOCREATE,
  499. 0);
  500. LEAVE_CACHE_API();
  501. }
  502. BOOLAPI GetUrlCacheEntryInfoExA(
  503. IN LPCSTR lpszUrl,
  504. OUT LPINTERNET_CACHE_ENTRY_INFOA lpCEI,
  505. IN OUT LPDWORD lpcbCEI,
  506. OUT LPSTR lpszOut,
  507. IN OUT LPDWORD lpcbOut,
  508. LPVOID lpReserved,
  509. DWORD dwFlags
  510. )
  511. {
  512. ENTER_CACHE_API ((DBG_API, Bool, "GetUrlCacheEntryInfoExA",
  513. "%q, %#x, %#x, %#x, %#x, %#x, %#x", lpszUrl, lpCEI, lpcbCEI, lpszOut, lpcbOut, lpReserved, dwFlags));
  514. DWORD Error;
  515. // Validate parameters
  516. // NOTE: once the following params change, edit GetUrlCacheEntryInfoExW accordingly.
  517. if ( IsBadUrl(lpszUrl)
  518. || lpszOut
  519. || lpcbOut
  520. || lpReserved
  521. )
  522. {
  523. INET_ASSERT (FALSE);
  524. Error = ERROR_INVALID_PARAMETER;
  525. goto Cleanup;
  526. }
  527. // Initialize globals.
  528. if (!InitGlobals())
  529. {
  530. Error = ERROR_INTERNET_INTERNAL_ERROR;
  531. goto Cleanup;
  532. }
  533. // We allow mixing of INTERNET_CACHE_FLAG_ALLOW_COLLISIONS with lookup flags
  534. Error = GlobalUrlContainers->GetUrlInfo
  535. (lpszUrl, lpCEI, lpcbCEI, LOOKUP_URL_TRANSLATE | (dwFlags & INTERNET_CACHE_FLAG_ALLOW_COLLISIONS), dwFlags);
  536. LEAVE_CACHE_API();
  537. }
  538. URLCACHEAPI_(BOOL) SetUrlCacheEntryInfoA(
  539. IN LPCSTR lpszUrlName,
  540. IN LPCACHE_ENTRY_INFOA lpCacheEntryInfo,
  541. IN DWORD dwFieldControl
  542. )
  543. /*++
  544. Routine Description:
  545. This function sets the specified fields of the cache entry info.
  546. Arguments:
  547. lpszUrlName : name of the url file (unused now).
  548. lpCacheEntryInfo : pointer to the url info structure that has the url info to
  549. be set.
  550. dwFieldControl : Bitmask that specifies the fields to be set.
  551. Return Value:
  552. Windows Error Code.
  553. --*/
  554. {
  555. ENTER_CACHE_API ((DBG_API, Bool, "SetUrlCacheEntryInfoA", "%q, %#x, %d",
  556. lpszUrlName, lpCacheEntryInfo, dwFieldControl));
  557. DWORD Error;
  558. //
  559. // validate parameters.
  560. //
  561. if( IsBadUrl( lpszUrlName ) ||
  562. IsBadReadUrlInfo( lpCacheEntryInfo )) {
  563. Error = ERROR_INVALID_PARAMETER;
  564. goto Cleanup;
  565. }
  566. // Initialize globals.
  567. if (!InitGlobals())
  568. {
  569. Error = ERROR_INTERNET_INTERNAL_ERROR;
  570. goto Cleanup;
  571. }
  572. Error = GlobalUrlContainers->SetUrlInfo(
  573. lpszUrlName,
  574. lpCacheEntryInfo,
  575. dwFieldControl );
  576. LEAVE_CACHE_API();
  577. }
  578. URLCACHEAPI_(HANDLE) FindFirstUrlCacheEntryA(
  579. IN LPCSTR lpszUrlSearchPattern,
  580. OUT LPCACHE_ENTRY_INFOA lpFirstCacheEntryInfo,
  581. IN OUT LPDWORD lpdwFirstCacheEntryInfoBufferSize
  582. )
  583. /*++
  584. Routine Description:
  585. This member function starts the cache entries enumeration and returns
  586. the first entry in the cache.
  587. Arguments:
  588. lpszUrlSearchPattern : pointer to a search pattern string. Currently
  589. it is not implemented.
  590. lpFirstCacheEntryInfo : pointer to a cache entry info structure.
  591. Return Value:
  592. Returns the find first handle. If the returned handle is NULL,
  593. GetLastError() returns the extended error code.
  594. --*/
  595. {
  596. ENTER_CACHE_API ((DBG_API, Bool, "FindFirstUrlCacheEntryA",
  597. "%q, %#x, %#x",
  598. lpszUrlSearchPattern,
  599. lpFirstCacheEntryInfo,
  600. lpdwFirstCacheEntryInfoBufferSize
  601. ));
  602. DWORD Error;
  603. HANDLE hFind = 0;
  604. // Validate parameters.
  605. if (IsBadWriteUrlInfo(lpFirstCacheEntryInfo,
  606. *lpdwFirstCacheEntryInfoBufferSize))
  607. {
  608. Error = ERROR_INVALID_PARAMETER;
  609. goto Cleanup;
  610. }
  611. // Initialize globals.
  612. if (!InitGlobals())
  613. {
  614. Error = ERROR_INTERNET_INTERNAL_ERROR;
  615. goto Cleanup;
  616. }
  617. // Get the first entry.
  618. Error = GlobalUrlContainers->FindNextEntry(&hFind,
  619. lpszUrlSearchPattern,
  620. lpFirstCacheEntryInfo,
  621. lpdwFirstCacheEntryInfoBufferSize,
  622. URLCACHE_FIND_DEFAULT_FILTER,
  623. NULL,
  624. FIND_FLAGS_OLD_SEMANTICS);
  625. Cleanup:
  626. if( Error != ERROR_SUCCESS )
  627. {
  628. GlobalUrlContainers->FreeFindHandle(hFind);
  629. hFind = NULL;
  630. SetLastError(Error);
  631. DEBUG_ERROR(API, Error);
  632. }
  633. DEBUG_LEAVE_API (hFind);
  634. return hFind;
  635. }
  636. URLCACHEAPI_(BOOL) FindNextUrlCacheEntryA(
  637. IN HANDLE hFind,
  638. OUT LPCACHE_ENTRY_INFOA lpNextCacheEntryInfo,
  639. IN OUT LPDWORD lpdwNextCacheEntryInfoBufferSize
  640. )
  641. /*++
  642. Routine Description:
  643. This member function returns the next entry in the cache.
  644. Arguments:
  645. hEnumHandle : Find First handle.
  646. lpFirstCacheEntryInfo : pointer to a cache entry info structure.
  647. Return Value:
  648. Returns the find first handle. If the returned handle is NULL,
  649. GetLastError() returns the extended error code. It returns
  650. ERROR_NO_MORE_ITEMS after it returns the last entry in the cache.
  651. --*/
  652. {
  653. ENTER_CACHE_API ((DBG_API, Bool, "FindNextUrlCacheEntryA",
  654. "%#x, %#x, %#x",
  655. hFind,
  656. lpNextCacheEntryInfo,
  657. lpdwNextCacheEntryInfoBufferSize
  658. ));
  659. DWORD Error = ERROR_SUCCESS;
  660. CACHE_FIND_FIRST_HANDLE* pFind;
  661. // Validate parameters.
  662. if (!hFind || IsBadWriteUrlInfo(lpNextCacheEntryInfo,
  663. *lpdwNextCacheEntryInfoBufferSize))
  664. {
  665. Error = ERROR_INVALID_PARAMETER;
  666. goto Cleanup;
  667. }
  668. // Initialize globals.
  669. if (!InitGlobals())
  670. {
  671. Error = ERROR_INTERNET_INTERNAL_ERROR;
  672. goto Cleanup;
  673. }
  674. // Get the next entry.
  675. Error = GlobalUrlContainers->FindNextEntry(&hFind,
  676. NULL,
  677. lpNextCacheEntryInfo,
  678. lpdwNextCacheEntryInfoBufferSize,
  679. URLCACHE_FIND_DEFAULT_FILTER,
  680. NULL,
  681. FIND_FLAGS_OLD_SEMANTICS);
  682. Cleanup:
  683. if (Error!=ERROR_SUCCESS)
  684. {
  685. SetLastError(Error);
  686. DEBUG_ERROR(INET, Error);
  687. }
  688. DEBUG_LEAVE_API(Error==ERROR_SUCCESS);
  689. return (Error == ERROR_SUCCESS );
  690. }
  691. INTERNETAPI_(HANDLE) FindFirstUrlCacheEntryExA(
  692. IN LPCSTR lpszUrlSearchPattern,
  693. IN DWORD dwFlags,
  694. IN DWORD dwFilter,
  695. IN GROUPID GroupId,
  696. OUT LPINTERNET_CACHE_ENTRY_INFOA pEntryInfo,
  697. IN OUT LPDWORD pcbEntryInfo,
  698. OUT LPVOID lpGroupAttributes, // must pass NULL
  699. IN OUT LPDWORD pcbGroupAttributes, // must pass NULL
  700. IN LPVOID lpReserved // must pass NULL
  701. )
  702. {
  703. ENTER_CACHE_API ((DBG_API, Bool, "FindFirstUrlCacheEntryExA",
  704. "%q, %#x, %#x, %#x, %#x, %#x, %#x, %#x, %#x",
  705. lpszUrlSearchPattern,
  706. dwFlags,
  707. dwFilter,
  708. GroupId,
  709. pEntryInfo,
  710. pcbEntryInfo,
  711. lpGroupAttributes,
  712. pcbGroupAttributes,
  713. lpReserved
  714. ));
  715. DWORD Error;
  716. HANDLE hFind = NULL;
  717. // Validate parameters.
  718. if (IsBadWritePtr (pcbEntryInfo, sizeof(DWORD)))
  719. {
  720. Error = ERROR_INVALID_PARAMETER;
  721. goto Cleanup;
  722. }
  723. // Initialize globals.
  724. if (!InitGlobals())
  725. {
  726. Error = ERROR_INTERNET_INTERNAL_ERROR;
  727. goto Cleanup;
  728. }
  729. // Get the first entry.
  730. Error = GlobalUrlContainers->FindNextEntry(&hFind,
  731. lpszUrlSearchPattern,
  732. pEntryInfo,
  733. pcbEntryInfo,
  734. dwFilter,
  735. GroupId,
  736. dwFlags);
  737. Cleanup:
  738. if( Error != ERROR_SUCCESS )
  739. {
  740. if (hFind)
  741. {
  742. GlobalUrlContainers->FreeFindHandle(hFind);
  743. hFind = NULL;
  744. }
  745. SetLastError(Error);
  746. DEBUG_ERROR(API, Error);
  747. }
  748. DEBUG_LEAVE_API (hFind);
  749. return hFind;
  750. }
  751. BOOLAPI FindNextUrlCacheEntryExA(
  752. IN HANDLE hFind,
  753. OUT LPINTERNET_CACHE_ENTRY_INFOA pEntryInfo,
  754. IN OUT LPDWORD pcbEntryInfo,
  755. OUT LPVOID lpGroupAttributes, // must pass NULL
  756. IN OUT LPDWORD pcbGroupAttributes, // must pass NULL
  757. IN LPVOID lpReserved // must pass NULL
  758. )
  759. {
  760. ENTER_CACHE_API ((DBG_API, Bool, "FindNextUrlCacheEntryExA",
  761. "%#x, %#x, %#x, %#x, %#x, %#x",
  762. hFind,
  763. pEntryInfo,
  764. pcbEntryInfo,
  765. lpGroupAttributes,
  766. pcbGroupAttributes,
  767. lpReserved
  768. ));
  769. DWORD Error;
  770. // Validate parameters.
  771. if (!hFind || IsBadWritePtr (pcbEntryInfo, sizeof(DWORD)))
  772. {
  773. Error = ERROR_INVALID_PARAMETER;
  774. goto Cleanup;
  775. }
  776. // Initialize globals.
  777. if (!InitGlobals())
  778. {
  779. Error = ERROR_INTERNET_INTERNAL_ERROR;
  780. goto Cleanup;
  781. }
  782. // Get the next entry.
  783. Error = GlobalUrlContainers->FindNextEntry(&hFind,
  784. NULL,
  785. pEntryInfo,
  786. pcbEntryInfo,
  787. NULL,
  788. NULL,
  789. NULL);
  790. LEAVE_CACHE_API();
  791. }
  792. URLCACHEAPI_(BOOL) FreeUrlCacheSpaceA(
  793. IN LPCSTR lpszCachePath,
  794. IN DWORD dwFactor,
  795. IN DWORD dwFilter
  796. )
  797. /*++
  798. Routine Description:
  799. This function cleans up the cache entries in the specified ccahe
  800. path to make space for future cache entries.
  801. Arguments:
  802. dwFactor: % of free space
  803. Return Value:
  804. TRUE if the cleanup is successful. Otherwise FALSE, GetLastError()
  805. returns the extended error.
  806. --*/
  807. {
  808. DWORD Error;
  809. ENTER_CACHE_API ((DBG_API, Bool, "FreeUrlCacheSpace",
  810. "<path>,%d, %#x", dwFactor, dwFilter));
  811. // Initialize globals.
  812. if (!InitGlobals())
  813. {
  814. Error = ERROR_INTERNET_INTERNAL_ERROR;
  815. goto Cleanup;
  816. }
  817. Error = GlobalUrlContainers->CleanupUrls(lpszCachePath, dwFactor, dwFilter);
  818. LEAVE_CACHE_API();
  819. }
  820. URLCACHEAPI_(BOOL) UnlockUrlCacheEntryFileA(
  821. LPCSTR lpszUrlName,
  822. IN DWORD dwReserved
  823. )
  824. /*++
  825. Routine Description:
  826. This API checks in the file that was check out as part of
  827. RetrieveUrlFile API.
  828. Arguments:
  829. lpszUrlName : name of the URL that is being retrieved.
  830. dwReserved : reserved for future use.
  831. Return Value:
  832. Windows Error code.
  833. --*/
  834. {
  835. DWORD Error;
  836. DWORD i;
  837. ENTER_CACHE_API ((DBG_API, Bool, "UnlockUrlCacheEntryFile",
  838. "%q, %#x", lpszUrlName, dwReserved));
  839. // validate parameters.
  840. if( IsBadUrl( lpszUrlName ) ) {
  841. Error = ERROR_INVALID_PARAMETER;
  842. goto Cleanup;
  843. }
  844. // Initialize globals
  845. if (!InitGlobals())
  846. {
  847. Error = ERROR_INTERNET_INTERNAL_ERROR;
  848. goto Cleanup;
  849. }
  850. Error = GlobalUrlContainers->UnlockUrl(lpszUrlName);
  851. LEAVE_CACHE_API();
  852. }
  853. URLCACHEAPI_(BOOL) DeleteUrlCacheEntryA(
  854. IN LPCSTR lpszUrlName
  855. )
  856. {
  857. ENTER_CACHE_API ((DBG_API, Bool, "DeleteUrlCacheEntry",
  858. "%q", lpszUrlName));
  859. DWORD Error;
  860. // Validate parameters.
  861. if( IsBadUrl( lpszUrlName ) ) {
  862. Error = ERROR_INVALID_PARAMETER;
  863. goto Cleanup;
  864. }
  865. // Initialize globals
  866. if (!InitGlobals())
  867. {
  868. Error = ERROR_INTERNET_INTERNAL_ERROR;
  869. goto Cleanup;
  870. }
  871. Error = GlobalUrlContainers->DeleteUrl(lpszUrlName);
  872. LEAVE_CACHE_API();
  873. }
  874. BOOLAPI SetUrlCacheEntryGroupA(
  875. IN LPCSTR lpszUrlName,
  876. IN DWORD dwFlags,
  877. IN GROUPID GroupId,
  878. IN LPBYTE pbGroupAttributes, // must pass NULL
  879. IN DWORD cbGroupAttributes, // must pass 0
  880. IN LPVOID lpReserved // must pass NULL
  881. )
  882. {
  883. ENTER_CACHE_API ((DBG_API, Bool, "SetUrlCacheEntryGroupA",
  884. "%q, %#x, %#x, %#x, %#x, %#x", lpszUrlName, dwFlags, GroupId, pbGroupAttributes, cbGroupAttributes, lpReserved));
  885. DWORD Error;
  886. // Validate parameters.
  887. if (IsBadUrl(lpszUrlName)
  888. || !GroupId
  889. || pbGroupAttributes
  890. || cbGroupAttributes
  891. || lpReserved
  892. )
  893. {
  894. Error = ERROR_INVALID_PARAMETER;
  895. goto Cleanup;
  896. }
  897. // Initialize globals
  898. if (!InitGlobals())
  899. {
  900. Error = ERROR_INTERNET_INTERNAL_ERROR;
  901. goto Cleanup;
  902. }
  903. Error = GlobalUrlContainers->SetUrlGroup (lpszUrlName, dwFlags, GroupId);
  904. LEAVE_CACHE_API();
  905. }
  906. URLCACHEAPI_(BOOL) GetUrlCacheGroupAttributeA(
  907. IN GROUPID gid,
  908. IN DWORD dwFlags,
  909. IN DWORD dwAttributes,
  910. OUT LPINTERNET_CACHE_GROUP_INFOA lpGroupInfo,
  911. IN OUT LPDWORD lpdwGroupInfo,
  912. IN OUT LPVOID lpReserved
  913. )
  914. {
  915. ENTER_CACHE_API ((DBG_API, Bool, "GetUrlCacheGroupAttributeA",
  916. "%#x, %d, %d, %#x, %#x, %#x",
  917. gid, dwFlags, dwAttributes, lpGroupInfo, lpdwGroupInfo, lpReserved ));
  918. DWORD Error;
  919. // Validate parameters.
  920. if( !lpGroupInfo ||
  921. !lpdwGroupInfo ||
  922. IsBadWriteUrlInfo(lpGroupInfo, *lpdwGroupInfo) )
  923. {
  924. Error = ERROR_INVALID_PARAMETER;
  925. goto Cleanup;
  926. }
  927. if( *lpdwGroupInfo < sizeof(INTERNET_CACHE_GROUP_INFOA) )
  928. {
  929. Error = ERROR_INSUFFICIENT_BUFFER;
  930. goto Cleanup;
  931. }
  932. // Initialize globals.
  933. if (!InitGlobals())
  934. {
  935. Error = ERROR_INTERNET_INTERNAL_ERROR;
  936. goto Cleanup;
  937. }
  938. Error = GlobalUrlContainers->GetGroupAttributes(
  939. gid,
  940. dwAttributes,
  941. lpGroupInfo,
  942. lpdwGroupInfo );
  943. LEAVE_CACHE_API();
  944. }
  945. URLCACHEAPI_(BOOL) SetUrlCacheGroupAttributeA(
  946. IN GROUPID gid,
  947. IN DWORD dwFlags,
  948. IN DWORD dwAttributes,
  949. IN LPINTERNET_CACHE_GROUP_INFOA lpGroupInfo,
  950. IN OUT LPVOID lpReserved
  951. )
  952. {
  953. ENTER_CACHE_API ((DBG_API, Bool, "SetUrlCacheGroupAttributeA",
  954. "%#x, %d, %d, %#x, %#x",
  955. gid, dwFlags, dwAttributes, lpGroupInfo, lpReserved));
  956. DWORD Error;
  957. // validate parameters.
  958. if( IsBadReadPtr(lpGroupInfo, sizeof(INTERNET_CACHE_GROUP_INFOA) ) )
  959. {
  960. Error = ERROR_INVALID_PARAMETER;
  961. goto Cleanup;
  962. }
  963. // Initialize globals.
  964. if (!InitGlobals())
  965. {
  966. Error = ERROR_INTERNET_INTERNAL_ERROR;
  967. goto Cleanup;
  968. }
  969. Error = GlobalUrlContainers->SetGroupAttributes(
  970. gid, dwAttributes, lpGroupInfo);
  971. LEAVE_CACHE_API();
  972. }
  973. BOOLAPI IsUrlCacheEntryExpiredA(
  974. IN LPCSTR lpszUrlName,
  975. IN DWORD dwFlags,
  976. IN OUT FILETIME* pftLastModifiedTime
  977. )
  978. {
  979. BOOL bRet = TRUE;
  980. CACHE_ENTRY_INFOEX* pCEI = NULL;
  981. DWORD cbCEI;
  982. DWORD dwError;
  983. BOOL bLazy = FALSE;
  984. BOOL fLocked = FALSE;
  985. // Validate parameters.
  986. if( IsBadUrl( lpszUrlName ) || !pftLastModifiedTime ) {
  987. INET_ASSERT(FALSE);
  988. return ERROR_INVALID_PARAMETER;
  989. }
  990. // set out LastModTime to 0
  991. pftLastModifiedTime->dwLowDateTime = 0 ;
  992. pftLastModifiedTime->dwHighDateTime = 0 ;
  993. if (!InitGlobals())
  994. {
  995. INET_ASSERT(FALSE);
  996. return ERROR_INTERNET_INTERNAL_ERROR;
  997. }
  998. //
  999. // BUGBUG
  1000. // ideally, we should use GlobalUrlContainers->GetUrlInfo()
  1001. // with NO_ALLOCATION and HEADONLY flag for perf.
  1002. // however, there is a flag (lookup flag v.s entry flag) collision
  1003. // in that code path which prevents this working
  1004. // so we use this anti-perf RetrieveUrl for now until that one
  1005. // gets fixed
  1006. // --DanpoZ, 98.09.09
  1007. // Find the container and search the index.
  1008. dwError = GlobalUrlContainers->RetrieveUrl(
  1009. lpszUrlName,
  1010. (CACHE_ENTRY_INFO**) &pCEI,
  1011. &cbCEI,
  1012. (dwFlags & INTERNET_FLAG_FWD_BACK)?
  1013. LOOKUP_URL_TRANSLATE : LOOKUP_URL_NOCREATE,
  1014. RETRIEVE_WITHOUT_CHECKS | RETRIEVE_WITH_ALLOCATION);
  1015. // not found in cache
  1016. if( dwError != ERROR_SUCCESS )
  1017. goto Cleanup;
  1018. fLocked = TRUE;
  1019. // found in cache, get the last modified time
  1020. *pftLastModifiedTime = pCEI->LastModifiedTime;
  1021. bRet = IsExpired(pCEI, dwFlags, &bLazy);
  1022. if( bRet && bLazy )
  1023. {
  1024. //
  1025. // the entry is not expired, however, we need to post-fetch
  1026. // so we have to return EXPIRED back to trident to force them
  1027. // issue a binding, on the new binding, urlmon-wininet returns
  1028. // the cache content and queue a background update
  1029. // (an alternative would be to ask trident to catch this case
  1030. // and call background update themself)
  1031. //
  1032. bRet = FALSE;
  1033. }
  1034. Cleanup:
  1035. if( pCEI )
  1036. FREE_MEMORY(pCEI);
  1037. if (fLocked)
  1038. GlobalUrlContainers->UnlockUrl(lpszUrlName);
  1039. return bRet;
  1040. }