windows-nt/Source/XPSP1/NT/inetsrv/iis/svcs/iisrtl2/isplat.cxx
2020-09-26 16:20:57 +08:00

223 lines
5.5 KiB
C++

/*++
Copyright (c) 1996 Microsoft Corporation
Module Name :
isplat.cxx
Abstract:
This module defines functions for determining platform types
Author:
Johnson Apacible (johnsona) 19-Nov-1996
Murali Krishnan (MuraliK) 17-Apr-1997
Added CriticalSectionWith SpinCount stuff
--*/
#include "precomp.hxx"
#include <inetsvcs.h>
typedef
BOOLEAN
(NTAPI *GET_PRODUCT_TYPE)(
PNT_PRODUCT_TYPE
);
extern "C"
PLATFORM_TYPE
IISGetPlatformType(
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;
BOOL isNt = TRUE;
OSVERSIONINFO osInfo;
//
// See if the platform type has already been discovered.
//
if ( g_PlatformType != PtInvalid ) {
return(g_PlatformType);
}
//
// see if this is win95
//
osInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
if ( GetVersionEx( &osInfo ) ) {
isNt = (osInfo.dwPlatformId == VER_PLATFORM_WIN32_NT);
} else {
IIS_PRINTF((buff,"GetVersionEx failed with %d\n",
GetLastError()));
}
if ( isNt ) {
HINSTANCE hNtdll;
NT_PRODUCT_TYPE ntType;
GET_PRODUCT_TYPE pfnGetProductType;
//
// Get the product type from the system
//
pt = PtNtWorkstation;
hNtdll = LoadLibrary("ntdll.dll");
if ( hNtdll != NULL ) {
pfnGetProductType = (GET_PRODUCT_TYPE)
GetProcAddress(hNtdll, "RtlGetNtProductType");
if ( (pfnGetProductType != NULL) &&
pfnGetProductType( &ntType ) ) {
if ( (ntType == NtProductLanManNt) ||
(ntType == NtProductServer) ) {
pt = PtNtServer;
}
}
FreeLibrary( hNtdll );
}
} else {
pt = PtWindows95;
}
g_PlatformType = pt;
return(pt);
} // IISGetPlatformType
//------------------------------------------------------------------------
// SetCriticalSectionSpinCount hackery
typedef
DWORD
(WINAPI * PFN_SET_CRITICAL_SECTION_SPIN_COUNT)(
LPCRITICAL_SECTION lpCriticalSection,
DWORD dwSpinCount
);
static PFN_SET_CRITICAL_SECTION_SPIN_COUNT g_pfnSetCSSpinCount = NULL;
//------------------------------------------------------------------------
// Function: FakeSetCriticalSectionSpinCount
// Synopsis: This function fakes setting critical section spin count.
// See CCritSec::SetSpinCount() for details
// Returns: 0 - since we are faking the set of cs with spin count
//------------------------------------------------------------------------
static DWORD
FakeSetCriticalSectionSpinCount(
LPCRITICAL_SECTION /*lpCriticalSection*/,
DWORD /*dwSpinCount*/)
{
// For faked critical sections, the previous spin count is just ZERO!
return 0;
}
//------------------------------------------------------------------------
// Function: CCritSec::SetSpinCount
// Synopsis: This function is used to call the appropriate underlying
// functions to set the spin count for the supplied critical
// section. The original function is supposed to be exported out
// of kernel32.dll from NT 4.0 SP3. If the func is not available
// from the dll, we will use a fake function.
//
// Arguments:
// lpCriticalSection
// Points to the critical section object.
//
// dwSpinCount
// Supplies the spin count for the critical section object. For UP
// systems, the spin count is ignored and the critical section spin
// count is set to 0. For MP systems, if contention occurs, instead of
// waiting on a semaphore associated with the critical section, the
// calling thread will spin for spin count iterations before doing the
// hard wait. If the critical section becomes free during the spin, a
// wait is avoided.
//
// Returns:
// The previous spin count for the critical section is returned.
//------------------------------------------------------------------------
DWORD
IISSetCriticalSectionSpinCount(
LPCRITICAL_SECTION lpCriticalSection,
DWORD dwSpinCount)
{
if ( g_pfnSetCSSpinCount == NULL )
{
HINSTANCE tmpInstance;
//
// load kernel32 and get NT specific entry points
//
tmpInstance = LoadLibrary("kernel32.dll");
if ( tmpInstance != NULL )
{
g_pfnSetCSSpinCount = (PFN_SET_CRITICAL_SECTION_SPIN_COUNT )
GetProcAddress( tmpInstance, "SetCriticalSectionSpinCount");
if ( g_pfnSetCSSpinCount == NULL ) {
// the set CS Spincount function is not availble.
// Just thunk it.
g_pfnSetCSSpinCount = FakeSetCriticalSectionSpinCount;
}
//
// We can free this because we are statically linked to it
//
FreeLibrary(tmpInstance);
}
}
// Pass the inputs to the global function pointer which is already setup.
return ( g_pfnSetCSSpinCount( lpCriticalSection, dwSpinCount));
}
VOID
IISInitializeCriticalSection(
LPCRITICAL_SECTION lpCriticalSection)
{
InitializeCriticalSection(lpCriticalSection);
IISSetCriticalSectionSpinCount(lpCriticalSection, IIS_DEFAULT_CS_SPIN_COUNT);
}