/*++ Copyright (c) 1995 Microsoft Corporation Module Name : tsinit.cxx Abstract: This module contains the tsunami initialization code. Author: Murali R. Krishnan ( MuraliK ) 16-Jan-1995 --*/ #include "TsunamiP.Hxx" # include #pragma hdrstop HANDLE heventQuitEvent = NULL; HANDLE heventNewItem = NULL; LONG lInitializeCalled = 0; BOOL fInitializeCompleted = FALSE; DWORD dwInitializationError = NO_ERROR; // // Disables Tsunami Caching // BOOL DisableTsunamiCaching = FALSE; // // Allows us to mask the invalid flags // DWORD TsValidCreateFileOptions = TS_IIS_VALID_FLAGS; // // Indicates the platform type the IIS is running on // dllexp PLATFORM_TYPE TsPlatformType = PtInvalid; // // Declaration of debugging variables // DECLARE_DEBUG_PRINTS_OBJECT(); DECLARE_DEBUG_VARIABLE(); BOOL Tsunami_Initialize( VOID ) /*++ Description: Initializes the tsunami package --*/ { HKEY hKey; DWORD dwType; DWORD nBytes; DWORD dwValue; DWORD cacheSize; DWORD err; if ( InterlockedExchange( &lInitializeCalled, 1 ) ) { DBGPRINTF((DBG_CONTEXT, "Tsunami Library already initialized\n")); // // Wait until initialization is complete // while ( !fInitializeCompleted ) { Sleep( 500 ); } // // If initialization failed for the first thread, copy the error // code and fail initilization for this thread also // if ( dwInitializationError ) { SetLastError( dwInitializationError ); return FALSE; } return TRUE; } CREATE_DEBUG_PRINT_OBJECT( "tsunami"); SET_DEBUG_FLAGS( 0); // // Initialize global events // heventQuitEvent = CreateEvent( NULL, TRUE, FALSE, NULL ); heventNewItem = CreateEvent( NULL, FALSE, FALSE, NULL ); if ( (heventQuitEvent == NULL) || (heventNewItem == NULL) ) { goto Failure; } // // Set defaults // { MEMORYSTATUS ms; ms.dwLength = sizeof(MEMORYSTATUS); GlobalMemoryStatus( &ms ); // // Default is 10% of physical memory // cacheSize = ms.dwTotalPhys / 10; if ( cacheSize < INETA_DEF_MEMORY_CACHE_SIZE ) { cacheSize = INETA_DEF_MEMORY_CACHE_SIZE; } } // // If this is not a NTS, disable tsunami caching by default // if ( !TsIsNtServer() ) { DisableTsunamiCaching = TRUE; } // // Read the registry key to see whether tsunami caching is enabled // err = RegOpenKeyEx( HKEY_LOCAL_MACHINE, INETA_PARAMETERS_KEY, 0, KEY_ALL_ACCESS, &hKey ); if ( err == ERROR_SUCCESS ) { nBytes = sizeof(dwValue); err = RegQueryValueEx( hKey, INETA_DISABLE_TSUNAMI_CACHING, NULL, &dwType, (LPBYTE)&dwValue, &nBytes ); if ( (err == ERROR_SUCCESS) && (dwType == REG_DWORD) ) { DisableTsunamiCaching = (BOOL)dwValue; } // // Read the cache size // nBytes = sizeof(dwValue); err = RegQueryValueEx( hKey, INETA_MEMORY_CACHE_SIZE, NULL, &dwType, (LPBYTE) &dwValue, &nBytes ); RegCloseKey( hKey ); // // Default the cache size if we failed to query the value // if ( (err == ERROR_SUCCESS) && (dwType == REG_DWORD) ) { // // Limit the cache size to 2 gigs so integer comparisons will work // if ( dwValue > 0x7fffffff ) { cacheSize = 0x7fffffff; } else { cacheSize = dwValue; } } } // // if tsunami caching is disabled, set cache size to 0 // if ( DisableTsunamiCaching ) { cacheSize = 0; TsValidCreateFileOptions = TS_PWS_VALID_FLAGS; } // // Initialize the directory change manager // if ( !DirectoryChangeManager_Initialize( heventQuitEvent, heventNewItem )) { goto Failure; } // // Initialize the tsunami cache manager // if ( !Cache_Initialize( cacheSize )) { goto Failure; } fInitializeCompleted = TRUE; return( TRUE ); Failure: dwInitializationError = GetLastError(); DBGPRINTF( ( DBG_CONTEXT, "Tsunami_Initialize() Failed. Error = %d\n", GetLastError())); if ( heventQuitEvent ) { CloseHandle( heventQuitEvent ); heventQuitEvent = NULL; } if ( heventNewItem ) { CloseHandle( heventNewItem ); heventNewItem = NULL; } fInitializeCompleted = TRUE; return FALSE; } // Tsunami_Initialize VOID Tsunami_Terminate( VOID ) /*++ Description: Cleans up the Tsunami package --*/ { DWORD dwResult; if ( !InterlockedExchange( &lInitializeCalled, 0 )) { // // Don't return until the termination has finished // while ( fInitializeCompleted ) { Sleep( 500 ); } DBGPRINTF((DBG_CONTEXT, "Tsunami Library, not initialized. No cleanup\n")); return; } if ( !SetEvent( heventQuitEvent ) ) { DBGPRINTF((DBG_CONTEXT, "No Quit event posted for Tsunami. No Cleanup\n")); return; } // // Flush all items from the cache // TsCacheFlush( 0 ); // // Synchronize with our thread so we don't leave here before the // thread has finished cleaning up // if ( g_hChangeWaitThread != NULL ) { dwResult = WaitForSingleObject( g_hChangeWaitThread, INFINITE ); ASSERT( dwResult == WAIT_OBJECT_0 ); CloseHandle( g_hChangeWaitThread); } CloseHandle( heventQuitEvent ); CloseHandle( heventNewItem ); DeleteCriticalSection( &csVirtualRoots ); DELETE_DEBUG_PRINT_OBJECT(); fInitializeCompleted = FALSE; } // Tsunami_Terminate PLATFORM_TYPE TsGetPlatformType( VOID ) /*++ This function consults the registry and determines the platform type for this machine. Arguments: None Returns: Platform type --*/ { PLATFORM_TYPE pt; LONG result; HKEY keyHandle; WCHAR productType[30]; DWORD type; DWORD dataLength; DWORD i; // // See if the platform type has already been discovered. // if ( TsPlatformType != PtInvalid ) { return(TsPlatformType); } #ifndef CHICAGO // // First grab the product type string from the registry. // pt = PtNtWorkstation; result = RegOpenKeyW( HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Control\\ProductOptions", &keyHandle ); if ( result == NO_ERROR) { dataLength = 30; result = RegQueryValueExW( keyHandle, L"ProductType", NULL, &type, (LPBYTE)productType, &dataLength ); RegCloseKey( keyHandle); if ( result == NO_ERROR ) { // // Now determine whether this is a server box. // if ( _wcsicmp( productType, L"WinNT" ) != 0 ) { pt = PtNtServer; } } } #else pt = PtWindows95; #endif TsPlatformType = pt; return(pt); } // TsGetPlatformType