Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2359 lines
68 KiB

  1. /*++
  2. Copyright (c) 1996 Microsoft Corporation.
  3. All rights reserved
  4. Module Name:
  5. licsetup.cpp
  6. Abstract:
  7. This module exports a function, LicenseSetupRequestWizardPages, which
  8. gives NT Setup a wizard page for licensing to use in system setup (if
  9. licensing should be installed).
  10. This wizard page is responsible for all license system configuration,
  11. including:
  12. o Creating the LicenseService
  13. o Creating the ...\CurrentControlSet\Services\LicenseService key and
  14. its values. (This key contains all configuration information for the
  15. LicenseService.)
  16. o Creating the ...\CurrentControlSet\Services\LicenseInfo key and its
  17. values. (This key contains all product-specific license info.)
  18. o Creating the appropriate registry key to register the LicenseService
  19. with the EventLog.
  20. Portions of this module were extracted from SETUP (specifically from
  21. \nt\private\windows\setup\syssetup\license.c).
  22. Author:
  23. Jeff Parham (jeffparh) 15-Apr-1996
  24. Revision History:
  25. Jeff Parham (jeffparh) 17-Jul-1997
  26. Added KSecDD to FilePrint services table for SFM
  27. --*/
  28. #include <windows.h>
  29. #include <commctrl.h>
  30. #include <setupapi.h>
  31. #include <syssetup.h>
  32. #include <setupbat.h>
  33. #include <stdlib.h>
  34. #include <htmlhelp.h>
  35. #include <Accctrl.h>
  36. #include <aclapi.h>
  37. #include "liccpa.hpp"
  38. #include "help.hpp"
  39. #include "clicreg.hpp"
  40. #include "config.hpp"
  41. #include "resource.h"
  42. #include "pridlgs.hpp"
  43. #include "special.hpp"
  44. #include <objbase.h>
  45. #include <iads.h>
  46. #include <ole2.h>
  47. #include <oaidl.h>
  48. #include <adshlp.h>
  49. #include <strsafe.h>
  50. #define ROOT_DSE_PATH L"LDAP://RootDSE"
  51. #define CONFIG_CNTNR L"ConfigurationNamingContext"
  52. //============================================================================
  53. //
  54. // MACROS
  55. //
  56. // used by setup tests? simulates a click on the NEXT button
  57. #define WM_SIMULATENEXT ( WM_USER + 287 )
  58. // begin or end a wait cursor
  59. #define WM_BEGINWAITCURSOR ( WM_USER + 300 )
  60. #define WM_ENDWAITCURSOR ( WM_USER + 301 )
  61. #define LICENSEINFO_PATH TEXT("MACHINE\\SYSTEM\\CurrentControlSet\\Services\\LicenseInfo")
  62. #define LICENSESERVICE_PATH TEXT("MACHINE\\SYSTEM\\CurrentControlSet\\Services\\LicenseService\\Parameters")
  63. #define DONTLOAD_PATH TEXT("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Control Panel\\don't load")
  64. // number of license wizard pages
  65. const DWORD NUM_LICENSE_PAGES = 1;
  66. // limits for per server licenses entered from the edit box in the
  67. // license mode page
  68. const int PERSERVER_EDIT_MAX = 9999;
  69. const int PERSERVER_EDIT_MIN = 5;
  70. // the number of chars to represent PERSERVER_EDIT_MAX
  71. const int PERSERVER_EDIT_WIDTH = 4;
  72. //============================================================================
  73. //
  74. // LOCAL PROTOTYPES
  75. //
  76. // decides, based on the setup type, whether licensing is installed
  77. static BOOL LicenseSetupDisplayLicensePagesQuery( PINTERNAL_SETUP_DATA );
  78. // License mode page functions
  79. static HPROPSHEETPAGE LicenseSetupModePageGet( PINTERNAL_SETUP_DATA );
  80. static INT_PTR CALLBACK LicenseSetupModeDlgProc( HWND, UINT, WPARAM, LPARAM );
  81. // License mode page Windows message handlers
  82. static void LicenseSetupModeOnInitDialog( HWND, LPARAM, PINTERNAL_SETUP_DATA *, LPBOOL, LPDWORD, LPDWORD );
  83. static void LicenseSetupModeOnSetActive( HWND, PINTERNAL_SETUP_DATA, LPBOOL, LPDWORD );
  84. static void LicenseSetupModeOnSetLicenseMode( HWND, BOOL, DWORD );
  85. static void LicenseSetupModeOnEditUpdate( HWND, HWND, BOOL, LPDWORD );
  86. static void LicenseSetupModeOnWaitCursor( HWND, BOOL, LPDWORD );
  87. static BOOL LicenseSetupModeOnSetCursor( HWND, WORD, DWORD );
  88. static void LicenseSetupModeOnNext( HWND, PINTERNAL_SETUP_DATA, BOOL, DWORD );
  89. static void LicenseSetupModeOnHelp( HWND );
  90. static void LicenseSetupModeOnSimulateNext( HWND );
  91. static void LicenseSetupModeOnKillActive( HWND );
  92. #ifndef SPECIAL_USERS
  93. static BOOL LicenseSetupModeDoUnattended( HWND, PINTERNAL_SETUP_DATA, LPBOOL, LPDWORD );
  94. #endif //SPECIAL_USERS
  95. // License configuration save functions
  96. static DWORD LicenseSetupWrite( BOOL, DWORD );
  97. static DWORD LicenseSetupWriteKeyLicenseInfo( BOOL, DWORD );
  98. static DWORD LicenseSetupWriteKeyLicenseService( BOOL fWriteParametersKey );
  99. static DWORD LicenseSetupWriteKeyEventLog();
  100. static DWORD LicenseSetupWriteService( BOOL * fCreated );
  101. // utility functions
  102. static int MessageBoxFromStringID( HWND, UINT, UINT, UINT );
  103. void CreateDirectoryWithAccess();
  104. void CreateFileWithAccess();
  105. void HideAppletIfBlade();
  106. static DWORD SetRight( IADs *, LONG, LONG, LONG, LPOLESTR, LPOLESTR );
  107. void ModifyRegistryWithWriteAccess();
  108. BOOL IsRestrictedSmallBusSrv( void );
  109. #define SBS_SPECIAL_USERS 10
  110. //============================================================================
  111. //
  112. // GLOBAL IMPLEMENTATION
  113. //
  114. BOOL
  115. APIENTRY
  116. LicenseSetupRequestWizardPages(
  117. HPROPSHEETPAGE * paPropSheetPages,
  118. UINT * pcPages,
  119. PINTERNAL_SETUP_DATA pSetupData )
  120. {
  121. BOOL fSuccess = FALSE;
  122. BOOL fDisplayLicensePages;
  123. // validate params
  124. if ( ( NULL != pcPages )
  125. && ( NULL != pSetupData )
  126. && ( sizeof( INTERNAL_SETUP_DATA ) == pSetupData->dwSizeOf ) )
  127. {
  128. fDisplayLicensePages = LicenseSetupDisplayLicensePagesQuery( pSetupData );
  129. if ( NULL == paPropSheetPages )
  130. {
  131. // request for number of pages only
  132. *pcPages = fDisplayLicensePages ? NUM_LICENSE_PAGES : 0;
  133. fSuccess = TRUE;
  134. }
  135. else
  136. {
  137. // request for actual pages
  138. if ( !fDisplayLicensePages )
  139. {
  140. // no pages needed
  141. *pcPages = 0;
  142. fSuccess = TRUE;
  143. }
  144. else if ( *pcPages >= NUM_LICENSE_PAGES )
  145. {
  146. // create and return pages
  147. paPropSheetPages[ 0 ] = LicenseSetupModePageGet( pSetupData );
  148. if ( NULL != paPropSheetPages[ 0 ] )
  149. {
  150. *pcPages = NUM_LICENSE_PAGES;
  151. fSuccess = TRUE;
  152. }
  153. }
  154. }
  155. }
  156. return fSuccess;
  157. }
  158. //============================================================================
  159. //
  160. // LOCAL IMPLEMENTATIONS
  161. //
  162. static
  163. BOOL
  164. LicenseSetupDisplayLicensePagesQuery(
  165. PINTERNAL_SETUP_DATA pSetupData )
  166. //
  167. // The following code was extracted and modified from
  168. // \nt\private\windows\setup\syssetup\license.c
  169. // in setup. It returns TRUE iff the licensing wizard pages should be
  170. // displayed as a part of setup.
  171. //
  172. {
  173. BOOL fDisplayLicensePages;
  174. if ( PRODUCT_WORKSTATION == pSetupData->ProductType )
  175. {
  176. //
  177. // If installing a workstation, then do not display the licensing page
  178. //
  179. fDisplayLicensePages = FALSE;
  180. }
  181. else
  182. {
  183. if ( !( pSetupData->OperationFlags & SETUPOPER_NTUPGRADE ) )
  184. {
  185. //
  186. // The licensing page needs to be displayed on a clean install
  187. // of a server
  188. //
  189. fDisplayLicensePages = TRUE;
  190. }
  191. else
  192. {
  193. //
  194. // If upgrading a server, find out if it was already licensed
  195. // (NT 3.51 and later). If it was, then do not display the
  196. // licensing page.
  197. // We find out whether or not the system was licensed by looking
  198. // at a value entry in the registry.
  199. // Note that NT 3.1 and 3.5 will never have this value in the
  200. // registry, and in these cases the licensing page needs to be
  201. // displayed.
  202. //
  203. DWORD winStatus;
  204. CLicRegLicenseService FilePrintService( FILEPRINT_SERVICE_REG_KEY );
  205. winStatus = FilePrintService.Open( NULL, FALSE );
  206. if ( ERROR_SUCCESS != winStatus )
  207. {
  208. fDisplayLicensePages = TRUE;
  209. }
  210. else
  211. {
  212. LICENSE_MODE LicenseMode;
  213. winStatus = FilePrintService.GetMode( LicenseMode );
  214. if ( ( ERROR_SUCCESS != winStatus )
  215. || ( ( LICMODE_PERSEAT != LicenseMode )
  216. && ( LICMODE_PERSERVER != LicenseMode ) ) )
  217. {
  218. fDisplayLicensePages = TRUE;
  219. }
  220. else
  221. {
  222. // set FlipAllow value if it's not already set (a setup bug in
  223. // the betas of NT 4.0 caused this value to be absent)
  224. FilePrintService.CanChangeMode();
  225. // add KSecDD to FilePrint services table if it isn't there already
  226. HKEY hkeySFM;
  227. DWORD dwDisposition;
  228. winStatus = RegCreateKeyEx( HKEY_LOCAL_MACHINE,
  229. TEXT( "System\\CurrentControlSet\\Services\\LicenseService\\FilePrint\\KSecDD" ),
  230. 0,
  231. NULL,
  232. 0,
  233. KEY_ALL_ACCESS,
  234. NULL,
  235. &hkeySFM,
  236. &dwDisposition );
  237. if ( ERROR_SUCCESS == winStatus )
  238. {
  239. RegCloseKey( hkeySFM );
  240. }
  241. // Change FilePrint License name from Windows NT to Windows.
  242. CLicRegLicenseService l_FilePrintService(
  243. FILEPRINT_SERVICE_REG_KEY );
  244. winStatus = l_FilePrintService.Open( NULL, FALSE );
  245. if ( ERROR_SUCCESS == winStatus )
  246. {
  247. winStatus = l_FilePrintService.SetFamilyDisplayName(
  248. FILEPRINT_SERVICE_FAMILY_DISPLAY_NAME );
  249. if ( ERROR_SUCCESS == winStatus )
  250. {
  251. winStatus = l_FilePrintService.SetDisplayName(
  252. FILEPRINT_SERVICE_DISPLAY_NAME );
  253. }
  254. }
  255. //
  256. // makarp: setting fDisplayLicensePages to true is wrong, because in such case
  257. // the pages will be displayed, and the original settings will be lost.
  258. //
  259. // fDisplayLicensePages = TRUE;
  260. //
  261. // instead we do the stuff we want to explicitely here.
  262. //
  263. BOOL bFlag = FALSE;
  264. LicenseSetupWriteService(&bFlag);
  265. HideAppletIfBlade();
  266. CreateDirectoryWithAccess();
  267. CreateFileWithAccess();
  268. ModifyRegistryWithWriteAccess();
  269. fDisplayLicensePages = FALSE;
  270. }
  271. }
  272. }
  273. }
  274. return fDisplayLicensePages;
  275. }
  276. static
  277. HPROPSHEETPAGE
  278. LicenseSetupModePageGet(
  279. PINTERNAL_SETUP_DATA pSetupData )
  280. //
  281. // Returns an HPROPSHEETPAGE for the license mode wizard page, or
  282. // NULL if error.
  283. //
  284. {
  285. HPROPSHEETPAGE hpsp;
  286. PROPSHEETPAGE psp;
  287. TCHAR szHeader[256];
  288. TCHAR szSubHeader[512];
  289. psp.dwSize = sizeof( psp );
  290. psp.dwFlags = PSP_USETITLE | PSP_HASHELP | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE;
  291. psp.hInstance = g_hinst;
  292. psp.pszTemplate = MAKEINTRESOURCE( IDD_SETUP_LICENSE_MODE_PAGE );
  293. psp.hIcon = NULL;
  294. psp.pfnDlgProc = LicenseSetupModeDlgProc;
  295. psp.lParam = (LPARAM) pSetupData;
  296. psp.pszTitle = pSetupData->WizardTitle;
  297. szHeader[0] = L'\0';
  298. szSubHeader[0] = L'\0';
  299. LoadString( g_hinst,
  300. IDS_SETUP_HEADER,
  301. szHeader,
  302. sizeof( szHeader ) / sizeof( *szHeader ) );
  303. LoadString( g_hinst,
  304. IDS_SETUP_SUBHEADER,
  305. szSubHeader,
  306. sizeof( szSubHeader ) / sizeof( *szSubHeader ) );
  307. psp.pszHeaderTitle = szHeader;
  308. psp.pszHeaderSubTitle = szSubHeader;
  309. hpsp = CreatePropertySheetPage( &psp );
  310. return hpsp;
  311. }
  312. static
  313. INT_PTR
  314. CALLBACK
  315. LicenseSetupModeDlgProc(
  316. HWND hwndPage,
  317. UINT msg,
  318. WPARAM wParam,
  319. LPARAM lParam )
  320. //
  321. // Dialog procedure for the license mode wizard page.
  322. //
  323. {
  324. // static data initialized by WM_INITDIALOG
  325. static PINTERNAL_SETUP_DATA pSetupData = NULL;
  326. static BOOL fLicensePerServer;
  327. static DWORD cPerServerLicenses;
  328. static DWORD cWaitCursor;
  329. BOOL fReturn = TRUE;
  330. switch ( msg )
  331. {
  332. case WM_INITDIALOG:
  333. LicenseSetupModeOnInitDialog( hwndPage, lParam, &pSetupData, &fLicensePerServer, &cPerServerLicenses, &cWaitCursor );
  334. break;
  335. case WM_SIMULATENEXT:
  336. LicenseSetupModeOnSimulateNext( hwndPage );
  337. break;
  338. case WM_BEGINWAITCURSOR:
  339. LicenseSetupModeOnWaitCursor( hwndPage, TRUE, &cWaitCursor );
  340. break;
  341. case WM_ENDWAITCURSOR:
  342. LicenseSetupModeOnWaitCursor( hwndPage, FALSE, &cWaitCursor );
  343. break;
  344. case WM_SETCURSOR:
  345. LicenseSetupModeOnSetCursor( hwndPage, LOWORD( lParam ), cWaitCursor );
  346. break;
  347. case WM_COMMAND:
  348. switch ( HIWORD( wParam ) )
  349. {
  350. case BN_CLICKED:
  351. switch ( LOWORD( wParam ) )
  352. {
  353. case IDC_PERSEAT:
  354. fLicensePerServer = FALSE;
  355. LicenseSetupModeOnSetLicenseMode( hwndPage, fLicensePerServer, cPerServerLicenses );
  356. break;
  357. case IDC_PERSERVER:
  358. fLicensePerServer = TRUE;
  359. LicenseSetupModeOnSetLicenseMode( hwndPage, fLicensePerServer, cPerServerLicenses );
  360. break;
  361. }
  362. break;
  363. case EN_UPDATE:
  364. if ( IDC_USERCOUNT == LOWORD( wParam ) )
  365. {
  366. LicenseSetupModeOnEditUpdate( hwndPage, (HWND) lParam, fLicensePerServer, &cPerServerLicenses );
  367. }
  368. break;
  369. default:
  370. fReturn = FALSE;
  371. break;
  372. }
  373. break;
  374. case WM_NOTIFY:
  375. {
  376. NMHDR * pNmHdr;
  377. pNmHdr = (NMHDR *)lParam;
  378. switch ( pNmHdr->code )
  379. {
  380. case PSN_SETACTIVE:
  381. LicenseSetupModeOnSetActive( hwndPage, pSetupData, &fLicensePerServer, &cPerServerLicenses );
  382. break;
  383. case PSN_KILLACTIVE:
  384. LicenseSetupModeOnKillActive( hwndPage );
  385. break;
  386. case PSN_WIZNEXT:
  387. case PSN_WIZFINISH:
  388. LicenseSetupModeOnNext( hwndPage, pSetupData, fLicensePerServer, cPerServerLicenses );
  389. break;
  390. case PSN_HELP:
  391. LicenseSetupModeOnHelp( hwndPage );
  392. break;
  393. default:
  394. fReturn = FALSE;
  395. break;
  396. }
  397. }
  398. break;
  399. default:
  400. fReturn = FALSE;
  401. }
  402. return fReturn;
  403. }
  404. static
  405. void
  406. LicenseSetupModeOnInitDialog(
  407. HWND hwndPage,
  408. LPARAM lParam,
  409. PINTERNAL_SETUP_DATA * ppSetupData,
  410. LPBOOL pfLicensePerServer,
  411. LPDWORD pcPerServerLicenses,
  412. LPDWORD pcWaitCursor )
  413. //
  414. // Message handler for WM_INITDIALOG
  415. //
  416. {
  417. // initialize static data
  418. *ppSetupData = (PINTERNAL_SETUP_DATA) ( (LPPROPSHEETPAGE) lParam )->lParam;
  419. *pcPerServerLicenses = 5;
  420. *pfLicensePerServer = TRUE;
  421. *pcWaitCursor = 0;
  422. // limit license count edit text length
  423. SendMessage( GetDlgItem( hwndPage, IDC_USERCOUNT ), EM_LIMITTEXT, PERSERVER_EDIT_WIDTH, 0 );
  424. // limit license count up-down range
  425. LONG lRange;
  426. lRange = (LPARAM) MAKELONG( (short) PERSERVER_EDIT_MAX, (short) PERSERVER_EDIT_MIN );
  427. SendMessage( GetDlgItem( hwndPage, IDC_USERCOUNTARROW ), UDM_SETRANGE, 0, (LPARAM) lRange );
  428. // initialize for default license mode
  429. LicenseSetupModeOnSetLicenseMode( hwndPage, *pfLicensePerServer, *pcPerServerLicenses );
  430. }
  431. static
  432. void
  433. LicenseSetupModeOnSetActive(
  434. HWND hwndPage,
  435. PINTERNAL_SETUP_DATA pSetupData,
  436. LPBOOL pfLicensePerServer,
  437. LPDWORD pcPerServerLicenses )
  438. //
  439. // Notification handler for PSN_SETACTIVE
  440. //
  441. {
  442. static BOOL fFirstTime = TRUE;
  443. BOOL fSkipPage;
  444. OSVERSIONINFOEX ovi;
  445. BOOL fBlade = FALSE;
  446. ovi.dwOSVersionInfoSize = sizeof(ovi);
  447. if (GetVersionEx((OSVERSIONINFO *) &ovi))
  448. {
  449. if( ovi.wSuiteMask & VER_SUITE_BLADE )
  450. {
  451. fBlade = TRUE;
  452. }
  453. }
  454. #ifdef SPECIAL_USERS
  455. *pfLicensePerServer = TRUE;
  456. *pcPerServerLicenses = SPECIAL_USERS;
  457. fSkipPage = TRUE;
  458. #else
  459. if ( fBlade || IsRestrictedSmallBusSrv() )
  460. {
  461. *pfLicensePerServer = TRUE;
  462. *pcPerServerLicenses = SBS_SPECIAL_USERS;
  463. fSkipPage = TRUE;
  464. }
  465. else if ( pSetupData->OperationFlags & SETUPOPER_BATCH )
  466. {
  467. // operating in unattended mode; attempt to get all answers
  468. // from the unattend configuration file
  469. fSkipPage = LicenseSetupModeDoUnattended( hwndPage,
  470. pSetupData,
  471. pfLicensePerServer,
  472. pcPerServerLicenses );
  473. if ( !fSkipPage )
  474. {
  475. // Set defaults from unattended file
  476. LicenseSetupModeOnSetLicenseMode( hwndPage,
  477. *pfLicensePerServer,
  478. *pcPerServerLicenses );
  479. //
  480. // makarp: setting skippage to true is wrong, because we do not want to skip page.
  481. // we came here because we did not find sufficent answers in answer file.
  482. //
  483. // fSkipPage = TRUE;
  484. }
  485. }
  486. else
  487. {
  488. // operating in interactive mode; get answers from user
  489. fSkipPage = FALSE;
  490. }
  491. #endif
  492. HWND hwndSheet = GetParent( hwndPage );
  493. if ( fSkipPage )
  494. {
  495. if (fFirstTime)
  496. {
  497. fFirstTime = FALSE;
  498. // skip page
  499. // Only the first time do we need to do the processing which happens on next
  500. PostMessage( hwndSheet, PSM_PRESSBUTTON, (WPARAM)PSBTN_NEXT, 0 );
  501. }
  502. else
  503. {
  504. // After the first time the processing is already done and we don't have to do anything
  505. // This also solves the problem where the page needs to be skipped when the user clicks back
  506. // on a later page and this pages needs to be skipped.
  507. SetWindowLongPtr( hwndPage, DWLP_MSGRESULT, (LONG_PTR)-1 );
  508. return;
  509. }
  510. }
  511. else
  512. {
  513. // display page
  514. // hide Cancel button
  515. HWND hwndCancel = GetDlgItem( hwndSheet, IDCANCEL );
  516. EnableWindow( hwndCancel, FALSE);
  517. ShowWindow( hwndCancel, SW_HIDE);
  518. PropSheet_SetWizButtons( hwndSheet, PSWIZB_NEXT | PSWIZB_BACK );
  519. if (pSetupData)
  520. {
  521. pSetupData->ShowHideWizardPage(TRUE);
  522. }
  523. }
  524. // success
  525. SetWindowLongPtr( hwndPage, DWLP_MSGRESULT, (LONG_PTR)0 );
  526. }
  527. static
  528. void
  529. LicenseSetupModeOnSetLicenseMode(
  530. HWND hwndPage,
  531. BOOL fToPerServer,
  532. DWORD cPerServerLicenses )
  533. //
  534. // Handles changing the page to signify that the given license mode
  535. // is selected.
  536. //
  537. {
  538. HWND hwndCount = GetDlgItem( hwndPage, IDC_USERCOUNT );
  539. HWND hwndSpin = GetDlgItem( hwndPage, IDC_USERCOUNTARROW );
  540. // set radio button states
  541. CheckDlgButton( hwndPage, IDC_PERSEAT, !fToPerServer );
  542. CheckDlgButton( hwndPage, IDC_PERSERVER, fToPerServer );
  543. // set user count edit control
  544. if ( fToPerServer )
  545. {
  546. // display per server count
  547. SetDlgItemInt( hwndPage, IDC_USERCOUNT, cPerServerLicenses, FALSE );
  548. SetFocus( hwndCount );
  549. SendMessage( hwndCount, EM_SETSEL, 0, -1 );
  550. }
  551. else
  552. {
  553. // remove per server count
  554. SetDlgItemText( hwndPage, IDC_USERCOUNT, TEXT( "" ) );
  555. }
  556. // display count up-down and edit box iff per server mode is selected
  557. EnableWindow( hwndCount, fToPerServer );
  558. EnableWindow( hwndSpin, fToPerServer );
  559. }
  560. static
  561. void
  562. LicenseSetupModeOnEditUpdate(
  563. HWND hwndPage,
  564. HWND hwndCount,
  565. BOOL fLicensePerServer,
  566. LPDWORD pcPerServerLicenses )
  567. //
  568. // Command handler for EN_UPDATE of count edit box
  569. //
  570. {
  571. if ( fLicensePerServer )
  572. {
  573. BOOL fTranslated;
  574. UINT nValue;
  575. BOOL fModified = FALSE;
  576. nValue = GetDlgItemInt( hwndPage, IDC_USERCOUNT, &fTranslated, FALSE );
  577. if ( fTranslated )
  578. {
  579. // count translated; ensure its within the valid range
  580. if ( PERSERVER_EDIT_MAX < nValue )
  581. {
  582. // too big
  583. nValue = PERSERVER_EDIT_MAX;
  584. fModified = TRUE;
  585. }
  586. *pcPerServerLicenses = nValue;
  587. }
  588. else
  589. {
  590. // count couldn't be translated; reset to last value
  591. nValue = *pcPerServerLicenses;
  592. fModified = TRUE;
  593. }
  594. if ( fModified )
  595. {
  596. // text in edit box is invalid; change it to the proper value
  597. SetDlgItemInt( hwndPage, IDC_USERCOUNT, nValue, FALSE );
  598. SetFocus( hwndCount );
  599. SendMessage( hwndCount, EM_SETSEL, 0, -1 );
  600. MessageBeep( MB_VALUELIMIT );
  601. }
  602. }
  603. }
  604. static
  605. void
  606. LicenseSetupModeOnWaitCursor(
  607. HWND hwndDlg,
  608. BOOL fWait,
  609. LPDWORD pcWaitCursor )
  610. //
  611. // Handler for WM_BEGINWAITCURSOR / WM_ENDWAITCURSOR
  612. //
  613. {
  614. if ( fWait )
  615. {
  616. (*pcWaitCursor)++;
  617. if ( 1 == (*pcWaitCursor) )
  618. {
  619. // display wait cursor
  620. SetCursor( LoadCursor( NULL, MAKEINTRESOURCE( IDC_WAIT ) ) );
  621. }
  622. }
  623. else
  624. {
  625. if ( 0 < *pcWaitCursor )
  626. {
  627. (*pcWaitCursor)--;
  628. }
  629. if ( 0 == *pcWaitCursor )
  630. {
  631. // display regular cursor
  632. SetCursor( LoadCursor( NULL, MAKEINTRESOURCE( IDC_ARROW ) ) );
  633. }
  634. }
  635. // success
  636. SetWindowLongPtr( hwndDlg, DWLP_MSGRESULT, (LONG_PTR)*pcWaitCursor );
  637. }
  638. static
  639. BOOL
  640. LicenseSetupModeOnSetCursor(
  641. HWND hwndDlg,
  642. WORD nHitTest,
  643. DWORD cWaitCursor )
  644. //
  645. // Handler for WM_SETCURSOR
  646. //
  647. {
  648. BOOL frt = FALSE;
  649. if ( HTCLIENT == nHitTest )
  650. {
  651. if ( cWaitCursor > 0 )
  652. {
  653. // display wait cursor instead of regular cursor
  654. SetCursor( LoadCursor( NULL, MAKEINTRESOURCE( IDC_WAIT ) ) );
  655. SetWindowLongPtr( hwndDlg, DWLP_MSGRESULT, (LONG_PTR)TRUE );
  656. frt = TRUE;
  657. }
  658. }
  659. return frt;
  660. }
  661. static
  662. void
  663. LicenseSetupModeOnNext(
  664. HWND hwndPage,
  665. PINTERNAL_SETUP_DATA pSetupData,
  666. BOOL fLicensePerServer,
  667. DWORD cPerServerLicenses )
  668. //
  669. // Notification handler for PSN_WIZNEXT
  670. //
  671. {
  672. DWORD winStatus;
  673. int nButton;
  674. if ( ( fLicensePerServer )
  675. && ( PERSERVER_EDIT_MIN > cPerServerLicenses )
  676. && !( pSetupData->OperationFlags & SETUPOPER_BATCH ) )
  677. {
  678. // warn user about using per server mode with less then 5 licenses
  679. MessageBoxFromStringID( hwndPage,
  680. IDS_LICENSE_SETUP_NO_PER_SERVER_LICENSES,
  681. IDS_WARNING,
  682. MB_ICONERROR | MB_OK );
  683. nButton = IDCANCEL;
  684. }
  685. else
  686. {
  687. // per seat mode or per server mode with positive license count
  688. nButton = IDOK;
  689. }
  690. if ( IDOK == nButton )
  691. {
  692. do
  693. {
  694. // save license configuration
  695. SendMessage( hwndPage, WM_BEGINWAITCURSOR, 0, 0 );
  696. winStatus = LicenseSetupWrite( fLicensePerServer, cPerServerLicenses );
  697. SendMessage( hwndPage, WM_ENDWAITCURSOR, 0, 0 );
  698. if ( ERROR_SUCCESS != winStatus )
  699. {
  700. // save failed; alert user
  701. nButton = MessageBoxFromStringID( hwndPage,
  702. IDS_LICENSE_SETUP_SAVE_FAILED,
  703. IDS_ERROR,
  704. MB_ICONSTOP | MB_ABORTRETRYIGNORE | MB_DEFBUTTON2 );
  705. if ( IDIGNORE == nButton )
  706. {
  707. nButton = IDOK;
  708. }
  709. }
  710. else
  711. {
  712. // save succeeded
  713. nButton = IDOK;
  714. }
  715. } while ( IDRETRY == nButton );
  716. }
  717. if ( IDOK != nButton )
  718. {
  719. // don't advance to next page
  720. SetWindowLongPtr( hwndPage, DWLP_MSGRESULT, (LONG_PTR)-1 );
  721. }
  722. }
  723. static
  724. void
  725. LicenseSetupModeOnHelp(
  726. HWND hwndPage )
  727. //
  728. // Notification handler for PSN_HELP
  729. //
  730. {
  731. ::HtmlHelp( hwndPage, LICCPA_HTMLHELPFILE, HH_DISPLAY_TOPIC,0);
  732. }
  733. static
  734. void
  735. LicenseSetupModeOnSimulateNext(
  736. HWND hwndPage )
  737. //
  738. // Handler for WM_SIMULATENEXT (used by setup tests?)
  739. //
  740. {
  741. // simulate the next button
  742. PropSheet_PressButton( GetParent( hwndPage ), PSBTN_NEXT );
  743. }
  744. static
  745. void
  746. LicenseSetupModeOnKillActive(
  747. HWND hwndPage )
  748. //
  749. // Notification handler for PSN_KILLACTIVE
  750. //
  751. {
  752. // success
  753. SetWindowLong( hwndPage, DWLP_MSGRESULT, 0);
  754. }
  755. typedef enum {
  756. UnattendFullUnattend,
  757. UnattendGUIAttended,
  758. UnattendDefaultHide,
  759. UnattendProvideDefault,
  760. UnattendReadOnly } UNATTENDMODE;
  761. #ifndef SPECIAL_USERS
  762. static
  763. BOOL
  764. LicenseSetupModeDoUnattended(
  765. HWND hwndPage,
  766. PINTERNAL_SETUP_DATA pSetupData,
  767. LPBOOL pfLicensePerServer,
  768. LPDWORD pcPerServerLicenses )
  769. //
  770. // Get answers to wizard page from unattend file.
  771. //
  772. {
  773. int cch;
  774. LPTSTR pszBadParam;
  775. TCHAR szLicenseMode[ 64 ];
  776. TCHAR szPerServerLicenses[ 64 ];
  777. TCHAR szUnattendMode[ 64 ];
  778. UNATTENDMODE UnattendMode = UnattendDefaultHide;
  779. pszBadParam = NULL;
  780. SendMessage( hwndPage, WM_BEGINWAITCURSOR, 0, 0 );
  781. // Get Unattend Mode
  782. cch = GetPrivateProfileString( WINNT_UNATTENDED,
  783. WINNT_U_UNATTENDMODE,
  784. TEXT( "" ),
  785. szUnattendMode,
  786. sizeof( szUnattendMode ) / sizeof( *szUnattendMode ),
  787. pSetupData->UnattendFile );
  788. if ( 0 < cch )
  789. {
  790. if ( !lstrcmpi( szUnattendMode, WINNT_A_FULLUNATTENDED ) )
  791. {
  792. UnattendMode = UnattendFullUnattend;
  793. }
  794. else if ( !lstrcmpi( szUnattendMode, WINNT_A_PROVIDEDEFAULT ) )
  795. {
  796. UnattendMode = UnattendProvideDefault;
  797. }
  798. else if ( !lstrcmpi( szUnattendMode, WINNT_A_READONLY ) )
  799. {
  800. UnattendMode = UnattendReadOnly;
  801. }
  802. else if ( !lstrcmpi( szUnattendMode, WINNT_A_GUIATTENDED ) )
  803. {
  804. // This should never happen
  805. UnattendMode = UnattendGUIAttended;
  806. }
  807. }
  808. // get license mode
  809. cch = GetPrivateProfileString( WINNT_LICENSEDATA_W,
  810. WINNT_L_AUTOMODE_W,
  811. TEXT( "" ),
  812. szLicenseMode,
  813. sizeof( szLicenseMode ) / sizeof( *szLicenseMode ),
  814. pSetupData->UnattendFile );
  815. SendMessage( hwndPage, WM_ENDWAITCURSOR, 0, 0 );
  816. if ( 0 < cch )
  817. {
  818. if ( !lstrcmpi( szLicenseMode, WINNT_A_PERSEAT_W ) )
  819. {
  820. *pfLicensePerServer = FALSE;
  821. }
  822. else if ( !lstrcmpi( szLicenseMode, WINNT_A_PERSERVER_W ) )
  823. {
  824. *pfLicensePerServer = TRUE;
  825. }
  826. else
  827. {
  828. cch = 0;
  829. }
  830. }
  831. if ( cch <= 0 )
  832. {
  833. // license mode absent or invalid
  834. pszBadParam = WINNT_L_AUTOMODE_W;
  835. }
  836. else if ( !*pfLicensePerServer )
  837. {
  838. // per seat mode; no need to read per server license count
  839. *pcPerServerLicenses = 0;
  840. }
  841. else
  842. {
  843. // get per server license count
  844. SendMessage( hwndPage, WM_BEGINWAITCURSOR, 0, 0 );
  845. cch = GetPrivateProfileString( WINNT_LICENSEDATA_W,
  846. WINNT_L_AUTOUSERS_W,
  847. TEXT( "" ),
  848. szPerServerLicenses,
  849. sizeof( szPerServerLicenses ) / sizeof( *szPerServerLicenses ),
  850. pSetupData->UnattendFile );
  851. SendMessage( hwndPage, WM_ENDWAITCURSOR, 0, 0 );
  852. if ( 0 < cch )
  853. {
  854. *pcPerServerLicenses = wcstoul( szPerServerLicenses, NULL, 10 );
  855. if ( ( PERSERVER_EDIT_MIN > *pcPerServerLicenses )
  856. || ( PERSERVER_EDIT_MAX < *pcPerServerLicenses ) )
  857. {
  858. // Don't let things go without setting a valid server license
  859. // count.
  860. *pcPerServerLicenses = PERSERVER_EDIT_MIN;
  861. cch = 0;
  862. }
  863. }
  864. if ( cch <= 0 )
  865. {
  866. // per server license count absent or invalid
  867. pszBadParam = WINNT_L_AUTOUSERS_W;
  868. }
  869. }
  870. //
  871. // Do not display the error message on preinstall.
  872. //
  873. if ( NULL != pszBadParam &&
  874. !(pSetupData->OperationFlags & (SETUPOPER_PREINSTALL | SETUPOPER_NTUPGRADE)) &&
  875. UnattendMode == UnattendFullUnattend )
  876. {
  877. // encountered a bad unattended parameter; display error
  878. TCHAR szCaption[ 64 ];
  879. TCHAR szFormat[ 1024 ];
  880. TCHAR szText[ 1024 ];
  881. LoadString( g_hinst,
  882. IDS_LICENSE_SETUP_BAD_UNATTEND_PARAM,
  883. szFormat,
  884. sizeof( szFormat ) / sizeof( *szFormat ) );
  885. LoadString( g_hinst,
  886. IDS_ERROR,
  887. szCaption,
  888. sizeof( szCaption ) / sizeof( *szCaption ) );
  889. HRESULT hr = StringCbPrintf( szText, sizeof(szText), szFormat, pszBadParam );
  890. if (SUCCEEDED(hr))
  891. MessageBox( hwndPage,
  892. szText,
  893. szCaption,
  894. MB_OK | MB_ICONSTOP );
  895. }
  896. // If just providing defaults, return FALSE to force the page to show
  897. if ( UnattendMode == UnattendProvideDefault )
  898. return ( FALSE );
  899. return ( NULL == pszBadParam );
  900. }
  901. #endif //SPECIAL_USERS
  902. static
  903. DWORD
  904. LicenseSetupWrite(
  905. BOOL fLicensePerServer,
  906. DWORD cPerServerLicenses )
  907. //
  908. // Write license configuration; returns ERROR_SUCCESS or Windows error.
  909. //
  910. {
  911. DWORD winStatus;
  912. BOOL fCreated = TRUE; // TRUE if service entry is created
  913. // Used to determine if we should create
  914. // the parameters key or leave it alone.
  915. winStatus = LicenseSetupWriteService( &fCreated );
  916. if ( ERROR_SUCCESS == winStatus )
  917. {
  918. winStatus = LicenseSetupWriteKeyLicenseInfo( fLicensePerServer,
  919. cPerServerLicenses );
  920. if ( ERROR_SUCCESS == winStatus )
  921. {
  922. winStatus = LicenseSetupWriteKeyLicenseService( fCreated );
  923. if ( ERROR_SUCCESS == winStatus )
  924. {
  925. winStatus = LicenseSetupWriteKeyEventLog();
  926. }
  927. }
  928. }
  929. return winStatus;
  930. }
  931. static
  932. DWORD
  933. LicenseSetupWriteKeyLicenseInfo(
  934. BOOL fLicensePerServer,
  935. DWORD cPerServerLicenses )
  936. //
  937. // Create registry values:
  938. //
  939. // HKEY_LOCAL_MACHINE
  940. // \System
  941. // \CurrentControlSet
  942. // \Services
  943. // \LicenseInfo
  944. // ErrorControl : REG_DWORD : 1
  945. // Start : REG_DWORD : 3
  946. // Type : REG_DWORD : 4
  947. // \FilePrint
  948. // ConcurrentLimit : REG_DWORD : fLicensePerServer ? cPerServerLicenses : 0
  949. // DisplayName : REG_SZ : "Windows Server"
  950. // FamilyDisplayName : REG_SZ : "Windows Server"
  951. // Mode : REG_DWORD : fLicensePerServer ? 1 : 0
  952. // FlipAllow : REG_DWORD : fLicensePerServer ? 1 : 0
  953. //
  954. {
  955. DWORD winStatus;
  956. BOOL fCreatedNewServiceList;
  957. CLicRegLicense ServiceList;
  958. winStatus = ServiceList.Open( fCreatedNewServiceList );
  959. if ( ERROR_SUCCESS == winStatus )
  960. {
  961. CLicRegLicenseService FilePrintService( FILEPRINT_SERVICE_REG_KEY );
  962. winStatus = FilePrintService.Open( NULL, TRUE );
  963. if ( ERROR_SUCCESS == winStatus )
  964. {
  965. LICENSE_MODE lm;
  966. lm = fLicensePerServer ? LICMODE_PERSERVER : LICMODE_PERSEAT;
  967. winStatus = FilePrintService.SetMode( lm );
  968. if ( ERROR_SUCCESS == winStatus )
  969. {
  970. winStatus = FilePrintService.SetUserLimit( fLicensePerServer ? cPerServerLicenses : 0 );
  971. if ( ERROR_SUCCESS == winStatus )
  972. {
  973. winStatus = FilePrintService.SetChangeFlag( fLicensePerServer );
  974. if ( ERROR_SUCCESS == winStatus )
  975. {
  976. winStatus = FilePrintService.SetFamilyDisplayName( FILEPRINT_SERVICE_FAMILY_DISPLAY_NAME );
  977. if ( ERROR_SUCCESS == winStatus )
  978. {
  979. winStatus = FilePrintService.SetDisplayName( FILEPRINT_SERVICE_DISPLAY_NAME );
  980. }
  981. }
  982. }
  983. }
  984. }
  985. }
  986. return winStatus;
  987. }
  988. static
  989. DWORD
  990. LicenseSetupWriteKeyLicenseService( BOOL fWriteParametersKey )
  991. //
  992. // Create registry values:
  993. //
  994. // HKEY_LOCAL_MACHINE
  995. // \System
  996. // \CurrentControlSet
  997. // \Services
  998. // \LicenseService
  999. // \FilePrint
  1000. // \KSecDD
  1001. // \MSAfpSrv
  1002. // \SMBServer
  1003. // \TCP/IP Print Server
  1004. // \Parameters
  1005. // UseEnterprise : REG_DWORD : 0
  1006. // ReplicationType : REG_DWORD : 0
  1007. // ReplicationTime : REG_DWORD : 24 * 60 * 60
  1008. // EnterpriseServer : REG_SZ : ""
  1009. //
  1010. {
  1011. DWORD winStatus;
  1012. HKEY hKeyLicenseService;
  1013. DWORD dwKeyCreateDisposition;
  1014. // create LicenseInfo key
  1015. winStatus = RegCreateKeyEx( HKEY_LOCAL_MACHINE,
  1016. LICENSE_SERVICE_REG_KEY,
  1017. 0,
  1018. NULL,
  1019. 0,
  1020. KEY_ALL_ACCESS,
  1021. NULL,
  1022. &hKeyLicenseService,
  1023. &dwKeyCreateDisposition );
  1024. if ( ERROR_SUCCESS == winStatus )
  1025. {
  1026. HKEY hKeyFilePrint;
  1027. // create FilePrint key
  1028. winStatus = RegCreateKeyEx( hKeyLicenseService,
  1029. TEXT( "FilePrint" ),
  1030. 0,
  1031. NULL,
  1032. 0,
  1033. KEY_ALL_ACCESS,
  1034. NULL,
  1035. &hKeyFilePrint,
  1036. &dwKeyCreateDisposition );
  1037. if ( ERROR_SUCCESS == winStatus )
  1038. {
  1039. const LPCTSTR apszFilePrintSubkeys[] =
  1040. {
  1041. TEXT( "KSecDD" ),
  1042. TEXT( "MSAfpSrv" ),
  1043. TEXT( "SMBServer" ),
  1044. TEXT( "TCP/IP Print Server" ),
  1045. NULL
  1046. };
  1047. HKEY hKeyFilePrintSubkey;
  1048. DWORD iSubkey;
  1049. for ( iSubkey = 0; NULL != apszFilePrintSubkeys[ iSubkey ]; iSubkey++ )
  1050. {
  1051. winStatus = RegCreateKeyEx( hKeyFilePrint,
  1052. apszFilePrintSubkeys[ iSubkey ],
  1053. 0,
  1054. NULL,
  1055. 0,
  1056. KEY_ALL_ACCESS,
  1057. NULL,
  1058. &hKeyFilePrintSubkey,
  1059. &dwKeyCreateDisposition );
  1060. if ( ERROR_SUCCESS == winStatus )
  1061. {
  1062. RegCloseKey( hKeyFilePrintSubkey );
  1063. }
  1064. else
  1065. {
  1066. break;
  1067. }
  1068. }
  1069. RegCloseKey( hKeyFilePrint );
  1070. }
  1071. RegCloseKey( hKeyLicenseService );
  1072. }
  1073. //
  1074. // Only write the Parameters key if the service was just created. That is,
  1075. // this is not an upgrade
  1076. //
  1077. if ( fWriteParametersKey && (ERROR_SUCCESS == winStatus) )
  1078. {
  1079. HKEY hKeyParameters;
  1080. // create Parameters key
  1081. winStatus = RegCreateKeyEx( HKEY_LOCAL_MACHINE,
  1082. szLicenseKey, // const
  1083. 0,
  1084. NULL,
  1085. 0,
  1086. KEY_ALL_ACCESS,
  1087. NULL,
  1088. &hKeyParameters,
  1089. &dwKeyCreateDisposition );
  1090. if ( ERROR_SUCCESS == winStatus )
  1091. {
  1092. // create LicenseService\Parameters values
  1093. winStatus = RegSetValueEx( hKeyParameters,
  1094. szUseEnterprise, // const
  1095. 0,
  1096. REG_DWORD,
  1097. (CONST BYTE *) &dwUseEnterprise, // const
  1098. sizeof( dwUseEnterprise ) );
  1099. if ( ERROR_SUCCESS == winStatus )
  1100. {
  1101. winStatus = RegSetValueEx( hKeyParameters,
  1102. szReplicationType, // const
  1103. 0,
  1104. REG_DWORD,
  1105. (CONST BYTE *) &dwReplicationType, // const
  1106. sizeof( dwReplicationType ) );
  1107. if ( ERROR_SUCCESS == winStatus )
  1108. {
  1109. winStatus = RegSetValueEx( hKeyParameters,
  1110. szReplicationTime, // const
  1111. 0,
  1112. REG_DWORD,
  1113. (CONST BYTE *) &dwReplicationTimeInSec, // const
  1114. sizeof( dwReplicationTimeInSec ) );
  1115. if ( ERROR_SUCCESS == winStatus )
  1116. {
  1117. LPCTSTR pszEnterpriseServer = TEXT( "" );
  1118. winStatus = RegSetValueEx( hKeyParameters,
  1119. szEnterpriseServer, // const
  1120. 0,
  1121. REG_SZ,
  1122. (CONST BYTE *) pszEnterpriseServer,
  1123. ( 1 + lstrlen( pszEnterpriseServer ) ) * sizeof( *pszEnterpriseServer ) );
  1124. }
  1125. }
  1126. }
  1127. RegCloseKey( hKeyParameters );
  1128. }
  1129. }
  1130. ModifyRegistryWithWriteAccess();
  1131. return winStatus;
  1132. }
  1133. static
  1134. DWORD
  1135. LicenseSetupWriteKeyEventLog()
  1136. //
  1137. // Create registry values:
  1138. //
  1139. // HKEY_LOCAL_MACHINE
  1140. // \System
  1141. // \CurrentControlSet
  1142. // \Services
  1143. // \EventLog
  1144. // \Application
  1145. // \LicenseService
  1146. // EventMessageFile : REG_EXPAND_SZ : %SystemRoot%\System32\llsrpc.dll
  1147. // TypesSupported : REG_DWORD : 7
  1148. //
  1149. {
  1150. DWORD winStatus;
  1151. HKEY hKeyLicenseService;
  1152. DWORD dwKeyCreateDisposition;
  1153. // create LicenseService key
  1154. winStatus = RegCreateKeyEx( HKEY_LOCAL_MACHINE,
  1155. TEXT( "System\\CurrentControlSet\\Services\\EventLog\\Application\\LicenseService" ),
  1156. 0,
  1157. NULL,
  1158. 0,
  1159. KEY_ALL_ACCESS,
  1160. NULL,
  1161. &hKeyLicenseService,
  1162. &dwKeyCreateDisposition );
  1163. if ( ERROR_SUCCESS == winStatus )
  1164. {
  1165. LPCTSTR pszEventMessageFile = TEXT( "%SystemRoot%\\System32\\llsrpc.dll" );
  1166. const DWORD dwTypesSupported = ( EVENTLOG_ERROR_TYPE
  1167. | EVENTLOG_WARNING_TYPE
  1168. | EVENTLOG_INFORMATION_TYPE );
  1169. winStatus = RegSetValueEx( hKeyLicenseService,
  1170. TEXT( "TypesSupported" ),
  1171. 0,
  1172. REG_DWORD,
  1173. (CONST BYTE *) &dwTypesSupported,
  1174. sizeof( dwTypesSupported ) );
  1175. if ( ERROR_SUCCESS == winStatus )
  1176. {
  1177. winStatus = RegSetValueEx( hKeyLicenseService,
  1178. TEXT( "EventMessageFile" ),
  1179. 0,
  1180. REG_SZ,
  1181. (CONST BYTE *) pszEventMessageFile,
  1182. ( 1 + lstrlen( pszEventMessageFile ) ) * sizeof( *pszEventMessageFile ) );
  1183. }
  1184. RegCloseKey( hKeyLicenseService );
  1185. }
  1186. return winStatus;
  1187. }
  1188. static
  1189. DWORD SetRight(
  1190. IADs *pObject,
  1191. long lAccessMask,
  1192. long lAccessType,
  1193. long lAccessInheritFlags,
  1194. LPOLESTR szObjectGUID,
  1195. LPOLESTR szInheritedObjectGUID)
  1196. {
  1197. VARIANT varSD;
  1198. DWORD dwStatus = S_OK;
  1199. IDispatch *pDispDACL = NULL;
  1200. IDispatch *pDispACE = NULL;
  1201. IADsAccessControlList *pACL = NULL;
  1202. IADsSecurityDescriptor *pSD = NULL;
  1203. IADsAccessControlEntry *pACE = NULL;
  1204. long lFlags = 0L;
  1205. BSTR bstrNameProp = NULL;
  1206. BSTR bstrSecID = NULL;
  1207. if ( !pObject)
  1208. {
  1209. dwStatus = (DWORD)E_INVALIDARG;
  1210. goto CleanExit;
  1211. }
  1212. VariantClear(&varSD);
  1213. // Get the nTSecurityDescriptor.
  1214. // Type should be VT_DISPATCH--an IDispatch ptr to the security descriptor object.
  1215. bstrNameProp = SysAllocString(L"nTSecurityDescriptor");
  1216. if (NULL == bstrNameProp)
  1217. {
  1218. dwStatus = ERROR_OUTOFMEMORY;
  1219. goto CleanExit;
  1220. }
  1221. dwStatus = pObject->Get(bstrNameProp, &varSD);
  1222. if ( FAILED(dwStatus) || varSD.vt != VT_DISPATCH ) {
  1223. return dwStatus;
  1224. }
  1225. dwStatus = V_DISPATCH(&varSD)->QueryInterface(IID_IADsSecurityDescriptor,(void**)&pSD);
  1226. if ( FAILED(dwStatus) ) {
  1227. goto CleanExit;
  1228. }
  1229. // Get the DACL.
  1230. dwStatus = pSD->get_DiscretionaryAcl(&pDispDACL);
  1231. if (SUCCEEDED(dwStatus))
  1232. dwStatus = pDispDACL->QueryInterface(IID_IADsAccessControlList,(void**)&pACL);
  1233. if ( FAILED(dwStatus) ) {
  1234. goto CleanExit;
  1235. }
  1236. // Create the COM object for the new ACE.
  1237. dwStatus = CoCreateInstance(
  1238. CLSID_AccessControlEntry,
  1239. NULL,
  1240. CLSCTX_INPROC_SERVER,
  1241. IID_IADsAccessControlEntry,
  1242. (void **)&pACE
  1243. );
  1244. if ( FAILED(dwStatus) ) {
  1245. goto CleanExit;
  1246. }
  1247. dwStatus = pACE->put_AccessMask(lAccessMask );
  1248. if ( FAILED(dwStatus) ) {
  1249. goto CleanExit;
  1250. }
  1251. bstrSecID = SysAllocString(TEXT("NT AUTHORITY\\NetworkService"));
  1252. if (NULL == bstrSecID)
  1253. {
  1254. dwStatus = ERROR_OUTOFMEMORY;
  1255. goto CleanExit;
  1256. }
  1257. dwStatus = pACE->put_Trustee(bstrSecID);
  1258. if ( FAILED(dwStatus) ) {
  1259. goto CleanExit;
  1260. }
  1261. dwStatus = pACE->put_AceType(lAccessType );
  1262. if ( FAILED(dwStatus) ) {
  1263. goto CleanExit;
  1264. }
  1265. dwStatus = pACE->put_AceFlags(lAccessInheritFlags );
  1266. if ( FAILED(dwStatus) ) {
  1267. goto CleanExit;
  1268. }
  1269. // If an szObjectGUID is specified, add ADS_FLAG_OBJECT_TYPE_PRESENT
  1270. // to the lFlags mask and set the ObjectType.
  1271. if (szObjectGUID)
  1272. {
  1273. BSTR bstrObjectGUID = SysAllocString(szObjectGUID);
  1274. if (NULL != bstrObjectGUID)
  1275. {
  1276. lFlags |= ADS_FLAG_OBJECT_TYPE_PRESENT;
  1277. dwStatus = pACE->put_ObjectType(bstrObjectGUID);
  1278. SysFreeString(bstrObjectGUID);
  1279. }
  1280. }
  1281. // If an szInheritedObjectGUID is specified, add ADS_FLAG_INHERITED_OBJECT_TYPE_PRESENT
  1282. // to the lFlags mask and set the InheritedObjectType.
  1283. if (SUCCEEDED(dwStatus) && szInheritedObjectGUID)
  1284. {
  1285. BSTR bstrInheritedObjectGUID = SysAllocString(szInheritedObjectGUID);
  1286. if (NULL != bstrInheritedObjectGUID)
  1287. {
  1288. lFlags |= ADS_FLAG_INHERITED_OBJECT_TYPE_PRESENT;
  1289. dwStatus = pACE->put_InheritedObjectType(bstrInheritedObjectGUID );
  1290. SysFreeString(bstrInheritedObjectGUID);
  1291. }
  1292. }
  1293. // Set flags if ObjectType or InheritedObjectType were set.
  1294. if (SUCCEEDED(dwStatus) && lFlags)
  1295. dwStatus = pACE->put_Flags(lFlags);
  1296. // Add the ACE to the ACL to the SD to the cache to the object.
  1297. // Need to QI for the IDispatch pointer to pass to the AddAce method.
  1298. dwStatus = pACE->QueryInterface(IID_IDispatch, (void**)&pDispACE);
  1299. if (SUCCEEDED(dwStatus))
  1300. {
  1301. dwStatus = pACL->AddAce(pDispACE);
  1302. if (SUCCEEDED(dwStatus))
  1303. {
  1304. // Write the DACL
  1305. dwStatus = pSD->put_DiscretionaryAcl(pDispDACL);
  1306. if (SUCCEEDED(dwStatus))
  1307. {
  1308. // Write the ntSecurityDescriptor property to the property cache.
  1309. BSTR bstrSD = SysAllocString(L"nTSecurityDescriptor");
  1310. if (NULL != bstrSD)
  1311. {
  1312. dwStatus = pObject->Put(bstrSD, varSD);
  1313. if (SUCCEEDED(dwStatus))
  1314. {
  1315. // Call SetInfo to update the property on the object in the directory.
  1316. dwStatus = pObject->SetInfo();
  1317. }
  1318. SysFreeString(bstrSD);
  1319. }
  1320. }
  1321. }
  1322. }
  1323. CleanExit:
  1324. if (pDispACE)
  1325. pDispACE->Release();
  1326. if (pDispDACL)
  1327. pDispDACL->Release();
  1328. if (pACE)
  1329. pACE->Release();
  1330. if (pACL)
  1331. pACL->Release();
  1332. if (pSD)
  1333. pSD->Release();
  1334. if (NULL != bstrNameProp)
  1335. SysFreeString(bstrNameProp);
  1336. if (NULL != bstrSecID)
  1337. SysFreeString(bstrSecID);
  1338. VariantClear(&varSD);
  1339. return dwStatus;
  1340. }
  1341. static
  1342. DWORD
  1343. LicenseSetupWriteService( BOOL * fCreated )
  1344. //
  1345. // Create/modify service:
  1346. //
  1347. // lpServiceName = "LicenseService"
  1348. // lpDisplayName = "License Logging Service"
  1349. // dwServiceType = SERVICE_WIN32_OWN_PROCESS
  1350. // dwStartType = LanManServerInstalled ? SERVICE_AUTO_START : SERVICE_DISABLED
  1351. // dwErrorControl = SERVICE_ERROR_NORMAL
  1352. // lpBinaryPathName = "%SystemRoot%\\System32\\llssrv.exe"
  1353. // lpLoadOrderGroup = NULL
  1354. // lpdwTagId = NULL
  1355. // lpDependencies = NULL
  1356. // lpServiceStartName = NULL
  1357. // lpPassword = NULL
  1358. //
  1359. {
  1360. SC_HANDLE hSC;
  1361. DWORD winStatus;
  1362. DWORD dwRes = S_OK;
  1363. IADs * pADs = NULL;
  1364. VARIANT varSD;
  1365. VariantInit(&varSD);
  1366. BSTR bstrConfigCntnr = NULL;
  1367. *fCreated = FALSE;
  1368. hSC = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS );
  1369. if ( NULL == hSC )
  1370. {
  1371. winStatus = GetLastError();
  1372. }
  1373. else
  1374. {
  1375. HKEY hKeyLanmanServerParameters;
  1376. DWORD dwStartType ;
  1377. SC_HANDLE hLicenseService = NULL;
  1378. TCHAR szServiceDisplayName[ 128 ] = TEXT( "License Logging" );
  1379. TCHAR szServiceDescription[1024] = TEXT("");
  1380. TCHAR szServiceStartName [] = TEXT("NT AUTHORITY\\NetworkService");
  1381. TCHAR szServicePassword[]=TEXT("");
  1382. SERVICE_DESCRIPTION svcDescription;
  1383. QUERY_SERVICE_CONFIG* pConfig = NULL;
  1384. DWORD cbBytesNeeded = 0;
  1385. BOOL frt;
  1386. DWORD dwDesiredAccess = SERVICE_ALL_ACCESS;
  1387. // enable service iff LanmanServer was installed
  1388. winStatus = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
  1389. TEXT( "SYSTEM\\CurrentControlSet\\Services\\LanmanServer\\Parameters" ),
  1390. 0,
  1391. KEY_READ,
  1392. &hKeyLanmanServerParameters );
  1393. if ( ERROR_SUCCESS == winStatus )
  1394. {
  1395. //
  1396. // BUG# 559376
  1397. // LLS is now disabled by default on clean installs
  1398. //
  1399. dwStartType = SERVICE_DISABLED; //dwStartType = SERVICE_AUTO_START;
  1400. hLicenseService = OpenService( hSC, TEXT( "LicenseService"), dwDesiredAccess );
  1401. if( hLicenseService != NULL )
  1402. {
  1403. cbBytesNeeded = sizeof(QUERY_SERVICE_CONFIG) + 4096;
  1404. pConfig = (LPQUERY_SERVICE_CONFIG) LocalAlloc( LPTR, cbBytesNeeded );
  1405. if ( pConfig != NULL )
  1406. {
  1407. frt = ::QueryServiceConfig( hLicenseService,
  1408. pConfig,
  1409. cbBytesNeeded,
  1410. &cbBytesNeeded );
  1411. if ( frt )
  1412. {
  1413. dwStartType = pConfig->dwStartType;
  1414. }
  1415. LocalFree ( pConfig ) ;
  1416. }
  1417. CloseServiceHandle( hLicenseService );
  1418. }
  1419. RegCloseKey( hKeyLanmanServerParameters );
  1420. }
  1421. else
  1422. {
  1423. dwStartType = SERVICE_DISABLED;
  1424. }
  1425. LoadString( g_hinst,
  1426. IDS_SERVICE_DISPLAY_NAME,
  1427. szServiceDisplayName,
  1428. sizeof( szServiceDisplayName ) / sizeof( *szServiceDisplayName ) );
  1429. LoadString( g_hinst,
  1430. IDS_SERVICE_DESCRIPTION,
  1431. szServiceDescription,
  1432. sizeof( szServiceDescription ) / sizeof( *szServiceDescription ) );
  1433. svcDescription.lpDescription = szServiceDescription;
  1434. hLicenseService = CreateService( hSC,
  1435. TEXT( "LicenseService" ),
  1436. szServiceDisplayName,
  1437. // 14659: needed to call ChangeConfig2 later
  1438. SERVICE_CHANGE_CONFIG,
  1439. SERVICE_WIN32_OWN_PROCESS,
  1440. dwStartType,
  1441. SERVICE_ERROR_NORMAL,
  1442. TEXT( "%SystemRoot%\\System32\\llssrv.exe" ),
  1443. NULL,
  1444. NULL,
  1445. NULL,
  1446. szServiceStartName,
  1447. szServicePassword );
  1448. if ( NULL != hLicenseService )
  1449. {
  1450. // service successfully created
  1451. ChangeServiceConfig2( hLicenseService,
  1452. SERVICE_CONFIG_DESCRIPTION,
  1453. &svcDescription );
  1454. CloseServiceHandle( hLicenseService );
  1455. winStatus = ERROR_SUCCESS;
  1456. *fCreated = TRUE;
  1457. }
  1458. else
  1459. {
  1460. winStatus = GetLastError();
  1461. if ( ERROR_SERVICE_EXISTS == winStatus )
  1462. {
  1463. // service already exists; change configuration of existing service
  1464. hLicenseService = OpenService( hSC,
  1465. TEXT( "LicenseService" ),
  1466. SERVICE_CHANGE_CONFIG );
  1467. if ( NULL == hLicenseService )
  1468. {
  1469. winStatus = GetLastError();
  1470. }
  1471. else
  1472. {
  1473. SC_LOCK scLock;
  1474. BOOL ok;
  1475. scLock = LockServiceDatabase( hSC );
  1476. // continue even if we can't lock the database
  1477. ok = ChangeServiceConfig( hLicenseService,
  1478. SERVICE_WIN32_OWN_PROCESS,
  1479. dwStartType,
  1480. SERVICE_ERROR_NORMAL,
  1481. TEXT( "%SystemRoot%\\System32\\llssrv.exe" ),
  1482. NULL,
  1483. NULL,
  1484. NULL,
  1485. szServiceStartName,
  1486. szServicePassword,
  1487. szServiceDisplayName );
  1488. if ( !ok )
  1489. {
  1490. winStatus = GetLastError();
  1491. }
  1492. else
  1493. {
  1494. ChangeServiceConfig2( hLicenseService,
  1495. SERVICE_CONFIG_DESCRIPTION,
  1496. &svcDescription);
  1497. winStatus = ERROR_SUCCESS;
  1498. }
  1499. if ( NULL != scLock )
  1500. {
  1501. UnlockServiceDatabase( scLock );
  1502. }
  1503. CloseServiceHandle( hLicenseService );
  1504. }
  1505. }
  1506. }
  1507. CloseServiceHandle( hSC );
  1508. }
  1509. CreateDirectoryWithAccess();
  1510. CreateFileWithAccess();
  1511. HideAppletIfBlade();
  1512. dwRes = ADsGetObject(ROOT_DSE_PATH, IID_IADs, (void **)&pADs);
  1513. if (FAILED(dwRes)) {
  1514. goto CleanExit;
  1515. }
  1516. bstrConfigCntnr = SysAllocString(CONFIG_CNTNR);
  1517. if (NULL == bstrConfigCntnr)
  1518. {
  1519. dwRes = ERROR_OUTOFMEMORY;
  1520. goto CleanExit;
  1521. }
  1522. dwRes = pADs->Get(bstrConfigCntnr, &varSD);
  1523. if (FAILED(dwRes)) {
  1524. goto CleanExit;
  1525. }
  1526. dwRes = SetRight(
  1527. pADs, // IADs pointer to the object
  1528. ADS_RIGHT_DS_READ_PROP | ADS_RIGHT_DS_WRITE_PROP,
  1529. ADS_ACETYPE_ACCESS_ALLOWED_OBJECT,
  1530. ADS_ACEFLAG_INHERIT_ACE,
  1531. L"{1be8f17d-a9ff-11d0-afe2-00c04fd930c9}",
  1532. NULL // no inherited object type GUID
  1533. );
  1534. CleanExit:
  1535. if(pADs)
  1536. pADs->Release();
  1537. if (NULL != bstrConfigCntnr)
  1538. SysFreeString(bstrConfigCntnr);
  1539. VariantClear(&varSD);
  1540. ModifyRegistryWithWriteAccess();
  1541. return winStatus;
  1542. }
  1543. void ModifyRegistryWithWriteAccess()
  1544. {
  1545. DWORD winStatus = 0;
  1546. PACL pNewDacl1 = NULL;
  1547. PACL pOldDacl1 = NULL;
  1548. PACL pNewDacl2 = NULL;
  1549. PACL pOldDacl2 = NULL;
  1550. PSECURITY_DESCRIPTOR pSD1 = NULL;
  1551. PSECURITY_DESCRIPTOR pSD2 = NULL;
  1552. PSID pSid = NULL;
  1553. BOOL bFlag = FALSE;
  1554. EXPLICIT_ACCESS ExplicitEntries;
  1555. SID_IDENTIFIER_AUTHORITY ntSidAuthority = SECURITY_NT_AUTHORITY;
  1556. // Creating new EXPLICIT_ACCESS structure to set on the directory
  1557. ZeroMemory( &ExplicitEntries, sizeof(ExplicitEntries) );
  1558. bFlag = AllocateAndInitializeSid(
  1559. &ntSidAuthority,
  1560. 1,
  1561. SECURITY_NETWORK_SERVICE_RID,0,
  1562. 0, 0, 0, 0, 0, 0,
  1563. &pSid );
  1564. if ( !bFlag || (pSid == NULL) ) {
  1565. goto cleanup;
  1566. }
  1567. BuildTrusteeWithSid( &ExplicitEntries.Trustee, pSid );
  1568. ExplicitEntries.grfInheritance = SUB_CONTAINERS_AND_OBJECTS_INHERIT;
  1569. ExplicitEntries.grfAccessMode = SET_ACCESS;
  1570. ExplicitEntries.grfAccessPermissions = KEY_READ|KEY_WRITE;
  1571. ExplicitEntries.Trustee.TrusteeForm = TRUSTEE_IS_SID;
  1572. ExplicitEntries.Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
  1573. if( GetNamedSecurityInfoW( LICENSEINFO_PATH,
  1574. SE_REGISTRY_KEY,
  1575. DACL_SECURITY_INFORMATION,
  1576. NULL, // psidOwner
  1577. NULL, // psidGroup
  1578. &pOldDacl1, // pDacl
  1579. NULL, // pSacl
  1580. &pSD1 ) != ERROR_SUCCESS)
  1581. {
  1582. goto cleanup;
  1583. }
  1584. //
  1585. // Set the Acl with the ExplicitEntry rights
  1586. //
  1587. if( SetEntriesInAcl( 1,
  1588. &ExplicitEntries,
  1589. pOldDacl1,
  1590. &pNewDacl1 ) != ERROR_SUCCESS)
  1591. {
  1592. goto cleanup;
  1593. }
  1594. //
  1595. // SET security on the Directory
  1596. //
  1597. winStatus = SetNamedSecurityInfo(
  1598. LICENSEINFO_PATH, // object name
  1599. SE_REGISTRY_KEY , // object type
  1600. DACL_SECURITY_INFORMATION | UNPROTECTED_DACL_SECURITY_INFORMATION , // type
  1601. NULL, // new owner SID
  1602. NULL, // new primary group SID
  1603. pNewDacl1, // new DACL
  1604. NULL // new SACL
  1605. );
  1606. if( GetNamedSecurityInfoW( LICENSESERVICE_PATH,
  1607. SE_REGISTRY_KEY,
  1608. DACL_SECURITY_INFORMATION,
  1609. NULL, // psidOwner
  1610. NULL, // psidGroup
  1611. &pOldDacl2, // pDacl
  1612. NULL, // pSacl
  1613. &pSD2 ) != ERROR_SUCCESS)
  1614. {
  1615. goto cleanup;
  1616. }
  1617. //
  1618. // Set the Acl with the ExplicitEntry rights
  1619. //
  1620. if( SetEntriesInAcl( 1,
  1621. &ExplicitEntries,
  1622. pOldDacl2,
  1623. &pNewDacl2 ) != ERROR_SUCCESS)
  1624. {
  1625. goto cleanup;
  1626. }
  1627. //
  1628. // SET security on the Directory
  1629. //
  1630. winStatus = SetNamedSecurityInfo(
  1631. LICENSESERVICE_PATH, // object name
  1632. SE_REGISTRY_KEY , // object type
  1633. DACL_SECURITY_INFORMATION | UNPROTECTED_DACL_SECURITY_INFORMATION , // type
  1634. NULL, // new owner SID
  1635. NULL, // new primary group SID
  1636. pNewDacl2, // new DACL
  1637. NULL // new SACL
  1638. );
  1639. cleanup:
  1640. if(pSid)
  1641. {
  1642. LocalFree( pSid );
  1643. }
  1644. if(pSD1)
  1645. {
  1646. LocalFree(pSD1);
  1647. pSD1 = NULL;
  1648. }
  1649. if(pNewDacl1)
  1650. {
  1651. LocalFree(pNewDacl1);
  1652. pNewDacl1 = NULL;
  1653. }
  1654. if(pSD2)
  1655. {
  1656. LocalFree(pSD2);
  1657. pSD2 = NULL;
  1658. }
  1659. if(pNewDacl2)
  1660. {
  1661. LocalFree(pNewDacl2);
  1662. pNewDacl2 = NULL;
  1663. }
  1664. }
  1665. void HideAppletIfBlade()
  1666. {
  1667. OSVERSIONINFOEX ovi;
  1668. HRESULT hr = S_OK;
  1669. HKEY hKey = NULL;
  1670. DWORD dwVal;
  1671. ovi.dwOSVersionInfoSize = sizeof(ovi);
  1672. if (GetVersionEx((OSVERSIONINFO *) &ovi))
  1673. {
  1674. if( ovi.wSuiteMask & VER_SUITE_BLADE )
  1675. {
  1676. hr = RegCreateKeyEx( HKEY_LOCAL_MACHINE,
  1677. DONTLOAD_PATH,
  1678. 0,
  1679. NULL,
  1680. REG_OPTION_NON_VOLATILE,
  1681. KEY_ALL_ACCESS ,
  1682. NULL,
  1683. &hKey,
  1684. &dwVal);
  1685. if(ERROR_SUCCESS == hr)
  1686. {
  1687. TCHAR szValue[] = L"";
  1688. DWORD cbName = (lstrlen(szValue)+ 1) * sizeof(TCHAR);
  1689. hr = RegSetValueEx( hKey ,
  1690. L"Liccpa.cpl",
  1691. NULL ,
  1692. REG_SZ,
  1693. ( CONST LPBYTE )szValue ,
  1694. cbName );
  1695. }
  1696. if(NULL != hKey)
  1697. {
  1698. RegCloseKey(hKey);
  1699. hKey = NULL;
  1700. }
  1701. }
  1702. }
  1703. }
  1704. void CreateDirectoryWithAccess()
  1705. {
  1706. DWORD winStatus = 0;
  1707. TCHAR tchWinDirPath[MAX_PATH+1] = L"";
  1708. PACL pNewDacl = NULL;
  1709. PACL pOldDacl = NULL;
  1710. PSECURITY_DESCRIPTOR pSD = NULL;
  1711. TCHAR tchLLSDirPath[ MAX_PATH +1] = L"";
  1712. BOOL bFlag = FALSE;
  1713. PSID pSid = NULL;
  1714. EXPLICIT_ACCESS ExplicitEntries;
  1715. SID_IDENTIFIER_AUTHORITY ntSidAuthority = SECURITY_NT_AUTHORITY;
  1716. HRESULT hr;
  1717. winStatus = GetSystemWindowsDirectory( tchWinDirPath , MAX_PATH+1);
  1718. if(winStatus == 0)
  1719. {
  1720. goto cleanup;
  1721. }
  1722. hr = StringCbCopy(tchLLSDirPath, sizeof(tchLLSDirPath), tchWinDirPath);
  1723. if (S_OK != hr)
  1724. return;
  1725. hr = StringCbCat( tchLLSDirPath, sizeof(tchLLSDirPath), L"\\system32\\lls" );
  1726. if (S_OK != hr)
  1727. return;
  1728. // Creating new EXPLICIT_ACCESS structure to set on the directory
  1729. ZeroMemory( &ExplicitEntries, sizeof(ExplicitEntries) );
  1730. bFlag = AllocateAndInitializeSid(
  1731. &ntSidAuthority,
  1732. 1,
  1733. SECURITY_NETWORK_SERVICE_RID,0,
  1734. 0, 0, 0, 0, 0, 0,
  1735. &pSid );
  1736. if ( !bFlag || (pSid == NULL) ) {
  1737. goto cleanup;
  1738. }
  1739. BuildTrusteeWithSid( &ExplicitEntries.Trustee, pSid );
  1740. ExplicitEntries.grfInheritance = SUB_CONTAINERS_AND_OBJECTS_INHERIT;
  1741. ExplicitEntries.grfAccessMode = SET_ACCESS;
  1742. ExplicitEntries.grfAccessPermissions = FILE_ALL_ACCESS;
  1743. ExplicitEntries.Trustee.TrusteeForm = TRUSTEE_IS_SID;
  1744. ExplicitEntries.Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
  1745. bFlag = CreateDirectory( tchLLSDirPath, NULL );
  1746. if ( !bFlag )
  1747. {
  1748. winStatus = GetLastError();
  1749. if (ERROR_ALREADY_EXISTS != winStatus)
  1750. {
  1751. goto cleanup;
  1752. }
  1753. }
  1754. if( GetNamedSecurityInfoW( tchLLSDirPath,
  1755. SE_FILE_OBJECT,
  1756. DACL_SECURITY_INFORMATION,
  1757. NULL, // psidOwner
  1758. NULL, // psidGroup
  1759. &pOldDacl, // pDacl
  1760. NULL, // pSacl
  1761. &pSD ) != ERROR_SUCCESS)
  1762. {
  1763. goto cleanup;
  1764. }
  1765. //
  1766. // Set the Acl with the ExplicitEntry rights
  1767. //
  1768. if( SetEntriesInAcl( 1,
  1769. &ExplicitEntries,
  1770. pOldDacl,
  1771. &pNewDacl ) != ERROR_SUCCESS)
  1772. {
  1773. goto cleanup;
  1774. }
  1775. //
  1776. // SET security on the Directory
  1777. //
  1778. winStatus = SetNamedSecurityInfo(
  1779. tchLLSDirPath, // object name
  1780. SE_FILE_OBJECT , // object type
  1781. DACL_SECURITY_INFORMATION | UNPROTECTED_DACL_SECURITY_INFORMATION , // type
  1782. NULL, // new owner SID
  1783. NULL, // new primary group SID
  1784. pNewDacl, // new DACL
  1785. NULL // new SACL
  1786. );
  1787. cleanup:
  1788. if(pSid)
  1789. {
  1790. LocalFree( pSid );
  1791. }
  1792. if(pSD)
  1793. {
  1794. LocalFree(pSD);
  1795. pSD = NULL;
  1796. }
  1797. if(pNewDacl)
  1798. {
  1799. LocalFree(pNewDacl);
  1800. pNewDacl = NULL;
  1801. }
  1802. }
  1803. void CreateFileWithAccess()
  1804. {
  1805. DWORD winStatus = 0;
  1806. TCHAR tchWinDirPath[MAX_PATH+1] = L"";
  1807. PACL pNewDacl = NULL;
  1808. PACL pOldDacl = NULL;
  1809. PSECURITY_DESCRIPTOR pSD = NULL;
  1810. TCHAR tchCPLFilePath[ MAX_PATH+1 ] = L"";
  1811. BOOL bFlag = FALSE;
  1812. PSID pSid = NULL;
  1813. EXPLICIT_ACCESS ExplicitEntries;
  1814. SID_IDENTIFIER_AUTHORITY ntSidAuthority = SECURITY_NT_AUTHORITY;
  1815. HANDLE hFile = NULL;
  1816. HRESULT hr;
  1817. winStatus = GetSystemWindowsDirectory( tchWinDirPath , MAX_PATH+1);
  1818. if(winStatus == 0)
  1819. {
  1820. goto cleanup;
  1821. }
  1822. hr = StringCbCopy(tchCPLFilePath, sizeof(tchCPLFilePath), tchWinDirPath);
  1823. if (S_OK != hr)
  1824. return;
  1825. hr = StringCbCat( tchCPLFilePath , sizeof(tchCPLFilePath), L"\\system32\\cpl.cfg" );
  1826. if (S_OK != hr)
  1827. return;
  1828. // Creating new EXPLICIT_ACCESS structure to set on the file
  1829. ZeroMemory( &ExplicitEntries, sizeof(ExplicitEntries) );
  1830. bFlag = AllocateAndInitializeSid(
  1831. &ntSidAuthority,
  1832. 1,
  1833. SECURITY_NETWORK_SERVICE_RID,0,
  1834. 0, 0, 0, 0, 0, 0,
  1835. &pSid );
  1836. if ( !bFlag || (pSid == NULL) ) {
  1837. goto cleanup;
  1838. }
  1839. BuildTrusteeWithSid( &ExplicitEntries.Trustee, pSid );
  1840. ExplicitEntries.grfAccessMode = SET_ACCESS;
  1841. ExplicitEntries.grfAccessPermissions = FILE_ALL_ACCESS;
  1842. ExplicitEntries.Trustee.TrusteeForm = TRUSTEE_IS_SID;
  1843. ExplicitEntries.Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
  1844. hFile = CreateFile(tchCPLFilePath,
  1845. GENERIC_READ | GENERIC_WRITE,
  1846. FILE_SHARE_READ | FILE_SHARE_WRITE,
  1847. NULL,
  1848. OPEN_ALWAYS,
  1849. 0,
  1850. NULL);
  1851. if(hFile == NULL)
  1852. {
  1853. winStatus = GetLastError();
  1854. if (winStatus != ERROR_ALREADY_EXISTS) {
  1855. goto cleanup ;
  1856. }
  1857. }
  1858. if( GetNamedSecurityInfoW( tchCPLFilePath,
  1859. SE_FILE_OBJECT,
  1860. DACL_SECURITY_INFORMATION,
  1861. NULL, // psidOwner
  1862. NULL, // psidGroup
  1863. &pOldDacl, // pDacl
  1864. NULL, // pSacl
  1865. &pSD ) != ERROR_SUCCESS)
  1866. {
  1867. goto cleanup;
  1868. }
  1869. //
  1870. // Set the Acl with the ExplicitEntry rights
  1871. //
  1872. if( SetEntriesInAcl( 1,
  1873. &ExplicitEntries,
  1874. pOldDacl,
  1875. &pNewDacl ) != ERROR_SUCCESS)
  1876. {
  1877. goto cleanup;
  1878. }
  1879. //
  1880. // SET security on the File
  1881. //
  1882. winStatus = SetNamedSecurityInfo(
  1883. tchCPLFilePath, // object name
  1884. SE_FILE_OBJECT , // object type
  1885. DACL_SECURITY_INFORMATION | UNPROTECTED_DACL_SECURITY_INFORMATION , // type
  1886. NULL, // new owner SID
  1887. NULL, // new primary group SID
  1888. pNewDacl, // new DACL
  1889. NULL // new SACL
  1890. );
  1891. cleanup:
  1892. if(hFile)
  1893. {
  1894. CloseHandle(hFile);
  1895. }
  1896. if(pSid)
  1897. {
  1898. LocalFree( pSid );
  1899. }
  1900. if(pSD)
  1901. {
  1902. LocalFree(pSD);
  1903. pSD = NULL;
  1904. }
  1905. if(pNewDacl)
  1906. {
  1907. LocalFree(pNewDacl);
  1908. pNewDacl = NULL;
  1909. }
  1910. }
  1911. static
  1912. int
  1913. MessageBoxFromStringID(
  1914. HWND hwndParent,
  1915. UINT uTextID,
  1916. UINT uCaptionID,
  1917. UINT uType )
  1918. //
  1919. // Same as MessageBox(), except Text and Caption are string resources
  1920. // instead of string pointers.
  1921. //
  1922. {
  1923. int nButton;
  1924. TCHAR szText[ 1024 ];
  1925. TCHAR szCaption[ 64 ];
  1926. LoadString( g_hinst, uTextID, szText, sizeof( szText ) / sizeof( *szText ) );
  1927. LoadString( g_hinst, uCaptionID, szCaption, sizeof( szCaption ) / sizeof( *szCaption ) );
  1928. nButton = MessageBox( hwndParent, szText, szCaption, uType );
  1929. return nButton;
  1930. }