|
|
//+---------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1998.
//
// File: N C A C S . C P P
//
// Contents: Installation support for ACS service
//
// Notes:
//
// Author: RameshPa 02/12/98
//
//----------------------------------------------------------------------------
#include "pch.h"
#pragma hdrstop
#include "ncxbase.h"
#include "ncerror.h"
#include "ncreg.h"
#include "ncacs.h"
#include "ncsvc.h"
#include "netoc.h"
#include "ncnetcfg.h"
#include "resource.h"
#include <iphlpapi.h>
#include <winsock2.h>
#include <ntsecapi.h>
extern const WCHAR c_szSvcRsvp[];
static const WCHAR c_szTcpIp[] = L"TcpIp"; static const WCHAR c_szAfd[] = L"Afd"; static const WCHAR c_szAcsService[] = L"AcsService"; static const WCHAR c_szRegKeyRsvpParams[] = L"System\\CurrentControlSet\\Services\\RSVP\\Parameters\\"; static const WCHAR c_szRegKeyRsvpSubnet1[] = L"System\\CurrentControlSet\\Services\\RSVP\\Parameters\\Subnet\\Subnet1\\"; static const WCHAR c_szRegKeyRsvpSubnet[] = L"System\\CurrentControlSet\\Services\\RSVP\\Parameters\\Subnet\\"; static const WCHAR c_szRegKeyRsvpAdapters[]= L"System\\CurrentControlSet\\Services\\RSVP\\Parameters\\Adapters\\"; static const WCHAR c_szRegKeyRsvpPcmConfig[]= L"System\\CurrentControlSet\\Services\\RSVP\\PCM Config\\"; static const WCHAR c_szRegKeyRsvpMsidlpm[] = L"System\\CurrentControlSet\\Services\\RSVP\\MSIDLPM\\";
//$ REVIEW : RameshPa : 02/13/98 : Is this defined anywhere?
const DWORD dwKilo = 1024; const DWORD dwMega = (1024 * dwKilo); const DWORD dwGiga = (1024 * dwMega);
static const WCHAR c_szIpHlpApiDllName[] = L"IpHlpApi"; static const CHAR c_szaGetIpAddrTable[] = "GetIpAddrTable";
typedef DWORD (*GETIPADDRTABLE)( OUT PMIB_IPADDRTABLE pIpAddrTable, IN OUT PDWORD pdwSize, IN BOOL bOrder);
struct ACS_SUBNET_REG_DATA { DWORD dwSubnetIpAddress; // This is in host order
DWORD dwDSBMPriority; DWORD dwMaxRSVPBandwidth; DWORD dwMaxTotalPeakRate; DWORD dwMaxTokenBucketRatePerFlow; DWORD dwMaxPeakRatePerFlow; DWORD dwIAmDsbmRefreshInterval; DWORD dwDSBMDeadInterval; BOOL fRunAsDSBM; };
// Subnet registry keys
//
static const WCHAR c_szRunAsDSBM[] = L"Run as DSBM"; static const WCHAR c_szSubnetIPAddress[] = L"Subnet IP Address"; static const WCHAR c_szMaxPeakRate[] = L"Maximum peak rate per flow"; static const WCHAR c_szMaxRSVPBandwidth[] = L"Maximum RSVP bandwidth"; static const WCHAR c_szMaxTokenBucket[] = L"Maximum token bucket rate per flow"; static const WCHAR c_szMaxTotalPeakRate[] = L"Maximum total peak rate"; static const WCHAR c_szIAmDsbmRefresh[] = L"I_AM_DSBM Refresh Interval"; static const WCHAR c_szDSBMDeadInterval[] = L"DSBM Dead Interval"; static const WCHAR c_szDSBMPriority[] = L"DSBM Priority";
// Default general property sheet values
//
const BOOL c_fRunAsDSBMDef = TRUE;
// Default subnet values
//
const DWORD c_dwIpAddressDef = 0; static const WCHAR c_szIpAddressDef[] = L"0.0.0.0"; const DWORD c_dwMaxPeakRateDef = 0xFFFFFFFF; const DWORD c_dwMaxRSVPBandwidthDef = 0; const DWORD c_dwMaxTokenBucketDef = 0xFFFFFFFF; const DWORD c_dwMaxTotalPeakRateDef = 0xFFFFFFFF; const DWORD c_dwIAmDsbmRefreshDef = 5; const DWORD c_dwDSBMDeadIntervalDef = 15; const DWORD c_dwDSBMPriorityDef = 4;
// General values
// 127.0.0.0, host order
//
const DWORD c_dwLocalSubnet = 0x7f000000; const DWORD c_dwNullSubnet = 0x00000000;
static const VALUETABLE c_avtAcsSubnet[] = { {c_szSubnetIPAddress, REG_IP, offsetof(ACS_SUBNET_REG_DATA, dwSubnetIpAddress), (BYTE*)(&c_szIpAddressDef)}, {c_szMaxPeakRate, REG_DWORD, offsetof(ACS_SUBNET_REG_DATA, dwMaxPeakRatePerFlow), (BYTE*)(&c_dwMaxPeakRateDef)}, {c_szMaxRSVPBandwidth, REG_DWORD, offsetof(ACS_SUBNET_REG_DATA, dwMaxRSVPBandwidth), (BYTE*)(&c_dwMaxRSVPBandwidthDef)}, {c_szMaxTokenBucket, REG_DWORD, offsetof(ACS_SUBNET_REG_DATA, dwMaxTokenBucketRatePerFlow), (BYTE*)(&c_dwMaxTokenBucketDef)}, {c_szMaxTotalPeakRate, REG_DWORD, offsetof(ACS_SUBNET_REG_DATA, dwMaxTotalPeakRate), (BYTE*)(&c_dwMaxTotalPeakRateDef)}, {c_szIAmDsbmRefresh, REG_DWORD, offsetof(ACS_SUBNET_REG_DATA, dwIAmDsbmRefreshInterval), (BYTE*)(&c_dwIAmDsbmRefreshDef)}, {c_szDSBMDeadInterval, REG_DWORD, offsetof(ACS_SUBNET_REG_DATA, dwDSBMDeadInterval), (BYTE*)(&c_dwDSBMDeadIntervalDef)}, {c_szDSBMPriority, REG_DWORD, offsetof(ACS_SUBNET_REG_DATA, dwDSBMPriority), (BYTE*)(&c_dwDSBMPriorityDef)}, {c_szRunAsDSBM, REG_BOOL, offsetof(ACS_SUBNET_REG_DATA, fRunAsDSBM), (BYTE*) &c_fRunAsDSBMDef}, };
//+---------------------------------------------------------------------------
//
// Function: OpenPolicy
//
// Purpose: This routine opens the policy object on the local computer
//
// Arguments: PolicyHandle - Pointer to the opended handle
//
// Returns: ERROR_SUCCESS if successful, Win32 error otherwise.
//
// Notes: The retruned PolicyHandle must be closed by the caller
//
DWORD OpenPolicy( PLSA_HANDLE PolicyHandle ) { NTSTATUS Status; DWORD Error;
LSA_OBJECT_ATTRIBUTES ObjectAttributes; SECURITY_QUALITY_OF_SERVICE QualityOfService;
QualityOfService.Length = sizeof(SECURITY_QUALITY_OF_SERVICE); QualityOfService.ImpersonationLevel = SecurityImpersonation; QualityOfService.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING; QualityOfService.EffectiveOnly = FALSE;
//
// The two fields that must be set are length and the quality of service.
//
ObjectAttributes.Length = sizeof(LSA_OBJECT_ATTRIBUTES); ObjectAttributes.RootDirectory = NULL; ObjectAttributes.ObjectName = NULL; ObjectAttributes.Attributes = 0; ObjectAttributes.SecurityDescriptor = NULL; ObjectAttributes.SecurityQualityOfService = &QualityOfService;
//
// Attempt to open the policy for all access on the local machine
//
Status = LsaOpenPolicy( NULL, &ObjectAttributes, POLICY_ALL_ACCESS, PolicyHandle );
Error = LsaNtStatusToWinError(Status);
return(Error); }
//+---------------------------------------------------------------------------
//
// Function: InitLsaString
//
// Purpose: This routine intializes LSA_UNICODE_STRING given an UNICODE string0
//
// Arguments: LsaString
// String
//
// Returns:
//
// Notes:
//
void InitLsaString( PLSA_UNICODE_STRING LsaString, PWSTR String ) { DWORD StringLength; if (String == NULL) { LsaString->Buffer = NULL; LsaString->Length = 0; LsaString->MaximumLength = 0; return; }
StringLength = wcslen(String); LsaString->Buffer = String; LsaString->Length = (USHORT) StringLength * sizeof(WCHAR); LsaString->MaximumLength = (USHORT) (StringLength + 1) * sizeof(WCHAR); }
//+---------------------------------------------------------------------------
//
// Function: InitLsaString
//
// Purpose: This routine intializes LSA_UNICODE_STRING given an UNICODE string0
//
// Arguments: LsaString
// String
//
// Returns:
//
// Notes:
//
PSID GetAccountSid( LSA_HANDLE PolicyHandle, PWSTR AccountName ) { DWORD NewSidLength; DWORD SubAuthorityCount; PSID Sid; PSID DomainSid; NTSTATUS Status;
PLSA_TRANSLATED_SID TranslatedSid; PLSA_REFERENCED_DOMAIN_LIST Domains; LSA_UNICODE_STRING AccountString;
//
// Convert the string to a LSA_UNICODE_STRING
//
InitLsaString( &AccountString, AccountName );
//
// Call the LSA to lookup the name
//
Status = LsaLookupNames( PolicyHandle, 1, &AccountString, &Domains, &TranslatedSid );
if (!SUCCEEDED(Status)) return(NULL);
//
// Build a SID from the Domain SID and account RID
//
DomainSid = Domains->Domains[TranslatedSid->DomainIndex].Sid; //
// Compute the length of the new SID. This is the length required for the
// number of subauthorities in the domain sid plus one for the user RID.
//
SubAuthorityCount = *GetSidSubAuthorityCount(DomainSid); NewSidLength = GetSidLengthRequired( (UCHAR) (SubAuthorityCount + 1) );
Sid = LocalAlloc(0,NewSidLength);
if (Sid == NULL) { LsaFreeMemory(Domains); LsaFreeMemory(TranslatedSid); return(NULL); }
//
// Build the SID by copying the domain SID and, increasing the sub-
// authority count in the new sid by one, and setting the last
// subauthority to be the relative id of the user.
//
CopySid( NewSidLength, Sid, DomainSid );
*GetSidSubAuthorityCount(Sid) = (UCHAR) SubAuthorityCount + 1; *GetSidSubAuthority(Sid, SubAuthorityCount) = TranslatedSid->RelativeId; LsaFreeMemory(Domains); LsaFreeMemory(TranslatedSid);
return(Sid);
}
//+---------------------------------------------------------------------------
//
// Function: AddUserRightToAccount
//
// Purpose: This routine grants the SE_TCB_NAME right to the specified user
// account on the local machine
//
// Arguments: PolicyHandle
// AccountName
//
// Returns: ERROR_SUCCESS if the right was granted successfully
// Win32 error otherwise
//
// Notes:
//
DWORD AddUserRightToAccount( PWSTR AccountName ) { DWORD Error; NTSTATUS Status; PSID AccountSid = NULL; LSA_HANDLE PolicyHandle; LSA_UNICODE_STRING UserRightString;
// Get a LSA policy handle to manipulate user rights
Error = OpenPolicy ( &PolicyHandle ); if ( Error ) return Error;
// Get the SID for the account
AccountSid = GetAccountSid( PolicyHandle, AccountName ); if (AccountSid == NULL) { LsaClose ( &PolicyHandle );
return(ERROR_NOT_ENOUGH_MEMORY); }
//
// Create a LSA_UNICODE_STRING for the right name
//
InitLsaString( &UserRightString, SE_TCB_NAME );
// Grant the right
Status = LsaAddAccountRights( PolicyHandle, AccountSid, &UserRightString, 1 );
Error = LsaNtStatusToWinError(Status);
LocalFree( AccountSid );
LsaClose ( &PolicyHandle );
return(Error); }
//+---------------------------------------------------------------------------
//
// Function: AddUserRightToAccount
//
// Purpose: This routine removes the SE_TCB_NAME right to the specified user
// account on the local machine
//
// Arguments: PolicyHandle
// AccountName
//
// Returns: ERROR_SUCCESS if the right was rmoved successfully
// Win32 error otherwise
//
// Notes:
//
DWORD RemoveUserRightFromAccount( PWSTR AccountName ) { NTSTATUS Status; DWORD Error; PSID AccountSid; LSA_HANDLE PolicyHandle;
LSA_UNICODE_STRING UserRightString;
// Get a LSA policy handle to manipulate user rights
Error = OpenPolicy ( &PolicyHandle ); if ( Error ) return Error;
AccountSid = GetAccountSid( PolicyHandle, AccountName ); if (AccountSid == NULL) { LsaClose ( &PolicyHandle ); return(ERROR_NOT_ENOUGH_MEMORY); }
//
// Create a LSA_UNICODE_STRING for the right name
//
InitLsaString( &UserRightString, SE_TCB_NAME );
Status = LsaRemoveAccountRights( PolicyHandle, AccountSid, FALSE, // don't remove all rights
&UserRightString, 1 );
Error = LsaNtStatusToWinError(Status);
LocalFree(AccountSid);
LsaClose ( &PolicyHandle );
return(Error); }
//+---------------------------------------------------------------------------
//
// Function: HrGetAcsServiceAccountName
//
// Purpose: This routine returns the AcsService account name in the
// DomainName\UserName format. DomainName is obtained from
// the current logon domain.
//
// Arguments: lpwNtAccountName - Buffer to return the account name.
//
// Returns: S_OK If the account name was generated
// Win32 error otherwise
//
// Notes:
//
HRESULT HrGetAcsServiceAccountName ( PWSTR lpwNtAccountName ) { DWORD dwErr; HRESULT hr; PWSTR lpwDomain = NULL; PWSTR lpwDcName = NULL; LPBYTE lpbUserInfo = NULL;
NETSETUP_JOIN_STATUS js;
lpwNtAccountName[0] = 0;
// Get the name of the DC for the logged on domain
dwErr = NetGetDCName ( NULL, NULL, (LPBYTE *) &lpwDcName ); if ( dwErr ) {
hr = HRESULT_FROM_WIN32(dwErr); goto Exit; }
// Next get user info to verify that there is a user
// account for AcsService
dwErr = NetUserGetInfo ( lpwDcName, c_szAcsService, 2, &lpbUserInfo ); if ( dwErr ) {
hr = HRESULT_FROM_WIN32(dwErr); goto Exit; }
// Find out the name of the domain into which this compter
// is currently logged on to
dwErr = NetGetJoinInformation ( NULL, &lpwDomain, &js ); if ( dwErr ) {
hr = HRESULT_FROM_WIN32(dwErr); goto Exit; }
if ( js != NetSetupDomainName ) {
hr = NETCFG_E_NOT_JOINED; goto Exit; }
// Generate the account name by concatenating domain name and "AcsService"
wcscpy ( lpwNtAccountName, lpwDomain ); wcscat ( lpwNtAccountName, L"\\" ); wcscat ( lpwNtAccountName, c_szAcsService );
hr = S_OK;
Exit:
if ( lpwDcName ) NetApiBufferFree ( lpwDcName );
if ( lpbUserInfo ) NetApiBufferFree ( lpbUserInfo );
if ( lpwDomain ) NetApiBufferFree ( lpwDomain );
TraceError("HrGetAcsServiceAccountName", hr); return hr; }
//+---------------------------------------------------------------------------
//
// Function: HrSetAcsServiceRights
//
// Purpose: This routine adds the AcsService account to the administrators group
// on the local computer and grants SE_TCB_NAME right also
//
// Arguments:
//
// Returns: S_OK Success
// Win32 error otherwise
//
// Notes:
//
HRESULT HrSetAcsServiceRights( ) { DWORD dwErr; HRESULT hr; WCHAR szAcsUserName[UNLEN+GNLEN+2]; PWSTR lpwAcsUserName;
LOCALGROUP_MEMBERS_INFO_3 localgroup_members;
// First get the user name of AcsService in the format
// DomainName\UserName
hr = ::HrGetAcsServiceAccountName ( szAcsUserName ); if ( hr ) {
hr = HRESULT_FROM_WIN32(ERROR_INVALID_ACCOUNT_NAME); goto Exit; }
if ( !szAcsUserName[0] ) {
hr = HRESULT_FROM_WIN32(ERROR_INVALID_ACCOUNT_NAME); goto Exit; }
// Add AcsService account to be a local administrator
localgroup_members.lgrmi3_domainandname = szAcsUserName; dwErr = NetLocalGroupAddMembers( NULL, // PDC name
L"Administrators", // group name
3, // passing in name
(LPBYTE)&localgroup_members, // Buffer
1 ); // count passed in
if ( dwErr ) {
if ( dwErr == ERROR_MEMBER_IN_ALIAS ) { hr = S_OK; dwErr = 0; } else { hr = HRESULT_FROM_WIN32(dwErr); goto Exit; } }
// Grant SE_TCB_NAME "Act as part of Operating system" right to AcsService
dwErr = AddUserRightToAccount( szAcsUserName ); if ( dwErr ) {
hr = HRESULT_FROM_WIN32( dwErr ); goto Exit; }
hr = S_OK;
Exit: TraceError ( "HrSetAcsServiceRights", hr );
return hr; }
//+---------------------------------------------------------------------------
//
// Function: HrRemoveAcsServiceRights
//
// Purpose: This routine removes the AcsService account from the administrators group
// on the local computer and removes SE_TCB_NAME right.
//
// Arguments:
//
// Returns: S_OK Success
// Win32 error otherwise
//
// Notes:
//
HRESULT HrRemoveAcsServiceRights( ) { DWORD dwErr; HRESULT hr; WCHAR szAcsUserName[UNLEN+GNLEN+2];
LOCALGROUP_MEMBERS_INFO_3 localgroup_members;
// First get the user name of AcsService in the format
// DomainName\UserName
hr = ::HrGetAcsServiceAccountName ( szAcsUserName ); if ( hr ) {
hr = HRESULT_FROM_WIN32(ERROR_INVALID_ACCOUNT_NAME); goto Exit; }
if ( !szAcsUserName[0] ) {
hr = HRESULT_FROM_WIN32(ERROR_INVALID_ACCOUNT_NAME); goto Exit; }
// Remove AcsService account to be a local administrator
localgroup_members.lgrmi3_domainandname = szAcsUserName; dwErr = NetLocalGroupDelMembers( NULL, // PDC name
L"Administrators", // group name
3, // passing in name
(LPBYTE)&localgroup_members, // Buffer
1 ); // count passed in
if ( dwErr ) {
if ( dwErr == ERROR_MEMBER_NOT_IN_ALIAS ) { hr = S_OK; dwErr = 0; } else { hr = HRESULT_FROM_WIN32(dwErr); goto Exit; } }
// Grant "Act as part of Operating system" right to AcsService
dwErr = RemoveUserRightFromAccount( szAcsUserName ); if ( dwErr ) {
hr = HRESULT_FROM_WIN32( dwErr ); goto Exit; }
hr = S_OK;
Exit: TraceError ( "HrRemoveAcsServiceRights", hr ); return hr; }
//+---------------------------------------------------------------------------
//
// Function: HrGetIpAddrTable
//
// Purpose: Gets the address table of the subnets that machine can see
//
// Arguments: ppmiat - Where to return the allocated address table
//
// Returns: S_OK if successful, Win32 error otherwise.
//
// Notes: The result must be freed by the caller
//
HRESULT HrGetIpAddrTable(MIB_IPADDRTABLE** ppmiat) { HRESULT hr = S_OK; DWORD dwErr = NO_ERROR; HMODULE hIpHelpApi = NULL; GETIPADDRTABLE pfnGetIpAddrTable = NULL;
AssertSz(ppmiat , "HrGetIpAddrTable doesn't have a ppmiat");
// Make sure we have our function loaded
//
hr = ::HrLoadLibAndGetProc( c_szIpHlpApiDllName, c_szaGetIpAddrTable, &hIpHelpApi, (FARPROC*)&pfnGetIpAddrTable); if (SUCCEEDED(hr)) { DWORD dwAddrCount = 0;
AssertSz(pfnGetIpAddrTable, "We should have a pfnGetIpAddrTable");
// Find out how big a buffer we need.
//
dwErr = pfnGetIpAddrTable(*ppmiat, &dwAddrCount, FALSE); hr = HRESULT_FROM_WIN32(dwErr);
// Allocate the buffer of the correct size
//
if ((NO_ERROR == dwErr) || (ERROR_INSUFFICIENT_BUFFER == dwErr)) { UINT cbTable = 0;
// Create the buffer
//
cbTable = (sizeof(MIB_IPADDRTABLE) + (sizeof(MIB_IPADDRROW) * (dwAddrCount)));
*ppmiat = reinterpret_cast<MIB_IPADDRTABLE*>(new BYTE [cbTable]);
// Try a second time with the correct buffer
//
dwErr = pfnGetIpAddrTable(*ppmiat, &dwAddrCount, FALSE); hr = HRESULT_FROM_WIN32(dwErr); }
// Unload the DLL
//
(VOID)::FreeLibrary(hIpHelpApi);
}
TraceErrorOptional("HrGetIpAddrTable", hr, (HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED) == hr)); return hr; }
//+---------------------------------------------------------------------------
//
// Function: HrFindFirstSubnet
//
// Purpose: Finds the first available subnet on the system to be used as
// the default entry in the registry. If a subnet cannot be found
// 000.000.000.000 is used.
//
// Arguments: pdwSubnet - Where to return the subnet
//
// Returns: Error code
//
// Notes:
//
HRESULT HrFindFirstSubnet(DWORD* pdwSubnet) { HRESULT hr = S_OK; MIB_IPADDRTABLE* ppmiat = NULL;
// Get our list of address entries
//
hr = HrGetIpAddrTable(&ppmiat); if (SUCCEEDED(hr)) { MIB_IPADDRROW* pmiarTemp = ppmiat->table; DWORD dwIpAddrCount = ppmiat->dwNumEntries; DWORD dwSubnet = 0x0;
while (dwIpAddrCount--) { // Find out what the sub net is
//
dwSubnet = (pmiarTemp->dwAddr & pmiarTemp->dwMask);
// The APIs return the value in network order, and we want to
// store the data in host order, so we have to convert the
// address
//
dwSubnet = ntohl(dwSubnet);
// Don't add invalid subnets to the list
//
if ((c_dwLocalSubnet != dwSubnet) && (c_dwNullSubnet != dwSubnet)) { // We found one!!
//
*pdwSubnet = dwSubnet;
break; }
// Look at the next entry
//
pmiarTemp++; }
// Free the allocated memory
//
delete ppmiat; }
TraceError("HrFindFirstSubnet", hr); return hr; }
//+---------------------------------------------------------------------------
//
// Function: HrWriteAcsSubnetDataToReg
//
// Purpose: Writes out the subnet information to the registry
//
// Arguments: pasrdSubnet - The data that has to be written
//
// Returns: Error code
//
// Notes:
//
HRESULT HrWriteAcsSubnetDataToReg(ACS_SUBNET_REG_DATA* pasrdSubnet) { HRESULT hr = S_OK; HKEY hkeySubnet = NULL; DWORD dwDisposition = 0x0;
hr = ::HrRegCreateKeyEx( HKEY_LOCAL_MACHINE, c_szRegKeyRsvpSubnet, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hkeySubnet, &dwDisposition); if (SUCCEEDED(hr)) { // Write out the parameters
//
hr = ::HrRegWriteValueTable( hkeySubnet, celems(c_avtAcsSubnet), c_avtAcsSubnet, reinterpret_cast<BYTE*>(pasrdSubnet), REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS);
::RegSafeCloseKey(hkeySubnet); }
TraceError("HrWriteAcsSubnetDataToReg", hr); return hr; }
//+---------------------------------------------------------------------------
//
// Function: HrWriteAcsRegistryData
//
// Purpose: Writes to the registry all of ACS's default parameters
//
// Arguments: pnocd - The option component information that is
// needed to get an INetCfg instance
// pasrdSubnet - The subnet information
// palrdLog - The logging information
//
// Returns: Error code
//
// Notes:
//
HRESULT HrWriteAcsRegistryData( PNETOCDATA pnocd ) { HRESULT hr = S_OK; ACS_SUBNET_REG_DATA asrdSubnet = { 0 };
// See if we can find a subnet
//
hr = ::HrFindFirstSubnet(&(asrdSubnet.dwSubnetIpAddress)); if (SUCCEEDED(hr)) { // Default subnet values
//
asrdSubnet.dwDSBMPriority = c_dwDSBMPriorityDef; asrdSubnet.dwMaxPeakRatePerFlow = c_dwMaxPeakRateDef; asrdSubnet.dwMaxRSVPBandwidth = c_dwMaxRSVPBandwidthDef; asrdSubnet.dwMaxTokenBucketRatePerFlow = c_dwMaxTokenBucketDef; asrdSubnet.dwMaxTotalPeakRate = c_dwMaxTotalPeakRateDef; asrdSubnet.dwIAmDsbmRefreshInterval = c_dwIAmDsbmRefreshDef; asrdSubnet.dwDSBMDeadInterval = c_dwDSBMDeadIntervalDef; asrdSubnet.fRunAsDSBM = c_fRunAsDSBMDef;
hr = ::HrWriteAcsSubnetDataToReg(&asrdSubnet); if (SUCCEEDED(hr)) { ::HrWriteAcsRegistryData(pnocd); } }
TraceError("HrWriteAcsRegistryData", hr);
return hr; }
//+---------------------------------------------------------------------------
//
// Function: HrChangeRsvpService
//
// Purpose: Change some RSVP service parameters
//
// Arguments: szDisplayName - The new display name
// dwStartType - The new start type
// fStartService - If the service should be started
//
// Returns: Error code
//
// Notes:
//
HRESULT HrChangeRsvpService( const WCHAR* szDisplayName, DWORD dwStartType, BOOL fStartService) { HRESULT hr = S_OK; CServiceManager scm; CService svc;
// Open the RSVP service with a lock on the service controller.
//
hr = scm.HrOpenService(&svc, c_szSvcRsvp, NO_LOCK); if (SUCCEEDED(hr)) { hr = scm.HrAddServiceDependency ( c_szSvcRsvp, c_szTcpIp ); if (SUCCEEDED(hr)) { hr = scm.HrAddServiceDependency ( c_szSvcRsvp, c_szAfd ); if (SUCCEEDED(hr)) { // Set the new start type
//
hr = svc.HrSetStartType(dwStartType); if (SUCCEEDED(hr)) { // Change the display name
//
hr = svc.HrSetDisplayName(szDisplayName); if (SUCCEEDED(hr) && fStartService) { // Unlock the Service Control Manager so that we can
// start the service.
//
// scm.Unlock();
// Start up the service
//
hr = scm.HrStartServiceNoWait(c_szSvcRsvp); } } } } }
TraceError("HrChangeRsvpService", hr); return hr; }
//+---------------------------------------------------------------------------
//
// Function: HrInstallACS
//
// Purpose: Called when ACS service is being installed. Handles all of the
// additional installation for ACS beyond that of the INF file.
//
// Arguments:
// pnocd [in] Pointer to NETOC data.
//
// Returns: S_OK if successful, Win32 error otherwise.
//
// Notes:
//
HRESULT HrInstallACS(PNETOCDATA pnocd) { HRESULT hr = S_OK;
#ifdef NEVER
// For NT 5.0 beta 2, setting rights for AcsService user name will not be done as this
// is introducing significant delay.
// Make AcsService to be local admin and grant SE_TCB_NAME right
hr = ::HrSetAcsServiceRights(); if (SUCCEEDED(hr)) {
// Display a message box asking the user to change the logon name
NcMsgBox( g_ocmData.hwnd, IDS_OC_CAPTION, IDS_OC_ACS_CHG_LOGON, MB_ICONSTOP | MB_OK); }
#endif // NEVER
// Ignoring any error from changing rights and continue with the
// setup so that ACS will run in Resouce only mode.
// Change the RSVP service parameters
hr = ::HrChangeRsvpService( ::SzLoadIds(IDS_OC_ACS_SERVICE_NAME), SERVICE_AUTO_START, TRUE);
TraceError("HrInstallACS", hr); return hr; }
//+---------------------------------------------------------------------------
//
// Function: HrRemoveACS
//
// Purpose: Handles additional removal requirements for ACS Service
// component.
//
// hwnd [in] Parent window for displaying UI.
// poc [in] Pointer to optional component being installed.
//
// Returns: S_OK if successful, Win32 error otherwise.
//
// Notes:
//
HRESULT HrRemoveACS(PNETOCDATA pnocd) { HRESULT hr = S_OK;
#ifdef NEVER
// For NT 5.0 beta 2, Removing AcsService user right will not be done as this
// is introducing significant delay.
// Drop the membership from local admins and remove SE_TCB_NAME right
(VOID)::HrRemoveAcsServiceRights ();
#endif // NEVER
//
// Clean out the adapters and subnet reg keys (if present)
//
(VOID)::HrRegDeleteKeyTree(HKEY_LOCAL_MACHINE, c_szRegKeyRsvpAdapters); (VOID)::HrRegDeleteKeyTree(HKEY_LOCAL_MACHINE, c_szRegKeyRsvpSubnet1); (VOID)::HrRegDeleteKeyTree(HKEY_LOCAL_MACHINE, c_szRegKeyRsvpSubnet);
// Put the name back the way it should be
//
(VOID)::HrChangeRsvpService( ::SzLoadIds(IDS_OC_RSVP_SERVICE_NAME), SERVICE_DEMAND_START, FALSE);
TraceError("HrRemoveACS", hr); return hr; }
//+---------------------------------------------------------------------------
//
// Function: HrOcExtACS
//
// Purpose: NetOC external message handler
//
// Arguments:
// pnocd []
// uMsg []
// wParam []
// lParam []
//
// Returns:
//
// Author: danielwe 17 Sep 1998
//
// Notes:
//
HRESULT HrOcExtACS(PNETOCDATA pnocd, UINT uMsg, WPARAM wParam, LPARAM lParam) { HRESULT hr = S_OK;
Assert(pnocd);
switch (uMsg) { case NETOCM_POST_INSTALL: hr = HrOcAcsOnInstall(pnocd); break;
case NETOCM_QUERY_CHANGE_SEL_STATE: hr = HrOcAcsOnQueryChangeSelState(pnocd, static_cast<BOOL>(wParam)); break; }
TraceError("HrOcExtACS", hr); return hr; }
//+---------------------------------------------------------------------------
//
// Function: HrOcAcsOnInstall
//
// Purpose: Called by optional components installer code to handle
// additional installation requirements for ACS Server
//
// Arguments:
// pnocd [in] Pointer to NETOC data
//
// Returns: S_OK if successful, Win32 error otherwise.
//
// Notes:
//
HRESULT HrOcAcsOnInstall(PNETOCDATA pnocd) { HRESULT hr = S_OK;
if (IT_INSTALL == pnocd->eit) { hr = HrInstallACS(pnocd); } else if (IT_REMOVE == pnocd->eit) { hr = HrRemoveACS(pnocd); }
TraceError("HrOcAcsOnInstall", hr); return hr; }
//+---------------------------------------------------------------------------
//
// Function: HrOcAcsOnQueryChangeSelState
//
// Purpose: Handles the request of the OC framework of whether or not
// the user should be allowed to install ACS on this host.
//
// Arguments:
// pnocd [in] NetOC Data
// fShowUi [in] TRUE if UI should be shown, FALSE if not
//
// Returns: S_OK if install is allowed, S_FALSE if not, Win32 error
// otherwise
//
// Author: rameshpa 23 April 1998
//
// Notes:
//
HRESULT HrOcAcsOnQueryChangeSelState(PNETOCDATA pnocd, BOOL fShowUi) { HRESULT hr = S_OK;
#ifdef NEVER
// For NT 5.0 beta 2, checking for user name will not be done as this
// is introducing significant delay.
WCHAR szAcsUserName[UNLEN+GNLEN+2];
Assert(pnocd); Assert(g_ocmData.hwnd);
// See if AcsService account exists in this domain or not
hr = HrGetAcsServiceAccountName(szAcsUserName); if ( FAILED(hr) || !szAcsUserName[0] ) { if (fShowUi) { NcMsgBox( g_ocmData.hwnd, IDS_OC_CAPTION, IDS_OC_NO_ACS_USER_ACCOUNT, MB_ICONSTOP | MB_OK); }
// Allow ACS setup to continue, as ACS will default to
// Resource only
hr = S_FALSE; }
TraceError("HrOcAcsOnQueryChangeSelState", hr);
#endif // NEVER
return hr; }
|