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.
2359 lines
68 KiB
2359 lines
68 KiB
/*++
|
|
|
|
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;
|
|
}
|
|
|
|
|
|
|