|
|
/*++
Copyright (c) 1996 Microsoft Corporation. All rights reserved
Module Name:
licsetup.cpp
Abstract:
This module exports a function, LicenseSetupRequestWizardPages, which gives NT Setup a wizard page for licensing to use in system setup (if licensing should be installed).
This wizard page is responsible for all license system configuration, including: o Creating the LicenseService o Creating the ...\CurrentControlSet\Services\LicenseService key and its values. (This key contains all configuration information for the LicenseService.) o Creating the ...\CurrentControlSet\Services\LicenseInfo key and its values. (This key contains all product-specific license info.) o Creating the appropriate registry key to register the LicenseService with the EventLog.
Portions of this module were extracted from SETUP (specifically from \nt\private\windows\setup\syssetup\license.c).
Author:
Jeff Parham (jeffparh) 15-Apr-1996
Revision History:
Jeff Parham (jeffparh) 17-Jul-1997 Added KSecDD to FilePrint services table for SFM
--*/
#include <windows.h>
#include <commctrl.h>
#include <setupapi.h>
#include <syssetup.h>
#include <setupbat.h>
#include <stdlib.h>
#include <htmlhelp.h>
#include <Accctrl.h>
#include <aclapi.h>
#include "liccpa.hpp"
#include "help.hpp"
#include "clicreg.hpp"
#include "config.hpp"
#include "resource.h"
#include "pridlgs.hpp"
#include "special.hpp"
#include <objbase.h>
#include <iads.h>
#include <ole2.h>
#include <oaidl.h>
#include <adshlp.h>
#include <strsafe.h>
#define ROOT_DSE_PATH L"LDAP://RootDSE"
#define CONFIG_CNTNR L"ConfigurationNamingContext"
//============================================================================
//
// MACROS
//
// used by setup tests? simulates a click on the NEXT button
#define WM_SIMULATENEXT ( WM_USER + 287 )
// begin or end a wait cursor
#define WM_BEGINWAITCURSOR ( WM_USER + 300 )
#define WM_ENDWAITCURSOR ( WM_USER + 301 )
#define LICENSEINFO_PATH TEXT("MACHINE\\SYSTEM\\CurrentControlSet\\Services\\LicenseInfo")
#define LICENSESERVICE_PATH TEXT("MACHINE\\SYSTEM\\CurrentControlSet\\Services\\LicenseService\\Parameters")
#define DONTLOAD_PATH TEXT("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Control Panel\\don't load")
// number of license wizard pages
const DWORD NUM_LICENSE_PAGES = 1;
// limits for per server licenses entered from the edit box in the
// license mode page
const int PERSERVER_EDIT_MAX = 9999; const int PERSERVER_EDIT_MIN = 5;
// the number of chars to represent PERSERVER_EDIT_MAX
const int PERSERVER_EDIT_WIDTH = 4;
//============================================================================
//
// LOCAL PROTOTYPES
//
// decides, based on the setup type, whether licensing is installed
static BOOL LicenseSetupDisplayLicensePagesQuery( PINTERNAL_SETUP_DATA );
// License mode page functions
static HPROPSHEETPAGE LicenseSetupModePageGet( PINTERNAL_SETUP_DATA ); static INT_PTR CALLBACK LicenseSetupModeDlgProc( HWND, UINT, WPARAM, LPARAM );
// License mode page Windows message handlers
static void LicenseSetupModeOnInitDialog( HWND, LPARAM, PINTERNAL_SETUP_DATA *, LPBOOL, LPDWORD, LPDWORD ); static void LicenseSetupModeOnSetActive( HWND, PINTERNAL_SETUP_DATA, LPBOOL, LPDWORD ); static void LicenseSetupModeOnSetLicenseMode( HWND, BOOL, DWORD ); static void LicenseSetupModeOnEditUpdate( HWND, HWND, BOOL, LPDWORD ); static void LicenseSetupModeOnWaitCursor( HWND, BOOL, LPDWORD ); static BOOL LicenseSetupModeOnSetCursor( HWND, WORD, DWORD ); static void LicenseSetupModeOnNext( HWND, PINTERNAL_SETUP_DATA, BOOL, DWORD ); static void LicenseSetupModeOnHelp( HWND ); static void LicenseSetupModeOnSimulateNext( HWND ); static void LicenseSetupModeOnKillActive( HWND ); #ifndef SPECIAL_USERS
static BOOL LicenseSetupModeDoUnattended( HWND, PINTERNAL_SETUP_DATA, LPBOOL, LPDWORD ); #endif //SPECIAL_USERS
// License configuration save functions
static DWORD LicenseSetupWrite( BOOL, DWORD ); static DWORD LicenseSetupWriteKeyLicenseInfo( BOOL, DWORD ); static DWORD LicenseSetupWriteKeyLicenseService( BOOL fWriteParametersKey ); static DWORD LicenseSetupWriteKeyEventLog(); static DWORD LicenseSetupWriteService( BOOL * fCreated );
// utility functions
static int MessageBoxFromStringID( HWND, UINT, UINT, UINT );
void CreateDirectoryWithAccess();
void CreateFileWithAccess();
void HideAppletIfBlade();
static DWORD SetRight( IADs *, LONG, LONG, LONG, LPOLESTR, LPOLESTR ); void ModifyRegistryWithWriteAccess();
BOOL IsRestrictedSmallBusSrv( void ); #define SBS_SPECIAL_USERS 10
//============================================================================
//
// GLOBAL IMPLEMENTATION
//
BOOL APIENTRY LicenseSetupRequestWizardPages( HPROPSHEETPAGE * paPropSheetPages, UINT * pcPages, PINTERNAL_SETUP_DATA pSetupData ) { BOOL fSuccess = FALSE; BOOL fDisplayLicensePages;
// validate params
if ( ( NULL != pcPages ) && ( NULL != pSetupData ) && ( sizeof( INTERNAL_SETUP_DATA ) == pSetupData->dwSizeOf ) ) { fDisplayLicensePages = LicenseSetupDisplayLicensePagesQuery( pSetupData );
if ( NULL == paPropSheetPages ) { // request for number of pages only
*pcPages = fDisplayLicensePages ? NUM_LICENSE_PAGES : 0; fSuccess = TRUE; } else { // request for actual pages
if ( !fDisplayLicensePages ) { // no pages needed
*pcPages = 0; fSuccess = TRUE; } else if ( *pcPages >= NUM_LICENSE_PAGES ) { // create and return pages
paPropSheetPages[ 0 ] = LicenseSetupModePageGet( pSetupData );
if ( NULL != paPropSheetPages[ 0 ] ) { *pcPages = NUM_LICENSE_PAGES; fSuccess = TRUE; } } } }
return fSuccess; }
//============================================================================
//
// LOCAL IMPLEMENTATIONS
//
static BOOL LicenseSetupDisplayLicensePagesQuery( PINTERNAL_SETUP_DATA pSetupData ) //
// The following code was extracted and modified from
// \nt\private\windows\setup\syssetup\license.c
// in setup. It returns TRUE iff the licensing wizard pages should be
// displayed as a part of setup.
//
{ BOOL fDisplayLicensePages;
if ( PRODUCT_WORKSTATION == pSetupData->ProductType ) { //
// If installing a workstation, then do not display the licensing page
//
fDisplayLicensePages = FALSE; } else { if ( !( pSetupData->OperationFlags & SETUPOPER_NTUPGRADE ) ) { //
// The licensing page needs to be displayed on a clean install
// of a server
//
fDisplayLicensePages = TRUE; } else { //
// If upgrading a server, find out if it was already licensed
// (NT 3.51 and later). If it was, then do not display the
// licensing page.
// We find out whether or not the system was licensed by looking
// at a value entry in the registry.
// Note that NT 3.1 and 3.5 will never have this value in the
// registry, and in these cases the licensing page needs to be
// displayed.
//
DWORD winStatus; CLicRegLicenseService FilePrintService( FILEPRINT_SERVICE_REG_KEY );
winStatus = FilePrintService.Open( NULL, FALSE );
if ( ERROR_SUCCESS != winStatus ) { fDisplayLicensePages = TRUE; } else { LICENSE_MODE LicenseMode;
winStatus = FilePrintService.GetMode( LicenseMode );
if ( ( ERROR_SUCCESS != winStatus ) || ( ( LICMODE_PERSEAT != LicenseMode ) && ( LICMODE_PERSERVER != LicenseMode ) ) ) { fDisplayLicensePages = TRUE; } else { // set FlipAllow value if it's not already set (a setup bug in
// the betas of NT 4.0 caused this value to be absent)
FilePrintService.CanChangeMode();
// add KSecDD to FilePrint services table if it isn't there already
HKEY hkeySFM; DWORD dwDisposition;
winStatus = RegCreateKeyEx( HKEY_LOCAL_MACHINE, TEXT( "System\\CurrentControlSet\\Services\\LicenseService\\FilePrint\\KSecDD" ), 0, NULL, 0, KEY_ALL_ACCESS, NULL, &hkeySFM, &dwDisposition );
if ( ERROR_SUCCESS == winStatus ) { RegCloseKey( hkeySFM ); }
// Change FilePrint License name from Windows NT to Windows.
CLicRegLicenseService l_FilePrintService( FILEPRINT_SERVICE_REG_KEY );
winStatus = l_FilePrintService.Open( NULL, FALSE );
if ( ERROR_SUCCESS == winStatus ) { winStatus = l_FilePrintService.SetFamilyDisplayName( FILEPRINT_SERVICE_FAMILY_DISPLAY_NAME );
if ( ERROR_SUCCESS == winStatus ) { winStatus = l_FilePrintService.SetDisplayName( FILEPRINT_SERVICE_DISPLAY_NAME ); } }
//
// makarp: setting fDisplayLicensePages to true is wrong, because in such case
// the pages will be displayed, and the original settings will be lost.
//
// fDisplayLicensePages = TRUE;
//
// instead we do the stuff we want to explicitely here.
//
BOOL bFlag = FALSE; LicenseSetupWriteService(&bFlag); HideAppletIfBlade(); CreateDirectoryWithAccess(); CreateFileWithAccess(); ModifyRegistryWithWriteAccess();
fDisplayLicensePages = FALSE; } } } }
return fDisplayLicensePages; }
static HPROPSHEETPAGE LicenseSetupModePageGet( PINTERNAL_SETUP_DATA pSetupData ) //
// Returns an HPROPSHEETPAGE for the license mode wizard page, or
// NULL if error.
//
{ HPROPSHEETPAGE hpsp; PROPSHEETPAGE psp; TCHAR szHeader[256]; TCHAR szSubHeader[512];
psp.dwSize = sizeof( psp ); psp.dwFlags = PSP_USETITLE | PSP_HASHELP | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE; psp.hInstance = g_hinst; psp.pszTemplate = MAKEINTRESOURCE( IDD_SETUP_LICENSE_MODE_PAGE ); psp.hIcon = NULL; psp.pfnDlgProc = LicenseSetupModeDlgProc; psp.lParam = (LPARAM) pSetupData; psp.pszTitle = pSetupData->WizardTitle;
szHeader[0] = L'\0'; szSubHeader[0] = L'\0';
LoadString( g_hinst, IDS_SETUP_HEADER, szHeader, sizeof( szHeader ) / sizeof( *szHeader ) );
LoadString( g_hinst, IDS_SETUP_SUBHEADER, szSubHeader, sizeof( szSubHeader ) / sizeof( *szSubHeader ) );
psp.pszHeaderTitle = szHeader; psp.pszHeaderSubTitle = szSubHeader;
hpsp = CreatePropertySheetPage( &psp );
return hpsp; }
static INT_PTR CALLBACK LicenseSetupModeDlgProc( HWND hwndPage, UINT msg, WPARAM wParam, LPARAM lParam ) //
// Dialog procedure for the license mode wizard page.
//
{ // static data initialized by WM_INITDIALOG
static PINTERNAL_SETUP_DATA pSetupData = NULL; static BOOL fLicensePerServer; static DWORD cPerServerLicenses; static DWORD cWaitCursor;
BOOL fReturn = TRUE;
switch ( msg ) { case WM_INITDIALOG: LicenseSetupModeOnInitDialog( hwndPage, lParam, &pSetupData, &fLicensePerServer, &cPerServerLicenses, &cWaitCursor ); break;
case WM_SIMULATENEXT: LicenseSetupModeOnSimulateNext( hwndPage ); break;
case WM_BEGINWAITCURSOR: LicenseSetupModeOnWaitCursor( hwndPage, TRUE, &cWaitCursor ); break;
case WM_ENDWAITCURSOR: LicenseSetupModeOnWaitCursor( hwndPage, FALSE, &cWaitCursor ); break;
case WM_SETCURSOR: LicenseSetupModeOnSetCursor( hwndPage, LOWORD( lParam ), cWaitCursor ); break;
case WM_COMMAND: switch ( HIWORD( wParam ) ) { case BN_CLICKED: switch ( LOWORD( wParam ) ) { case IDC_PERSEAT: fLicensePerServer = FALSE; LicenseSetupModeOnSetLicenseMode( hwndPage, fLicensePerServer, cPerServerLicenses ); break;
case IDC_PERSERVER: fLicensePerServer = TRUE; LicenseSetupModeOnSetLicenseMode( hwndPage, fLicensePerServer, cPerServerLicenses ); break; } break;
case EN_UPDATE: if ( IDC_USERCOUNT == LOWORD( wParam ) ) { LicenseSetupModeOnEditUpdate( hwndPage, (HWND) lParam, fLicensePerServer, &cPerServerLicenses ); } break;
default: fReturn = FALSE; break; } break;
case WM_NOTIFY: { NMHDR * pNmHdr;
pNmHdr = (NMHDR *)lParam;
switch ( pNmHdr->code ) { case PSN_SETACTIVE: LicenseSetupModeOnSetActive( hwndPage, pSetupData, &fLicensePerServer, &cPerServerLicenses ); break;
case PSN_KILLACTIVE: LicenseSetupModeOnKillActive( hwndPage ); break;
case PSN_WIZNEXT: case PSN_WIZFINISH: LicenseSetupModeOnNext( hwndPage, pSetupData, fLicensePerServer, cPerServerLicenses ); break;
case PSN_HELP: LicenseSetupModeOnHelp( hwndPage ); break;
default: fReturn = FALSE; break; } }
break;
default: fReturn = FALSE; }
return fReturn; }
static void LicenseSetupModeOnInitDialog( HWND hwndPage, LPARAM lParam, PINTERNAL_SETUP_DATA * ppSetupData, LPBOOL pfLicensePerServer, LPDWORD pcPerServerLicenses, LPDWORD pcWaitCursor ) //
// Message handler for WM_INITDIALOG
//
{ // initialize static data
*ppSetupData = (PINTERNAL_SETUP_DATA) ( (LPPROPSHEETPAGE) lParam )->lParam; *pcPerServerLicenses = 5; *pfLicensePerServer = TRUE; *pcWaitCursor = 0;
// limit license count edit text length
SendMessage( GetDlgItem( hwndPage, IDC_USERCOUNT ), EM_LIMITTEXT, PERSERVER_EDIT_WIDTH, 0 );
// limit license count up-down range
LONG lRange;
lRange = (LPARAM) MAKELONG( (short) PERSERVER_EDIT_MAX, (short) PERSERVER_EDIT_MIN ); SendMessage( GetDlgItem( hwndPage, IDC_USERCOUNTARROW ), UDM_SETRANGE, 0, (LPARAM) lRange );
// initialize for default license mode
LicenseSetupModeOnSetLicenseMode( hwndPage, *pfLicensePerServer, *pcPerServerLicenses ); }
static void LicenseSetupModeOnSetActive( HWND hwndPage, PINTERNAL_SETUP_DATA pSetupData, LPBOOL pfLicensePerServer, LPDWORD pcPerServerLicenses ) //
// Notification handler for PSN_SETACTIVE
//
{ static BOOL fFirstTime = TRUE; BOOL fSkipPage; OSVERSIONINFOEX ovi; BOOL fBlade = FALSE;
ovi.dwOSVersionInfoSize = sizeof(ovi); if (GetVersionEx((OSVERSIONINFO *) &ovi)) { if( ovi.wSuiteMask & VER_SUITE_BLADE ) { fBlade = TRUE; } }
#ifdef SPECIAL_USERS
*pfLicensePerServer = TRUE; *pcPerServerLicenses = SPECIAL_USERS; fSkipPage = TRUE; #else
if ( fBlade || IsRestrictedSmallBusSrv() ) { *pfLicensePerServer = TRUE; *pcPerServerLicenses = SBS_SPECIAL_USERS; fSkipPage = TRUE; } else if ( pSetupData->OperationFlags & SETUPOPER_BATCH ) { // operating in unattended mode; attempt to get all answers
// from the unattend configuration file
fSkipPage = LicenseSetupModeDoUnattended( hwndPage, pSetupData, pfLicensePerServer, pcPerServerLicenses ); if ( !fSkipPage ) { // Set defaults from unattended file
LicenseSetupModeOnSetLicenseMode( hwndPage, *pfLicensePerServer, *pcPerServerLicenses ); //
// makarp: setting skippage to true is wrong, because we do not want to skip page.
// we came here because we did not find sufficent answers in answer file.
//
// fSkipPage = TRUE;
} } else { // operating in interactive mode; get answers from user
fSkipPage = FALSE; } #endif
HWND hwndSheet = GetParent( hwndPage );
if ( fSkipPage ) {
if (fFirstTime) { fFirstTime = FALSE; // skip page
// Only the first time do we need to do the processing which happens on next
PostMessage( hwndSheet, PSM_PRESSBUTTON, (WPARAM)PSBTN_NEXT, 0 ); } else { // After the first time the processing is already done and we don't have to do anything
// This also solves the problem where the page needs to be skipped when the user clicks back
// on a later page and this pages needs to be skipped.
SetWindowLongPtr( hwndPage, DWLP_MSGRESULT, (LONG_PTR)-1 ); return; }
} else { // display page
// hide Cancel button
HWND hwndCancel = GetDlgItem( hwndSheet, IDCANCEL ); EnableWindow( hwndCancel, FALSE); ShowWindow( hwndCancel, SW_HIDE);
PropSheet_SetWizButtons( hwndSheet, PSWIZB_NEXT | PSWIZB_BACK );
if (pSetupData) { pSetupData->ShowHideWizardPage(TRUE); } }
// success
SetWindowLongPtr( hwndPage, DWLP_MSGRESULT, (LONG_PTR)0 ); }
static void LicenseSetupModeOnSetLicenseMode( HWND hwndPage, BOOL fToPerServer, DWORD cPerServerLicenses ) //
// Handles changing the page to signify that the given license mode
// is selected.
//
{ HWND hwndCount = GetDlgItem( hwndPage, IDC_USERCOUNT ); HWND hwndSpin = GetDlgItem( hwndPage, IDC_USERCOUNTARROW );
// set radio button states
CheckDlgButton( hwndPage, IDC_PERSEAT, !fToPerServer ); CheckDlgButton( hwndPage, IDC_PERSERVER, fToPerServer );
// set user count edit control
if ( fToPerServer ) { // display per server count
SetDlgItemInt( hwndPage, IDC_USERCOUNT, cPerServerLicenses, FALSE ); SetFocus( hwndCount ); SendMessage( hwndCount, EM_SETSEL, 0, -1 ); } else { // remove per server count
SetDlgItemText( hwndPage, IDC_USERCOUNT, TEXT( "" ) ); }
// display count up-down and edit box iff per server mode is selected
EnableWindow( hwndCount, fToPerServer ); EnableWindow( hwndSpin, fToPerServer ); }
static void LicenseSetupModeOnEditUpdate( HWND hwndPage, HWND hwndCount, BOOL fLicensePerServer, LPDWORD pcPerServerLicenses ) //
// Command handler for EN_UPDATE of count edit box
//
{ if ( fLicensePerServer ) { BOOL fTranslated; UINT nValue; BOOL fModified = FALSE;
nValue = GetDlgItemInt( hwndPage, IDC_USERCOUNT, &fTranslated, FALSE );
if ( fTranslated ) { // count translated; ensure its within the valid range
if ( PERSERVER_EDIT_MAX < nValue ) { // too big
nValue = PERSERVER_EDIT_MAX; fModified = TRUE; }
*pcPerServerLicenses = nValue; } else { // count couldn't be translated; reset to last value
nValue = *pcPerServerLicenses; fModified = TRUE; }
if ( fModified ) { // text in edit box is invalid; change it to the proper value
SetDlgItemInt( hwndPage, IDC_USERCOUNT, nValue, FALSE ); SetFocus( hwndCount ); SendMessage( hwndCount, EM_SETSEL, 0, -1 ); MessageBeep( MB_VALUELIMIT ); } } }
static void LicenseSetupModeOnWaitCursor( HWND hwndDlg, BOOL fWait, LPDWORD pcWaitCursor ) //
// Handler for WM_BEGINWAITCURSOR / WM_ENDWAITCURSOR
//
{ if ( fWait ) { (*pcWaitCursor)++;
if ( 1 == (*pcWaitCursor) ) { // display wait cursor
SetCursor( LoadCursor( NULL, MAKEINTRESOURCE( IDC_WAIT ) ) ); } } else { if ( 0 < *pcWaitCursor ) { (*pcWaitCursor)--; }
if ( 0 == *pcWaitCursor ) { // display regular cursor
SetCursor( LoadCursor( NULL, MAKEINTRESOURCE( IDC_ARROW ) ) ); } }
// success
SetWindowLongPtr( hwndDlg, DWLP_MSGRESULT, (LONG_PTR)*pcWaitCursor ); }
static BOOL LicenseSetupModeOnSetCursor( HWND hwndDlg, WORD nHitTest, DWORD cWaitCursor ) //
// Handler for WM_SETCURSOR
//
{ BOOL frt = FALSE;
if ( HTCLIENT == nHitTest ) { if ( cWaitCursor > 0 ) { // display wait cursor instead of regular cursor
SetCursor( LoadCursor( NULL, MAKEINTRESOURCE( IDC_WAIT ) ) ); SetWindowLongPtr( hwndDlg, DWLP_MSGRESULT, (LONG_PTR)TRUE ); frt = TRUE; } }
return frt; }
static void LicenseSetupModeOnNext( HWND hwndPage, PINTERNAL_SETUP_DATA pSetupData, BOOL fLicensePerServer, DWORD cPerServerLicenses ) //
// Notification handler for PSN_WIZNEXT
//
{ DWORD winStatus; int nButton;
if ( ( fLicensePerServer ) && ( PERSERVER_EDIT_MIN > cPerServerLicenses ) && !( pSetupData->OperationFlags & SETUPOPER_BATCH ) ) { // warn user about using per server mode with less then 5 licenses
MessageBoxFromStringID( hwndPage, IDS_LICENSE_SETUP_NO_PER_SERVER_LICENSES, IDS_WARNING, MB_ICONERROR | MB_OK ); nButton = IDCANCEL; } else { // per seat mode or per server mode with positive license count
nButton = IDOK; }
if ( IDOK == nButton ) { do { // save license configuration
SendMessage( hwndPage, WM_BEGINWAITCURSOR, 0, 0 );
winStatus = LicenseSetupWrite( fLicensePerServer, cPerServerLicenses );
SendMessage( hwndPage, WM_ENDWAITCURSOR, 0, 0 );
if ( ERROR_SUCCESS != winStatus ) { // save failed; alert user
nButton = MessageBoxFromStringID( hwndPage, IDS_LICENSE_SETUP_SAVE_FAILED, IDS_ERROR, MB_ICONSTOP | MB_ABORTRETRYIGNORE | MB_DEFBUTTON2 );
if ( IDIGNORE == nButton ) { nButton = IDOK; } } else { // save succeeded
nButton = IDOK; } } while ( IDRETRY == nButton ); }
if ( IDOK != nButton ) { // don't advance to next page
SetWindowLongPtr( hwndPage, DWLP_MSGRESULT, (LONG_PTR)-1 ); } }
static void LicenseSetupModeOnHelp( HWND hwndPage ) //
// Notification handler for PSN_HELP
//
{ ::HtmlHelp( hwndPage, LICCPA_HTMLHELPFILE, HH_DISPLAY_TOPIC,0); }
static void LicenseSetupModeOnSimulateNext( HWND hwndPage ) //
// Handler for WM_SIMULATENEXT (used by setup tests?)
//
{ // simulate the next button
PropSheet_PressButton( GetParent( hwndPage ), PSBTN_NEXT ); }
static void LicenseSetupModeOnKillActive( HWND hwndPage ) //
// Notification handler for PSN_KILLACTIVE
//
{ // success
SetWindowLong( hwndPage, DWLP_MSGRESULT, 0); }
typedef enum { UnattendFullUnattend, UnattendGUIAttended, UnattendDefaultHide, UnattendProvideDefault, UnattendReadOnly } UNATTENDMODE;
#ifndef SPECIAL_USERS
static BOOL LicenseSetupModeDoUnattended( HWND hwndPage, PINTERNAL_SETUP_DATA pSetupData, LPBOOL pfLicensePerServer, LPDWORD pcPerServerLicenses ) //
// Get answers to wizard page from unattend file.
//
{ int cch; LPTSTR pszBadParam; TCHAR szLicenseMode[ 64 ]; TCHAR szPerServerLicenses[ 64 ]; TCHAR szUnattendMode[ 64 ]; UNATTENDMODE UnattendMode = UnattendDefaultHide;
pszBadParam = NULL;
SendMessage( hwndPage, WM_BEGINWAITCURSOR, 0, 0 );
// Get Unattend Mode
cch = GetPrivateProfileString( WINNT_UNATTENDED, WINNT_U_UNATTENDMODE, TEXT( "" ), szUnattendMode, sizeof( szUnattendMode ) / sizeof( *szUnattendMode ), pSetupData->UnattendFile ); if ( 0 < cch ) { if ( !lstrcmpi( szUnattendMode, WINNT_A_FULLUNATTENDED ) ) { UnattendMode = UnattendFullUnattend; } else if ( !lstrcmpi( szUnattendMode, WINNT_A_PROVIDEDEFAULT ) ) { UnattendMode = UnattendProvideDefault; } else if ( !lstrcmpi( szUnattendMode, WINNT_A_READONLY ) ) { UnattendMode = UnattendReadOnly; } else if ( !lstrcmpi( szUnattendMode, WINNT_A_GUIATTENDED ) ) { // This should never happen
UnattendMode = UnattendGUIAttended; } }
// get license mode
cch = GetPrivateProfileString( WINNT_LICENSEDATA_W, WINNT_L_AUTOMODE_W, TEXT( "" ), szLicenseMode, sizeof( szLicenseMode ) / sizeof( *szLicenseMode ), pSetupData->UnattendFile );
SendMessage( hwndPage, WM_ENDWAITCURSOR, 0, 0 );
if ( 0 < cch ) { if ( !lstrcmpi( szLicenseMode, WINNT_A_PERSEAT_W ) ) { *pfLicensePerServer = FALSE; } else if ( !lstrcmpi( szLicenseMode, WINNT_A_PERSERVER_W ) ) { *pfLicensePerServer = TRUE; } else { cch = 0; } }
if ( cch <= 0 ) { // license mode absent or invalid
pszBadParam = WINNT_L_AUTOMODE_W; } else if ( !*pfLicensePerServer ) { // per seat mode; no need to read per server license count
*pcPerServerLicenses = 0; } else { // get per server license count
SendMessage( hwndPage, WM_BEGINWAITCURSOR, 0, 0 );
cch = GetPrivateProfileString( WINNT_LICENSEDATA_W, WINNT_L_AUTOUSERS_W, TEXT( "" ), szPerServerLicenses, sizeof( szPerServerLicenses ) / sizeof( *szPerServerLicenses ), pSetupData->UnattendFile );
SendMessage( hwndPage, WM_ENDWAITCURSOR, 0, 0 );
if ( 0 < cch ) { *pcPerServerLicenses = wcstoul( szPerServerLicenses, NULL, 10 );
if ( ( PERSERVER_EDIT_MIN > *pcPerServerLicenses ) || ( PERSERVER_EDIT_MAX < *pcPerServerLicenses ) ) { // Don't let things go without setting a valid server license
// count.
*pcPerServerLicenses = PERSERVER_EDIT_MIN; cch = 0; } }
if ( cch <= 0 ) { // per server license count absent or invalid
pszBadParam = WINNT_L_AUTOUSERS_W; } }
//
// Do not display the error message on preinstall.
//
if ( NULL != pszBadParam && !(pSetupData->OperationFlags & (SETUPOPER_PREINSTALL | SETUPOPER_NTUPGRADE)) && UnattendMode == UnattendFullUnattend ) { // encountered a bad unattended parameter; display error
TCHAR szCaption[ 64 ]; TCHAR szFormat[ 1024 ]; TCHAR szText[ 1024 ];
LoadString( g_hinst, IDS_LICENSE_SETUP_BAD_UNATTEND_PARAM, szFormat, sizeof( szFormat ) / sizeof( *szFormat ) );
LoadString( g_hinst, IDS_ERROR, szCaption, sizeof( szCaption ) / sizeof( *szCaption ) );
HRESULT hr = StringCbPrintf( szText, sizeof(szText), szFormat, pszBadParam ); if (SUCCEEDED(hr)) MessageBox( hwndPage, szText, szCaption, MB_OK | MB_ICONSTOP ); }
// If just providing defaults, return FALSE to force the page to show
if ( UnattendMode == UnattendProvideDefault ) return ( FALSE ); return ( NULL == pszBadParam ); } #endif //SPECIAL_USERS
static DWORD LicenseSetupWrite( BOOL fLicensePerServer, DWORD cPerServerLicenses ) //
// Write license configuration; returns ERROR_SUCCESS or Windows error.
//
{ DWORD winStatus; BOOL fCreated = TRUE; // TRUE if service entry is created
// Used to determine if we should create
// the parameters key or leave it alone.
winStatus = LicenseSetupWriteService( &fCreated );
if ( ERROR_SUCCESS == winStatus ) { winStatus = LicenseSetupWriteKeyLicenseInfo( fLicensePerServer, cPerServerLicenses );
if ( ERROR_SUCCESS == winStatus ) { winStatus = LicenseSetupWriteKeyLicenseService( fCreated );
if ( ERROR_SUCCESS == winStatus ) { winStatus = LicenseSetupWriteKeyEventLog(); } } }
return winStatus; }
static DWORD LicenseSetupWriteKeyLicenseInfo( BOOL fLicensePerServer, DWORD cPerServerLicenses ) //
// Create registry values:
//
// HKEY_LOCAL_MACHINE
// \System
// \CurrentControlSet
// \Services
// \LicenseInfo
// ErrorControl : REG_DWORD : 1
// Start : REG_DWORD : 3
// Type : REG_DWORD : 4
// \FilePrint
// ConcurrentLimit : REG_DWORD : fLicensePerServer ? cPerServerLicenses : 0
// DisplayName : REG_SZ : "Windows Server"
// FamilyDisplayName : REG_SZ : "Windows Server"
// Mode : REG_DWORD : fLicensePerServer ? 1 : 0
// FlipAllow : REG_DWORD : fLicensePerServer ? 1 : 0
//
{ DWORD winStatus; BOOL fCreatedNewServiceList; CLicRegLicense ServiceList;
winStatus = ServiceList.Open( fCreatedNewServiceList );
if ( ERROR_SUCCESS == winStatus ) { CLicRegLicenseService FilePrintService( FILEPRINT_SERVICE_REG_KEY );
winStatus = FilePrintService.Open( NULL, TRUE );
if ( ERROR_SUCCESS == winStatus ) { LICENSE_MODE lm;
lm = fLicensePerServer ? LICMODE_PERSERVER : LICMODE_PERSEAT;
winStatus = FilePrintService.SetMode( lm );
if ( ERROR_SUCCESS == winStatus ) { winStatus = FilePrintService.SetUserLimit( fLicensePerServer ? cPerServerLicenses : 0 );
if ( ERROR_SUCCESS == winStatus ) { winStatus = FilePrintService.SetChangeFlag( fLicensePerServer );
if ( ERROR_SUCCESS == winStatus ) { winStatus = FilePrintService.SetFamilyDisplayName( FILEPRINT_SERVICE_FAMILY_DISPLAY_NAME );
if ( ERROR_SUCCESS == winStatus ) { winStatus = FilePrintService.SetDisplayName( FILEPRINT_SERVICE_DISPLAY_NAME ); } } } } } }
return winStatus; }
static DWORD LicenseSetupWriteKeyLicenseService( BOOL fWriteParametersKey ) //
// Create registry values:
//
// HKEY_LOCAL_MACHINE
// \System
// \CurrentControlSet
// \Services
// \LicenseService
// \FilePrint
// \KSecDD
// \MSAfpSrv
// \SMBServer
// \TCP/IP Print Server
// \Parameters
// UseEnterprise : REG_DWORD : 0
// ReplicationType : REG_DWORD : 0
// ReplicationTime : REG_DWORD : 24 * 60 * 60
// EnterpriseServer : REG_SZ : ""
//
{ DWORD winStatus; HKEY hKeyLicenseService; DWORD dwKeyCreateDisposition;
// create LicenseInfo key
winStatus = RegCreateKeyEx( HKEY_LOCAL_MACHINE, LICENSE_SERVICE_REG_KEY, 0, NULL, 0, KEY_ALL_ACCESS, NULL, &hKeyLicenseService, &dwKeyCreateDisposition );
if ( ERROR_SUCCESS == winStatus ) { HKEY hKeyFilePrint;
// create FilePrint key
winStatus = RegCreateKeyEx( hKeyLicenseService, TEXT( "FilePrint" ), 0, NULL, 0, KEY_ALL_ACCESS, NULL, &hKeyFilePrint, &dwKeyCreateDisposition );
if ( ERROR_SUCCESS == winStatus ) { const LPCTSTR apszFilePrintSubkeys[] = { TEXT( "KSecDD" ), TEXT( "MSAfpSrv" ), TEXT( "SMBServer" ), TEXT( "TCP/IP Print Server" ), NULL };
HKEY hKeyFilePrintSubkey; DWORD iSubkey;
for ( iSubkey = 0; NULL != apszFilePrintSubkeys[ iSubkey ]; iSubkey++ ) { winStatus = RegCreateKeyEx( hKeyFilePrint, apszFilePrintSubkeys[ iSubkey ], 0, NULL, 0, KEY_ALL_ACCESS, NULL, &hKeyFilePrintSubkey, &dwKeyCreateDisposition );
if ( ERROR_SUCCESS == winStatus ) { RegCloseKey( hKeyFilePrintSubkey ); } else { break; } }
RegCloseKey( hKeyFilePrint ); }
RegCloseKey( hKeyLicenseService ); }
//
// Only write the Parameters key if the service was just created. That is,
// this is not an upgrade
//
if ( fWriteParametersKey && (ERROR_SUCCESS == winStatus) ) { HKEY hKeyParameters;
// create Parameters key
winStatus = RegCreateKeyEx( HKEY_LOCAL_MACHINE, szLicenseKey, // const
0, NULL, 0, KEY_ALL_ACCESS, NULL, &hKeyParameters, &dwKeyCreateDisposition );
if ( ERROR_SUCCESS == winStatus ) { // create LicenseService\Parameters values
winStatus = RegSetValueEx( hKeyParameters, szUseEnterprise, // const
0, REG_DWORD, (CONST BYTE *) &dwUseEnterprise, // const
sizeof( dwUseEnterprise ) );
if ( ERROR_SUCCESS == winStatus ) { winStatus = RegSetValueEx( hKeyParameters, szReplicationType, // const
0, REG_DWORD, (CONST BYTE *) &dwReplicationType, // const
sizeof( dwReplicationType ) );
if ( ERROR_SUCCESS == winStatus ) { winStatus = RegSetValueEx( hKeyParameters, szReplicationTime, // const
0, REG_DWORD, (CONST BYTE *) &dwReplicationTimeInSec, // const
sizeof( dwReplicationTimeInSec ) );
if ( ERROR_SUCCESS == winStatus ) { LPCTSTR pszEnterpriseServer = TEXT( "" );
winStatus = RegSetValueEx( hKeyParameters, szEnterpriseServer, // const
0, REG_SZ, (CONST BYTE *) pszEnterpriseServer, ( 1 + lstrlen( pszEnterpriseServer ) ) * sizeof( *pszEnterpriseServer ) ); } } }
RegCloseKey( hKeyParameters ); } }
ModifyRegistryWithWriteAccess();
return winStatus; }
static DWORD LicenseSetupWriteKeyEventLog() //
// Create registry values:
//
// HKEY_LOCAL_MACHINE
// \System
// \CurrentControlSet
// \Services
// \EventLog
// \Application
// \LicenseService
// EventMessageFile : REG_EXPAND_SZ : %SystemRoot%\System32\llsrpc.dll
// TypesSupported : REG_DWORD : 7
//
{ DWORD winStatus; HKEY hKeyLicenseService; DWORD dwKeyCreateDisposition;
// create LicenseService key
winStatus = RegCreateKeyEx( HKEY_LOCAL_MACHINE, TEXT( "System\\CurrentControlSet\\Services\\EventLog\\Application\\LicenseService" ), 0, NULL, 0, KEY_ALL_ACCESS, NULL, &hKeyLicenseService, &dwKeyCreateDisposition );
if ( ERROR_SUCCESS == winStatus ) { LPCTSTR pszEventMessageFile = TEXT( "%SystemRoot%\\System32\\llsrpc.dll" ); const DWORD dwTypesSupported = ( EVENTLOG_ERROR_TYPE | EVENTLOG_WARNING_TYPE | EVENTLOG_INFORMATION_TYPE );
winStatus = RegSetValueEx( hKeyLicenseService, TEXT( "TypesSupported" ), 0, REG_DWORD, (CONST BYTE *) &dwTypesSupported, sizeof( dwTypesSupported ) );
if ( ERROR_SUCCESS == winStatus ) { winStatus = RegSetValueEx( hKeyLicenseService, TEXT( "EventMessageFile" ), 0, REG_SZ, (CONST BYTE *) pszEventMessageFile, ( 1 + lstrlen( pszEventMessageFile ) ) * sizeof( *pszEventMessageFile ) ); }
RegCloseKey( hKeyLicenseService ); }
return winStatus; }
static DWORD SetRight( IADs *pObject, long lAccessMask, long lAccessType, long lAccessInheritFlags, LPOLESTR szObjectGUID, LPOLESTR szInheritedObjectGUID) { VARIANT varSD; DWORD dwStatus = S_OK;
IDispatch *pDispDACL = NULL; IDispatch *pDispACE = NULL; IADsAccessControlList *pACL = NULL; IADsSecurityDescriptor *pSD = NULL; IADsAccessControlEntry *pACE = NULL; long lFlags = 0L;
BSTR bstrNameProp = NULL; BSTR bstrSecID = NULL;
if ( !pObject) { dwStatus = (DWORD)E_INVALIDARG; goto CleanExit; } VariantClear(&varSD);
// Get the nTSecurityDescriptor.
// Type should be VT_DISPATCH--an IDispatch ptr to the security descriptor object.
bstrNameProp = SysAllocString(L"nTSecurityDescriptor"); if (NULL == bstrNameProp) { dwStatus = ERROR_OUTOFMEMORY; goto CleanExit; }
dwStatus = pObject->Get(bstrNameProp, &varSD); if ( FAILED(dwStatus) || varSD.vt != VT_DISPATCH ) { return dwStatus; }
dwStatus = V_DISPATCH(&varSD)->QueryInterface(IID_IADsSecurityDescriptor,(void**)&pSD); if ( FAILED(dwStatus) ) { goto CleanExit; } // Get the DACL.
dwStatus = pSD->get_DiscretionaryAcl(&pDispDACL); if (SUCCEEDED(dwStatus)) dwStatus = pDispDACL->QueryInterface(IID_IADsAccessControlList,(void**)&pACL); if ( FAILED(dwStatus) ) { goto CleanExit; }
// Create the COM object for the new ACE.
dwStatus = CoCreateInstance( CLSID_AccessControlEntry, NULL, CLSCTX_INPROC_SERVER, IID_IADsAccessControlEntry, (void **)&pACE ); if ( FAILED(dwStatus) ) { goto CleanExit; }
dwStatus = pACE->put_AccessMask(lAccessMask ); if ( FAILED(dwStatus) ) { goto CleanExit; }
bstrSecID = SysAllocString(TEXT("NT AUTHORITY\\NetworkService")); if (NULL == bstrSecID) { dwStatus = ERROR_OUTOFMEMORY; goto CleanExit; }
dwStatus = pACE->put_Trustee(bstrSecID);
if ( FAILED(dwStatus) ) { goto CleanExit; }
dwStatus = pACE->put_AceType(lAccessType );
if ( FAILED(dwStatus) ) { goto CleanExit; }
dwStatus = pACE->put_AceFlags(lAccessInheritFlags );
if ( FAILED(dwStatus) ) { goto CleanExit; }
// If an szObjectGUID is specified, add ADS_FLAG_OBJECT_TYPE_PRESENT
// to the lFlags mask and set the ObjectType.
if (szObjectGUID) { BSTR bstrObjectGUID = SysAllocString(szObjectGUID); if (NULL != bstrObjectGUID) { lFlags |= ADS_FLAG_OBJECT_TYPE_PRESENT; dwStatus = pACE->put_ObjectType(bstrObjectGUID); SysFreeString(bstrObjectGUID); } } // If an szInheritedObjectGUID is specified, add ADS_FLAG_INHERITED_OBJECT_TYPE_PRESENT
// to the lFlags mask and set the InheritedObjectType.
if (SUCCEEDED(dwStatus) && szInheritedObjectGUID) { BSTR bstrInheritedObjectGUID = SysAllocString(szInheritedObjectGUID); if (NULL != bstrInheritedObjectGUID) { lFlags |= ADS_FLAG_INHERITED_OBJECT_TYPE_PRESENT; dwStatus = pACE->put_InheritedObjectType(bstrInheritedObjectGUID ); SysFreeString(bstrInheritedObjectGUID); } }
// Set flags if ObjectType or InheritedObjectType were set.
if (SUCCEEDED(dwStatus) && lFlags) dwStatus = pACE->put_Flags(lFlags); // Add the ACE to the ACL to the SD to the cache to the object.
// Need to QI for the IDispatch pointer to pass to the AddAce method.
dwStatus = pACE->QueryInterface(IID_IDispatch, (void**)&pDispACE); if (SUCCEEDED(dwStatus)) { dwStatus = pACL->AddAce(pDispACE); if (SUCCEEDED(dwStatus)) { // Write the DACL
dwStatus = pSD->put_DiscretionaryAcl(pDispDACL); if (SUCCEEDED(dwStatus)) { // Write the ntSecurityDescriptor property to the property cache.
BSTR bstrSD = SysAllocString(L"nTSecurityDescriptor"); if (NULL != bstrSD) { dwStatus = pObject->Put(bstrSD, varSD); if (SUCCEEDED(dwStatus)) { // Call SetInfo to update the property on the object in the directory.
dwStatus = pObject->SetInfo(); } SysFreeString(bstrSD); } } } }
CleanExit: if (pDispACE) pDispACE->Release(); if (pDispDACL) pDispDACL->Release(); if (pACE) pACE->Release(); if (pACL) pACL->Release(); if (pSD) pSD->Release(); if (NULL != bstrNameProp) SysFreeString(bstrNameProp); if (NULL != bstrSecID) SysFreeString(bstrSecID);
VariantClear(&varSD); return dwStatus;
}
static DWORD LicenseSetupWriteService( BOOL * fCreated ) //
// Create/modify service:
//
// lpServiceName = "LicenseService"
// lpDisplayName = "License Logging Service"
// dwServiceType = SERVICE_WIN32_OWN_PROCESS
// dwStartType = LanManServerInstalled ? SERVICE_AUTO_START : SERVICE_DISABLED
// dwErrorControl = SERVICE_ERROR_NORMAL
// lpBinaryPathName = "%SystemRoot%\\System32\\llssrv.exe"
// lpLoadOrderGroup = NULL
// lpdwTagId = NULL
// lpDependencies = NULL
// lpServiceStartName = NULL
// lpPassword = NULL
//
{ SC_HANDLE hSC; DWORD winStatus; DWORD dwRes = S_OK; IADs * pADs = NULL; VARIANT varSD; VariantInit(&varSD); BSTR bstrConfigCntnr = NULL;
*fCreated = FALSE;
hSC = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS );
if ( NULL == hSC ) { winStatus = GetLastError(); } else { HKEY hKeyLanmanServerParameters; DWORD dwStartType ; SC_HANDLE hLicenseService = NULL; TCHAR szServiceDisplayName[ 128 ] = TEXT( "License Logging" ); TCHAR szServiceDescription[1024] = TEXT(""); TCHAR szServiceStartName [] = TEXT("NT AUTHORITY\\NetworkService"); TCHAR szServicePassword[]=TEXT(""); SERVICE_DESCRIPTION svcDescription; QUERY_SERVICE_CONFIG* pConfig = NULL; DWORD cbBytesNeeded = 0; BOOL frt; DWORD dwDesiredAccess = SERVICE_ALL_ACCESS;
// enable service iff LanmanServer was installed
winStatus = RegOpenKeyEx( HKEY_LOCAL_MACHINE, TEXT( "SYSTEM\\CurrentControlSet\\Services\\LanmanServer\\Parameters" ), 0, KEY_READ, &hKeyLanmanServerParameters );
if ( ERROR_SUCCESS == winStatus ) { //
// BUG# 559376
// LLS is now disabled by default on clean installs
//
dwStartType = SERVICE_DISABLED; //dwStartType = SERVICE_AUTO_START;
hLicenseService = OpenService( hSC, TEXT( "LicenseService"), dwDesiredAccess );
if( hLicenseService != NULL ) { cbBytesNeeded = sizeof(QUERY_SERVICE_CONFIG) + 4096;
pConfig = (LPQUERY_SERVICE_CONFIG) LocalAlloc( LPTR, cbBytesNeeded ); if ( pConfig != NULL ) {
frt = ::QueryServiceConfig( hLicenseService, pConfig, cbBytesNeeded, &cbBytesNeeded ); if ( frt ) { dwStartType = pConfig->dwStartType; }
LocalFree ( pConfig ) ; } CloseServiceHandle( hLicenseService ); }
RegCloseKey( hKeyLanmanServerParameters ); } else { dwStartType = SERVICE_DISABLED; }
LoadString( g_hinst, IDS_SERVICE_DISPLAY_NAME, szServiceDisplayName, sizeof( szServiceDisplayName ) / sizeof( *szServiceDisplayName ) );
LoadString( g_hinst, IDS_SERVICE_DESCRIPTION, szServiceDescription, sizeof( szServiceDescription ) / sizeof( *szServiceDescription ) );
svcDescription.lpDescription = szServiceDescription;
hLicenseService = CreateService( hSC, TEXT( "LicenseService" ), szServiceDisplayName, // 14659: needed to call ChangeConfig2 later
SERVICE_CHANGE_CONFIG, SERVICE_WIN32_OWN_PROCESS, dwStartType, SERVICE_ERROR_NORMAL, TEXT( "%SystemRoot%\\System32\\llssrv.exe" ), NULL, NULL, NULL, szServiceStartName, szServicePassword );
if ( NULL != hLicenseService ) { // service successfully created
ChangeServiceConfig2( hLicenseService, SERVICE_CONFIG_DESCRIPTION, &svcDescription );
CloseServiceHandle( hLicenseService );
winStatus = ERROR_SUCCESS; *fCreated = TRUE; } else { winStatus = GetLastError();
if ( ERROR_SERVICE_EXISTS == winStatus ) { // service already exists; change configuration of existing service
hLicenseService = OpenService( hSC, TEXT( "LicenseService" ), SERVICE_CHANGE_CONFIG );
if ( NULL == hLicenseService ) { winStatus = GetLastError(); } else { SC_LOCK scLock; BOOL ok;
scLock = LockServiceDatabase( hSC ); // continue even if we can't lock the database
ok = ChangeServiceConfig( hLicenseService, SERVICE_WIN32_OWN_PROCESS, dwStartType, SERVICE_ERROR_NORMAL, TEXT( "%SystemRoot%\\System32\\llssrv.exe" ), NULL, NULL, NULL, szServiceStartName, szServicePassword, szServiceDisplayName );
if ( !ok ) { winStatus = GetLastError(); } else { ChangeServiceConfig2( hLicenseService, SERVICE_CONFIG_DESCRIPTION, &svcDescription);
winStatus = ERROR_SUCCESS; }
if ( NULL != scLock ) { UnlockServiceDatabase( scLock ); }
CloseServiceHandle( hLicenseService ); } } }
CloseServiceHandle( hSC ); }
CreateDirectoryWithAccess();
CreateFileWithAccess();
HideAppletIfBlade();
dwRes = ADsGetObject(ROOT_DSE_PATH, IID_IADs, (void **)&pADs);
if (FAILED(dwRes)) { goto CleanExit; }
bstrConfigCntnr = SysAllocString(CONFIG_CNTNR); if (NULL == bstrConfigCntnr) { dwRes = ERROR_OUTOFMEMORY; goto CleanExit; }
dwRes = pADs->Get(bstrConfigCntnr, &varSD); if (FAILED(dwRes)) { goto CleanExit; }
dwRes = SetRight( pADs, // IADs pointer to the object
ADS_RIGHT_DS_READ_PROP | ADS_RIGHT_DS_WRITE_PROP, ADS_ACETYPE_ACCESS_ALLOWED_OBJECT, ADS_ACEFLAG_INHERIT_ACE, L"{1be8f17d-a9ff-11d0-afe2-00c04fd930c9}", NULL // no inherited object type GUID
);
CleanExit: if(pADs) pADs->Release();
if (NULL != bstrConfigCntnr) SysFreeString(bstrConfigCntnr);
VariantClear(&varSD);
ModifyRegistryWithWriteAccess();
return winStatus; }
void ModifyRegistryWithWriteAccess() {
DWORD winStatus = 0; PACL pNewDacl1 = NULL; PACL pOldDacl1 = NULL; PACL pNewDacl2 = NULL; PACL pOldDacl2 = NULL; PSECURITY_DESCRIPTOR pSD1 = NULL; PSECURITY_DESCRIPTOR pSD2 = NULL; PSID pSid = NULL; BOOL bFlag = FALSE; EXPLICIT_ACCESS ExplicitEntries; SID_IDENTIFIER_AUTHORITY ntSidAuthority = SECURITY_NT_AUTHORITY;
// Creating new EXPLICIT_ACCESS structure to set on the directory
ZeroMemory( &ExplicitEntries, sizeof(ExplicitEntries) );
bFlag = AllocateAndInitializeSid( &ntSidAuthority, 1, SECURITY_NETWORK_SERVICE_RID,0, 0, 0, 0, 0, 0, 0, &pSid );
if ( !bFlag || (pSid == NULL) ) {
goto cleanup; }
BuildTrusteeWithSid( &ExplicitEntries.Trustee, pSid );
ExplicitEntries.grfInheritance = SUB_CONTAINERS_AND_OBJECTS_INHERIT; ExplicitEntries.grfAccessMode = SET_ACCESS; ExplicitEntries.grfAccessPermissions = KEY_READ|KEY_WRITE; ExplicitEntries.Trustee.TrusteeForm = TRUSTEE_IS_SID; ExplicitEntries.Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
if( GetNamedSecurityInfoW( LICENSEINFO_PATH, SE_REGISTRY_KEY, DACL_SECURITY_INFORMATION, NULL, // psidOwner
NULL, // psidGroup
&pOldDacl1, // pDacl
NULL, // pSacl
&pSD1 ) != ERROR_SUCCESS) {
goto cleanup; }
//
// Set the Acl with the ExplicitEntry rights
//
if( SetEntriesInAcl( 1, &ExplicitEntries, pOldDacl1, &pNewDacl1 ) != ERROR_SUCCESS) { goto cleanup; }
//
// SET security on the Directory
//
winStatus = SetNamedSecurityInfo( LICENSEINFO_PATH, // object name
SE_REGISTRY_KEY , // object type
DACL_SECURITY_INFORMATION | UNPROTECTED_DACL_SECURITY_INFORMATION , // type
NULL, // new owner SID
NULL, // new primary group SID
pNewDacl1, // new DACL
NULL // new SACL
);
if( GetNamedSecurityInfoW( LICENSESERVICE_PATH, SE_REGISTRY_KEY, DACL_SECURITY_INFORMATION, NULL, // psidOwner
NULL, // psidGroup
&pOldDacl2, // pDacl
NULL, // pSacl
&pSD2 ) != ERROR_SUCCESS) {
goto cleanup; }
//
// Set the Acl with the ExplicitEntry rights
//
if( SetEntriesInAcl( 1, &ExplicitEntries, pOldDacl2, &pNewDacl2 ) != ERROR_SUCCESS) { goto cleanup; }
//
// SET security on the Directory
//
winStatus = SetNamedSecurityInfo( LICENSESERVICE_PATH, // object name
SE_REGISTRY_KEY , // object type
DACL_SECURITY_INFORMATION | UNPROTECTED_DACL_SECURITY_INFORMATION , // type
NULL, // new owner SID
NULL, // new primary group SID
pNewDacl2, // new DACL
NULL // new SACL
); cleanup: if(pSid) { LocalFree( pSid ); } if(pSD1) { LocalFree(pSD1); pSD1 = NULL; }
if(pNewDacl1) { LocalFree(pNewDacl1); pNewDacl1 = NULL; } if(pSD2) { LocalFree(pSD2); pSD2 = NULL; }
if(pNewDacl2) { LocalFree(pNewDacl2); pNewDacl2 = NULL; } }
void HideAppletIfBlade() { OSVERSIONINFOEX ovi; HRESULT hr = S_OK; HKEY hKey = NULL; DWORD dwVal;
ovi.dwOSVersionInfoSize = sizeof(ovi); if (GetVersionEx((OSVERSIONINFO *) &ovi)) { if( ovi.wSuiteMask & VER_SUITE_BLADE ) { hr = RegCreateKeyEx( HKEY_LOCAL_MACHINE, DONTLOAD_PATH, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS , NULL, &hKey, &dwVal);
if(ERROR_SUCCESS == hr) { TCHAR szValue[] = L""; DWORD cbName = (lstrlen(szValue)+ 1) * sizeof(TCHAR); hr = RegSetValueEx( hKey , L"Liccpa.cpl", NULL , REG_SZ, ( CONST LPBYTE )szValue , cbName ); }
if(NULL != hKey) { RegCloseKey(hKey); hKey = NULL; }
} } }
void CreateDirectoryWithAccess() { DWORD winStatus = 0; TCHAR tchWinDirPath[MAX_PATH+1] = L""; PACL pNewDacl = NULL; PACL pOldDacl = NULL; PSECURITY_DESCRIPTOR pSD = NULL; TCHAR tchLLSDirPath[ MAX_PATH +1] = L""; BOOL bFlag = FALSE; PSID pSid = NULL; EXPLICIT_ACCESS ExplicitEntries; SID_IDENTIFIER_AUTHORITY ntSidAuthority = SECURITY_NT_AUTHORITY; HRESULT hr;
winStatus = GetSystemWindowsDirectory( tchWinDirPath , MAX_PATH+1); if(winStatus == 0) { goto cleanup; }
hr = StringCbCopy(tchLLSDirPath, sizeof(tchLLSDirPath), tchWinDirPath); if (S_OK != hr) return; hr = StringCbCat( tchLLSDirPath, sizeof(tchLLSDirPath), L"\\system32\\lls" ); if (S_OK != hr) return; // Creating new EXPLICIT_ACCESS structure to set on the directory
ZeroMemory( &ExplicitEntries, sizeof(ExplicitEntries) );
bFlag = AllocateAndInitializeSid( &ntSidAuthority, 1, SECURITY_NETWORK_SERVICE_RID,0, 0, 0, 0, 0, 0, 0, &pSid );
if ( !bFlag || (pSid == NULL) ) {
goto cleanup; }
BuildTrusteeWithSid( &ExplicitEntries.Trustee, pSid );
ExplicitEntries.grfInheritance = SUB_CONTAINERS_AND_OBJECTS_INHERIT; ExplicitEntries.grfAccessMode = SET_ACCESS; ExplicitEntries.grfAccessPermissions = FILE_ALL_ACCESS; ExplicitEntries.Trustee.TrusteeForm = TRUSTEE_IS_SID; ExplicitEntries.Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
bFlag = CreateDirectory( tchLLSDirPath, NULL );
if ( !bFlag ) {
winStatus = GetLastError();
if (ERROR_ALREADY_EXISTS != winStatus) { goto cleanup; } }
if( GetNamedSecurityInfoW( tchLLSDirPath, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, NULL, // psidOwner
NULL, // psidGroup
&pOldDacl, // pDacl
NULL, // pSacl
&pSD ) != ERROR_SUCCESS) {
goto cleanup; }
//
// Set the Acl with the ExplicitEntry rights
//
if( SetEntriesInAcl( 1, &ExplicitEntries, pOldDacl, &pNewDacl ) != ERROR_SUCCESS) { goto cleanup; }
//
// SET security on the Directory
//
winStatus = SetNamedSecurityInfo( tchLLSDirPath, // object name
SE_FILE_OBJECT , // object type
DACL_SECURITY_INFORMATION | UNPROTECTED_DACL_SECURITY_INFORMATION , // type
NULL, // new owner SID
NULL, // new primary group SID
pNewDacl, // new DACL
NULL // new SACL
); cleanup: if(pSid) { LocalFree( pSid ); } if(pSD) { LocalFree(pSD); pSD = NULL; }
if(pNewDacl) { LocalFree(pNewDacl); pNewDacl = NULL; } }
void CreateFileWithAccess() { DWORD winStatus = 0; TCHAR tchWinDirPath[MAX_PATH+1] = L""; PACL pNewDacl = NULL; PACL pOldDacl = NULL; PSECURITY_DESCRIPTOR pSD = NULL; TCHAR tchCPLFilePath[ MAX_PATH+1 ] = L""; BOOL bFlag = FALSE; PSID pSid = NULL; EXPLICIT_ACCESS ExplicitEntries; SID_IDENTIFIER_AUTHORITY ntSidAuthority = SECURITY_NT_AUTHORITY; HANDLE hFile = NULL; HRESULT hr; winStatus = GetSystemWindowsDirectory( tchWinDirPath , MAX_PATH+1); if(winStatus == 0) { goto cleanup; } hr = StringCbCopy(tchCPLFilePath, sizeof(tchCPLFilePath), tchWinDirPath); if (S_OK != hr) return;
hr = StringCbCat( tchCPLFilePath , sizeof(tchCPLFilePath), L"\\system32\\cpl.cfg" ); if (S_OK != hr) return; // Creating new EXPLICIT_ACCESS structure to set on the file
ZeroMemory( &ExplicitEntries, sizeof(ExplicitEntries) );
bFlag = AllocateAndInitializeSid( &ntSidAuthority, 1, SECURITY_NETWORK_SERVICE_RID,0, 0, 0, 0, 0, 0, 0, &pSid );
if ( !bFlag || (pSid == NULL) ) {
goto cleanup; }
BuildTrusteeWithSid( &ExplicitEntries.Trustee, pSid );
ExplicitEntries.grfAccessMode = SET_ACCESS; ExplicitEntries.grfAccessPermissions = FILE_ALL_ACCESS; ExplicitEntries.Trustee.TrusteeForm = TRUSTEE_IS_SID; ExplicitEntries.Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
hFile = CreateFile(tchCPLFilePath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_ALWAYS, 0, NULL);
if(hFile == NULL) { winStatus = GetLastError();
if (winStatus != ERROR_ALREADY_EXISTS) { goto cleanup ; }
}
if( GetNamedSecurityInfoW( tchCPLFilePath, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, NULL, // psidOwner
NULL, // psidGroup
&pOldDacl, // pDacl
NULL, // pSacl
&pSD ) != ERROR_SUCCESS)
{ goto cleanup; }
//
// Set the Acl with the ExplicitEntry rights
//
if( SetEntriesInAcl( 1, &ExplicitEntries, pOldDacl, &pNewDacl ) != ERROR_SUCCESS) {
goto cleanup; }
//
// SET security on the File
//
winStatus = SetNamedSecurityInfo( tchCPLFilePath, // object name
SE_FILE_OBJECT , // object type
DACL_SECURITY_INFORMATION | UNPROTECTED_DACL_SECURITY_INFORMATION , // type
NULL, // new owner SID
NULL, // new primary group SID
pNewDacl, // new DACL
NULL // new SACL
);
cleanup:
if(hFile) { CloseHandle(hFile); } if(pSid) { LocalFree( pSid ); } if(pSD) { LocalFree(pSD); pSD = NULL; }
if(pNewDacl) { LocalFree(pNewDacl); pNewDacl = NULL; } }
static int MessageBoxFromStringID( HWND hwndParent, UINT uTextID, UINT uCaptionID, UINT uType ) //
// Same as MessageBox(), except Text and Caption are string resources
// instead of string pointers.
//
{ int nButton; TCHAR szText[ 1024 ]; TCHAR szCaption[ 64 ];
LoadString( g_hinst, uTextID, szText, sizeof( szText ) / sizeof( *szText ) ); LoadString( g_hinst, uCaptionID, szCaption, sizeof( szCaption ) / sizeof( *szCaption ) );
nButton = MessageBox( hwndParent, szText, szCaption, uType );
return nButton; }
|