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.

610 lines
18 KiB

  1. /*++
  2. Copyright (c) 1997 Microsoft Corporation
  3. Module Name:
  4. ntoc.cpp
  5. Abstract:
  6. This file implements the NT OC Manager DLL.
  7. Environment:
  8. WIN32 User Mode
  9. Author:
  10. Wesley Witt (wesw) 7-Aug-1997
  11. --*/
  12. #include "ntoc.h"
  13. #pragma hdrstop
  14. //
  15. // types
  16. //
  17. typedef void (*PWIZINIT)(void);
  18. typedef void (*PWIZCOMMIT)(void);
  19. //
  20. // structures
  21. //
  22. typedef struct _WIZPAGE {
  23. DWORD ButtonState;
  24. DWORD PageId;
  25. DWORD DlgId;
  26. DLGPROC DlgProc;
  27. DWORD Title;
  28. DWORD SubTitle;
  29. DWORD WizPageType;
  30. PWIZINIT WizInit;
  31. PWIZCOMMIT WizCommit;
  32. DWORDLONG Modes;
  33. } WIZPAGE, *PWIZPAGE;
  34. //
  35. // globals
  36. //
  37. WIZPAGE SetupWizardPages[WizPageMaximum] =
  38. {
  39. {
  40. PSWIZB_NEXT,
  41. WizPageTapiLoc,
  42. IDD_TAPI_LOCATIONS,
  43. TapiLocDlgProc,
  44. IDS_TAPILOC_TITLE,
  45. IDS_TAPILOC_SUBTITLE,
  46. WizPagesEarly,
  47. TapiInit,
  48. TapiCommitChanges,
  49. -1
  50. },
  51. /*
  52. {
  53. PSWIZB_NEXT,
  54. WizPageDisplay,
  55. IDD_DISPLAY,
  56. DisplayDlgProc,
  57. IDS_DISPLAY_TITLE,
  58. IDS_DISPLAY_SUBTITLE,
  59. WizPagesEarly,
  60. DisplayInit,
  61. DisplayCommitChanges,
  62. -1
  63. },
  64. */
  65. {
  66. PSWIZB_NEXT,
  67. WizPageDateTime,
  68. IDD_DATETIME,
  69. DateTimeDlgProc,
  70. IDS_DATETIME_TITLE,
  71. IDS_DATETIME_SUBTITLE,
  72. WizPagesEarly,
  73. DateTimeInit,
  74. DateTimeCommitChanges,
  75. -1
  76. },
  77. {
  78. PSWIZB_NEXT,
  79. WizPageWelcome,
  80. IDD_NTOC_WELCOME,
  81. WelcomeDlgProc,
  82. 0,
  83. 0,
  84. WizPagesWelcome,
  85. WelcomeInit,
  86. WelcomeCommit,
  87. SETUPOP_STANDALONE
  88. },
  89. /*
  90. {
  91. PSWIZB_NEXT,
  92. WizPageReinstall,
  93. IDD_REINSTALL,
  94. ReinstallDlgProc,
  95. 0,
  96. 0,
  97. WizPagesEarly,
  98. ReinstallInit,
  99. ReinstallCommit,
  100. SETUPOP_STANDALONE
  101. },
  102. */
  103. {
  104. PSWIZB_FINISH,
  105. WizPageFinal,
  106. IDD_NTOC_FINISH,
  107. FinishDlgProc,
  108. 0,
  109. 0,
  110. WizPagesFinal,
  111. FinishInit,
  112. FinishCommit,
  113. SETUPOP_STANDALONE
  114. }
  115. };
  116. DWORD NtOcWizardPages[] =
  117. {
  118. WizPageTapiLoc,
  119. // WizPageDisplay,
  120. WizPageDateTime,
  121. WizPageWelcome,
  122. //WizPageReinstall,
  123. WizPageFinal
  124. };
  125. //DWORD NtOcWrapPages[] =
  126. //{
  127. //}
  128. #define MAX_NTOC_PAGES (sizeof(NtOcWizardPages)/sizeof(NtOcWizardPages[0]))
  129. //#define MAX_NTOC_WRAP_PAGES (sizeof(NtOcWrapPages)/sizeof(NtOcWrapPages[0]))
  130. HINSTANCE hInstance;
  131. HPROPSHEETPAGE WizardPageHandles[WizPageMaximum];
  132. PROPSHEETPAGE WizardPages[WizPageMaximum];
  133. //HPROPSHEETPAGE WrapPageHandles[WizPageMaximum];
  134. //PROPSHEETPAGE WizardPages[WizPageMaximum];
  135. SETUP_INIT_COMPONENT SetupInitComponent;
  136. extern "C"
  137. DWORD
  138. NtOcDllInit(
  139. HINSTANCE hInst,
  140. DWORD Reason,
  141. LPVOID Context
  142. )
  143. {
  144. if (Reason == DLL_PROCESS_ATTACH) {
  145. hInstance = hInst;
  146. DisableThreadLibraryCalls( hInstance );
  147. InitCommonControls();
  148. }
  149. return TRUE;
  150. }
  151. DWORD
  152. NtOcSetupProc(
  153. IN LPCVOID ComponentId,
  154. IN LPCVOID SubcomponentId,
  155. IN UINT Function,
  156. IN UINT Param1,
  157. IN OUT PVOID Param2
  158. )
  159. {
  160. DWORD i;
  161. DWORD cnt;
  162. DWORD WizPageCount = 0;
  163. WCHAR TitleBuffer[256];
  164. PSETUP_REQUEST_PAGES SetupRequestPages;
  165. switch( Function ) {
  166. case OC_PREINITIALIZE:
  167. return OCFLAG_UNICODE;
  168. case OC_INIT_COMPONENT:
  169. if (OCMANAGER_VERSION <= ((PSETUP_INIT_COMPONENT)Param2)->OCManagerVersion) {
  170. ((PSETUP_INIT_COMPONENT)Param2)->ComponentVersion = OCMANAGER_VERSION;
  171. } else {
  172. return ERROR_CALL_NOT_IMPLEMENTED;
  173. }
  174. CopyMemory( &SetupInitComponent, (LPVOID)Param2, sizeof(SETUP_INIT_COMPONENT) );
  175. for (i=0; i<MAX_NTOC_PAGES; i++) {
  176. if (SetupWizardPages[NtOcWizardPages[i]].WizInit &&
  177. (SetupWizardPages[NtOcWizardPages[i]].Modes &
  178. SetupInitComponent.SetupData.OperationFlags)) {
  179. SetupWizardPages[NtOcWizardPages[i]].WizInit();
  180. }
  181. }
  182. if ((SetupInitComponent.SetupData.OperationFlags & SETUPOP_STANDALONE)) {
  183. if (!RunningAsAdministrator()) {
  184. FmtMessageBox(NULL,
  185. MB_ICONINFORMATION | MB_OK | MB_SETFOREGROUND,
  186. FALSE,
  187. ID_DSP_TXT_CHANGE_SETTINGS,
  188. ID_DSP_TXT_ADMIN_CHANGE);
  189. return ERROR_CANCELLED;
  190. }
  191. }
  192. return 0;
  193. case OC_REQUEST_PAGES:
  194. SetupRequestPages = (PSETUP_REQUEST_PAGES) Param2;
  195. //
  196. // if this isn't gui-mode setup, then let's supply the welcome and finish pages
  197. //
  198. // Note that this code path "short circuits" inside this if statement
  199. //
  200. if ((SetupInitComponent.SetupData.OperationFlags & SETUPOP_STANDALONE)) {
  201. switch (Param1) {
  202. case WizPagesWelcome:
  203. i = WizPageWelcome;
  204. cnt = 1;
  205. break;
  206. case WizPagesFinal:
  207. cnt = 1;
  208. i = WizPageFinal;
  209. break;
  210. // case WizPagesEarly:
  211. // cnt = 1;
  212. // i = WizPageReinstall;
  213. // break;
  214. default:
  215. cnt = 0;
  216. i = 0;
  217. break;
  218. }
  219. if (cnt > SetupRequestPages->MaxPages) {
  220. return cnt;
  221. }
  222. if (cnt == 0) {
  223. goto getallpages;
  224. }
  225. WizardPages[WizPageCount].dwSize = sizeof(PROPSHEETPAGE);
  226. // if (i == WizPageReinstall) {
  227. // WizardPages[WizPageCount].dwFlags = PSP_DEFAULT | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE;
  228. // } else {
  229. WizardPages[WizPageCount].dwFlags = PSP_DEFAULT | PSP_HIDEHEADER;
  230. // }
  231. WizardPages[WizPageCount].hInstance = hInstance;
  232. WizardPages[WizPageCount].pszTemplate = MAKEINTRESOURCE(SetupWizardPages[NtOcWizardPages[i]].DlgId);
  233. WizardPages[WizPageCount].pszIcon = NULL;
  234. WizardPages[WizPageCount].pszTitle = NULL;
  235. WizardPages[WizPageCount].pfnDlgProc = SetupWizardPages[NtOcWizardPages[i]].DlgProc;
  236. WizardPages[WizPageCount].lParam = 0;
  237. WizardPages[WizPageCount].pfnCallback = NULL;
  238. WizardPages[WizPageCount].pcRefParent = NULL;
  239. WizardPages[WizPageCount].pszHeaderTitle = NULL;
  240. WizardPages[WizPageCount].pszHeaderSubTitle = NULL;
  241. if (SetupWizardPages[NtOcWizardPages[i]].Title) {
  242. if (LoadString(
  243. hInstance,
  244. SetupWizardPages[NtOcWizardPages[i]].Title,
  245. TitleBuffer,
  246. sizeof(TitleBuffer)/sizeof(WCHAR)
  247. ))
  248. {
  249. WizardPages[WizPageCount].pszHeaderTitle = _wcsdup( TitleBuffer );
  250. }
  251. }
  252. if (SetupWizardPages[NtOcWizardPages[i]].SubTitle) {
  253. if (LoadString(
  254. hInstance,
  255. SetupWizardPages[NtOcWizardPages[i]].SubTitle,
  256. TitleBuffer,
  257. sizeof(TitleBuffer)/sizeof(WCHAR)
  258. ))
  259. {
  260. WizardPages[WizPageCount].pszHeaderSubTitle = _wcsdup( TitleBuffer );
  261. }
  262. }
  263. WizardPageHandles[WizPageCount] = CreatePropertySheetPage( &WizardPages[WizPageCount] );
  264. if (WizardPageHandles[WizPageCount]) {
  265. SetupRequestPages->Pages[WizPageCount] = WizardPageHandles[WizPageCount];
  266. WizPageCount += 1;
  267. }
  268. return WizPageCount;
  269. }
  270. getallpages:
  271. for (i=0,cnt=0; i<MAX_NTOC_PAGES; i++) {
  272. if ((SetupWizardPages[NtOcWizardPages[i]].WizPageType == Param1) &&
  273. (SetupInitComponent.SetupData.OperationFlags & SetupWizardPages[NtOcWizardPages[i]].Modes)) {
  274. cnt += 1;
  275. }
  276. }
  277. // if this is not gui mode setup, don't display pages
  278. if ((SetupInitComponent.SetupData.OperationFlags & SETUPOP_STANDALONE)) {
  279. cnt = 0;
  280. }
  281. if (cnt == 0) {
  282. return cnt;
  283. }
  284. if (cnt > SetupRequestPages->MaxPages) {
  285. return cnt;
  286. }
  287. for (i=0; i<MAX_NTOC_PAGES; i++) {
  288. if ((SetupWizardPages[NtOcWizardPages[i]].WizPageType != Param1) &&
  289. (SetupInitComponent.SetupData.OperationFlags & SetupWizardPages[NtOcWizardPages[i]].Modes) == 0) {
  290. continue;
  291. }
  292. WizardPages[WizPageCount].dwSize = sizeof(PROPSHEETPAGE);
  293. WizardPages[WizPageCount].dwFlags = PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE;
  294. WizardPages[WizPageCount].hInstance = hInstance;
  295. WizardPages[WizPageCount].pszTemplate = MAKEINTRESOURCE(SetupWizardPages[NtOcWizardPages[i]].DlgId);
  296. WizardPages[WizPageCount].pszIcon = NULL;
  297. WizardPages[WizPageCount].pszTitle = NULL;
  298. WizardPages[WizPageCount].pfnDlgProc = SetupWizardPages[NtOcWizardPages[i]].DlgProc;
  299. WizardPages[WizPageCount].lParam = 0;
  300. WizardPages[WizPageCount].pfnCallback = NULL;
  301. WizardPages[WizPageCount].pcRefParent = NULL;
  302. WizardPages[WizPageCount].pszHeaderTitle = NULL;
  303. WizardPages[WizPageCount].pszHeaderSubTitle = NULL;
  304. if (SetupWizardPages[NtOcWizardPages[i]].Title) {
  305. if (LoadString(
  306. hInstance,
  307. SetupWizardPages[NtOcWizardPages[i]].Title,
  308. TitleBuffer,
  309. sizeof(TitleBuffer)/sizeof(WCHAR)
  310. ))
  311. {
  312. WizardPages[WizPageCount].pszHeaderTitle = _wcsdup( TitleBuffer );
  313. }
  314. }
  315. if (SetupWizardPages[NtOcWizardPages[i]].SubTitle) {
  316. if (LoadString(
  317. hInstance,
  318. SetupWizardPages[NtOcWizardPages[i]].SubTitle,
  319. TitleBuffer,
  320. sizeof(TitleBuffer)/sizeof(WCHAR)
  321. ))
  322. {
  323. WizardPages[WizPageCount].pszHeaderSubTitle = _wcsdup( TitleBuffer );
  324. }
  325. }
  326. WizardPageHandles[WizPageCount] = CreatePropertySheetPage( &WizardPages[WizPageCount] );
  327. if (WizardPageHandles[WizPageCount]) {
  328. SetupRequestPages->Pages[WizPageCount] = WizardPageHandles[WizPageCount];
  329. WizPageCount += 1;
  330. }
  331. }
  332. return WizPageCount;
  333. case OC_QUERY_SKIP_PAGE:
  334. // if this is gui mode setup and the system is NT Workstation,
  335. // skip the select components page
  336. // remove workstation check to make this change effective on servers as well
  337. // if (SetupInitComponent.SetupData.ProductType == PRODUCT_WORKSTATION) {
  338. if (!(SetupInitComponent.SetupData.OperationFlags & SETUPOP_STANDALONE)) {
  339. return TRUE;
  340. }
  341. // }
  342. return FALSE;
  343. case OC_COMPLETE_INSTALLATION:
  344. // if this is not gui mode setup, do nothing, else commit the pages
  345. if ((SetupInitComponent.SetupData.OperationFlags & SETUPOP_STANDALONE)) {
  346. break;
  347. }
  348. for (i=0; i<MAX_NTOC_PAGES; i++) {
  349. if (SetupWizardPages[NtOcWizardPages[i]].WizCommit) {
  350. SetupWizardPages[NtOcWizardPages[i]].WizCommit();
  351. }
  352. }
  353. break;
  354. case OC_QUERY_STATE:
  355. // we are always installed
  356. return SubcompOn;
  357. default:
  358. break;
  359. }
  360. return 0;
  361. }
  362. /*---------------------------------------------------------------------------*\
  363. Function: RunningAsAdministrator()
  364. |*---------------------------------------------------------------------------*|
  365. Description: Checks whether we are running as administrator on the machine
  366. or not
  367. \*---------------------------------------------------------------------------*/
  368. BOOL
  369. RunningAsAdministrator(
  370. VOID
  371. )
  372. {
  373. #ifdef _CHICAGO_
  374. return TRUE;
  375. #else
  376. BOOL fAdmin;
  377. HANDLE hThread;
  378. TOKEN_GROUPS *ptg = NULL;
  379. DWORD cbTokenGroups;
  380. DWORD dwGroup;
  381. PSID psidAdmin;
  382. SID_IDENTIFIER_AUTHORITY SystemSidAuthority= SECURITY_NT_AUTHORITY;
  383. // First we must open a handle to the access token for this thread.
  384. if ( !OpenThreadToken ( GetCurrentThread(), TOKEN_QUERY, FALSE, &hThread))
  385. {
  386. if ( GetLastError() == ERROR_NO_TOKEN)
  387. {
  388. // If the thread does not have an access token, we'll examine the
  389. // access token associated with the process.
  390. if (! OpenProcessToken ( GetCurrentProcess(), TOKEN_QUERY,
  391. &hThread))
  392. return ( FALSE);
  393. }
  394. else
  395. return ( FALSE);
  396. }
  397. // Then we must query the size of the group information associated with
  398. // the token. Note that we expect a FALSE result from GetTokenInformation
  399. // because we've given it a NULL buffer. On exit cbTokenGroups will tell
  400. // the size of the group information.
  401. if ( GetTokenInformation ( hThread, TokenGroups, NULL, 0, &cbTokenGroups))
  402. return ( FALSE);
  403. // Here we verify that GetTokenInformation failed for lack of a large
  404. // enough buffer.
  405. if ( GetLastError() != ERROR_INSUFFICIENT_BUFFER)
  406. return ( FALSE);
  407. // Now we allocate a buffer for the group information.
  408. // Since _alloca allocates on the stack, we don't have
  409. // to explicitly deallocate it. That happens automatically
  410. // when we exit this function.
  411. if ( ! ( ptg= (TOKEN_GROUPS *)malloc ( cbTokenGroups)))
  412. return ( FALSE);
  413. // Now we ask for the group information again.
  414. // This may fail if an administrator has added this account
  415. // to an additional group between our first call to
  416. // GetTokenInformation and this one.
  417. if ( !GetTokenInformation ( hThread, TokenGroups, ptg, cbTokenGroups,
  418. &cbTokenGroups) )
  419. {
  420. free(ptg);
  421. return ( FALSE);
  422. }
  423. // Now we must create a System Identifier for the Admin group.
  424. if ( ! AllocateAndInitializeSid ( &SystemSidAuthority, 2,
  425. SECURITY_BUILTIN_DOMAIN_RID,
  426. DOMAIN_ALIAS_RID_ADMINS,
  427. 0, 0, 0, 0, 0, 0, &psidAdmin) )
  428. {
  429. free(ptg);
  430. return ( FALSE);
  431. }
  432. // Finally we'll iterate through the list of groups for this access
  433. // token looking for a match against the SID we created above.
  434. fAdmin= FALSE;
  435. for ( dwGroup= 0; dwGroup < ptg->GroupCount; dwGroup++)
  436. {
  437. if ( EqualSid ( ptg->Groups[dwGroup].Sid, psidAdmin))
  438. {
  439. fAdmin = TRUE;
  440. break;
  441. }
  442. }
  443. // Before we exit we must explicity deallocate the SID we created.
  444. FreeSid ( psidAdmin);
  445. free(ptg);
  446. return ( fAdmin);
  447. #endif //_CHICAGO_
  448. }
  449. LRESULT
  450. CommonWizardProc(
  451. HWND hDlg,
  452. UINT message,
  453. WPARAM wParam,
  454. LPARAM lParam,
  455. DWORD WizardId
  456. )
  457. /*++
  458. Routine Description:
  459. Common procedure for handling wizard pages:
  460. Arguments:
  461. hDlg - Identifies the wizard page
  462. message - Specifies the message
  463. wParam - Specifies additional message-specific information
  464. lParam - Specifies additional message-specific information
  465. WizardId - Indicate which wizard page this is for
  466. Return Value:
  467. NULL - Message is processed and the dialog procedure should return FALSE
  468. Otherwise - Message is not completely processed and
  469. The return value is a pointer to the user mode memory structure
  470. --*/
  471. {
  472. switch (message) {
  473. case WM_NOTIFY:
  474. switch (((NMHDR *) lParam)->code) {
  475. case PSN_SETACTIVE:
  476. PropSheet_SetWizButtons( GetParent(hDlg),
  477. SetupWizardPages[WizardId].ButtonState
  478. );
  479. break;
  480. default:
  481. ;
  482. }
  483. break;
  484. default:
  485. ;
  486. }
  487. return FALSE;
  488. }