Windows2003-3790/inetsrv/iis/setup/iiscomp/iiscomp.cpp
2020-09-30 16:53:55 +02:00

331 lines
9.1 KiB
C++

#include <tchar.h>
# include <nt.h>
# include <ntrtl.h>
# include <nturtl.h>
# include <windows.h>
// For the compatibility check function and types
#include <comp.h>
#include <clusapi.h>
#include "resource.h"
#include "iiscomp.hxx"
#include "disblwww.hxx"
HANDLE g_hMyHandle = NULL;
//
// Standard Win32 DLL Entry point
//
BOOL WINAPI DllMain(IN HANDLE DllHandle,IN DWORD Reason,IN LPVOID Reserved)
{
BOOL bReturn = FALSE;
switch(Reason)
{
case DLL_PROCESS_ATTACH:
g_hMyHandle = DllHandle;
bReturn = TRUE;
break;
case DLL_THREAD_ATTACH:
bReturn = TRUE;
break;
case DLL_PROCESS_DETACH:
bReturn = TRUE;
break;
case DLL_THREAD_DETACH:
bReturn = TRUE;
break;
}
return(bReturn);
}
// function: IISUpgradeCompatibilityCheck
//
// Checks the IIS Upgrade Comapatability. At this time, this is only used to
// tell if the machine is clustered for IIS. Because this upgrade is not seemless
//
// Parameters:
// PCOMPAIBILITYCALLBACK pfnCompatibilityCallbackIn
// Points to the callback function used to supply compatibility
// information to WinNT32.exe
//
// LPVOID pvContextIn
// Pointer to the context buffer supplied by WinNT32.exe
//
// Return Values:
// TRUE - Everything worked fine
// FALSE - There was a failure
//
extern "C"
BOOL
IISUpgradeCompatibilityCheck(
PCOMPAIBILITYCALLBACK pfnCompatibilityCallbackIn
, LPVOID pvContextIn
)
{
BOOL bRet = TRUE;
BOOL bDisableW3SVC;
BOOL bInstallingOnFat;
BOOL bIISIsInstalled;
COMPATIBILITY_ENTRY ceCompatibilityEntry;
if ( !IsIISInstalled( &bIISIsInstalled ) )
{
// Failed to do check, error out
return FALSE;
}
if ( !bIISIsInstalled )
{
// IIS is not installed, so there is nothing we need to do
return TRUE;
}
// Check for Clustering Compatability Issue
if ( IsClusterResourceInstalled( IISCOMPAT_RESOURCETYPE ) )
{
// Since we have the comaptabilty problem, we have to call the winnt32 callback funcion
SetCompatabilityContext( &ceCompatibilityEntry,
IDS_COMPATABILITY_DESCRIPTION_CLUSTER,
IISCOMPAT_TEXTNAME,
IISCOMPAT_HTMLNAME );
bRet = pfnCompatibilityCallbackIn( &ceCompatibilityEntry, pvContextIn );
}
// Check for disabling the W3SVC Service
if ( ShouldW3SVCBeDisabledOnUpgrade( &bDisableW3SVC ) )
{
if ( !NotifyIISToDisableW3SVCOnUpgrade( bDisableW3SVC ) )
{
bRet = FALSE;
}
if ( bDisableW3SVC )
{
// Since we have the comaptabilty problem, we have to call the winnt32 callback funcion
SetCompatabilityContext( &ceCompatibilityEntry,
IDS_COMPATABILITY_DESCRIPTION_W3SVCDISABLE,
IISCOMPAT_W3SVCDISABLE_TEXTNAME,
IISCOMPAT_W3SVCDISABLE_HTMLNAME );
if ( !pfnCompatibilityCallbackIn( &ceCompatibilityEntry, pvContextIn ) )
{
bRet = FALSE;
}
}
}
else
{
// Could not do check, so fail
bRet = FALSE;
}
// Warning about installing on FAT
if ( IsIISInstallingonFat( &bInstallingOnFat ) )
{
if ( bInstallingOnFat )
{
// Since we have the comaptabilty problem, we have to call the winnt32 callback funcion
SetCompatabilityContext( &ceCompatibilityEntry,
IDS_COMPATABILITY_DESCRIPTION_FAT,
IISCOMPAT_FAT_TEXTNAME,
IISCOMPAT_FAT_HTMLNAME );
if ( !pfnCompatibilityCallbackIn( &ceCompatibilityEntry, pvContextIn ) )
{
bRet = FALSE;
}
}
}
else
{
// Could not do check, so fail
bRet = FALSE;
}
return bRet;
}
// IsIISInstallingonFat
//
// Parameters:
// pbInstallingOnFat [out] - Is IIS installing on FAT?
//
// Return Values:
// TRUE - Successfully checked
// FALSE - Failure checking
//
BOOL
IsIISInstallingonFat( LPBOOL pbInstallingOnFat )
{
TCHAR szSystemDrive[ MAX_PATH ];
DWORD dwDriveFlags;
UINT iReturn;
iReturn = GetWindowsDirectory( szSystemDrive,
sizeof(szSystemDrive)/sizeof(szSystemDrive[0]) );
if ( ( iReturn == 0 ) || // Call failed
( iReturn >= MAX_PATH ) || // Buffer was not large enough
( iReturn < 3 ) || // sizeof 'x:\'
( szSystemDrive[1] != _T(':') ) || // Not in a format we expect
( szSystemDrive[2] != _T('\\') ) )
{
// Failure checking
return FALSE;
}
// Null terminate drive
szSystemDrive[3] = _T('\0');
if ( !GetVolumeInformation( szSystemDrive,
NULL, // Volume Name Buffer
0, // Size of Buffer
NULL, // Serial Number Buffer
NULL, // Max Component Lenght
&dwDriveFlags, // System Flags
NULL, // FS Type
0 ) )
{
// Failed to do query
return FALSE;
}
*pbInstallingOnFat = ( dwDriveFlags & FS_PERSISTENT_ACLS ) == 0;
return TRUE;
}
// SetCompatabilityContext
//
// Set the Context of the Compatabilty stucrute that we must send back to
// the compat stuff
//
void
SetCompatabilityContext( COMPATIBILITY_ENTRY *pCE, DWORD dwDescriptionID, LPTSTR szTxtFile, LPTSTR szHtmlFile )
{
static WCHAR szDescriptionBuffer[ 100 ];
DWORD dwErr;
dwErr = LoadStringW( (HINSTANCE) g_hMyHandle,
dwDescriptionID,
szDescriptionBuffer,
sizeof(szDescriptionBuffer)/sizeof(szDescriptionBuffer[0]) );
if ( dwErr == 0 )
{
// This should not happen, since we control the length
// of the resource
ASSERT( ( sizeof(IISCOMPAT_DESCRIPTION)/sizeof(WCHAR) ) <
( sizeof(szDescriptionBuffer)/sizeof(szDescriptionBuffer[0]) ) );
ASSERT( dwErr != 0 /* FALSE */ );
_tcscpy(szDescriptionBuffer, IISCOMPAT_DESCRIPTION );
}
pCE->Description = szDescriptionBuffer;
pCE->HtmlName = szHtmlFile;
pCE->TextName = szTxtFile;
pCE->RegKeyName = NULL;
pCE->RegValName = NULL ;
pCE->RegValDataSize = 0;
pCE->RegValData = NULL;
pCE->SaveValue = NULL;
pCE->Flags = 0;
pCE->InfName = NULL;
pCE->InfSection = NULL;
}
// function: IsClusterResourceInstalled
//
// Check to see if there is a Cluster with a resource of a particular
// type that you are looking for.
//
// Parameters:
// szResourceType - The type of resource that you are looking for
//
// Return Values:
// TRUE - There is a cluster with that resource type
// FALSE - There is not a cluster with that resource type, or we
// failed during the search
//
BOOL
IsClusterResourceInstalled(LPWSTR szResourceType)
{
HCLUSTER hCluster;
HINSTANCE hClusApi = NULL;
HCLUSENUM hClusEnum = NULL;
BOOL bResourceFound = FALSE;
if (hCluster = OpenCluster(NULL))
{
// Open cluster resource
hClusEnum = ClusterOpenEnum(hCluster, CLUSTER_ENUM_RESOURCE);
}
if (hClusEnum != NULL)
{
DWORD dwEnumIndex = 0;
DWORD dwErr = ERROR_SUCCESS;
WCHAR szClusterName[CLUSTERNAME_MAXLENGTH];
WCHAR szClusterResourceType[CLUSTERNAME_MAXLENGTH];
DWORD dwType;
DWORD dwLen;
HRESOURCE hClusResource;
HKEY hResourceRoot;
HKEY hClusResourceKey;
while ( ( dwErr == ERROR_SUCCESS ) && !bResourceFound )
{
// Get the cluster name
dwLen = CLUSTERNAME_MAXLENGTH;
dwErr = ClusterEnum( hClusEnum, dwEnumIndex++, &dwType, szClusterName, &dwLen );
if ( ( dwErr == ERROR_SUCCESS ) && ( dwType == CLUSTER_ENUM_RESOURCE ) )
{
hClusResource = NULL;
hClusResourceKey = NULL;
dwLen = CLUSTERNAME_MAXLENGTH;
// For each cluster, check out the resources
if ( ( hClusResource = OpenClusterResource( hCluster, szClusterName ) ) &&
( hClusResourceKey = GetClusterResourceKey( hClusResource, KEY_READ ) ) &&
( ClusterRegQueryValue( hClusResourceKey, L"Type", &dwType, (LPBYTE) szClusterResourceType , &dwLen ) == ERROR_SUCCESS) &&
( dwType == REG_SZ ) &&
( !_wcsicmp( szClusterResourceType , szResourceType ) )
)
{
// Found the Resource we were looking for
bResourceFound = TRUE;
}
if ( hClusResourceKey )
{
ClusterRegCloseKey( hClusResourceKey );
}
if ( hClusResource )
{
CloseClusterResource( hClusResource );
}
}
}
}
if ( hClusEnum )
{
ClusterCloseEnum( hClusEnum );
}
if ( hCluster )
{
CloseCluster( hCluster);
}
return bResourceFound;
}