Source code of Windows XP (NT5)
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.

1874 lines
52 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. //============================================================================
  45. //
  46. // MACROS
  47. //
  48. // used by setup tests? simulates a click on the NEXT button
  49. #define WM_SIMULATENEXT ( WM_USER + 287 )
  50. // begin or end a wait cursor
  51. #define WM_BEGINWAITCURSOR ( WM_USER + 300 )
  52. #define WM_ENDWAITCURSOR ( WM_USER + 301 )
  53. // number of license wizard pages
  54. const DWORD NUM_LICENSE_PAGES = 1;
  55. // limits for per server licenses entered from the edit box in the
  56. // license mode page
  57. const int PERSERVER_EDIT_MAX = 9999;
  58. const int PERSERVER_EDIT_MIN = 5;
  59. // the number of chars to represent PERSERVER_EDIT_MAX
  60. const int PERSERVER_EDIT_WIDTH = 4;
  61. //============================================================================
  62. //
  63. // LOCAL PROTOTYPES
  64. //
  65. // decides, based on the setup type, whether licensing is installed
  66. static BOOL LicenseSetupDisplayLicensePagesQuery( PINTERNAL_SETUP_DATA );
  67. // License mode page functions
  68. static HPROPSHEETPAGE LicenseSetupModePageGet( PINTERNAL_SETUP_DATA );
  69. static INT_PTR CALLBACK LicenseSetupModeDlgProc( HWND, UINT, WPARAM, LPARAM );
  70. // License mode page Windows message handlers
  71. static void LicenseSetupModeOnInitDialog( HWND, LPARAM, PINTERNAL_SETUP_DATA *, LPBOOL, LPDWORD, LPDWORD );
  72. static void LicenseSetupModeOnSetActive( HWND, PINTERNAL_SETUP_DATA, LPBOOL, LPDWORD );
  73. static void LicenseSetupModeOnSetLicenseMode( HWND, BOOL, DWORD );
  74. static void LicenseSetupModeOnEditUpdate( HWND, HWND, BOOL, LPDWORD );
  75. static void LicenseSetupModeOnWaitCursor( HWND, BOOL, LPDWORD );
  76. static BOOL LicenseSetupModeOnSetCursor( HWND, WORD, DWORD );
  77. static void LicenseSetupModeOnNext( HWND, PINTERNAL_SETUP_DATA, BOOL, DWORD );
  78. static void LicenseSetupModeOnHelp( HWND );
  79. static void LicenseSetupModeOnSimulateNext( HWND );
  80. static void LicenseSetupModeOnKillActive( HWND );
  81. static BOOL LicenseSetupModeDoUnattended( HWND, PINTERNAL_SETUP_DATA, LPBOOL, LPDWORD );
  82. // License configuration save functions
  83. static DWORD LicenseSetupWrite( BOOL, DWORD );
  84. static DWORD LicenseSetupWriteKeyLicenseInfo( BOOL, DWORD );
  85. static DWORD LicenseSetupWriteKeyLicenseService( BOOL fWriteParametersKey );
  86. static DWORD LicenseSetupWriteKeyEventLog();
  87. static DWORD LicenseSetupWriteService( BOOL * fCreated );
  88. // utility functions
  89. static int MessageBoxFromStringID( HWND, UINT, UINT, UINT );
  90. void CreateDirectoryWithAccess();
  91. void CreateFileWithAccess();
  92. BOOL IsRestrictedSmallBusSrv( void );
  93. #define SBS_SPECIAL_USERS 10
  94. //============================================================================
  95. //
  96. // GLOBAL IMPLEMENTATION
  97. //
  98. BOOL
  99. APIENTRY
  100. LicenseSetupRequestWizardPages(
  101. HPROPSHEETPAGE * paPropSheetPages,
  102. UINT * pcPages,
  103. PINTERNAL_SETUP_DATA pSetupData )
  104. {
  105. BOOL fSuccess = FALSE;
  106. BOOL fDisplayLicensePages;
  107. // validate params
  108. if ( ( NULL != pcPages )
  109. && ( NULL != pSetupData )
  110. && ( sizeof( INTERNAL_SETUP_DATA ) == pSetupData->dwSizeOf ) )
  111. {
  112. fDisplayLicensePages = LicenseSetupDisplayLicensePagesQuery( pSetupData );
  113. if ( NULL == paPropSheetPages )
  114. {
  115. // request for number of pages only
  116. *pcPages = fDisplayLicensePages ? NUM_LICENSE_PAGES : 0;
  117. fSuccess = TRUE;
  118. }
  119. else
  120. {
  121. // request for actual pages
  122. if ( !fDisplayLicensePages )
  123. {
  124. // no pages needed
  125. *pcPages = 0;
  126. fSuccess = TRUE;
  127. }
  128. else if ( *pcPages >= NUM_LICENSE_PAGES )
  129. {
  130. // create and return pages
  131. paPropSheetPages[ 0 ] = LicenseSetupModePageGet( pSetupData );
  132. if ( NULL != paPropSheetPages[ 0 ] )
  133. {
  134. *pcPages = NUM_LICENSE_PAGES;
  135. fSuccess = TRUE;
  136. }
  137. }
  138. }
  139. }
  140. return fSuccess;
  141. }
  142. //============================================================================
  143. //
  144. // LOCAL IMPLEMENTATIONS
  145. //
  146. static
  147. BOOL
  148. LicenseSetupDisplayLicensePagesQuery(
  149. PINTERNAL_SETUP_DATA pSetupData )
  150. //
  151. // The following code was extracted and modified from
  152. // \nt\private\windows\setup\syssetup\license.c
  153. // in setup. It returns TRUE iff the licensing wizard pages should be
  154. // displayed as a part of setup.
  155. //
  156. {
  157. BOOL fDisplayLicensePages;
  158. if ( PRODUCT_WORKSTATION == pSetupData->ProductType )
  159. {
  160. //
  161. // If installing a workstation, then do not display the licensing page
  162. //
  163. fDisplayLicensePages = FALSE;
  164. }
  165. else
  166. {
  167. if ( !( pSetupData->OperationFlags & SETUPOPER_NTUPGRADE ) )
  168. {
  169. //
  170. // The licensing page needs to be displayed on a clean install
  171. // of a server
  172. //
  173. fDisplayLicensePages = TRUE;
  174. }
  175. else
  176. {
  177. //
  178. // If upgrading a server, find out if it was already licensed
  179. // (NT 3.51 and later). If it was, then do not display the
  180. // licensing page.
  181. // We find out whether or not the system was licensed by looking
  182. // at a value entry in the registry.
  183. // Note that NT 3.1 and 3.5 will never have this value in the
  184. // registry, and in these cases the licensing page needs to be
  185. // displayed.
  186. //
  187. DWORD winStatus;
  188. CLicRegLicenseService FilePrintService( FILEPRINT_SERVICE_REG_KEY );
  189. winStatus = FilePrintService.Open( NULL, FALSE );
  190. if ( ERROR_SUCCESS != winStatus )
  191. {
  192. fDisplayLicensePages = TRUE;
  193. }
  194. else
  195. {
  196. LICENSE_MODE LicenseMode;
  197. winStatus = FilePrintService.GetMode( LicenseMode );
  198. if ( ( ERROR_SUCCESS != winStatus )
  199. || ( ( LICMODE_PERSEAT != LicenseMode )
  200. && ( LICMODE_PERSERVER != LicenseMode ) ) )
  201. {
  202. fDisplayLicensePages = TRUE;
  203. }
  204. else
  205. {
  206. // set FlipAllow value if it's not already set (a setup bug in
  207. // the betas of NT 4.0 caused this value to be absent)
  208. FilePrintService.CanChangeMode();
  209. // add KSecDD to FilePrint services table if it isn't there already
  210. HKEY hkeySFM;
  211. DWORD dwDisposition;
  212. winStatus = RegCreateKeyEx( HKEY_LOCAL_MACHINE,
  213. TEXT( "System\\CurrentControlSet\\Services\\LicenseService\\FilePrint\\KSecDD" ),
  214. 0,
  215. NULL,
  216. 0,
  217. KEY_ALL_ACCESS,
  218. NULL,
  219. &hkeySFM,
  220. &dwDisposition );
  221. if ( ERROR_SUCCESS == winStatus )
  222. {
  223. RegCloseKey( hkeySFM );
  224. }
  225. // Change FilePrint License name from Windows NT to Windows.
  226. CLicRegLicenseService FilePrintService(
  227. FILEPRINT_SERVICE_REG_KEY );
  228. winStatus = FilePrintService.Open( NULL, FALSE );
  229. if ( ERROR_SUCCESS == winStatus )
  230. {
  231. winStatus = FilePrintService.SetFamilyDisplayName(
  232. FILEPRINT_SERVICE_FAMILY_DISPLAY_NAME );
  233. if ( ERROR_SUCCESS == winStatus )
  234. {
  235. winStatus = FilePrintService.SetDisplayName(
  236. FILEPRINT_SERVICE_DISPLAY_NAME );
  237. }
  238. }
  239. //
  240. // makarp: setting fDisplayLicensePages to true is wrong, because in such case
  241. // the pages will be displayed, and the original settings will be lost.
  242. //
  243. // fDisplayLicensePages = TRUE;
  244. //
  245. // instead we do the stuff we want to explicitely here.
  246. //
  247. BOOL bFlag = FALSE;
  248. LicenseSetupWriteService(&bFlag);
  249. CreateDirectoryWithAccess();
  250. CreateFileWithAccess();
  251. fDisplayLicensePages = FALSE;
  252. }
  253. }
  254. }
  255. }
  256. return fDisplayLicensePages;
  257. }
  258. static
  259. HPROPSHEETPAGE
  260. LicenseSetupModePageGet(
  261. PINTERNAL_SETUP_DATA pSetupData )
  262. //
  263. // Returns an HPROPSHEETPAGE for the license mode wizard page, or
  264. // NULL if error.
  265. //
  266. {
  267. HPROPSHEETPAGE hpsp;
  268. PROPSHEETPAGE psp;
  269. TCHAR szHeader[256];
  270. TCHAR szSubHeader[512];
  271. psp.dwSize = sizeof( psp );
  272. psp.dwFlags = PSP_USETITLE | PSP_HASHELP | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE;
  273. psp.hInstance = g_hinst;
  274. psp.pszTemplate = MAKEINTRESOURCE( IDD_SETUP_LICENSE_MODE_PAGE );
  275. psp.hIcon = NULL;
  276. psp.pfnDlgProc = LicenseSetupModeDlgProc;
  277. psp.lParam = (LPARAM) pSetupData;
  278. psp.pszTitle = pSetupData->WizardTitle;
  279. szHeader[0] = L'\0';
  280. szSubHeader[0] = L'\0';
  281. LoadString( g_hinst,
  282. IDS_SETUP_HEADER,
  283. szHeader,
  284. sizeof( szHeader ) / sizeof( *szHeader ) );
  285. LoadString( g_hinst,
  286. IDS_SETUP_SUBHEADER,
  287. szSubHeader,
  288. sizeof( szSubHeader ) / sizeof( *szSubHeader ) );
  289. psp.pszHeaderTitle = szHeader;
  290. psp.pszHeaderSubTitle = szSubHeader;
  291. hpsp = CreatePropertySheetPage( &psp );
  292. return hpsp;
  293. }
  294. static
  295. INT_PTR
  296. CALLBACK
  297. LicenseSetupModeDlgProc(
  298. HWND hwndPage,
  299. UINT msg,
  300. WPARAM wParam,
  301. LPARAM lParam )
  302. //
  303. // Dialog procedure for the license mode wizard page.
  304. //
  305. {
  306. // static data initialized by WM_INITDIALOG
  307. static PINTERNAL_SETUP_DATA pSetupData = NULL;
  308. static BOOL fLicensePerServer;
  309. static DWORD cPerServerLicenses;
  310. static DWORD cWaitCursor;
  311. BOOL fReturn = TRUE;
  312. switch ( msg )
  313. {
  314. case WM_INITDIALOG:
  315. LicenseSetupModeOnInitDialog( hwndPage, lParam, &pSetupData, &fLicensePerServer, &cPerServerLicenses, &cWaitCursor );
  316. break;
  317. case WM_SIMULATENEXT:
  318. LicenseSetupModeOnSimulateNext( hwndPage );
  319. break;
  320. case WM_BEGINWAITCURSOR:
  321. LicenseSetupModeOnWaitCursor( hwndPage, TRUE, &cWaitCursor );
  322. break;
  323. case WM_ENDWAITCURSOR:
  324. LicenseSetupModeOnWaitCursor( hwndPage, FALSE, &cWaitCursor );
  325. break;
  326. case WM_SETCURSOR:
  327. LicenseSetupModeOnSetCursor( hwndPage, LOWORD( lParam ), cWaitCursor );
  328. break;
  329. case WM_COMMAND:
  330. switch ( HIWORD( wParam ) )
  331. {
  332. case BN_CLICKED:
  333. switch ( LOWORD( wParam ) )
  334. {
  335. case IDC_PERSEAT:
  336. fLicensePerServer = FALSE;
  337. LicenseSetupModeOnSetLicenseMode( hwndPage, fLicensePerServer, cPerServerLicenses );
  338. break;
  339. case IDC_PERSERVER:
  340. fLicensePerServer = TRUE;
  341. LicenseSetupModeOnSetLicenseMode( hwndPage, fLicensePerServer, cPerServerLicenses );
  342. break;
  343. }
  344. break;
  345. case EN_UPDATE:
  346. if ( IDC_USERCOUNT == LOWORD( wParam ) )
  347. {
  348. LicenseSetupModeOnEditUpdate( hwndPage, (HWND) lParam, fLicensePerServer, &cPerServerLicenses );
  349. }
  350. break;
  351. default:
  352. fReturn = FALSE;
  353. break;
  354. }
  355. break;
  356. case WM_NOTIFY:
  357. {
  358. NMHDR * pNmHdr;
  359. pNmHdr = (NMHDR *)lParam;
  360. switch ( pNmHdr->code )
  361. {
  362. case PSN_SETACTIVE:
  363. LicenseSetupModeOnSetActive( hwndPage, pSetupData, &fLicensePerServer, &cPerServerLicenses );
  364. break;
  365. case PSN_KILLACTIVE:
  366. LicenseSetupModeOnKillActive( hwndPage );
  367. break;
  368. case PSN_WIZNEXT:
  369. case PSN_WIZFINISH:
  370. LicenseSetupModeOnNext( hwndPage, pSetupData, fLicensePerServer, cPerServerLicenses );
  371. break;
  372. case PSN_HELP:
  373. LicenseSetupModeOnHelp( hwndPage );
  374. break;
  375. default:
  376. fReturn = FALSE;
  377. break;
  378. }
  379. }
  380. break;
  381. default:
  382. fReturn = FALSE;
  383. }
  384. return fReturn;
  385. }
  386. static
  387. void
  388. LicenseSetupModeOnInitDialog(
  389. HWND hwndPage,
  390. LPARAM lParam,
  391. PINTERNAL_SETUP_DATA * ppSetupData,
  392. LPBOOL pfLicensePerServer,
  393. LPDWORD pcPerServerLicenses,
  394. LPDWORD pcWaitCursor )
  395. //
  396. // Message handler for WM_INITDIALOG
  397. //
  398. {
  399. // initialize static data
  400. *ppSetupData = (PINTERNAL_SETUP_DATA) ( (LPPROPSHEETPAGE) lParam )->lParam;
  401. *pcPerServerLicenses = 5;
  402. *pfLicensePerServer = TRUE;
  403. *pcWaitCursor = 0;
  404. // limit license count edit text length
  405. SendMessage( GetDlgItem( hwndPage, IDC_USERCOUNT ), EM_LIMITTEXT, PERSERVER_EDIT_WIDTH, 0 );
  406. // limit license count up-down range
  407. LONG lRange;
  408. lRange = (LPARAM) MAKELONG( (short) PERSERVER_EDIT_MAX, (short) PERSERVER_EDIT_MIN );
  409. SendMessage( GetDlgItem( hwndPage, IDC_USERCOUNTARROW ), UDM_SETRANGE, 0, (LPARAM) lRange );
  410. // initialize for default license mode
  411. LicenseSetupModeOnSetLicenseMode( hwndPage, *pfLicensePerServer, *pcPerServerLicenses );
  412. }
  413. static
  414. void
  415. LicenseSetupModeOnSetActive(
  416. HWND hwndPage,
  417. PINTERNAL_SETUP_DATA pSetupData,
  418. LPBOOL pfLicensePerServer,
  419. LPDWORD pcPerServerLicenses )
  420. //
  421. // Notification handler for PSN_SETACTIVE
  422. //
  423. {
  424. static BOOL fFirstTime = TRUE;
  425. BOOL fSkipPage;
  426. #ifdef SPECIAL_USERS
  427. *pfLicensePerServer = TRUE;
  428. *pcPerServerLicenses = SPECIAL_USERS;
  429. fSkipPage = TRUE;
  430. #else
  431. if ( IsRestrictedSmallBusSrv() )
  432. {
  433. *pfLicensePerServer = TRUE;
  434. *pcPerServerLicenses = SBS_SPECIAL_USERS;
  435. fSkipPage = TRUE;
  436. }
  437. else if ( pSetupData->OperationFlags & SETUPOPER_BATCH )
  438. {
  439. // operating in unattended mode; attempt to get all answers
  440. // from the unattend configuration file
  441. fSkipPage = LicenseSetupModeDoUnattended( hwndPage,
  442. pSetupData,
  443. pfLicensePerServer,
  444. pcPerServerLicenses );
  445. if ( !fSkipPage )
  446. {
  447. // Set defaults from unattended file
  448. LicenseSetupModeOnSetLicenseMode( hwndPage,
  449. *pfLicensePerServer,
  450. *pcPerServerLicenses );
  451. //
  452. // makarp: setting skippage to true is wrong, because we do not want to skip page.
  453. // we came here because we did not find sufficent answers in answer file.
  454. //
  455. // fSkipPage = TRUE;
  456. }
  457. }
  458. else
  459. {
  460. // operating in interactive mode; get answers from user
  461. fSkipPage = FALSE;
  462. }
  463. #endif
  464. HWND hwndSheet = GetParent( hwndPage );
  465. if ( fSkipPage )
  466. {
  467. if (fFirstTime)
  468. {
  469. fFirstTime = FALSE;
  470. // skip page
  471. // Only the first time do we need to do the processing which happens on next
  472. PostMessage( hwndSheet, PSM_PRESSBUTTON, (WPARAM)PSBTN_NEXT, 0 );
  473. }
  474. else
  475. {
  476. // After the first time the processing is already done and we don't have to do anything
  477. // This also solves the problem where the page needs to be skipped when the user clicks back
  478. // on a later page and this pages needs to be skipped.
  479. SetWindowLongPtr( hwndPage, DWLP_MSGRESULT, (LONG_PTR)-1 );
  480. return;
  481. }
  482. }
  483. else
  484. {
  485. // display page
  486. // hide Cancel button
  487. HWND hwndCancel = GetDlgItem( hwndSheet, IDCANCEL );
  488. EnableWindow( hwndCancel, FALSE);
  489. ShowWindow( hwndCancel, SW_HIDE);
  490. PropSheet_SetWizButtons( hwndSheet, PSWIZB_NEXT | PSWIZB_BACK );
  491. if (pSetupData)
  492. {
  493. pSetupData->ShowHideWizardPage(TRUE);
  494. }
  495. }
  496. // success
  497. SetWindowLongPtr( hwndPage, DWLP_MSGRESULT, (LONG_PTR)0 );
  498. }
  499. static
  500. void
  501. LicenseSetupModeOnSetLicenseMode(
  502. HWND hwndPage,
  503. BOOL fToPerServer,
  504. DWORD cPerServerLicenses )
  505. //
  506. // Handles changing the page to signify that the given license mode
  507. // is selected.
  508. //
  509. {
  510. HWND hwndCount = GetDlgItem( hwndPage, IDC_USERCOUNT );
  511. HWND hwndSpin = GetDlgItem( hwndPage, IDC_USERCOUNTARROW );
  512. // set radio button states
  513. CheckDlgButton( hwndPage, IDC_PERSEAT, !fToPerServer );
  514. CheckDlgButton( hwndPage, IDC_PERSERVER, fToPerServer );
  515. // set user count edit control
  516. if ( fToPerServer )
  517. {
  518. // display per server count
  519. SetDlgItemInt( hwndPage, IDC_USERCOUNT, cPerServerLicenses, FALSE );
  520. SetFocus( hwndCount );
  521. SendMessage( hwndCount, EM_SETSEL, 0, -1 );
  522. }
  523. else
  524. {
  525. // remove per server count
  526. SetDlgItemText( hwndPage, IDC_USERCOUNT, TEXT( "" ) );
  527. }
  528. // display count up-down and edit box iff per server mode is selected
  529. EnableWindow( hwndCount, fToPerServer );
  530. EnableWindow( hwndSpin, fToPerServer );
  531. }
  532. static
  533. void
  534. LicenseSetupModeOnEditUpdate(
  535. HWND hwndPage,
  536. HWND hwndCount,
  537. BOOL fLicensePerServer,
  538. LPDWORD pcPerServerLicenses )
  539. //
  540. // Command handler for EN_UPDATE of count edit box
  541. //
  542. {
  543. if ( fLicensePerServer )
  544. {
  545. BOOL fTranslated;
  546. UINT nValue;
  547. BOOL fModified = FALSE;
  548. nValue = GetDlgItemInt( hwndPage, IDC_USERCOUNT, &fTranslated, FALSE );
  549. if ( fTranslated )
  550. {
  551. // count translated; ensure its within the valid range
  552. if ( PERSERVER_EDIT_MAX < nValue )
  553. {
  554. // too big
  555. nValue = PERSERVER_EDIT_MAX;
  556. fModified = TRUE;
  557. }
  558. *pcPerServerLicenses = nValue;
  559. }
  560. else
  561. {
  562. // count couldn't be translated; reset to last value
  563. nValue = *pcPerServerLicenses;
  564. fModified = TRUE;
  565. }
  566. if ( fModified )
  567. {
  568. // text in edit box is invalid; change it to the proper value
  569. SetDlgItemInt( hwndPage, IDC_USERCOUNT, nValue, FALSE );
  570. SetFocus( hwndCount );
  571. SendMessage( hwndCount, EM_SETSEL, 0, -1 );
  572. MessageBeep( MB_VALUELIMIT );
  573. }
  574. }
  575. }
  576. static
  577. void
  578. LicenseSetupModeOnWaitCursor(
  579. HWND hwndDlg,
  580. BOOL fWait,
  581. LPDWORD pcWaitCursor )
  582. //
  583. // Handler for WM_BEGINWAITCURSOR / WM_ENDWAITCURSOR
  584. //
  585. {
  586. if ( fWait )
  587. {
  588. (*pcWaitCursor)++;
  589. if ( 1 == (*pcWaitCursor) )
  590. {
  591. // display wait cursor
  592. SetCursor( LoadCursor( NULL, MAKEINTRESOURCE( IDC_WAIT ) ) );
  593. }
  594. }
  595. else
  596. {
  597. if ( 0 < *pcWaitCursor )
  598. {
  599. (*pcWaitCursor)--;
  600. }
  601. if ( 0 == *pcWaitCursor )
  602. {
  603. // display regular cursor
  604. SetCursor( LoadCursor( NULL, MAKEINTRESOURCE( IDC_ARROW ) ) );
  605. }
  606. }
  607. // success
  608. SetWindowLongPtr( hwndDlg, DWLP_MSGRESULT, (LONG_PTR)*pcWaitCursor );
  609. }
  610. static
  611. BOOL
  612. LicenseSetupModeOnSetCursor(
  613. HWND hwndDlg,
  614. WORD nHitTest,
  615. DWORD cWaitCursor )
  616. //
  617. // Handler for WM_SETCURSOR
  618. //
  619. {
  620. BOOL frt = FALSE;
  621. if ( HTCLIENT == nHitTest )
  622. {
  623. if ( cWaitCursor > 0 )
  624. {
  625. // display wait cursor instead of regular cursor
  626. SetCursor( LoadCursor( NULL, MAKEINTRESOURCE( IDC_WAIT ) ) );
  627. SetWindowLongPtr( hwndDlg, DWLP_MSGRESULT, (LONG_PTR)TRUE );
  628. frt = TRUE;
  629. }
  630. }
  631. return frt;
  632. }
  633. static
  634. void
  635. LicenseSetupModeOnNext(
  636. HWND hwndPage,
  637. PINTERNAL_SETUP_DATA pSetupData,
  638. BOOL fLicensePerServer,
  639. DWORD cPerServerLicenses )
  640. //
  641. // Notification handler for PSN_WIZNEXT
  642. //
  643. {
  644. DWORD winStatus;
  645. int nButton;
  646. if ( ( fLicensePerServer )
  647. && ( PERSERVER_EDIT_MIN > cPerServerLicenses )
  648. && !( pSetupData->OperationFlags & SETUPOPER_BATCH ) )
  649. {
  650. // warn user about using per server mode with less then 5 licenses
  651. MessageBoxFromStringID( hwndPage,
  652. IDS_LICENSE_SETUP_NO_PER_SERVER_LICENSES,
  653. IDS_WARNING,
  654. MB_ICONERROR | MB_OK );
  655. nButton = IDCANCEL;
  656. }
  657. else
  658. {
  659. // per seat mode or per server mode with positive license count
  660. nButton = IDOK;
  661. }
  662. if ( IDOK == nButton )
  663. {
  664. do
  665. {
  666. // save license configuration
  667. SendMessage( hwndPage, WM_BEGINWAITCURSOR, 0, 0 );
  668. winStatus = LicenseSetupWrite( fLicensePerServer, cPerServerLicenses );
  669. SendMessage( hwndPage, WM_ENDWAITCURSOR, 0, 0 );
  670. if ( ERROR_SUCCESS != winStatus )
  671. {
  672. // save failed; alert user
  673. nButton = MessageBoxFromStringID( hwndPage,
  674. IDS_LICENSE_SETUP_SAVE_FAILED,
  675. IDS_ERROR,
  676. MB_ICONSTOP | MB_ABORTRETRYIGNORE | MB_DEFBUTTON2 );
  677. if ( IDIGNORE == nButton )
  678. {
  679. nButton = IDOK;
  680. }
  681. }
  682. else
  683. {
  684. // save succeeded
  685. nButton = IDOK;
  686. }
  687. } while ( IDRETRY == nButton );
  688. }
  689. if ( IDOK != nButton )
  690. {
  691. // don't advance to next page
  692. SetWindowLongPtr( hwndPage, DWLP_MSGRESULT, (LONG_PTR)-1 );
  693. }
  694. }
  695. static
  696. void
  697. LicenseSetupModeOnHelp(
  698. HWND hwndPage )
  699. //
  700. // Notification handler for PSN_HELP
  701. //
  702. {
  703. ::HtmlHelp( hwndPage, LICCPA_HTMLHELPFILE, HH_DISPLAY_TOPIC,0);
  704. }
  705. static
  706. void
  707. LicenseSetupModeOnSimulateNext(
  708. HWND hwndPage )
  709. //
  710. // Handler for WM_SIMULATENEXT (used by setup tests?)
  711. //
  712. {
  713. // simulate the next button
  714. PropSheet_PressButton( GetParent( hwndPage ), PSBTN_NEXT );
  715. }
  716. static
  717. void
  718. LicenseSetupModeOnKillActive(
  719. HWND hwndPage )
  720. //
  721. // Notification handler for PSN_KILLACTIVE
  722. //
  723. {
  724. // success
  725. SetWindowLong( hwndPage, DWLP_MSGRESULT, 0);
  726. }
  727. typedef enum {
  728. UnattendFullUnattend,
  729. UnattendGUIAttended,
  730. UnattendDefaultHide,
  731. UnattendProvideDefault,
  732. UnattendReadOnly } UNATTENDMODE;
  733. static
  734. BOOL
  735. LicenseSetupModeDoUnattended(
  736. HWND hwndPage,
  737. PINTERNAL_SETUP_DATA pSetupData,
  738. LPBOOL pfLicensePerServer,
  739. LPDWORD pcPerServerLicenses )
  740. //
  741. // Get answers to wizard page from unattend file.
  742. //
  743. {
  744. int cch;
  745. LPTSTR pszBadParam;
  746. TCHAR szLicenseMode[ 64 ];
  747. TCHAR szPerServerLicenses[ 64 ];
  748. TCHAR szUnattendMode[ 64 ];
  749. UNATTENDMODE UnattendMode = UnattendDefaultHide;
  750. pszBadParam = NULL;
  751. SendMessage( hwndPage, WM_BEGINWAITCURSOR, 0, 0 );
  752. // Get Unattend Mode
  753. cch = GetPrivateProfileString( WINNT_UNATTENDED,
  754. WINNT_U_UNATTENDMODE,
  755. TEXT( "" ),
  756. szUnattendMode,
  757. sizeof( szUnattendMode ) / sizeof( *szUnattendMode ),
  758. pSetupData->UnattendFile );
  759. if ( 0 < cch )
  760. {
  761. if ( !lstrcmpi( szUnattendMode, WINNT_A_FULLUNATTENDED ) )
  762. {
  763. UnattendMode = UnattendFullUnattend;
  764. }
  765. else if ( !lstrcmpi( szUnattendMode, WINNT_A_PROVIDEDEFAULT ) )
  766. {
  767. UnattendMode = UnattendProvideDefault;
  768. }
  769. else if ( !lstrcmpi( szUnattendMode, WINNT_A_READONLY ) )
  770. {
  771. UnattendMode = UnattendReadOnly;
  772. }
  773. else if ( !lstrcmpi( szUnattendMode, WINNT_A_GUIATTENDED ) )
  774. {
  775. // This should never happen
  776. UnattendMode = UnattendGUIAttended;
  777. }
  778. }
  779. // get license mode
  780. cch = GetPrivateProfileString( WINNT_LICENSEDATA_W,
  781. WINNT_L_AUTOMODE_W,
  782. TEXT( "" ),
  783. szLicenseMode,
  784. sizeof( szLicenseMode ) / sizeof( *szLicenseMode ),
  785. pSetupData->UnattendFile );
  786. SendMessage( hwndPage, WM_ENDWAITCURSOR, 0, 0 );
  787. if ( 0 < cch )
  788. {
  789. if ( !lstrcmpi( szLicenseMode, WINNT_A_PERSEAT_W ) )
  790. {
  791. *pfLicensePerServer = FALSE;
  792. }
  793. else if ( !lstrcmpi( szLicenseMode, WINNT_A_PERSERVER_W ) )
  794. {
  795. *pfLicensePerServer = TRUE;
  796. }
  797. else
  798. {
  799. cch = 0;
  800. }
  801. }
  802. if ( cch <= 0 )
  803. {
  804. // license mode absent or invalid
  805. pszBadParam = WINNT_L_AUTOMODE_W;
  806. }
  807. else if ( !*pfLicensePerServer )
  808. {
  809. // per seat mode; no need to read per server license count
  810. *pcPerServerLicenses = 0;
  811. }
  812. else
  813. {
  814. // get per server license count
  815. SendMessage( hwndPage, WM_BEGINWAITCURSOR, 0, 0 );
  816. cch = GetPrivateProfileString( WINNT_LICENSEDATA_W,
  817. WINNT_L_AUTOUSERS_W,
  818. TEXT( "" ),
  819. szPerServerLicenses,
  820. sizeof( szPerServerLicenses ) / sizeof( *szPerServerLicenses ),
  821. pSetupData->UnattendFile );
  822. SendMessage( hwndPage, WM_ENDWAITCURSOR, 0, 0 );
  823. if ( 0 < cch )
  824. {
  825. *pcPerServerLicenses = wcstoul( szPerServerLicenses, NULL, 10 );
  826. if ( ( PERSERVER_EDIT_MIN > *pcPerServerLicenses )
  827. || ( PERSERVER_EDIT_MAX < *pcPerServerLicenses ) )
  828. {
  829. // Don't let things go without setting a valid server license
  830. // count.
  831. *pcPerServerLicenses = PERSERVER_EDIT_MIN;
  832. cch = 0;
  833. }
  834. }
  835. if ( cch <= 0 )
  836. {
  837. // per server license count absent or invalid
  838. pszBadParam = WINNT_L_AUTOUSERS_W;
  839. }
  840. }
  841. //
  842. // Do not display the error message on preinstall.
  843. //
  844. if ( NULL != pszBadParam &&
  845. !(pSetupData->OperationFlags & (SETUPOPER_PREINSTALL | SETUPOPER_NTUPGRADE)) &&
  846. UnattendMode == UnattendFullUnattend )
  847. {
  848. // encountered a bad unattended parameter; display error
  849. TCHAR szCaption[ 64 ];
  850. TCHAR szFormat[ 1024 ];
  851. TCHAR szText[ 1024 ];
  852. LoadString( g_hinst,
  853. IDS_LICENSE_SETUP_BAD_UNATTEND_PARAM,
  854. szFormat,
  855. sizeof( szFormat ) / sizeof( *szFormat ) );
  856. LoadString( g_hinst,
  857. IDS_ERROR,
  858. szCaption,
  859. sizeof( szCaption ) / sizeof( *szCaption ) );
  860. wsprintf( szText, szFormat, pszBadParam );
  861. MessageBox( hwndPage,
  862. szText,
  863. szCaption,
  864. MB_OK | MB_ICONSTOP );
  865. }
  866. // If just providing defaults, return FALSE to force the page to show
  867. if ( UnattendMode == UnattendProvideDefault )
  868. return ( FALSE );
  869. return ( NULL == pszBadParam );
  870. }
  871. static
  872. DWORD
  873. LicenseSetupWrite(
  874. BOOL fLicensePerServer,
  875. DWORD cPerServerLicenses )
  876. //
  877. // Write license configuration; returns ERROR_SUCCESS or Windows error.
  878. //
  879. {
  880. DWORD winStatus;
  881. BOOL fCreated = TRUE; // TRUE if service entry is created
  882. // Used to determine if we should create
  883. // the parameters key or leave it alone.
  884. winStatus = LicenseSetupWriteService( &fCreated );
  885. if ( ERROR_SUCCESS == winStatus )
  886. {
  887. winStatus = LicenseSetupWriteKeyLicenseInfo( fLicensePerServer,
  888. cPerServerLicenses );
  889. if ( ERROR_SUCCESS == winStatus )
  890. {
  891. winStatus = LicenseSetupWriteKeyLicenseService( fCreated );
  892. if ( ERROR_SUCCESS == winStatus )
  893. {
  894. winStatus = LicenseSetupWriteKeyEventLog();
  895. }
  896. }
  897. }
  898. return winStatus;
  899. }
  900. static
  901. DWORD
  902. LicenseSetupWriteKeyLicenseInfo(
  903. BOOL fLicensePerServer,
  904. DWORD cPerServerLicenses )
  905. //
  906. // Create registry values:
  907. //
  908. // HKEY_LOCAL_MACHINE
  909. // \System
  910. // \CurrentControlSet
  911. // \Services
  912. // \LicenseInfo
  913. // ErrorControl : REG_DWORD : 1
  914. // Start : REG_DWORD : 3
  915. // Type : REG_DWORD : 4
  916. // \FilePrint
  917. // ConcurrentLimit : REG_DWORD : fLicensePerServer ? cPerServerLicenses : 0
  918. // DisplayName : REG_SZ : "Windows Server"
  919. // FamilyDisplayName : REG_SZ : "Windows Server"
  920. // Mode : REG_DWORD : fLicensePerServer ? 1 : 0
  921. // FlipAllow : REG_DWORD : fLicensePerServer ? 1 : 0
  922. //
  923. {
  924. DWORD winStatus;
  925. BOOL fCreatedNewServiceList;
  926. CLicRegLicense ServiceList;
  927. winStatus = ServiceList.Open( fCreatedNewServiceList );
  928. if ( ERROR_SUCCESS == winStatus )
  929. {
  930. CLicRegLicenseService FilePrintService( FILEPRINT_SERVICE_REG_KEY );
  931. winStatus = FilePrintService.Open( NULL, TRUE );
  932. if ( ERROR_SUCCESS == winStatus )
  933. {
  934. LICENSE_MODE lm;
  935. lm = fLicensePerServer ? LICMODE_PERSERVER : LICMODE_PERSEAT;
  936. winStatus = FilePrintService.SetMode( lm );
  937. if ( ERROR_SUCCESS == winStatus )
  938. {
  939. winStatus = FilePrintService.SetUserLimit( fLicensePerServer ? cPerServerLicenses : 0 );
  940. if ( ERROR_SUCCESS == winStatus )
  941. {
  942. winStatus = FilePrintService.SetChangeFlag( fLicensePerServer );
  943. if ( ERROR_SUCCESS == winStatus )
  944. {
  945. winStatus = FilePrintService.SetFamilyDisplayName( FILEPRINT_SERVICE_FAMILY_DISPLAY_NAME );
  946. if ( ERROR_SUCCESS == winStatus )
  947. {
  948. winStatus = FilePrintService.SetDisplayName( FILEPRINT_SERVICE_DISPLAY_NAME );
  949. }
  950. }
  951. }
  952. }
  953. }
  954. }
  955. return winStatus;
  956. }
  957. static
  958. DWORD
  959. LicenseSetupWriteKeyLicenseService( BOOL fWriteParametersKey )
  960. //
  961. // Create registry values:
  962. //
  963. // HKEY_LOCAL_MACHINE
  964. // \System
  965. // \CurrentControlSet
  966. // \Services
  967. // \LicenseService
  968. // \FilePrint
  969. // \KSecDD
  970. // \MSAfpSrv
  971. // \SMBServer
  972. // \TCP/IP Print Server
  973. // \Parameters
  974. // UseEnterprise : REG_DWORD : 0
  975. // ReplicationType : REG_DWORD : 0
  976. // ReplicationTime : REG_DWORD : 24 * 60 * 60
  977. // EnterpriseServer : REG_SZ : ""
  978. //
  979. {
  980. DWORD winStatus;
  981. HKEY hKeyLicenseService;
  982. DWORD dwKeyCreateDisposition;
  983. // create LicenseInfo key
  984. winStatus = RegCreateKeyEx( HKEY_LOCAL_MACHINE,
  985. LICENSE_SERVICE_REG_KEY,
  986. 0,
  987. NULL,
  988. 0,
  989. KEY_ALL_ACCESS,
  990. NULL,
  991. &hKeyLicenseService,
  992. &dwKeyCreateDisposition );
  993. if ( ERROR_SUCCESS == winStatus )
  994. {
  995. HKEY hKeyFilePrint;
  996. // create FilePrint key
  997. winStatus = RegCreateKeyEx( hKeyLicenseService,
  998. TEXT( "FilePrint" ),
  999. 0,
  1000. NULL,
  1001. 0,
  1002. KEY_ALL_ACCESS,
  1003. NULL,
  1004. &hKeyFilePrint,
  1005. &dwKeyCreateDisposition );
  1006. if ( ERROR_SUCCESS == winStatus )
  1007. {
  1008. const LPCTSTR apszFilePrintSubkeys[] =
  1009. {
  1010. TEXT( "KSecDD" ),
  1011. TEXT( "MSAfpSrv" ),
  1012. TEXT( "SMBServer" ),
  1013. TEXT( "TCP/IP Print Server" ),
  1014. NULL
  1015. };
  1016. HKEY hKeyFilePrintSubkey;
  1017. DWORD iSubkey;
  1018. for ( iSubkey = 0; NULL != apszFilePrintSubkeys[ iSubkey ]; iSubkey++ )
  1019. {
  1020. winStatus = RegCreateKeyEx( hKeyFilePrint,
  1021. apszFilePrintSubkeys[ iSubkey ],
  1022. 0,
  1023. NULL,
  1024. 0,
  1025. KEY_ALL_ACCESS,
  1026. NULL,
  1027. &hKeyFilePrintSubkey,
  1028. &dwKeyCreateDisposition );
  1029. if ( ERROR_SUCCESS == winStatus )
  1030. {
  1031. RegCloseKey( hKeyFilePrintSubkey );
  1032. }
  1033. else
  1034. {
  1035. break;
  1036. }
  1037. }
  1038. RegCloseKey( hKeyFilePrint );
  1039. }
  1040. RegCloseKey( hKeyLicenseService );
  1041. }
  1042. //
  1043. // Only write the Parameters key if the service was just created. That is,
  1044. // this is not an upgrade
  1045. //
  1046. if ( fWriteParametersKey && (ERROR_SUCCESS == winStatus) )
  1047. {
  1048. HKEY hKeyParameters;
  1049. // create Parameters key
  1050. winStatus = RegCreateKeyEx( HKEY_LOCAL_MACHINE,
  1051. szLicenseKey, // const
  1052. 0,
  1053. NULL,
  1054. 0,
  1055. KEY_ALL_ACCESS,
  1056. NULL,
  1057. &hKeyParameters,
  1058. &dwKeyCreateDisposition );
  1059. if ( ERROR_SUCCESS == winStatus )
  1060. {
  1061. // create LicenseService\Parameters values
  1062. winStatus = RegSetValueEx( hKeyParameters,
  1063. szUseEnterprise, // const
  1064. 0,
  1065. REG_DWORD,
  1066. (CONST BYTE *) &dwUseEnterprise, // const
  1067. sizeof( dwUseEnterprise ) );
  1068. if ( ERROR_SUCCESS == winStatus )
  1069. {
  1070. winStatus = RegSetValueEx( hKeyParameters,
  1071. szReplicationType, // const
  1072. 0,
  1073. REG_DWORD,
  1074. (CONST BYTE *) &dwReplicationType, // const
  1075. sizeof( dwReplicationType ) );
  1076. if ( ERROR_SUCCESS == winStatus )
  1077. {
  1078. winStatus = RegSetValueEx( hKeyParameters,
  1079. szReplicationTime, // const
  1080. 0,
  1081. REG_DWORD,
  1082. (CONST BYTE *) &dwReplicationTimeInSec, // const
  1083. sizeof( dwReplicationTimeInSec ) );
  1084. if ( ERROR_SUCCESS == winStatus )
  1085. {
  1086. LPCTSTR pszEnterpriseServer = TEXT( "" );
  1087. winStatus = RegSetValueEx( hKeyParameters,
  1088. szEnterpriseServer, // const
  1089. 0,
  1090. REG_SZ,
  1091. (CONST BYTE *) pszEnterpriseServer,
  1092. ( 1 + lstrlen( pszEnterpriseServer ) ) * sizeof( *pszEnterpriseServer ) );
  1093. }
  1094. }
  1095. }
  1096. RegCloseKey( hKeyParameters );
  1097. }
  1098. }
  1099. return winStatus;
  1100. }
  1101. static
  1102. DWORD
  1103. LicenseSetupWriteKeyEventLog()
  1104. //
  1105. // Create registry values:
  1106. //
  1107. // HKEY_LOCAL_MACHINE
  1108. // \System
  1109. // \CurrentControlSet
  1110. // \Services
  1111. // \EventLog
  1112. // \Application
  1113. // \LicenseService
  1114. // EventMessageFile : REG_EXPAND_SZ : %SystemRoot%\System32\llsrpc.dll
  1115. // TypesSupported : REG_DWORD : 7
  1116. //
  1117. {
  1118. DWORD winStatus;
  1119. HKEY hKeyLicenseService;
  1120. DWORD dwKeyCreateDisposition;
  1121. // create LicenseService key
  1122. winStatus = RegCreateKeyEx( HKEY_LOCAL_MACHINE,
  1123. TEXT( "System\\CurrentControlSet\\Services\\EventLog\\Application\\LicenseService" ),
  1124. 0,
  1125. NULL,
  1126. 0,
  1127. KEY_ALL_ACCESS,
  1128. NULL,
  1129. &hKeyLicenseService,
  1130. &dwKeyCreateDisposition );
  1131. if ( ERROR_SUCCESS == winStatus )
  1132. {
  1133. LPCTSTR pszEventMessageFile = TEXT( "%SystemRoot%\\System32\\llsrpc.dll" );
  1134. const DWORD dwTypesSupported = ( EVENTLOG_ERROR_TYPE
  1135. | EVENTLOG_WARNING_TYPE
  1136. | EVENTLOG_INFORMATION_TYPE );
  1137. winStatus = RegSetValueEx( hKeyLicenseService,
  1138. TEXT( "TypesSupported" ),
  1139. 0,
  1140. REG_DWORD,
  1141. (CONST BYTE *) &dwTypesSupported,
  1142. sizeof( dwTypesSupported ) );
  1143. if ( ERROR_SUCCESS == winStatus )
  1144. {
  1145. winStatus = RegSetValueEx( hKeyLicenseService,
  1146. TEXT( "EventMessageFile" ),
  1147. 0,
  1148. REG_SZ,
  1149. (CONST BYTE *) pszEventMessageFile,
  1150. ( 1 + lstrlen( pszEventMessageFile ) ) * sizeof( *pszEventMessageFile ) );
  1151. }
  1152. RegCloseKey( hKeyLicenseService );
  1153. }
  1154. return winStatus;
  1155. }
  1156. static
  1157. DWORD
  1158. LicenseSetupWriteService( BOOL * fCreated )
  1159. //
  1160. // Create/modify service:
  1161. //
  1162. // lpServiceName = "LicenseService"
  1163. // lpDisplayName = "License Logging Service"
  1164. // dwServiceType = SERVICE_WIN32_OWN_PROCESS
  1165. // dwStartType = LanManServerInstalled ? SERVICE_AUTO_START : SERVICE_DISABLED
  1166. // dwErrorControl = SERVICE_ERROR_NORMAL
  1167. // lpBinaryPathName = "%SystemRoot%\\System32\\llssrv.exe"
  1168. // lpLoadOrderGroup = NULL
  1169. // lpdwTagId = NULL
  1170. // lpDependencies = NULL
  1171. // lpServiceStartName = NULL
  1172. // lpPassword = NULL
  1173. //
  1174. {
  1175. SC_HANDLE hSC;
  1176. DWORD winStatus;
  1177. *fCreated = FALSE;
  1178. hSC = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS );
  1179. if ( NULL == hSC )
  1180. {
  1181. winStatus = GetLastError();
  1182. }
  1183. else
  1184. {
  1185. HKEY hKeyLanmanServerParameters;
  1186. DWORD dwStartType ;
  1187. SC_HANDLE hLicenseService = NULL;
  1188. TCHAR szServiceDisplayName[ 128 ] = TEXT( "License Logging" );
  1189. TCHAR szServiceDescription[256] = TEXT("");
  1190. TCHAR szServiceStartName [] = TEXT("NT AUTHORITY\\NetworkService");
  1191. TCHAR szServicePassword[]=TEXT("");
  1192. SERVICE_DESCRIPTION svcDescription;
  1193. QUERY_SERVICE_CONFIG* pConfig = NULL;
  1194. DWORD cbBytesNeeded = 0;
  1195. BOOL frt;
  1196. DWORD dwDesiredAccess = SERVICE_ALL_ACCESS;
  1197. // enable service iff LanmanServer was installed
  1198. winStatus = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
  1199. TEXT( "SYSTEM\\CurrentControlSet\\Services\\LanmanServer\\Parameters" ),
  1200. 0,
  1201. KEY_READ,
  1202. &hKeyLanmanServerParameters );
  1203. if ( ERROR_SUCCESS == winStatus )
  1204. {
  1205. dwStartType = SERVICE_AUTO_START;
  1206. hLicenseService = OpenService( hSC, TEXT( "LicenseService"), dwDesiredAccess );
  1207. if( hLicenseService != NULL )
  1208. {
  1209. cbBytesNeeded = sizeof(QUERY_SERVICE_CONFIG) + 4096;
  1210. pConfig = (LPQUERY_SERVICE_CONFIG) LocalAlloc( LPTR, cbBytesNeeded );
  1211. if ( pConfig != NULL )
  1212. {
  1213. frt = ::QueryServiceConfig( hLicenseService,
  1214. pConfig,
  1215. cbBytesNeeded,
  1216. &cbBytesNeeded );
  1217. if ( frt )
  1218. {
  1219. dwStartType = pConfig->dwStartType;
  1220. }
  1221. LocalFree ( pConfig ) ;
  1222. }
  1223. CloseServiceHandle( hLicenseService );
  1224. }
  1225. RegCloseKey( hKeyLanmanServerParameters );
  1226. }
  1227. else
  1228. {
  1229. dwStartType = SERVICE_DISABLED;
  1230. }
  1231. LoadString( g_hinst,
  1232. IDS_SERVICE_DISPLAY_NAME,
  1233. szServiceDisplayName,
  1234. sizeof( szServiceDisplayName ) / sizeof( *szServiceDisplayName ) );
  1235. LoadString( g_hinst,
  1236. IDS_SERVICE_DESCRIPTION,
  1237. szServiceDescription,
  1238. sizeof( szServiceDescription ) / sizeof( *szServiceDescription ) );
  1239. svcDescription.lpDescription = szServiceDescription;
  1240. hLicenseService = CreateService( hSC,
  1241. TEXT( "LicenseService" ),
  1242. szServiceDisplayName,
  1243. // 14659: needed to call ChangeConfig2 later
  1244. SERVICE_CHANGE_CONFIG,
  1245. SERVICE_WIN32_OWN_PROCESS,
  1246. dwStartType,
  1247. SERVICE_ERROR_NORMAL,
  1248. TEXT( "%SystemRoot%\\System32\\llssrv.exe" ),
  1249. NULL,
  1250. NULL,
  1251. NULL,
  1252. szServiceStartName,
  1253. szServicePassword );
  1254. if ( NULL != hLicenseService )
  1255. {
  1256. // service successfully created
  1257. ChangeServiceConfig2( hLicenseService,
  1258. SERVICE_CONFIG_DESCRIPTION,
  1259. &svcDescription );
  1260. CloseServiceHandle( hLicenseService );
  1261. winStatus = ERROR_SUCCESS;
  1262. *fCreated = TRUE;
  1263. }
  1264. else
  1265. {
  1266. winStatus = GetLastError();
  1267. if ( ERROR_SERVICE_EXISTS == winStatus )
  1268. {
  1269. // service already exists; change configuration of existing service
  1270. hLicenseService = OpenService( hSC,
  1271. TEXT( "LicenseService" ),
  1272. SERVICE_CHANGE_CONFIG );
  1273. if ( NULL == hLicenseService )
  1274. {
  1275. winStatus = GetLastError();
  1276. }
  1277. else
  1278. {
  1279. SC_LOCK scLock;
  1280. BOOL ok;
  1281. scLock = LockServiceDatabase( hSC );
  1282. // continue even if we can't lock the database
  1283. ok = ChangeServiceConfig( hLicenseService,
  1284. SERVICE_WIN32_OWN_PROCESS,
  1285. dwStartType,
  1286. SERVICE_ERROR_NORMAL,
  1287. TEXT( "%SystemRoot%\\System32\\llssrv.exe" ),
  1288. NULL,
  1289. NULL,
  1290. NULL,
  1291. szServiceStartName,
  1292. szServicePassword,
  1293. szServiceDisplayName );
  1294. if ( !ok )
  1295. {
  1296. winStatus = GetLastError();
  1297. }
  1298. else
  1299. {
  1300. ChangeServiceConfig2( hLicenseService,
  1301. SERVICE_CONFIG_DESCRIPTION,
  1302. &svcDescription);
  1303. winStatus = ERROR_SUCCESS;
  1304. }
  1305. if ( NULL != scLock )
  1306. {
  1307. UnlockServiceDatabase( scLock );
  1308. }
  1309. CloseServiceHandle( hLicenseService );
  1310. }
  1311. }
  1312. }
  1313. CloseServiceHandle( hSC );
  1314. }
  1315. CreateDirectoryWithAccess();
  1316. CreateFileWithAccess();
  1317. return winStatus;
  1318. }
  1319. void CreateDirectoryWithAccess()
  1320. {
  1321. DWORD winStatus = 0;
  1322. TCHAR tchWinDirPath[MAX_PATH+1] = L"";
  1323. PACL pNewDacl = NULL;
  1324. PACL pOldDacl = NULL;
  1325. PSECURITY_DESCRIPTOR pSD = NULL;
  1326. TCHAR tchLLSDirPath[ MAX_PATH +1] = L"";
  1327. BOOL bFlag = FALSE;
  1328. PSID pSid = NULL;
  1329. EXPLICIT_ACCESS ExplicitEntries;
  1330. SID_IDENTIFIER_AUTHORITY ntSidAuthority = SECURITY_NT_AUTHORITY;
  1331. winStatus = GetSystemWindowsDirectory( tchWinDirPath , MAX_PATH+1);
  1332. if(winStatus == 0)
  1333. {
  1334. goto cleanup;
  1335. }
  1336. lstrcpy(tchLLSDirPath, tchWinDirPath);
  1337. lstrcat( tchLLSDirPath , L"\\system32\\lls" );
  1338. // Creating new EXPLICIT_ACCESS structure to set on the directory
  1339. ZeroMemory( &ExplicitEntries, sizeof(ExplicitEntries) );
  1340. bFlag = AllocateAndInitializeSid(
  1341. &ntSidAuthority,
  1342. 1,
  1343. SECURITY_NETWORK_SERVICE_RID,0,
  1344. 0, 0, 0, 0, 0, 0,
  1345. &pSid );
  1346. if ( !bFlag || (pSid == NULL) ) {
  1347. goto cleanup;
  1348. }
  1349. BuildTrusteeWithSid( &ExplicitEntries.Trustee, pSid );
  1350. ExplicitEntries.grfInheritance = SUB_CONTAINERS_AND_OBJECTS_INHERIT;
  1351. ExplicitEntries.grfAccessMode = SET_ACCESS;
  1352. ExplicitEntries.grfAccessPermissions = FILE_ALL_ACCESS;
  1353. ExplicitEntries.Trustee.TrusteeForm = TRUSTEE_IS_SID;
  1354. ExplicitEntries.Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
  1355. bFlag = CreateDirectory( tchLLSDirPath, NULL );
  1356. if ( !bFlag )
  1357. {
  1358. winStatus = GetLastError();
  1359. if (ERROR_ALREADY_EXISTS != winStatus)
  1360. {
  1361. goto cleanup;
  1362. }
  1363. }
  1364. if( GetNamedSecurityInfoW( tchLLSDirPath,
  1365. SE_FILE_OBJECT,
  1366. DACL_SECURITY_INFORMATION,
  1367. NULL, // psidOwner
  1368. NULL, // psidGroup
  1369. &pOldDacl, // pDacl
  1370. NULL, // pSacl
  1371. &pSD ) != ERROR_SUCCESS)
  1372. {
  1373. goto cleanup;
  1374. }
  1375. //
  1376. // Set the Acl with the ExplicitEntry rights
  1377. //
  1378. if( SetEntriesInAcl( 1,
  1379. &ExplicitEntries,
  1380. pOldDacl,
  1381. &pNewDacl ) != ERROR_SUCCESS)
  1382. {
  1383. goto cleanup;
  1384. }
  1385. //
  1386. // SET security on the Directory
  1387. //
  1388. winStatus = SetNamedSecurityInfo(
  1389. tchLLSDirPath, // object name
  1390. SE_FILE_OBJECT , // object type
  1391. DACL_SECURITY_INFORMATION | UNPROTECTED_DACL_SECURITY_INFORMATION , // type
  1392. NULL, // new owner SID
  1393. NULL, // new primary group SID
  1394. pNewDacl, // new DACL
  1395. NULL // new SACL
  1396. );
  1397. cleanup:
  1398. if(pSid)
  1399. {
  1400. LocalFree( pSid );
  1401. }
  1402. if(pSD)
  1403. {
  1404. LocalFree(pSD);
  1405. pSD = NULL;
  1406. }
  1407. if(pNewDacl)
  1408. {
  1409. LocalFree(pNewDacl);
  1410. pNewDacl = NULL;
  1411. }
  1412. }
  1413. void CreateFileWithAccess()
  1414. {
  1415. DWORD winStatus = 0;
  1416. TCHAR tchWinDirPath[MAX_PATH+1] = L"";
  1417. PACL pNewDacl = NULL;
  1418. PACL pOldDacl = NULL;
  1419. PSECURITY_DESCRIPTOR pSD = NULL;
  1420. TCHAR tchCPLFilePath[ MAX_PATH+1 ] = L"";
  1421. BOOL bFlag = FALSE;
  1422. PSID pSid = NULL;
  1423. EXPLICIT_ACCESS ExplicitEntries;
  1424. SID_IDENTIFIER_AUTHORITY ntSidAuthority = SECURITY_NT_AUTHORITY;
  1425. HANDLE hFile = NULL;
  1426. winStatus = GetSystemWindowsDirectory( tchWinDirPath , MAX_PATH+1);
  1427. if(winStatus == 0)
  1428. {
  1429. goto cleanup;
  1430. }
  1431. lstrcpy(tchCPLFilePath, tchWinDirPath);
  1432. lstrcat( tchCPLFilePath , L"\\system32\\cpl.cfg" );
  1433. // Creating new EXPLICIT_ACCESS structure to set on the file
  1434. ZeroMemory( &ExplicitEntries, sizeof(ExplicitEntries) );
  1435. bFlag = AllocateAndInitializeSid(
  1436. &ntSidAuthority,
  1437. 1,
  1438. SECURITY_NETWORK_SERVICE_RID,0,
  1439. 0, 0, 0, 0, 0, 0,
  1440. &pSid );
  1441. if ( !bFlag || (pSid == NULL) ) {
  1442. goto cleanup;
  1443. }
  1444. BuildTrusteeWithSid( &ExplicitEntries.Trustee, pSid );
  1445. ExplicitEntries.grfAccessMode = SET_ACCESS;
  1446. ExplicitEntries.grfAccessPermissions = FILE_ALL_ACCESS;
  1447. ExplicitEntries.Trustee.TrusteeForm = TRUSTEE_IS_SID;
  1448. ExplicitEntries.Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
  1449. hFile = CreateFile(tchCPLFilePath,
  1450. GENERIC_READ | GENERIC_WRITE,
  1451. FILE_SHARE_READ | FILE_SHARE_WRITE,
  1452. NULL,
  1453. OPEN_ALWAYS,
  1454. 0,
  1455. NULL);
  1456. if(hFile == NULL)
  1457. {
  1458. winStatus = GetLastError();
  1459. if (winStatus != ERROR_ALREADY_EXISTS) {
  1460. goto cleanup ;
  1461. }
  1462. }
  1463. if( GetNamedSecurityInfoW( tchCPLFilePath,
  1464. SE_FILE_OBJECT,
  1465. DACL_SECURITY_INFORMATION,
  1466. NULL, // psidOwner
  1467. NULL, // psidGroup
  1468. &pOldDacl, // pDacl
  1469. NULL, // pSacl
  1470. &pSD ) != ERROR_SUCCESS)
  1471. {
  1472. goto cleanup;
  1473. }
  1474. //
  1475. // Set the Acl with the ExplicitEntry rights
  1476. //
  1477. if( SetEntriesInAcl( 1,
  1478. &ExplicitEntries,
  1479. pOldDacl,
  1480. &pNewDacl ) != ERROR_SUCCESS)
  1481. {
  1482. goto cleanup;
  1483. }
  1484. //
  1485. // SET security on the File
  1486. //
  1487. winStatus = SetNamedSecurityInfo(
  1488. tchCPLFilePath, // object name
  1489. SE_FILE_OBJECT , // object type
  1490. DACL_SECURITY_INFORMATION | UNPROTECTED_DACL_SECURITY_INFORMATION , // type
  1491. NULL, // new owner SID
  1492. NULL, // new primary group SID
  1493. pNewDacl, // new DACL
  1494. NULL // new SACL
  1495. );
  1496. cleanup:
  1497. if(hFile)
  1498. {
  1499. CloseHandle(hFile);
  1500. }
  1501. if(pSid)
  1502. {
  1503. LocalFree( pSid );
  1504. }
  1505. if(pSD)
  1506. {
  1507. LocalFree(pSD);
  1508. pSD = NULL;
  1509. }
  1510. if(pNewDacl)
  1511. {
  1512. LocalFree(pNewDacl);
  1513. pNewDacl = NULL;
  1514. }
  1515. }
  1516. static
  1517. int
  1518. MessageBoxFromStringID(
  1519. HWND hwndParent,
  1520. UINT uTextID,
  1521. UINT uCaptionID,
  1522. UINT uType )
  1523. //
  1524. // Same as MessageBox(), except Text and Caption are string resources
  1525. // instead of string pointers.
  1526. //
  1527. {
  1528. int nButton;
  1529. TCHAR szText[ 1024 ];
  1530. TCHAR szCaption[ 64 ];
  1531. LoadString( g_hinst, uTextID, szText, sizeof( szText ) / sizeof( *szText ) );
  1532. LoadString( g_hinst, uCaptionID, szCaption, sizeof( szCaption ) / sizeof( *szCaption ) );
  1533. nButton = MessageBox( hwndParent, szText, szCaption, uType );
  1534. return nButton;
  1535. }