889 lines
21 KiB
C
889 lines
21 KiB
C
/*++
|
||
|
||
Copyright (c) 1992-1996 Microsoft Corporation
|
||
|
||
Module Name:
|
||
|
||
iisutil.c
|
||
|
||
Abstract:
|
||
|
||
IIS Resource utility routine DLL
|
||
|
||
Author:
|
||
|
||
Pete Benoit (v-pbenoi) 12-SEP-1996
|
||
|
||
Revision History:
|
||
|
||
--*/
|
||
|
||
#include "iisutil.h"
|
||
|
||
DWORD IISService[] = {
|
||
INET_HTTP,
|
||
INET_FTP,
|
||
INET_GOPHER
|
||
};
|
||
|
||
#define IIS_MNGT_DLLNAME L"infoadmn.dll"
|
||
|
||
//
|
||
// Define some globals used to get iis management routines
|
||
//
|
||
HINSTANCE iisDLL = NULL;
|
||
typedef NET_API_STATUS (NET_API_FUNCTION *INETINFOGETPROC)(LPWSTR,DWORD,LPINET_INFO_CONFIG_INFO *);
|
||
typedef NET_API_STATUS (NET_API_FUNCTION *INETINFOSETPROC)(LPWSTR,DWORD,LPINET_INFO_CONFIG_INFO);
|
||
typedef NET_API_STATUS (NET_API_FUNCTION *INETINFOFLUSHPROC)(LPWSTR,DWORD);
|
||
|
||
INETINFOGETPROC InetInfoGet = NULL;
|
||
INETINFOSETPROC InetInfoSet = NULL;
|
||
INETINFOFLUSHPROC InetInfoFlushMemory = NULL;
|
||
|
||
|
||
DWORD
|
||
IsIISMngtDllLoaded(
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
Checks to see if the IIS mngt dll loaded
|
||
Arguments:
|
||
|
||
|
||
Return Value:
|
||
ERROR_SUCCESS - Successfully loaded and found
|
||
A Win32 error code on failure.
|
||
|
||
--*/
|
||
|
||
{
|
||
if (iisDLL != NULL) {
|
||
return(ERROR_SUCCESS);
|
||
}
|
||
return(ERROR_SERVICE_NOT_ACTIVE);
|
||
}
|
||
|
||
DWORD
|
||
IISLoadMngtDll(
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
This routine tries to load the iis management dll. Then it attempts to
|
||
find the procedures required to manage it.
|
||
|
||
Arguments:
|
||
|
||
|
||
Return Value:
|
||
ERROR_SUCCESS - Successfully loaded and found
|
||
A Win32 error code on failure.
|
||
|
||
--*/
|
||
|
||
{
|
||
DWORD status;
|
||
//
|
||
// Try and load the IIS Mngt dll
|
||
//
|
||
iisDLL = LoadLibrary( IIS_MNGT_DLLNAME );
|
||
if (iisDLL == NULL) {
|
||
return(GetLastError());
|
||
}
|
||
//
|
||
// Try to locate the management routines
|
||
//
|
||
InetInfoGet = (INETINFOGETPROC)GetProcAddress(iisDLL,"InetInfoGetAdminInformation");
|
||
if (InetInfoGet == NULL) {
|
||
status = GetLastError();
|
||
goto error_exit;
|
||
}
|
||
|
||
InetInfoSet = (INETINFOSETPROC)GetProcAddress(iisDLL,"InetInfoSetAdminInformation");
|
||
if (InetInfoGet == NULL) {
|
||
status = GetLastError();
|
||
goto error_exit;
|
||
}
|
||
|
||
InetInfoFlushMemory = (INETINFOFLUSHPROC)GetProcAddress(iisDLL,"InetInfoFlushMemoryCache");
|
||
if (InetInfoFlushMemory == NULL) {
|
||
status = GetLastError();
|
||
goto error_exit;
|
||
}
|
||
return(ERROR_SUCCESS);
|
||
error_exit:
|
||
IISUnloadMngtDll();
|
||
return(status);
|
||
|
||
} // END IsIISInstalled
|
||
|
||
VOID
|
||
IISUnloadMngtDll(
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
This routine frees the IIS management DLL
|
||
|
||
Arguments:
|
||
|
||
|
||
Return Value:
|
||
|
||
--*/
|
||
{
|
||
if (iisDLL != NULL) {
|
||
FreeLibrary( iisDLL);
|
||
}
|
||
|
||
iisDLL = NULL;
|
||
InetInfoGet = NULL;
|
||
InetInfoSet = NULL;
|
||
InetInfoFlushMemory = NULL;
|
||
}
|
||
|
||
|
||
DWORD
|
||
GetIISInfo(
|
||
IN DWORD ServiceType,
|
||
OUT LPINET_INFO_CONFIG_INFO *IISInfo
|
||
)
|
||
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Get IIS information. This call returns a pointer
|
||
to an INET_INFO_CONFIG_INFO structure
|
||
|
||
Arguments:
|
||
|
||
ServiceType - The type of service
|
||
|
||
IISInfo - return a pointer to an INET_INFO_CONFIG_INFO structure. This
|
||
structure contains the virtual root information
|
||
|
||
|
||
Return Value:
|
||
|
||
NET_API_STATUS
|
||
|
||
--*/
|
||
|
||
{
|
||
DWORD Status;
|
||
if (InetInfoGet == NULL) {
|
||
return(ERROR_SERVICE_NOT_ACTIVE);
|
||
}
|
||
Status=InetInfoGet(NULL,IISService[ServiceType],IISInfo);
|
||
return(Status);
|
||
|
||
} // END GetIISInfo
|
||
|
||
|
||
|
||
|
||
DWORD
|
||
SetIISInfo(
|
||
IN DWORD ServiceType,
|
||
IN LPINET_INFO_CONFIG_INFO IISInfo
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Set IIS information. This call sets inet config infor using the
|
||
INET_INFO_CONFIG_INFO structure
|
||
|
||
Arguments:
|
||
|
||
ServiceType - The type of service
|
||
|
||
IISInfo - pointer to an INET_INFO_CONFIG_INFO structure. This structure
|
||
contains the virtual root information
|
||
|
||
|
||
Return Value:
|
||
|
||
ERROR_SUCCESS
|
||
NET ERROR Status
|
||
|
||
--*/
|
||
|
||
{
|
||
DWORD Status;
|
||
|
||
if ((InetInfoSet == NULL) || (InetInfoFlushMemory == NULL)) {
|
||
return(ERROR_SERVICE_NOT_ACTIVE);
|
||
}
|
||
//
|
||
// Only set the VirtualRoots
|
||
//
|
||
IISInfo->FieldControl = FC_INET_INFO_VIRTUAL_ROOTS;
|
||
|
||
Status=InetInfoSet(NULL,IISService[ServiceType],IISInfo);
|
||
|
||
if (Status != ERROR_SUCCESS) {
|
||
return(Status);
|
||
}
|
||
|
||
//
|
||
// If we sucessfully set the virtual root information
|
||
// flush the memory cache
|
||
//
|
||
Status = InetInfoFlushMemory(NULL,IISService[ServiceType]);
|
||
|
||
return(Status);
|
||
|
||
} // END SetIISInfo
|
||
|
||
|
||
|
||
|
||
DWORD
|
||
OffLineVirtualRoot(
|
||
IN LPIIS_RESOURCE ResourceEntry,
|
||
IN PLOG_EVENT_ROUTINE LogEvent
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Take offline all Virtual Roots for this resource
|
||
|
||
Arguments:
|
||
|
||
ResourceEntry - The resource that contains a list of virtual roots
|
||
|
||
Return Value:
|
||
|
||
ERROR_SUCCESS
|
||
W32 error code
|
||
|
||
--*/
|
||
|
||
{
|
||
|
||
LPINET_INFO_CONFIG_INFO IISInfo = NULL;
|
||
LPINET_INFO_VIRTUAL_ROOT_LIST tmpVRL = NULL;
|
||
LPINET_INFO_VIRTUAL_ROOT_LIST iisVRL = NULL;
|
||
LPINET_INFO_VIRTUAL_ROOT_ENTRY resVR = NULL;
|
||
DWORD Status = ERROR_SUCCESS;
|
||
DWORD i,c;
|
||
BOOLEAN MatchFound;
|
||
DWORD MatchingEntries = 0;
|
||
|
||
//
|
||
// Call IIS Management API to GET list of Virtual Roots
|
||
//
|
||
Status = GetIISInfo(ResourceEntry->ServiceType, &IISInfo);
|
||
if (Status != ERROR_SUCCESS) {
|
||
goto error_exit;
|
||
}
|
||
|
||
//
|
||
// For Robustness check to see if the IIS returned SUCCESS but
|
||
// did not return a valid address
|
||
//
|
||
if (IISInfo == NULL) {
|
||
(LogEvent)(
|
||
ResourceEntry->ResourceHandle,
|
||
LOG_ERROR,
|
||
L"Error [OffLineVirtualRoots] Get IIS information returned NULL\n");
|
||
Status = ERROR_RESOURCE_NOT_FOUND;
|
||
goto error_exit;
|
||
}
|
||
|
||
//
|
||
// Save pointer to original VirtualRoot Structure
|
||
//
|
||
iisVRL = IISInfo->VirtualRoots;
|
||
resVR = ResourceEntry->VirtualRoot;
|
||
|
||
//
|
||
// If the caller called terminate after open BUT before online
|
||
// the VR field of the resource could be NULL. Return so we don't accvio
|
||
//
|
||
|
||
if (resVR == NULL) {
|
||
(LogEvent)(
|
||
ResourceEntry->ResourceHandle,
|
||
LOG_ERROR,
|
||
L"Error [OffLineVirtualRoots] Resource VR information is NULL\n");
|
||
Status = ERROR_RESOURCE_NOT_FOUND;
|
||
goto error_exit;
|
||
}
|
||
//
|
||
// This is a sanity check
|
||
//
|
||
if ( (resVR->pszRoot == NULL) ||
|
||
(resVR->pszAddress == NULL) ||
|
||
(resVR->pszDirectory == NULL) ) {
|
||
(LogEvent)(
|
||
ResourceEntry->ResourceHandle,
|
||
LOG_ERROR,
|
||
L"Error [OffLineVirtualRoots] Resource has NULL entries for root , addr or directory\n");
|
||
Status = ERROR_RESOURCE_NOT_FOUND;
|
||
goto error_exit;
|
||
}
|
||
//
|
||
// Allocate storage to Filter out Virtual Roots managed by the Cluster
|
||
//
|
||
tmpVRL = LocalAlloc(LPTR,
|
||
( (iisVRL->cEntries + 1) *
|
||
sizeof(INET_INFO_VIRTUAL_ROOT_ENTRY) ) +
|
||
sizeof(INET_INFO_VIRTUAL_ROOT_LIST));
|
||
//
|
||
// Check to see we got a valid address
|
||
//
|
||
|
||
if (tmpVRL == NULL) {
|
||
(LogEvent)(
|
||
ResourceEntry->ResourceHandle,
|
||
LOG_ERROR,
|
||
L"Error [OffLineVirtualRoots] Allocation of TMP VR failed\n");
|
||
Status = ERROR_RESOURCE_NOT_FOUND;
|
||
goto error_exit;
|
||
}
|
||
|
||
//
|
||
// This is so ugly ...
|
||
// 1. Enumerate and compare each IIS VR KEY with the resource VR
|
||
// 2. Add ones that don't match to the tmpVR
|
||
// 3. Use the tmpVR to update the IIS service and mask resources entries
|
||
|
||
tmpVRL->cEntries = 0;
|
||
for (i=0;i<iisVRL->cEntries ;i++ ) {
|
||
MatchFound = FALSE;
|
||
|
||
|
||
if ( (_wcsicmp(iisVRL->aVirtRootEntry[i].pszRoot,resVR->pszRoot) == 0) &&
|
||
(_wcsicmp(iisVRL->aVirtRootEntry[i].pszAddress,resVR->pszAddress) == 0)
|
||
// (_wcsicmp(iisVRL->aVirtRootEntry[i].pszDirectory,resVR->pszDirectory) == 0)
|
||
){
|
||
// if all the VR primary keys match then skip this entry
|
||
MatchFound = TRUE;
|
||
MatchingEntries +=1;
|
||
} // END if
|
||
|
||
|
||
// No matching entry found in the Cluster config data so this VR is ok
|
||
if (!MatchFound) {
|
||
tmpVRL->aVirtRootEntry[tmpVRL->cEntries++] = iisVRL->aVirtRootEntry[i];
|
||
} // END if !MatchFound
|
||
|
||
} // END for i=0
|
||
|
||
|
||
IISInfo->VirtualRoots = tmpVRL;
|
||
//
|
||
// Call IIS Management API to SET list of Virtual Roots
|
||
// But only call this if we have something to remove
|
||
//
|
||
if (MatchingEntries > 0) {
|
||
Status = SetIISInfo(ResourceEntry->ServiceType, IISInfo);
|
||
}
|
||
|
||
// Destruct any temporary storage
|
||
IISInfo->VirtualRoots = iisVRL;
|
||
|
||
error_exit:
|
||
if (IISInfo != NULL) MIDL_user_free((LPVOID)IISInfo);
|
||
if (tmpVRL != NULL) LocalFree(tmpVRL);
|
||
|
||
return(Status);
|
||
} //OfflineVirtualRoot
|
||
|
||
|
||
|
||
DWORD
|
||
OnLineVirtualRoot(
|
||
IN LPIIS_RESOURCE ResourceEntry,
|
||
IN PLOG_EVENT_ROUTINE LogEvent
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Add this resources Virtual Root to the IIS
|
||
|
||
Arguments:
|
||
|
||
ResourceEntry - The resource that contains a list of virtual roots
|
||
|
||
Return Value:
|
||
|
||
ERROR_SUCCESS
|
||
W32 error code
|
||
|
||
--*/
|
||
{
|
||
|
||
|
||
LPINET_INFO_CONFIG_INFO IISInfo = NULL;
|
||
LPINET_INFO_VIRTUAL_ROOT_LIST tmpVRL = NULL;
|
||
LPINET_INFO_VIRTUAL_ROOT_LIST iisVRL = NULL;
|
||
LPINET_INFO_VIRTUAL_ROOT_ENTRY resVR = NULL;
|
||
DWORD Status = ERROR_SUCCESS;
|
||
DWORD i,c;
|
||
BOOLEAN MatchFound;
|
||
|
||
|
||
// Call IIS Management API to GET list of Virtual Roots
|
||
Status = GetIISInfo(ResourceEntry->ServiceType, &IISInfo);
|
||
if (Status != ERROR_SUCCESS) {
|
||
(LogEvent)(
|
||
ResourceEntry->ResourceHandle,
|
||
LOG_ERROR,
|
||
L"Error [OnLineVirtualRoots] Get IIS information call failed status = %1!u! \n",
|
||
Status);
|
||
goto error_exit;
|
||
}
|
||
|
||
// Save pointer to original VirtualRoot Structure
|
||
iisVRL = IISInfo->VirtualRoots;
|
||
resVR = ResourceEntry->VirtualRoot;
|
||
|
||
// Add Virtual Roots managed by the resource
|
||
if (resVR == NULL) {
|
||
(LogEvent)(
|
||
ResourceEntry->ResourceHandle,
|
||
LOG_ERROR,
|
||
L"Error [OnLineVirtualRoots] NULL virtual root entry \n");
|
||
Status = ERROR_RESOURCE_NOT_FOUND;
|
||
goto error_exit;
|
||
}
|
||
|
||
//
|
||
// See if the resource is already on line. In which
|
||
// case this is a duplicate
|
||
//
|
||
if ( VerifyIISService( ResourceEntry,FALSE,LogEvent ) ) {
|
||
// We found a duplicate or this resource is already online
|
||
(LogEvent)(
|
||
ResourceEntry->ResourceHandle,
|
||
LOG_INFORMATION,
|
||
L"Warning [OnLineThread] Resource already online or is a duplicate. Check for Unique Alias property\n");
|
||
// Status = ERROR_DUP_NAME;
|
||
Status = ERROR_SUCCESS;
|
||
goto error_exit;
|
||
}
|
||
|
||
#if DBG
|
||
(LogEvent)(
|
||
ResourceEntry->ResourceHandle,
|
||
LOG_INFORMATION,
|
||
L"[OnLineVirtualRoots] about to set info Root = %1!ws! ip = %2!ws! Dir = %3!ws! Mask = %4!u! Name = %5!ws! Pass = %6!ws! \n",
|
||
resVR->pszRoot,
|
||
resVR->pszAddress,
|
||
resVR->pszDirectory,
|
||
resVR->dwMask,
|
||
resVR->pszAccountName,
|
||
resVR->AccountPassword);
|
||
#endif
|
||
// Allocate temporary storage for cluster and iis vr entries
|
||
tmpVRL = LocalAlloc(LPTR,
|
||
((iisVRL->cEntries + 1) *
|
||
sizeof(INET_INFO_VIRTUAL_ROOT_ENTRY) ) +
|
||
sizeof(INET_INFO_VIRTUAL_ROOT_LIST));
|
||
// Make sure we didn't fail on the allocate
|
||
if (tmpVRL == NULL){
|
||
(LogEvent)(
|
||
ResourceEntry->ResourceHandle,
|
||
LOG_ERROR,
|
||
L"[OnLineVirtualRoots] LocalAlloc for temp VRL failed\n");
|
||
Status = ERROR_RESOURCE_NOT_FOUND;
|
||
goto error_exit;
|
||
}
|
||
|
||
|
||
tmpVRL->aVirtRootEntry[0] = *resVR;
|
||
|
||
|
||
// Add any additional VR not managed by the cluster
|
||
for (i=0;i<iisVRL->cEntries ;i++ ) {
|
||
tmpVRL->aVirtRootEntry[i+1] = iisVRL->aVirtRootEntry[i];
|
||
}
|
||
|
||
tmpVRL->cEntries = iisVRL->cEntries + 1;
|
||
|
||
|
||
IISInfo->VirtualRoots = tmpVRL;
|
||
#if DBG
|
||
for (i=0;i < tmpVRL->cEntries ;i++ ) {
|
||
(LogEvent)(
|
||
ResourceEntry->ResourceHandle,
|
||
LOG_INFORMATION,
|
||
L"[OnLineVirtualRoots] about to set info Root = %1!ws! Ipaddr = %2!ws! Dir = %3!ws! Mask = %4!u! Name = %5!ws! Pass = %6!ws! \n",
|
||
tmpVRL->aVirtRootEntry[i].pszRoot,
|
||
tmpVRL->aVirtRootEntry[i].pszAddress,
|
||
tmpVRL->aVirtRootEntry[i].pszDirectory,
|
||
tmpVRL->aVirtRootEntry[i].dwMask,
|
||
tmpVRL->aVirtRootEntry[i].pszAccountName,
|
||
tmpVRL->aVirtRootEntry[i].AccountPassword);
|
||
}
|
||
#endif
|
||
// Call IIS Management API to SET list of Virtual Roots
|
||
Status = SetIISInfo(ResourceEntry->ServiceType, IISInfo);
|
||
if (Status != ERROR_SUCCESS) {
|
||
(LogEvent)(
|
||
ResourceEntry->ResourceHandle,
|
||
LOG_ERROR,
|
||
L"[OnLineVirtualRoots] set info status = %1!u!\n",
|
||
Status);
|
||
} else {
|
||
|
||
//
|
||
// See if root came on line sucessfully
|
||
//
|
||
if ( !VerifyIISService( ResourceEntry,FALSE,LogEvent ) ) {
|
||
//
|
||
// The root was sucessfully added to iis but the iis could
|
||
// not access the root. Remove it here so the inet manager does
|
||
// not contain bad roots
|
||
//
|
||
OffLineVirtualRoot( ResourceEntry, LogEvent);
|
||
|
||
(LogEvent)(
|
||
ResourceEntry->ResourceHandle,
|
||
LOG_ERROR,
|
||
L"ERROR [OnLineThread] IIS could not bring resource online. Verify IIS root is accessable. \n");
|
||
Status = ERROR_RESOURCE_NOT_AVAILABLE;
|
||
|
||
} // if !VerifyIISService
|
||
|
||
} // if status != ERROR_SUCCESS
|
||
|
||
// Destruct any temporary storage
|
||
IISInfo->VirtualRoots = iisVRL;
|
||
error_exit:
|
||
if (IISInfo != NULL) MIDL_user_free((LPVOID)IISInfo);
|
||
if (tmpVRL != NULL) LocalFree(tmpVRL);
|
||
|
||
return(Status);
|
||
|
||
} // END OnLineVirtualRoot
|
||
|
||
|
||
|
||
VOID
|
||
FreeIISResource(
|
||
IN LPIIS_RESOURCE ResourceEntry
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Free all the storage for a IIS_RESOURCE
|
||
|
||
Arguments:
|
||
|
||
vr - virtual root to free
|
||
|
||
Return Value:
|
||
|
||
NONE
|
||
|
||
--*/
|
||
|
||
{
|
||
if (ResourceEntry != NULL) {
|
||
|
||
if (ResourceEntry->ParametersKey != NULL ) {
|
||
ClusterRegCloseKey( ResourceEntry->ParametersKey );
|
||
}
|
||
|
||
if (ResourceEntry->hResource != NULL ) {
|
||
CloseClusterResource( ResourceEntry->hResource );
|
||
}
|
||
LocalFree( ResourceEntry->Params.ServiceName );
|
||
LocalFree( ResourceEntry->Params.Alias );
|
||
LocalFree( ResourceEntry->Params.Directory );
|
||
|
||
if (ResourceEntry->VirtualRoot != NULL) {
|
||
DestructVR(ResourceEntry->VirtualRoot);
|
||
}
|
||
} // ResourceEntry != NULL
|
||
|
||
} // FreeIISResource
|
||
|
||
|
||
|
||
|
||
VOID
|
||
DestructIISResource(
|
||
IN LPIIS_RESOURCE ResourceEntry
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Free all the storage for a ResourceEntry and the ResourceEntry
|
||
|
||
Arguments:
|
||
|
||
vr - virtual root to free
|
||
|
||
Return Value:
|
||
|
||
NONE
|
||
|
||
--*/
|
||
{
|
||
if (ResourceEntry != NULL) {
|
||
FreeIISResource(ResourceEntry),
|
||
LocalFree(ResourceEntry);
|
||
} // ResourceEntry != NULL
|
||
|
||
} // DestructIISResource
|
||
|
||
|
||
|
||
|
||
VOID
|
||
FreeVR(
|
||
IN LPINET_INFO_VIRTUAL_ROOT_ENTRY vr
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Free all the storage for a Virtual Root
|
||
|
||
Arguments:
|
||
|
||
vr - virtual root to free
|
||
|
||
Return Value:
|
||
|
||
NONE
|
||
|
||
--*/
|
||
|
||
|
||
{
|
||
|
||
if (vr == NULL) {
|
||
return;
|
||
}
|
||
if (vr->pszRoot != NULL) {
|
||
LocalFree(vr->pszRoot);
|
||
}
|
||
if (vr->pszAddress != NULL) {
|
||
LocalFree(vr->pszAddress);
|
||
}
|
||
if (vr->pszDirectory != NULL) {
|
||
LocalFree(vr->pszDirectory);
|
||
}
|
||
if (vr->pszAccountName != NULL) {
|
||
LocalFree(vr->pszAccountName);
|
||
}
|
||
|
||
}// FreeVR
|
||
|
||
|
||
VOID
|
||
DestructVR(
|
||
LPINET_INFO_VIRTUAL_ROOT_ENTRY vr
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Free all the storage for a Virtual Root and vr
|
||
|
||
Arguments:
|
||
|
||
vr - virtual root to free
|
||
|
||
Return Value:
|
||
|
||
NONE
|
||
|
||
--*/
|
||
|
||
|
||
{
|
||
|
||
if (vr == NULL) {
|
||
return;
|
||
}
|
||
FreeVR(vr);
|
||
LocalFree(vr);
|
||
|
||
}// DestructVR
|
||
|
||
|
||
|
||
BOOL
|
||
VerifyIISService(
|
||
IN LPIIS_RESOURCE ResourceEntry,
|
||
IN BOOL IsAliveFlag,
|
||
IN PLOG_EVENT_ROUTINE LogEvent
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Verify that the IIS service is running and that it has virtual roots
|
||
contained in the resource
|
||
Steps:
|
||
1. Make sure the IIS service is running by calling the mngt API
|
||
2. Verfify that the resources virtual roots are currently in
|
||
the running system
|
||
3. Check the dwError field to make sure the VR for the resource is accessable
|
||
4. Sanity check to make sure the resources virtual root was found
|
||
|
||
Arguments:
|
||
|
||
Resource - supplies the resource id
|
||
|
||
IsAliveFlag - says this is an IsAlive call - used only for debug print
|
||
|
||
Return Value:
|
||
|
||
TRUE - if service is running and service contains resources virtual roots
|
||
|
||
FALSE - service is in any other state
|
||
|
||
--*/
|
||
{
|
||
DWORD status;
|
||
DWORD MatchingEntries = 0;
|
||
DWORD VRAccessErrors = 0;
|
||
BOOL MatchFound;
|
||
LPINET_INFO_CONFIG_INFO IISInfo = NULL;
|
||
LPINET_INFO_VIRTUAL_ROOT_ENTRY resVR = NULL;
|
||
LPINET_INFO_VIRTUAL_ROOT_LIST iisVRL = NULL;
|
||
DWORD c;
|
||
BOOL VerifyStatus = TRUE;
|
||
|
||
//
|
||
// Get IIS virtual root information
|
||
//
|
||
status = GetIISInfo(ResourceEntry->ServiceType, &IISInfo);
|
||
|
||
//
|
||
// Check the error status to see if the service is starting
|
||
//
|
||
if (status != ERROR_SUCCESS) {
|
||
if (status == ERROR_SERVICE_NOT_ACTIVE) {
|
||
//
|
||
// Service is not active
|
||
//
|
||
(LogEvent)(
|
||
ResourceEntry->ResourceHandle,
|
||
LOG_ERROR,
|
||
L"IsAlive/LooksAlive ERROR Service NOT active service %1!ws!.\n",
|
||
ResourceEntry->Params.ServiceName );
|
||
} else {
|
||
//
|
||
// Some type of error
|
||
//
|
||
(LogEvent)(
|
||
ResourceEntry->ResourceHandle,
|
||
LOG_ERROR,
|
||
L"IsAlive/LooksAlive ERROR getting information for service %1!ws! status = %2!u!\n",
|
||
ResourceEntry->Params.ServiceName,
|
||
status);
|
||
}
|
||
//
|
||
// Return false;
|
||
//
|
||
VerifyStatus = FALSE;
|
||
goto error_exit;
|
||
}
|
||
|
||
iisVRL = IISInfo->VirtualRoots;
|
||
resVR = ResourceEntry->VirtualRoot;
|
||
//
|
||
// Now check to see if the Virtual roots for this resource exist in the service
|
||
//
|
||
MatchFound = FALSE;
|
||
for (c=0;c<iisVRL->cEntries ;c++ ) {
|
||
if ( (_wcsicmp(resVR->pszRoot,iisVRL->aVirtRootEntry[c].pszRoot) == 0) &&
|
||
(_wcsicmp(resVR->pszAddress,iisVRL->aVirtRootEntry[c].pszAddress) == 0)
|
||
/// (_wcsicmp(resVR->pszDirectory,iisVRL->aVirtRootEntry[c].pszDirectory) == 0)
|
||
){
|
||
//
|
||
// if all the VR primary keys match
|
||
//
|
||
MatchFound = TRUE;
|
||
MatchingEntries +=1;
|
||
//
|
||
// See if the IIS can sucessfully access this virtual root
|
||
//
|
||
if (iisVRL->aVirtRootEntry[c].dwError != ERROR_SUCCESS) {
|
||
VRAccessErrors +=1;
|
||
(LogEvent)(
|
||
ResourceEntry->ResourceHandle,
|
||
LOG_INFORMATION,
|
||
L"IsAlive/LooksAlive virtual root %1!ws! IIS Access Error service %2!ws! error = %3!u!\n",
|
||
resVR->pszRoot,
|
||
ResourceEntry->Params.ServiceName,
|
||
iisVRL->aVirtRootEntry[c].dwError);
|
||
|
||
} // END dwERROR != ERROR_SUCCESS
|
||
|
||
break;
|
||
|
||
} // END if
|
||
|
||
} // END for c=0
|
||
|
||
// No matching entry found in the Cluster config data so this VR is ok
|
||
if (!MatchFound) {
|
||
if (IsAliveFlag) {
|
||
(LogEvent)(
|
||
ResourceEntry->ResourceHandle,
|
||
LOG_ERROR,
|
||
L"ERROR IsAlive/LooksAlive virtual root %1!ws! not found for service %2!ws!\n",
|
||
resVR->pszRoot,
|
||
ResourceEntry->Params.ServiceName,
|
||
status);
|
||
}
|
||
VerifyStatus = FALSE;
|
||
goto error_exit;
|
||
} // END if !MatchFound
|
||
|
||
|
||
//
|
||
// Perform sanity check
|
||
//
|
||
if (MatchingEntries != 1) {
|
||
(LogEvent)(
|
||
ResourceEntry->ResourceHandle,
|
||
LOG_ERROR,
|
||
L"ERROR IsAlive/LooksAlive more than one resource is active, service %1!ws!\n",
|
||
ResourceEntry->Params.ServiceName);
|
||
VerifyStatus = FALSE;
|
||
goto error_exit;
|
||
}
|
||
|
||
|
||
//
|
||
// If the resources virtual root is inaccessable then the resource is offline
|
||
//
|
||
if (VRAccessErrors != 0) {
|
||
VerifyStatus = FALSE;
|
||
}
|
||
|
||
error_exit:
|
||
if (IISInfo != NULL) MIDL_user_free((LPVOID)IISInfo);
|
||
return(VerifyStatus);
|
||
|
||
} // VerifyIISService
|
||
|
||
|