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.

330 lines
9.1 KiB

  1. #include <tchar.h>
  2. # include <nt.h>
  3. # include <ntrtl.h>
  4. # include <nturtl.h>
  5. # include <windows.h>
  6. // For the compatibility check function and types
  7. #include <comp.h>
  8. #include <clusapi.h>
  9. #include "resource.h"
  10. #include "iiscomp.hxx"
  11. #include "disblwww.hxx"
  12. HANDLE g_hMyHandle = NULL;
  13. //
  14. // Standard Win32 DLL Entry point
  15. //
  16. BOOL WINAPI DllMain(IN HANDLE DllHandle,IN DWORD Reason,IN LPVOID Reserved)
  17. {
  18. BOOL bReturn = FALSE;
  19. switch(Reason)
  20. {
  21. case DLL_PROCESS_ATTACH:
  22. g_hMyHandle = DllHandle;
  23. bReturn = TRUE;
  24. break;
  25. case DLL_THREAD_ATTACH:
  26. bReturn = TRUE;
  27. break;
  28. case DLL_PROCESS_DETACH:
  29. bReturn = TRUE;
  30. break;
  31. case DLL_THREAD_DETACH:
  32. bReturn = TRUE;
  33. break;
  34. }
  35. return(bReturn);
  36. }
  37. // function: IISUpgradeCompatibilityCheck
  38. //
  39. // Checks the IIS Upgrade Comapatability. At this time, this is only used to
  40. // tell if the machine is clustered for IIS. Because this upgrade is not seemless
  41. //
  42. // Parameters:
  43. // PCOMPAIBILITYCALLBACK pfnCompatibilityCallbackIn
  44. // Points to the callback function used to supply compatibility
  45. // information to WinNT32.exe
  46. //
  47. // LPVOID pvContextIn
  48. // Pointer to the context buffer supplied by WinNT32.exe
  49. //
  50. // Return Values:
  51. // TRUE - Everything worked fine
  52. // FALSE - There was a failure
  53. //
  54. extern "C"
  55. BOOL
  56. IISUpgradeCompatibilityCheck(
  57. PCOMPAIBILITYCALLBACK pfnCompatibilityCallbackIn
  58. , LPVOID pvContextIn
  59. )
  60. {
  61. BOOL bRet = TRUE;
  62. BOOL bDisableW3SVC;
  63. BOOL bInstallingOnFat;
  64. BOOL bIISIsInstalled;
  65. COMPATIBILITY_ENTRY ceCompatibilityEntry;
  66. if ( !IsIISInstalled( &bIISIsInstalled ) )
  67. {
  68. // Failed to do check, error out
  69. return FALSE;
  70. }
  71. if ( !bIISIsInstalled )
  72. {
  73. // IIS is not installed, so there is nothing we need to do
  74. return TRUE;
  75. }
  76. // Check for Clustering Compatability Issue
  77. if ( IsClusterResourceInstalled( IISCOMPAT_RESOURCETYPE ) )
  78. {
  79. // Since we have the comaptabilty problem, we have to call the winnt32 callback funcion
  80. SetCompatabilityContext( &ceCompatibilityEntry,
  81. IDS_COMPATABILITY_DESCRIPTION_CLUSTER,
  82. IISCOMPAT_TEXTNAME,
  83. IISCOMPAT_HTMLNAME );
  84. bRet = pfnCompatibilityCallbackIn( &ceCompatibilityEntry, pvContextIn );
  85. }
  86. // Check for disabling the W3SVC Service
  87. if ( ShouldW3SVCBeDisabledOnUpgrade( &bDisableW3SVC ) )
  88. {
  89. if ( !NotifyIISToDisableW3SVCOnUpgrade( bDisableW3SVC ) )
  90. {
  91. bRet = FALSE;
  92. }
  93. if ( bDisableW3SVC )
  94. {
  95. // Since we have the comaptabilty problem, we have to call the winnt32 callback funcion
  96. SetCompatabilityContext( &ceCompatibilityEntry,
  97. IDS_COMPATABILITY_DESCRIPTION_W3SVCDISABLE,
  98. IISCOMPAT_W3SVCDISABLE_TEXTNAME,
  99. IISCOMPAT_W3SVCDISABLE_HTMLNAME );
  100. if ( !pfnCompatibilityCallbackIn( &ceCompatibilityEntry, pvContextIn ) )
  101. {
  102. bRet = FALSE;
  103. }
  104. }
  105. }
  106. else
  107. {
  108. // Could not do check, so fail
  109. bRet = FALSE;
  110. }
  111. // Warning about installing on FAT
  112. if ( IsIISInstallingonFat( &bInstallingOnFat ) )
  113. {
  114. if ( bInstallingOnFat )
  115. {
  116. // Since we have the comaptabilty problem, we have to call the winnt32 callback funcion
  117. SetCompatabilityContext( &ceCompatibilityEntry,
  118. IDS_COMPATABILITY_DESCRIPTION_FAT,
  119. IISCOMPAT_FAT_TEXTNAME,
  120. IISCOMPAT_FAT_HTMLNAME );
  121. if ( !pfnCompatibilityCallbackIn( &ceCompatibilityEntry, pvContextIn ) )
  122. {
  123. bRet = FALSE;
  124. }
  125. }
  126. }
  127. else
  128. {
  129. // Could not do check, so fail
  130. bRet = FALSE;
  131. }
  132. return bRet;
  133. }
  134. // IsIISInstallingonFat
  135. //
  136. // Parameters:
  137. // pbInstallingOnFat [out] - Is IIS installing on FAT?
  138. //
  139. // Return Values:
  140. // TRUE - Successfully checked
  141. // FALSE - Failure checking
  142. //
  143. BOOL
  144. IsIISInstallingonFat( LPBOOL pbInstallingOnFat )
  145. {
  146. TCHAR szSystemDrive[ MAX_PATH ];
  147. DWORD dwDriveFlags;
  148. UINT iReturn;
  149. iReturn = GetWindowsDirectory( szSystemDrive,
  150. sizeof(szSystemDrive)/sizeof(szSystemDrive[0]) );
  151. if ( ( iReturn == 0 ) || // Call failed
  152. ( iReturn >= MAX_PATH ) || // Buffer was not large enough
  153. ( iReturn < 3 ) || // sizeof 'x:\'
  154. ( szSystemDrive[1] != _T(':') ) || // Not in a format we expect
  155. ( szSystemDrive[2] != _T('\\') ) )
  156. {
  157. // Failure checking
  158. return FALSE;
  159. }
  160. // Null terminate drive
  161. szSystemDrive[3] = _T('\0');
  162. if ( !GetVolumeInformation( szSystemDrive,
  163. NULL, // Volume Name Buffer
  164. 0, // Size of Buffer
  165. NULL, // Serial Number Buffer
  166. NULL, // Max Component Lenght
  167. &dwDriveFlags, // System Flags
  168. NULL, // FS Type
  169. 0 ) )
  170. {
  171. // Failed to do query
  172. return FALSE;
  173. }
  174. *pbInstallingOnFat = ( dwDriveFlags & FS_PERSISTENT_ACLS ) == 0;
  175. return TRUE;
  176. }
  177. // SetCompatabilityContext
  178. //
  179. // Set the Context of the Compatabilty stucrute that we must send back to
  180. // the compat stuff
  181. //
  182. void
  183. SetCompatabilityContext( COMPATIBILITY_ENTRY *pCE, DWORD dwDescriptionID, LPTSTR szTxtFile, LPTSTR szHtmlFile )
  184. {
  185. static WCHAR szDescriptionBuffer[ 100 ];
  186. DWORD dwErr;
  187. dwErr = LoadStringW( (HINSTANCE) g_hMyHandle,
  188. dwDescriptionID,
  189. szDescriptionBuffer,
  190. sizeof(szDescriptionBuffer)/sizeof(szDescriptionBuffer[0]) );
  191. if ( dwErr == 0 )
  192. {
  193. // This should not happen, since we control the length
  194. // of the resource
  195. ASSERT( ( sizeof(IISCOMPAT_DESCRIPTION)/sizeof(WCHAR) ) <
  196. ( sizeof(szDescriptionBuffer)/sizeof(szDescriptionBuffer[0]) ) );
  197. ASSERT( dwErr != 0 /* FALSE */ );
  198. _tcscpy(szDescriptionBuffer, IISCOMPAT_DESCRIPTION );
  199. }
  200. pCE->Description = szDescriptionBuffer;
  201. pCE->HtmlName = szHtmlFile;
  202. pCE->TextName = szTxtFile;
  203. pCE->RegKeyName = NULL;
  204. pCE->RegValName = NULL ;
  205. pCE->RegValDataSize = 0;
  206. pCE->RegValData = NULL;
  207. pCE->SaveValue = NULL;
  208. pCE->Flags = 0;
  209. pCE->InfName = NULL;
  210. pCE->InfSection = NULL;
  211. }
  212. // function: IsClusterResourceInstalled
  213. //
  214. // Check to see if there is a Cluster with a resource of a particular
  215. // type that you are looking for.
  216. //
  217. // Parameters:
  218. // szResourceType - The type of resource that you are looking for
  219. //
  220. // Return Values:
  221. // TRUE - There is a cluster with that resource type
  222. // FALSE - There is not a cluster with that resource type, or we
  223. // failed during the search
  224. //
  225. BOOL
  226. IsClusterResourceInstalled(LPWSTR szResourceType)
  227. {
  228. HCLUSTER hCluster;
  229. HINSTANCE hClusApi = NULL;
  230. HCLUSENUM hClusEnum = NULL;
  231. BOOL bResourceFound = FALSE;
  232. if (hCluster = OpenCluster(NULL))
  233. {
  234. // Open cluster resource
  235. hClusEnum = ClusterOpenEnum(hCluster, CLUSTER_ENUM_RESOURCE);
  236. }
  237. if (hClusEnum != NULL)
  238. {
  239. DWORD dwEnumIndex = 0;
  240. DWORD dwErr = ERROR_SUCCESS;
  241. WCHAR szClusterName[CLUSTERNAME_MAXLENGTH];
  242. WCHAR szClusterResourceType[CLUSTERNAME_MAXLENGTH];
  243. DWORD dwType;
  244. DWORD dwLen;
  245. HRESOURCE hClusResource;
  246. HKEY hResourceRoot;
  247. HKEY hClusResourceKey;
  248. while ( ( dwErr == ERROR_SUCCESS ) && !bResourceFound )
  249. {
  250. // Get the cluster name
  251. dwLen = CLUSTERNAME_MAXLENGTH;
  252. dwErr = ClusterEnum( hClusEnum, dwEnumIndex++, &dwType, szClusterName, &dwLen );
  253. if ( ( dwErr == ERROR_SUCCESS ) && ( dwType == CLUSTER_ENUM_RESOURCE ) )
  254. {
  255. hClusResource = NULL;
  256. hClusResourceKey = NULL;
  257. dwLen = CLUSTERNAME_MAXLENGTH;
  258. // For each cluster, check out the resources
  259. if ( ( hClusResource = OpenClusterResource( hCluster, szClusterName ) ) &&
  260. ( hClusResourceKey = GetClusterResourceKey( hClusResource, KEY_READ ) ) &&
  261. ( ClusterRegQueryValue( hClusResourceKey, L"Type", &dwType, (LPBYTE) szClusterResourceType , &dwLen ) == ERROR_SUCCESS) &&
  262. ( dwType == REG_SZ ) &&
  263. ( !_wcsicmp( szClusterResourceType , szResourceType ) )
  264. )
  265. {
  266. // Found the Resource we were looking for
  267. bResourceFound = TRUE;
  268. }
  269. if ( hClusResourceKey )
  270. {
  271. ClusterRegCloseKey( hClusResourceKey );
  272. }
  273. if ( hClusResource )
  274. {
  275. CloseClusterResource( hClusResource );
  276. }
  277. }
  278. }
  279. }
  280. if ( hClusEnum )
  281. {
  282. ClusterCloseEnum( hClusEnum );
  283. }
  284. if ( hCluster )
  285. {
  286. CloseCluster( hCluster);
  287. }
  288. return bResourceFound;
  289. }