|
|
/*++
Copyright (c) 1999-1999 Microsoft Corporation
Module Name:
dtsetup.c
Abstract:
Simple Duct-Tape setup.
Author:
Keith Moore (keithmo) 02-Sep-1999
Revision History:
--*/
#include "precomp.h"
#pragma hdrstop
//
// Configuration data.
//
#define UL_SERVICE_NAME L"UL"
#define UL_DISPLAY_NAME L"UL"
#define UL_DRIVER_NAME L"UL.SYS"
#define UL_DEPENDENCIES NULL
#define WAS_SERVICE_NAME L"IISW3ADM"
#define WAS_DISPLAY_NAME L"IIS Web Admin Service"
#define WAS_DLL_NAME L"iisw3adm.dll"
#define WAS_DEPENDENCIES L"UL"
#define WAS_COMMAND_LINE L"%SystemRoot%\\System32\\svchost.exe -k iissvcs"
#define WAS_PARAM_KEY L"System\\CurrentControlSet\\Services\\iisw3adm\\Parameters"
#define WAS_EVENT_KEY L"System\\CurrentControlSet\\Services\\EventLog\\System\\WAS"
#define WAS_SVCHOST_KEY L"Software\\Microsoft\\Windows NT\\CurrentVersion\\Svchost"
#define SERVICE_DLL_VALUE L"ServiceDll"
#define EVENT_MESSAGE_VALUE L"EventMessageFile"
#define SVCHOST_VALUE L"iissvcs"
#define CATALOG_DLL_NAME L"catalog.dll"
#define CATALOG_KEY L"Software\\Microsoft\\Catalog42"
#define CATALOG_URT_VALUE L"URT"
//
// Our command table.
//
typedef VOID (* PFN_COMMAND)( IN INT argc, IN PWSTR argv[] );
typedef struct _COMMAND_ENTRY { PWSTR pCommandName; PWSTR pUsageHelp; PFN_COMMAND pCommandHandler;
} COMMAND_ENTRY, *PCOMMAND_ENTRY;
//
// Private prototypes.
//
VOID Usage( VOID );
PCOMMAND_ENTRY FindCommandByName( IN PWSTR pCommand );
VOID DoInstall( IN INT argc, IN PWSTR argv[] );
VOID DoRemove( IN INT argc, IN PWSTR argv[] );
DWORD InstallUL( IN PWSTR pBaseDirectory );
DWORD InstallWAS( IN PWSTR pBaseDirectory );
DWORD InstallCatalog( IN PWSTR pBaseDirectory );
VOID RemoveCatalog( VOID );
VOID RemoveWAS( VOID );
VOID RemoveUL( VOID );
DWORD InstallService( IN PWSTR pServiceName, IN PWSTR pDisplayName OPTIONAL, IN PWSTR pBinPath, IN PWSTR pDependencies OPTIONAL, IN DWORD ServiceType, IN DWORD StartType, IN DWORD ErrorControl );
DWORD RemoveService( IN PWSTR pServiceName );
DWORD WriteRegValue( IN PWSTR pKeyName, IN PWSTR pValueName, IN PWSTR pValue );
DWORD DeleteRegKey( IN PWSTR pKeyName );
//
// Private globals.
//
COMMAND_ENTRY CommandTable[] = { { L"install", L"install UL and WAS", &DoInstall },
{ L"remove", L"remove UL and WAS", &DoRemove }
};
#define NUM_COMMAND_ENTRIES (sizeof(CommandTable) / sizeof(CommandTable[0]))
//
// Public functions.
//
INT __cdecl wmain( INT argc, PWSTR argv[] ) { PCOMMAND_ENTRY pEntry;
//
// Find the command handler.
//
if (argc == 1) { pEntry = NULL; } else { pEntry = FindCommandByName( argv[1] ); }
if (pEntry == NULL) { Usage(); return 1; }
//
// Call the handler.
//
argc--; argv++;
(pEntry->pCommandHandler)( argc, argv );
return 0;
} // wmain
//
// Private functions.
//
PCOMMAND_ENTRY FindCommandByName( IN PWSTR pCommand ) { PCOMMAND_ENTRY pEntry; INT i;
for (i = NUM_COMMAND_ENTRIES, pEntry = &CommandTable[0] ; i > 0 ; i--, pEntry++) { if (_wcsicmp( pCommand, pEntry->pCommandName ) == 0) { return pEntry; } }
return NULL;
} // FindCommandByName
VOID Usage( VOID ) { PCOMMAND_ENTRY pEntry; INT i; INT maxLength; INT len;
//
// Scan the command table, searching for the longest command name.
// (This makes the output much prettier...)
//
maxLength = 0;
for (i = NUM_COMMAND_ENTRIES, pEntry = &CommandTable[0] ; i > 0 ; i--, pEntry++) { len = wcslen( pEntry->pCommandName );
if (len > maxLength) { maxLength = len; } }
//
// Now display the usage information.
//
wprintf( L"use: dtsetup action [options]\n" L"\n" L"valid actions are:\n" L"\n" );
for (i = NUM_COMMAND_ENTRIES, pEntry = &CommandTable[0] ; i > 0 ; i--, pEntry++) { wprintf( L" %-*s - %s\n", maxLength, pEntry->pCommandName, pEntry->pUsageHelp ); }
} // Usage
VOID DoInstall( IN INT argc, IN PWSTR argv[] ) { PWSTR pBaseDirectory; DWORD err;
//
// Validate the arguments.
//
if (argc != 2) { wprintf( L"use: dtsetup install directory\n" ); return; }
//
// Install 'em.
//
wprintf( L"installing UL..." ); err = InstallUL( argv[1] );
if (err != NO_ERROR) { wprintf( L"error %lu\n", err ); return; }
wprintf( L"done\n" );
wprintf( L"installing WAS..." ); err = InstallWAS( argv[1] );
if (err != NO_ERROR) { wprintf( L"error %lu\n", err ); RemoveUL(); return; }
wprintf( L"done\n" );
wprintf( L"installing Catalog..." ); err = InstallCatalog( argv[1] );
if (err != NO_ERROR) { wprintf( L"error %lu\n", err ); RemoveWAS(); RemoveUL(); return; }
wprintf( L"done\n" );
//
// Success!
//
} // DoInstall
VOID DoRemove( IN INT argc, IN PWSTR argv[] ) { //
// Validate the arguments.
//
if (argc != 1) { wprintf( L"use: dtsetup remove\n" ); return; }
//
// Remove 'em.
//
wprintf( L"removing Catalog..." ); RemoveCatalog(); wprintf( L"done\n" );
wprintf( L"removing WAS..." ); RemoveWAS(); wprintf( L"done\n" );
wprintf( L"removing UL..." ); RemoveUL(); wprintf( L"done\n" );
} // DoRemove
DWORD InstallUL( IN PWSTR pBaseDirectory ) { DWORD err; WCHAR binPath[MAX_PATH];
//
// Build the path to the driver.
//
wcscpy( binPath, pBaseDirectory );
if (binPath[wcslen(binPath) - 1] != L'\\') { wcscat( binPath, L"\\" ); }
wcscat( binPath, UL_DRIVER_NAME );
//
// Install it.
//
err = InstallService( UL_SERVICE_NAME, // pServiceName
UL_DISPLAY_NAME, // pDisplayName
binPath, // pBinPath
UL_DEPENDENCIES, // pDependencies
SERVICE_KERNEL_DRIVER, // ServiceType
SERVICE_DEMAND_START, // StartType
SERVICE_ERROR_NORMAL // ErrorControl
);
return err;
} // InstallUL
DWORD InstallWAS( IN PWSTR pBaseDirectory ) { DWORD err; WCHAR binPath[MAX_PATH];
//
// Build the path to the service.
//
wcscpy( binPath, pBaseDirectory );
if (binPath[wcslen(binPath) - 1] != L'\\') { wcscat( binPath, L"\\" ); }
wcscat( binPath, WAS_DLL_NAME );
//
// Install it.
//
err = InstallService( WAS_SERVICE_NAME, // pServiceName
WAS_DISPLAY_NAME, // pDisplayName
WAS_COMMAND_LINE, // pBinPath
WAS_DEPENDENCIES, // pDependencies
SERVICE_WIN32_SHARE_PROCESS | // ServiceType
SERVICE_INTERACTIVE_PROCESS, SERVICE_DEMAND_START, // StartType
SERVICE_ERROR_NORMAL // ErrorControl
);
if (err == NO_ERROR) { err = WriteRegValue( WAS_PARAM_KEY, // pKeyName
SERVICE_DLL_VALUE, // pValueName
binPath // pValue
); }
if (err == NO_ERROR) { err = WriteRegValue( WAS_EVENT_KEY, // pKeyName
EVENT_MESSAGE_VALUE, // pValueName
binPath // pValue
); }
if (err == NO_ERROR) { err = WriteRegValue( WAS_SVCHOST_KEY, // pKeyName
SVCHOST_VALUE, // pValueName
WAS_SERVICE_NAME // pValue
); }
return err;
} // InstallWAS
DWORD InstallCatalog( IN PWSTR pBaseDirectory ) { DWORD err; WCHAR binPath[MAX_PATH];
//
// Build the path to the service.
//
wcscpy( binPath, pBaseDirectory );
if (binPath[wcslen(binPath) - 1] != L'\\') { wcscat( binPath, L"\\" ); }
wcscat( binPath, CATALOG_DLL_NAME );
//
// Install it.
//
err = WriteRegValue( CATALOG_KEY, // pKeyName
CATALOG_URT_VALUE, // pValueName
binPath // pValue
);
return err;
} // InstallCatalog
VOID RemoveCatalog( VOID ) { (VOID)DeleteRegKey( CATALOG_KEY );
} // RemoveCatalog
VOID RemoveWAS( VOID ) { (VOID)RemoveService( WAS_SERVICE_NAME ); (VOID)DeleteRegKey( WAS_EVENT_KEY );
} // RemoveWAS
VOID RemoveUL( VOID ) { (VOID)RemoveService( UL_SERVICE_NAME );
} // RemoveUL
DWORD InstallService( IN PWSTR pServiceName, IN PWSTR pDisplayName OPTIONAL, IN PWSTR pBinPath, IN PWSTR pDependencies OPTIONAL, IN DWORD ServiceType, IN DWORD StartType, IN DWORD ErrorControl ) { SC_HANDLE scHandle; SC_HANDLE svcHandle; DWORD err;
//
// Setup locals so we know how to cleanup on exit.
//
scHandle = NULL; svcHandle = NULL;
//
// If no display name specified, just use the service name.
//
if (pDisplayName == NULL) { pDisplayName = pServiceName; }
//
// Open the service controller.
//
scHandle = OpenSCManagerW( NULL, // lpMachineName
NULL, // lpDatabaseName
SC_MANAGER_ALL_ACCESS // dwDesiredAccess
);
if (scHandle == NULL) { err = GetLastError(); goto cleanup; }
//
// Create the service.
//
svcHandle = CreateServiceW( scHandle, // hSCManager
pServiceName, // lpServiceName
pDisplayName, // lpDisplayName
SERVICE_ALL_ACCESS, // dwDesiredAccess
ServiceType, // dwServiceType
StartType, // dwStartType
ErrorControl, // dwErrorControl
pBinPath, // lpBinaryPathName
NULL, // lpLoadOrderGroup
NULL, // lpdwTagId
pDependencies, // lpDependencies
NULL, // lpServiceStartName
NULL // lpPassword
);
if (svcHandle == NULL) { err = GetLastError(); goto cleanup; }
//
// Success!
//
err = 0;
cleanup:
if (svcHandle != NULL) { CloseServiceHandle( svcHandle ); }
if (scHandle != NULL) { CloseServiceHandle( scHandle ); }
return err;
} // InstallService
DWORD RemoveService( IN PWSTR pServiceName ) { SC_HANDLE scHandle; SC_HANDLE svcHandle; DWORD err;
//
// Setup locals so we know how to cleanup on exit.
//
scHandle = NULL; svcHandle = NULL;
//
// Open the service controller.
//
scHandle = OpenSCManagerW( NULL, // lpMachineName
NULL, // lpDatabaseName
SC_MANAGER_ALL_ACCESS // dwDesiredAccess
);
if (scHandle == NULL) { err = GetLastError(); goto cleanup; }
//
// Open the service.
//
svcHandle = OpenServiceW( scHandle, // hSCManager
pServiceName, // lpServiceName
SERVICE_ALL_ACCESS // dwDesiredAccess
);
if (svcHandle == NULL) { err = GetLastError(); goto cleanup; }
//
// Delete it.
//
if (!DeleteService( svcHandle )) { err = GetLastError(); goto cleanup; }
//
// Success!
//
err = 0;
cleanup:
if (svcHandle != NULL) { CloseServiceHandle( svcHandle ); }
if (scHandle != NULL) { CloseServiceHandle( scHandle ); }
return err;
} // RemoveService
DWORD WriteRegValue( IN PWSTR pKeyName, IN PWSTR pValueName, IN PWSTR pValue ) { DWORD err; HKEY key; DWORD disposition; DWORD length;
err = RegCreateKeyExW( HKEY_LOCAL_MACHINE, // hKey
pKeyName, // lpSubKey
0, // Reserved
NULL, // lpClass
REG_OPTION_NON_VOLATILE, // dwOptions
KEY_ALL_ACCESS, // samDesired
NULL, // lpSecurityAttributes,
&key, // phkResult
&disposition // lpdwDisposition
);
if (err == NO_ERROR) { length = (wcslen(pValue) + 1) * sizeof(pValue[0]);
err = RegSetValueExW( key, // hKey
pValueName, // lpValueName
0, // Reserved
REG_EXPAND_SZ, // dwType
(CONST BYTE *)pValue, // lpData
length // cbData
);
RegCloseKey( key ); }
return err;
} // WriteRegValue
DWORD DeleteRegKey( IN PWSTR pKeyName ) { DWORD err;
err = RegDeleteKeyW( HKEY_LOCAL_MACHINE, pKeyName );
return err;
} // DeleteRegKey
|