mirror of https://github.com/lianthony/NT4.0
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.
407 lines
8.0 KiB
407 lines
8.0 KiB
/*++
|
|
|
|
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 <dbgutil.h>
|
|
#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
|
|
|