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.
 
 
 
 
 
 

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;
}