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.

254 lines
7.1 KiB

  1. #include <cache.hxx>
  2. // Typedef for GetFileAttributeEx function
  3. typedef BOOL (WINAPI *PFNGETFILEATTREX)(LPCTSTR, GET_FILEEX_INFO_LEVELS, LPVOID);
  4. #ifdef unix
  5. #include <flock.hxx>
  6. #endif /* unix */
  7. //
  8. // global variables definition.
  9. //
  10. CRITICAL_SECTION GlobalCacheCritSect;
  11. BOOL GlobalCacheInitialized = FALSE;
  12. CConMgr *GlobalUrlContainers = NULL;
  13. LONG GlobalScavengerRunning = -1;
  14. DWORD GlobalRetrieveUrlCacheEntryFileCount = 0;
  15. PFNGETFILEATTREX gpfnGetFileAttributesEx = 0;
  16. char g_szFixup[sizeof(DWORD)];
  17. HINSTANCE g_hFixup;
  18. PFN_FIXUP g_pfnFixup;
  19. MEMORY *CacheHeap = NULL;
  20. HNDLMGR HandleMgr;
  21. #ifdef unix
  22. /***********************
  23. * ReadOnlyCache on Unix
  24. * *********************
  25. * When the cache resides on a file system which is shared over NFS
  26. * and the user can access the same cache from different work-stations,
  27. * it causes a problem. The fix is made so that, the first process has
  28. * write access to the cache and any subsequent browser process which
  29. * is started from a different host will receive a read-only version
  30. * of the cache and will not be able to get cookies etc. A symbolic
  31. * link is created in $HOME/.microsoft named ielock. Creation and
  32. * deletion of this symbolic link should be atomic. The functions
  33. * CreateAtomicCacheLockFile and DeleteAtomicCacheLockFile implement
  34. * this behavior. When a readonly cache is used, cache deletion is
  35. * not allowed (Scavenger thread need not be launched).
  36. *
  37. * g_ReadOnlyCaches denotes if a readonly cache is being used.
  38. * gszLockingHost denotes the host that holds the cache lock.
  39. */
  40. BOOL g_ReadOnlyCaches = FALSE;
  41. char *gszLockingHost = 0;
  42. extern "C" void unixGetWininetCacheLockStatus(BOOL *pBool, char **pszLockingHost)
  43. {
  44. if(pBool)
  45. *pBool = g_ReadOnlyCaches;
  46. if(pszLockingHost)
  47. *pszLockingHost = gszLockingHost;
  48. }
  49. #endif /* unix */
  50. #ifdef CHECKLOCK_PARANOID
  51. // Code to enforce strict ordering on resources to prevent deadlock
  52. // One cannot attempt to take the critical section for the first time
  53. // if one holds a container lock
  54. DWORD dwThreadLocked;
  55. DWORD dwLockLevel;
  56. void CheckEnterCritical(CRITICAL_SECTION *_cs)
  57. {
  58. EnterCriticalSection(_cs);
  59. if (_cs == &GlobalCacheCritSect && dwLockLevel++ == 0)
  60. {
  61. dwThreadLocked = GetCurrentThreadId();
  62. if (GlobalUrlContainers) GlobalUrlContainers->CheckNoLocks(dwThreadLocked);
  63. }
  64. }
  65. void CheckLeaveCritical(CRITICAL_SECTION *_cs)
  66. {
  67. if (_cs == &GlobalCacheCritSect)
  68. {
  69. INET_ASSERT(dwLockLevel);
  70. if (dwLockLevel == 1)
  71. {
  72. if (GlobalUrlContainers) GlobalUrlContainers->CheckNoLocks(dwThreadLocked);
  73. dwThreadLocked = 0;
  74. }
  75. dwLockLevel--;
  76. }
  77. LeaveCriticalSection(_cs);
  78. }
  79. #endif
  80. //
  81. /*++
  82. --*/
  83. BOOL InitGlobals (void)
  84. {
  85. if (GlobalCacheInitialized)
  86. return TRUE;
  87. LOCK_CACHE();
  88. if (GlobalCacheInitialized)
  89. goto done;
  90. GetWininetUserName();
  91. // Read registry settings.
  92. EnsureInternetSettingsKeyCached();
  93. InternetReadRegistryDword(vszSyncMode, &GlobalUrlCacheSyncMode);
  94. { // Detect a fixup handler. Open scope to avoid compiler complaint.
  95. REGISTRY_OBJ roCache (HKEY_LOCAL_MACHINE, OLD_CACHE_KEY);
  96. if (ERROR_SUCCESS == roCache.GetStatus())
  97. {
  98. DWORD cbFixup = sizeof(g_szFixup);
  99. if (ERROR_SUCCESS != roCache.GetValue
  100. ("FixupKey", (LPBYTE) g_szFixup, &cbFixup))
  101. {
  102. g_szFixup[0] = 0;
  103. }
  104. if (g_szFixup[0] != 'V' || g_szFixup[3] != 0)
  105. {
  106. g_szFixup[0] = 0;
  107. }
  108. }
  109. }
  110. {
  111. REGISTRY_OBJ roCache (HKEY_LOCAL_MACHINE, CACHE5_KEY);
  112. if (ERROR_SUCCESS == roCache.GetStatus())
  113. {
  114. DWORD dwDefTime;
  115. if (ERROR_SUCCESS == roCache.GetValue("SessionStartTimeDefaultDeltaSecs", &dwDefTime))
  116. {
  117. dwdwSessionStartTimeDefaultDelta = dwDefTime * (LONGLONG)10000000;
  118. dwdwSessionStartTime -= dwdwSessionStartTimeDefaultDelta;
  119. }
  120. }
  121. }
  122. // Seed the random number generator for random file name generation.
  123. srand(GetTickCount());
  124. GlobalUrlContainers = new CConMgr();
  125. GlobalCacheInitialized =
  126. GlobalUrlContainers && (GlobalUrlContainers->GetStatus() == ERROR_SUCCESS);
  127. if( GlobalCacheInitialized )
  128. {
  129. DWORD dwError = GlobalUrlContainers->CreateDefaultGroups();
  130. INET_ASSERT(dwError == ERROR_SUCCESS);
  131. }
  132. else
  133. {
  134. delete GlobalUrlContainers;
  135. GlobalUrlContainers = NULL;
  136. }
  137. done:
  138. UNLOCK_CACHE();
  139. return GlobalCacheInitialized;
  140. }
  141. BOOL
  142. DLLUrlCacheEntry(
  143. IN DWORD Reason
  144. )
  145. /*++
  146. Routine Description:
  147. Performs global initialization and termination for all protocol modules.
  148. This function only handles process attach and detach which are required for
  149. global initialization and termination, respectively. We disable thread
  150. attach and detach. New threads calling Wininet APIs will get an
  151. INTERNET_THREAD_INFO structure created for them by the first API requiring
  152. this structure
  153. Arguments:
  154. DllHandle - handle of this DLL. Unused
  155. Reason - process attach/detach or thread attach/detach
  156. Reserved - if DLL_PROCESS_ATTACH, NULL means DLL is being dynamically
  157. loaded, else static. For DLL_PROCESS_DETACH, NULL means DLL
  158. is being freed as a consequence of call to FreeLibrary()
  159. else the DLL is being freed as part of process termination
  160. Return Value:
  161. BOOL
  162. Success - TRUE
  163. Failure - FALSE. Failed to initialize
  164. --*/
  165. {
  166. HMODULE ModuleHandleKernel;
  167. switch (Reason)
  168. {
  169. case DLL_PROCESS_ATTACH:
  170. #ifdef CHECKLOCK_PARANOID
  171. dwThreadLocked = 0;
  172. dwLockLevel = 0;
  173. #endif
  174. ModuleHandleKernel = GetModuleHandle("KERNEL32");
  175. if (ModuleHandleKernel)
  176. {
  177. gpfnGetFileAttributesEx = (PFNGETFILEATTREX)
  178. GetProcAddress(ModuleHandleKernel, "GetFileAttributesExA");
  179. }
  180. InitializeCriticalSection (&GlobalCacheCritSect);
  181. // RunOnceUrlCache (NULL, NULL, NULL, 0); // test stub
  182. #ifdef unix
  183. if(CreateAtomicCacheLockFile(&g_ReadOnlyCaches,&gszLockingHost) == FALSE)
  184. return FALSE;
  185. #endif /* unix */
  186. break;
  187. case DLL_PROCESS_DETACH:
  188. // Clean up containers list.
  189. if (GlobalUrlContainers != NULL)
  190. {
  191. delete GlobalUrlContainers;
  192. GlobalUrlContainers = NULL;
  193. }
  194. // Unload fixup handler.
  195. if (g_hFixup)
  196. FreeLibrary (g_hFixup);
  197. HandleMgr.Destroy();
  198. #ifdef unix
  199. DeleteAtomicCacheLockFile();
  200. #endif /* unix */
  201. DeleteCriticalSection (&GlobalCacheCritSect);
  202. break;
  203. }
  204. return TRUE;
  205. }