Source code of Windows XP (NT5)
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.

222 lines
5.5 KiB

  1. /*++
  2. Copyright (c) 1996 Microsoft Corporation
  3. Module Name :
  4. isplat.cxx
  5. Abstract:
  6. This module defines functions for determining platform types
  7. Author:
  8. Johnson Apacible (johnsona) 19-Nov-1996
  9. Murali Krishnan (MuraliK) 17-Apr-1997
  10. Added CriticalSectionWith SpinCount stuff
  11. --*/
  12. #include "precomp.hxx"
  13. #include <inetsvcs.h>
  14. typedef
  15. BOOLEAN
  16. (NTAPI *GET_PRODUCT_TYPE)(
  17. PNT_PRODUCT_TYPE
  18. );
  19. extern "C"
  20. PLATFORM_TYPE
  21. IISGetPlatformType(
  22. VOID
  23. )
  24. /*++
  25. This function consults the registry and determines the platform type
  26. for this machine.
  27. Arguments:
  28. None
  29. Returns:
  30. Platform type
  31. --*/
  32. {
  33. PLATFORM_TYPE pt;
  34. LONG result;
  35. HKEY keyHandle;
  36. WCHAR productType[30];
  37. DWORD type;
  38. BOOL isNt = TRUE;
  39. OSVERSIONINFO osInfo;
  40. //
  41. // See if the platform type has already been discovered.
  42. //
  43. if ( g_PlatformType != PtInvalid ) {
  44. return(g_PlatformType);
  45. }
  46. //
  47. // see if this is win95
  48. //
  49. osInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
  50. if ( GetVersionEx( &osInfo ) ) {
  51. isNt = (osInfo.dwPlatformId == VER_PLATFORM_WIN32_NT);
  52. } else {
  53. IIS_PRINTF((buff,"GetVersionEx failed with %d\n",
  54. GetLastError()));
  55. }
  56. if ( isNt ) {
  57. HINSTANCE hNtdll;
  58. NT_PRODUCT_TYPE ntType;
  59. GET_PRODUCT_TYPE pfnGetProductType;
  60. //
  61. // Get the product type from the system
  62. //
  63. pt = PtNtWorkstation;
  64. hNtdll = LoadLibrary("ntdll.dll");
  65. if ( hNtdll != NULL ) {
  66. pfnGetProductType = (GET_PRODUCT_TYPE)
  67. GetProcAddress(hNtdll, "RtlGetNtProductType");
  68. if ( (pfnGetProductType != NULL) &&
  69. pfnGetProductType( &ntType ) ) {
  70. if ( (ntType == NtProductLanManNt) ||
  71. (ntType == NtProductServer) ) {
  72. pt = PtNtServer;
  73. }
  74. }
  75. FreeLibrary( hNtdll );
  76. }
  77. } else {
  78. pt = PtWindows95;
  79. }
  80. g_PlatformType = pt;
  81. return(pt);
  82. } // IISGetPlatformType
  83. //------------------------------------------------------------------------
  84. // SetCriticalSectionSpinCount hackery
  85. typedef
  86. DWORD
  87. (WINAPI * PFN_SET_CRITICAL_SECTION_SPIN_COUNT)(
  88. LPCRITICAL_SECTION lpCriticalSection,
  89. DWORD dwSpinCount
  90. );
  91. static PFN_SET_CRITICAL_SECTION_SPIN_COUNT g_pfnSetCSSpinCount = NULL;
  92. //------------------------------------------------------------------------
  93. // Function: FakeSetCriticalSectionSpinCount
  94. // Synopsis: This function fakes setting critical section spin count.
  95. // See CCritSec::SetSpinCount() for details
  96. // Returns: 0 - since we are faking the set of cs with spin count
  97. //------------------------------------------------------------------------
  98. static DWORD
  99. FakeSetCriticalSectionSpinCount(
  100. LPCRITICAL_SECTION /*lpCriticalSection*/,
  101. DWORD /*dwSpinCount*/)
  102. {
  103. // For faked critical sections, the previous spin count is just ZERO!
  104. return 0;
  105. }
  106. //------------------------------------------------------------------------
  107. // Function: CCritSec::SetSpinCount
  108. // Synopsis: This function is used to call the appropriate underlying
  109. // functions to set the spin count for the supplied critical
  110. // section. The original function is supposed to be exported out
  111. // of kernel32.dll from NT 4.0 SP3. If the func is not available
  112. // from the dll, we will use a fake function.
  113. //
  114. // Arguments:
  115. // lpCriticalSection
  116. // Points to the critical section object.
  117. //
  118. // dwSpinCount
  119. // Supplies the spin count for the critical section object. For UP
  120. // systems, the spin count is ignored and the critical section spin
  121. // count is set to 0. For MP systems, if contention occurs, instead of
  122. // waiting on a semaphore associated with the critical section, the
  123. // calling thread will spin for spin count iterations before doing the
  124. // hard wait. If the critical section becomes free during the spin, a
  125. // wait is avoided.
  126. //
  127. // Returns:
  128. // The previous spin count for the critical section is returned.
  129. //------------------------------------------------------------------------
  130. DWORD
  131. IISSetCriticalSectionSpinCount(
  132. LPCRITICAL_SECTION lpCriticalSection,
  133. DWORD dwSpinCount)
  134. {
  135. if ( g_pfnSetCSSpinCount == NULL )
  136. {
  137. HINSTANCE tmpInstance;
  138. //
  139. // load kernel32 and get NT specific entry points
  140. //
  141. tmpInstance = LoadLibrary("kernel32.dll");
  142. if ( tmpInstance != NULL )
  143. {
  144. g_pfnSetCSSpinCount = (PFN_SET_CRITICAL_SECTION_SPIN_COUNT )
  145. GetProcAddress( tmpInstance, "SetCriticalSectionSpinCount");
  146. if ( g_pfnSetCSSpinCount == NULL ) {
  147. // the set CS Spincount function is not availble.
  148. // Just thunk it.
  149. g_pfnSetCSSpinCount = FakeSetCriticalSectionSpinCount;
  150. }
  151. //
  152. // We can free this because we are statically linked to it
  153. //
  154. FreeLibrary(tmpInstance);
  155. }
  156. }
  157. // Pass the inputs to the global function pointer which is already setup.
  158. return ( g_pfnSetCSSpinCount( lpCriticalSection, dwSpinCount));
  159. }
  160. VOID
  161. IISInitializeCriticalSection(
  162. LPCRITICAL_SECTION lpCriticalSection)
  163. {
  164. InitializeCriticalSection(lpCriticalSection);
  165. IISSetCriticalSectionSpinCount(lpCriticalSection, IIS_DEFAULT_CS_SPIN_COUNT);
  166. }