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.
345 lines
8.0 KiB
345 lines
8.0 KiB
/*++
|
|
|
|
Copyright (c) 2001 Microsoft Corporation
|
|
|
|
Module Name :
|
|
|
|
urlscan.cpp
|
|
|
|
Abstract:
|
|
|
|
Replace Dll, and retrieve URLScan Path
|
|
|
|
Author:
|
|
|
|
Christopher Achille (cachille)
|
|
|
|
Project:
|
|
|
|
URLScan Update
|
|
|
|
Revision History:
|
|
|
|
March 2002: Created
|
|
|
|
--*/
|
|
|
|
#include "stdafx.h"
|
|
#include "windows.h"
|
|
#include "urlscan.h"
|
|
#include "updateini.h"
|
|
#include "service.h"
|
|
#include "resource.h"
|
|
#include <ole2.h>
|
|
#include "initguid.h"
|
|
#include <coguid.h>
|
|
#include "iadmw.h"
|
|
#include "iiscnfg.h"
|
|
|
|
// GetUrlScanPath
|
|
//
|
|
// Get the path to URLScan
|
|
//
|
|
// Parameters:
|
|
// pAdminBase - [in] Pointer to AdminBase Class
|
|
// szPath - [out] Path to urlscan
|
|
// dwCharsinBuff - [in] Size of buffer
|
|
BOOL
|
|
GetUrlScanPath( IMSAdminBase *pAdminBase, LPTSTR szPath, DWORD dwCharsinBuff )
|
|
{
|
|
METADATA_RECORD mdrData;
|
|
DWORD dwRequiredSize;
|
|
BOOL bRet = TRUE;
|
|
|
|
mdrData.dwMDIdentifier = MD_FILTER_IMAGE_PATH;
|
|
mdrData.dwMDAttributes = METADATA_NO_ATTRIBUTES;
|
|
mdrData.dwMDUserType = IIS_MD_UT_SERVER;
|
|
mdrData.dwMDDataType = STRING_METADATA;
|
|
mdrData.dwMDDataLen = ( dwCharsinBuff * sizeof( TCHAR ) );
|
|
mdrData.pbMDData = (UCHAR *) szPath;
|
|
|
|
if ( FAILED( pAdminBase->GetData( METADATA_MASTER_ROOT_HANDLE,
|
|
METABASE_URLSCANFILT_LOC,
|
|
&mdrData,
|
|
&dwRequiredSize ) ) )
|
|
{
|
|
bRet = FALSE;
|
|
}
|
|
|
|
return bRet;
|
|
}
|
|
|
|
// IsURLScanInstalled
|
|
//
|
|
// Determine if URLScan is installed.
|
|
//
|
|
// Parameters:
|
|
// szPath - The path to where URLScan is installed
|
|
//
|
|
// Return:
|
|
// TRUE - Yes, it is installed, and szPath points to it
|
|
// FALSE - It is not installed as a global filter
|
|
//
|
|
BOOL
|
|
IsUrlScanInstalled( LPTSTR szPath, DWORD dwCharsinBuff )
|
|
{
|
|
HRESULT hRes;
|
|
IMSAdminBase *pAdminBase = NULL;
|
|
IClassFactory *pcsfFactory = NULL;
|
|
|
|
if ( FAILED( CoInitializeEx(NULL, COINIT_MULTITHREADED) ) )
|
|
{
|
|
// Could not initialize COM
|
|
return FALSE;
|
|
}
|
|
|
|
hRes = CoGetClassObject( GETAdminBaseCLSID(TRUE), CLSCTX_SERVER, NULL, IID_IClassFactory, (void**) &pcsfFactory);
|
|
|
|
if ( SUCCEEDED(hRes) )
|
|
{
|
|
hRes = pcsfFactory->CreateInstance(NULL, IID_IMSAdminBase, (void **) &pAdminBase);
|
|
pcsfFactory->Release();
|
|
}
|
|
|
|
if ( SUCCEEDED(hRes) )
|
|
{
|
|
if ( !GetUrlScanPath( pAdminBase, szPath, dwCharsinBuff ) )
|
|
{
|
|
hRes = E_FAIL;
|
|
}
|
|
}
|
|
|
|
if ( pAdminBase )
|
|
{
|
|
pAdminBase->Release();
|
|
}
|
|
|
|
CoUninitialize();
|
|
|
|
return ( SUCCEEDED( hRes ) );
|
|
}
|
|
|
|
// InstallURLSCanFix
|
|
//
|
|
// Install the fix for URLScan
|
|
//
|
|
DWORD InstallURLScanFix( LPTSTR szUrlScanPath )
|
|
{
|
|
BOOL bServiceWasRunning;
|
|
DWORD dwRet = ERROR_SUCCESS;
|
|
|
|
// Stop web Service
|
|
if ( !StopWebSerivce( &bServiceWasRunning ) )
|
|
{
|
|
// Error Message about service not stopping
|
|
return IDS_ERROR_WEBSERVICE;
|
|
}
|
|
|
|
// Update the Inf
|
|
if ( !UpdateIni( szUrlScanPath ) )
|
|
{
|
|
dwRet = IDS_ERROR_INIUPDATE;
|
|
}
|
|
|
|
// Update Executable
|
|
if ( ( dwRet == ERROR_SUCCESS ) &&
|
|
( !MoveOldUrlScan( szUrlScanPath ) ||
|
|
!ExtractUrlScanFile( szUrlScanPath )
|
|
)
|
|
)
|
|
{
|
|
dwRet = IDS_ERROR_DLLUPDATE;
|
|
}
|
|
|
|
// Restart web service if it was running before,
|
|
// even if there was a failure along the way
|
|
if ( bServiceWasRunning &&
|
|
!StartWebSerivce()
|
|
)
|
|
{
|
|
// Error Message about not being able to start service
|
|
if ( dwRet == ERROR_SUCCESS )
|
|
{
|
|
dwRet = IDS_ERROR_RESTARTWEB;
|
|
}
|
|
}
|
|
|
|
return dwRet;
|
|
}
|
|
|
|
// ExtractUrlScanFile
|
|
//
|
|
// Extract the URLScan File to the FileSystem
|
|
//
|
|
// Parameters:
|
|
// szPath - Path to expand to
|
|
//
|
|
// Return:
|
|
// TRUE - Success
|
|
// FALSE - Failure
|
|
BOOL ExtractUrlScanFile( LPTSTR szPath )
|
|
{
|
|
HRSRC hrDllResource;
|
|
HGLOBAL hDllResource;
|
|
LPVOID pDllData;
|
|
HANDLE hFile;
|
|
DWORD dwBytesWritten;
|
|
DWORD dwSize;
|
|
BOOL bRet = FALSE;
|
|
DWORD dwTryCount = 0;
|
|
|
|
if ( ( ( hrDllResource = FindResource( NULL, (LPCWSTR) IDR_DATA1, RT_RCDATA) ) == NULL ) ||
|
|
( ( dwSize = SizeofResource( NULL, hrDllResource ) ) == 0 ) ||
|
|
( ( hDllResource = LoadResource( NULL, hrDllResource) ) == NULL ) ||
|
|
( ( pDllData = LockResource( hDllResource ) ) == NULL )
|
|
)
|
|
{
|
|
// Could not load resource
|
|
return FALSE;
|
|
}
|
|
|
|
do {
|
|
hFile = CreateFile( szPath,
|
|
GENERIC_WRITE,
|
|
0,
|
|
NULL,
|
|
CREATE_ALWAYS,
|
|
FILE_ATTRIBUTE_NORMAL,
|
|
NULL);
|
|
|
|
if ( GetLastError() == ERROR_SHARING_VIOLATION )
|
|
{
|
|
// If we are getting a sharing violation, it is possible that inetinfo.exe
|
|
// has released the handle, but the OS hasn't totally released it yet,
|
|
// so lets wait 5 seconds
|
|
Sleep( URLSCAN_DLL_INSTALL_INTERVAL );
|
|
}
|
|
|
|
dwTryCount++;
|
|
|
|
} while ( ( hFile == INVALID_HANDLE_VALUE) &&
|
|
( GetLastError() == ERROR_SHARING_VIOLATION ) &&
|
|
( dwTryCount < URLSCAN_DLL_INSTALL_MAXTRIES ) );
|
|
|
|
if ( hFile != INVALID_HANDLE_VALUE )
|
|
{
|
|
if ( WriteFile( hFile, pDllData, dwSize, &dwBytesWritten, NULL) )
|
|
{
|
|
bRet = TRUE;
|
|
}
|
|
|
|
CloseHandle(hFile);
|
|
|
|
if ( dwBytesWritten != dwSize )
|
|
{
|
|
bRet = FALSE;
|
|
}
|
|
}
|
|
|
|
return bRet;
|
|
}
|
|
|
|
// MoveOldUrlScan
|
|
//
|
|
// This will backup the old urlscan into a backup file location
|
|
//
|
|
// Parameters:
|
|
// szCurrentPath - The current path to urlscan
|
|
//
|
|
BOOL MoveOldUrlScan( LPTSTR szCurrentPath )
|
|
{
|
|
TCHAR szBackupLocation[ MAX_PATH ];
|
|
LPTSTR szCurrentPos;
|
|
DWORD dwPathLength = (DWORD) _tcslen( szCurrentPath );
|
|
|
|
if ( ( dwPathLength >= ( MAX_PATH - _tcslen(URLSCAN_DEFAULT_FILENAME) - _tcslen(URLSCAN_BACKUPKEY) - 1 ) ) ||
|
|
( dwPathLength == 0 )
|
|
)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
// Copy Filelocation over
|
|
_tcscpy( szBackupLocation, szCurrentPath );
|
|
|
|
// Find Last '\'
|
|
szCurrentPos = _tcsrchr( szBackupLocation, '\\' );
|
|
|
|
// If there is not slash, then reset to begining of string
|
|
if ( szCurrentPos == NULL )
|
|
{
|
|
szCurrentPos = szBackupLocation;
|
|
}
|
|
|
|
if ( *szCurrentPos == '\\' )
|
|
{
|
|
// Move forward one character to the first letter
|
|
szCurrentPos++;
|
|
}
|
|
|
|
// Append New FileName
|
|
_tcscpy( szCurrentPos, URLSCAN_BACKUPKEY);
|
|
_tcscat( szCurrentPos, URLSCAN_DEFAULT_FILENAME);
|
|
|
|
// Ignore Failure, since failure is most likely because we have done this
|
|
// before, and the backup file already exists
|
|
MoveFileEx( szCurrentPath, szBackupLocation, MOVEFILE_COPY_ALLOWED );
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
// IsAdministrator
|
|
//
|
|
// Return whether the user is an administrator or not
|
|
//
|
|
BOOL IsAdministrator()
|
|
{
|
|
SC_HANDLE hSCManager;
|
|
BOOL bRet;
|
|
|
|
hSCManager = OpenSCManager( NULL, NULL, SC_MANAGER_CREATE_SERVICE );
|
|
|
|
bRet = hSCManager != NULL;
|
|
|
|
if ( hSCManager )
|
|
{
|
|
CloseServiceHandle( hSCManager );
|
|
}
|
|
|
|
return bRet;
|
|
}
|
|
|
|
// UpdateRegistryforAddRemove
|
|
//
|
|
// Update the registry to reflect the new name for the uninstall
|
|
// program
|
|
//
|
|
BOOL
|
|
UpdateRegistryforAddRemove()
|
|
{
|
|
HKEY hRegKey;
|
|
BOOL bRet;
|
|
LPWSTR szValue = URLSCAN_TOOL_KEY_NEWVALUE;
|
|
|
|
if ( RegOpenKey( HKEY_LOCAL_MACHINE,
|
|
URLSCAN_TOOL_REGPATH,
|
|
&hRegKey ) != ERROR_SUCCESS )
|
|
{
|
|
// Failure to open registry key
|
|
// We will return success though, since they could of never installed
|
|
// the installer, but only the file by itself manually.
|
|
return TRUE;
|
|
}
|
|
|
|
bRet = RegSetValueEx( hRegKey,
|
|
URLSCAN_TOOL_KEY_NAME, // Value Name
|
|
NULL, // Reserved
|
|
REG_SZ, // String Value
|
|
(LPBYTE) szValue, // Value to set
|
|
( ( (DWORD) wcslen(szValue) + 1) * sizeof(WCHAR) )
|
|
) == ERROR_SUCCESS;
|
|
|
|
RegCloseKey( hRegKey );
|
|
|
|
return bRet;
|
|
}
|