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.

3577 lines
94 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows NT
  4. //
  5. // Copyright (C) Microsoft Corporation, 1995 - 1998
  6. //
  7. // File: cepsetup.cpp
  8. //
  9. // Contents: The setup code for MSCEP
  10. //--------------------------------------------------------------------------
  11. #include "global.hxx"
  12. #include <dbgdef.h>
  13. #include "objsel.h"
  14. #include "setuputil.h"
  15. #include "cepsetup.h"
  16. #include "resource.h"
  17. #include "wincred.h"
  18. #include "netlib.h"
  19. #include "dsrole.h"
  20. //-----------------------------------------------------------------------
  21. //
  22. // Global data
  23. //
  24. //-----------------------------------------------------------------------
  25. HMODULE g_hModule=NULL;
  26. UINT g_cfDsObjectPicker = RegisterClipboardFormat(CFSTR_DSOP_DS_SELECTION_LIST);
  27. //-----------------------------------------------------------------------
  28. //CN has to be the 1st item and O the third in the following list and C is the last item. No other requirements for
  29. //the order
  30. //-----------------------------------------------------------------------
  31. CEP_ENROLL_INFO g_rgRAEnrollInfo[RA_INFO_COUNT]=
  32. {L"CN=", IDC_ENROLL_NAME,
  33. L"E=", IDC_ENROLL_EMAIL,
  34. L"O=", IDC_ENROLL_COMPANY,
  35. L"OU=", IDC_ENROLL_DEPARTMENT,
  36. L"L=", IDC_ENROLL_CITY,
  37. L"S=", IDC_ENROLL_STATE,
  38. L"C=", IDC_ENROLL_COUNTRY,
  39. };
  40. //-----------------------------------------------------------------------
  41. //the key length table
  42. //-----------------------------------------------------------------------
  43. DWORD g_rgdwKeyLength[] =
  44. {
  45. 512,
  46. 1024,
  47. 2048,
  48. 4096,
  49. };
  50. DWORD g_dwKeyLengthCount=sizeof(g_rgdwKeyLength)/sizeof(g_rgdwKeyLength[0]);
  51. DWORD g_rgdwSmallKeyLength[] =
  52. {
  53. 128,
  54. 256,
  55. 512,
  56. 1024,
  57. };
  58. DWORD g_dwSmallKeyLengthCount=sizeof(g_rgdwSmallKeyLength)/sizeof(g_rgdwSmallKeyLength[0]);
  59. //the list of possible default key lenght in the order of preference
  60. DWORD g_rgdwDefaultKey[] =
  61. {
  62. 1024,
  63. 2048,
  64. 512,
  65. 256,
  66. 4096,
  67. 128
  68. };
  69. DWORD g_dwDefaultKeyCount=sizeof(g_rgdwDefaultKey)/sizeof(g_rgdwDefaultKey[0]);
  70. //-----------------------------------------------------------------------
  71. //
  72. //The winProc for each of the setup wizard page
  73. //
  74. //-----------------------------------------------------------------------
  75. //-----------------------------------------------------------------------
  76. //Welcome
  77. //-----------------------------------------------------------------------
  78. INT_PTR APIENTRY CEP_Welcome(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
  79. {
  80. CEP_WIZARD_INFO *pCEPWizardInfo=NULL;
  81. PROPSHEETPAGE *pPropSheet=NULL;
  82. switch (msg)
  83. {
  84. case WM_INITDIALOG:
  85. //set the wizard information so that it can be shared
  86. pPropSheet = (PROPSHEETPAGE *) lParam;
  87. pCEPWizardInfo = (CEP_WIZARD_INFO *) (pPropSheet->lParam);
  88. SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pCEPWizardInfo);
  89. SetControlFont(pCEPWizardInfo->hBigBold, hwndDlg,IDC_BIG_BOLD_TITLE);
  90. break;
  91. case WM_NOTIFY:
  92. switch (((NMHDR FAR *) lParam)->code)
  93. {
  94. case PSN_KILLACTIVE:
  95. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FALSE);
  96. return TRUE;
  97. break;
  98. case PSN_RESET:
  99. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FALSE);
  100. break;
  101. case PSN_SETACTIVE:
  102. PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_NEXT);
  103. break;
  104. case PSN_WIZBACK:
  105. break;
  106. case PSN_WIZNEXT:
  107. break;
  108. default:
  109. return FALSE;
  110. }
  111. break;
  112. default:
  113. return FALSE;
  114. }
  115. return TRUE;
  116. }
  117. //-----------------------------------------------------------------------
  118. //App_ID
  119. //-----------------------------------------------------------------------
  120. INT_PTR APIENTRY CEP_App_ID(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
  121. {
  122. CEP_WIZARD_INFO *pCEPWizardInfo=NULL;
  123. PROPSHEETPAGE *pPropSheet=NULL;
  124. switch (msg)
  125. {
  126. case WM_INITDIALOG:
  127. //set the wizard information so that it can be shared
  128. pPropSheet = (PROPSHEETPAGE *) lParam;
  129. pCEPWizardInfo = (CEP_WIZARD_INFO *) (pPropSheet->lParam);
  130. //make sure pCertWizardInfo is a valid pointer
  131. if(NULL==pCEPWizardInfo)
  132. break;
  133. SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pCEPWizardInfo);
  134. SetControlFont(pCEPWizardInfo->hBold, hwndDlg,IDC_BOLD_TITLE);
  135. //by default, we use local machine account
  136. SendMessage(GetDlgItem(hwndDlg, IDC_APP_ID_RADIO1), BM_SETCHECK, BST_CHECKED, 0);
  137. SendMessage(GetDlgItem(hwndDlg, IDC_APP_ID_RADIO2), BM_SETCHECK, BST_UNCHECKED, 0);
  138. break;
  139. case WM_COMMAND:
  140. if(HIWORD(wParam) == BN_CLICKED)
  141. {
  142. switch (LOWORD(wParam))
  143. {
  144. case IDC_APP_ID_RADIO1:
  145. SendMessage(GetDlgItem(hwndDlg, IDC_APP_ID_RADIO1), BM_SETCHECK, BST_CHECKED, 0);
  146. SendMessage(GetDlgItem(hwndDlg, IDC_APP_ID_RADIO2), BM_SETCHECK, BST_UNCHECKED, 0);
  147. break;
  148. case IDC_APP_ID_RADIO2:
  149. SendMessage(GetDlgItem(hwndDlg, IDC_APP_ID_RADIO1), BM_SETCHECK, BST_UNCHECKED, 0);
  150. SendMessage(GetDlgItem(hwndDlg, IDC_APP_ID_RADIO2), BM_SETCHECK, BST_CHECKED, 0);
  151. break;
  152. default:
  153. break;
  154. }
  155. }
  156. break;
  157. case WM_NOTIFY:
  158. switch (((NMHDR FAR *) lParam)->code)
  159. {
  160. case PSN_KILLACTIVE:
  161. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FALSE);
  162. return TRUE;
  163. break;
  164. case PSN_RESET:
  165. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FALSE);
  166. break;
  167. case PSN_SETACTIVE:
  168. PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_NEXT|PSWIZB_BACK);
  169. break;
  170. case PSN_WIZBACK:
  171. break;
  172. case PSN_WIZNEXT:
  173. if(NULL==(pCEPWizardInfo=(CEP_WIZARD_INFO *)GetWindowLongPtr(hwndDlg, DWLP_USER)))
  174. break;
  175. //check for the application identity options
  176. if(BST_CHECKED==SendDlgItemMessage(hwndDlg,IDC_APP_ID_RADIO1, BM_GETCHECK, 0, 0))
  177. {
  178. pCEPWizardInfo->fLocalSystem=TRUE;
  179. //skip the account page and goes to the challege page directly
  180. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, IDD_CHALLENGE);
  181. }
  182. else
  183. {
  184. pCEPWizardInfo->fLocalSystem=FALSE;
  185. }
  186. break;
  187. default:
  188. return FALSE;
  189. }
  190. break;
  191. default:
  192. return FALSE;
  193. }
  194. return TRUE;
  195. }
  196. //-----------------------------------------------------------------------
  197. //Account
  198. //-----------------------------------------------------------------------
  199. INT_PTR APIENTRY CEP_Account(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
  200. {
  201. CEP_WIZARD_INFO *pCEPWizardInfo=NULL;
  202. PROPSHEETPAGE *pPropSheet=NULL;
  203. WCHAR wszText[MAX_STRING_SIZE];
  204. int idsText=IDS_ACCOUNT_INTRO_STD;
  205. int idsErr=0;
  206. DWORD dwChar=0;
  207. DWORD dwDomainChar=0;
  208. DWORD dwWinStatus=0;
  209. WCHAR wszUser[CREDUI_MAX_USERNAME_LENGTH+1];
  210. WCHAR wszDomain[CREDUI_MAX_USERNAME_LENGTH+1];
  211. HRESULT hr=S_OK;
  212. int idsHrErr=0;
  213. BOOL fMember=FALSE;
  214. SID_NAME_USE SidName;
  215. PRIVILEGE_SET ps;
  216. DWORD dwPSSize=0;
  217. DWORD dwSize=0;
  218. BOOL fAccessAllowed = FALSE;
  219. DWORD grantAccess=0;
  220. GENERIC_MAPPING GenericMapping={
  221. ACTRL_DS_OPEN | ACTRL_DS_LIST | ACTRL_DS_SELF | ACTRL_DS_READ_PROP,
  222. ACTRL_DS_CREATE_CHILD | ACTRL_DS_DELETE_CHILD | ACTRL_DS_WRITE_PROP | ACTRL_DS_DELETE_TREE,
  223. ACTRL_DS_CREATE_CHILD | ACTRL_DS_DELETE_CHILD | ACTRL_DS_WRITE_PROP | ACTRL_DS_DELETE_TREE,
  224. ACTRL_DS_OPEN | ACTRL_DS_LIST | ACTRL_DS_SELF | ACTRL_DS_READ_PROP | ACTRL_DS_CREATE_CHILD | ACTRL_DS_DELETE_CHILD | ACTRL_DS_WRITE_PROP | ACTRL_DS_DELETE_TREE,
  225. };
  226. LPWSTR pwszObjectPicker=NULL;
  227. LPWSTR pwszConfirm=NULL;
  228. LPWSTR pwszAccount=NULL;
  229. LPWSTR pwszIIS=NULL; //"xiaohs4\IIS_WPG"
  230. LPWSTR pwszDomain=NULL;
  231. LPWSTR pwszComputerName=NULL;
  232. PSID pSidIIS=NULL;
  233. HCERTTYPE hCertType=NULL;
  234. PSECURITY_DESCRIPTOR pCertTypeSD=NULL;
  235. switch (msg)
  236. {
  237. case WM_INITDIALOG:
  238. //set the wizard information so that it can be shared
  239. pPropSheet = (PROPSHEETPAGE *) lParam;
  240. pCEPWizardInfo = (CEP_WIZARD_INFO *) (pPropSheet->lParam);
  241. //make sure pCertWizardInfo is a valid pointer
  242. if(NULL==pCEPWizardInfo)
  243. break;
  244. SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pCEPWizardInfo);
  245. SetControlFont(pCEPWizardInfo->hBold, hwndDlg,IDC_BOLD_TITLE);
  246. //update the intro statement based on the type of the CA
  247. if(pCEPWizardInfo->fEnterpriseCA)
  248. idsText=IDS_ACCOUNT_INTRO_ENT;
  249. if(LoadStringU(g_hModule, idsText, wszText, MAX_STRING_SIZE))
  250. {
  251. SetDlgItemTextU(hwndDlg, IDC_ACCOUNT_INTRO, wszText);
  252. }
  253. break;
  254. case WM_COMMAND:
  255. if(HIWORD(wParam) == BN_CLICKED)
  256. {
  257. //user wants to browse for the account name
  258. if(LOWORD(wParam) == IDC_ACCOUNT_BROWSE)
  259. {
  260. if(NULL==(pCEPWizardInfo=(CEP_WIZARD_INFO *)GetWindowLongPtr(hwndDlg, DWLP_USER)))
  261. break;
  262. if(CEPGetAccountNameFromPicker(hwndDlg,
  263. pCEPWizardInfo->pIDsObjectPicker,
  264. &pwszObjectPicker))
  265. {
  266. //set the account name in the edit box
  267. SetDlgItemTextU(hwndDlg, IDC_ACCOUNT_NAME, pwszObjectPicker);
  268. free(pwszObjectPicker);
  269. }
  270. }
  271. }
  272. break;
  273. case WM_NOTIFY:
  274. switch (((NMHDR FAR *) lParam)->code)
  275. {
  276. case PSN_KILLACTIVE:
  277. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FALSE);
  278. return TRUE;
  279. break;
  280. case PSN_RESET:
  281. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FALSE);
  282. break;
  283. case PSN_SETACTIVE:
  284. PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_NEXT|PSWIZB_BACK);
  285. break;
  286. case PSN_WIZBACK:
  287. break;
  288. case PSN_WIZNEXT:
  289. if(NULL==(pCEPWizardInfo=(CEP_WIZARD_INFO *)GetWindowLongPtr(hwndDlg, DWLP_USER)))
  290. break;
  291. //free the information
  292. if(pCEPWizardInfo->pwszUserName)
  293. {
  294. free(pCEPWizardInfo->pwszUserName);
  295. pCEPWizardInfo->pwszUserName=NULL;
  296. }
  297. if(pCEPWizardInfo->pwszPassword)
  298. {
  299. SecureZeroMemory(pCEPWizardInfo->pwszPassword, sizeof(WCHAR) * wcslen(pCEPWizardInfo->pwszPassword));
  300. free(pCEPWizardInfo->pwszPassword);
  301. pCEPWizardInfo->pwszPassword=NULL;
  302. }
  303. if(pCEPWizardInfo->hAccountToken)
  304. {
  305. CloseHandle(pCEPWizardInfo->hAccountToken);
  306. pCEPWizardInfo->hAccountToken=NULL;
  307. }
  308. //get the account name
  309. if(0==(dwChar=(DWORD)SendDlgItemMessage(hwndDlg, IDC_ACCOUNT_NAME, WM_GETTEXTLENGTH, 0, 0)))
  310. {
  311. idsErr=IDS_ACCOUNT_EMPTY;
  312. goto Account_Done;
  313. }
  314. pCEPWizardInfo->pwszUserName=(LPWSTR)malloc(sizeof(WCHAR)*(dwChar+1));
  315. if(NULL==(pCEPWizardInfo->pwszUserName))
  316. goto Account_Done;
  317. GetDlgItemTextU(hwndDlg, IDC_ACCOUNT_NAME, pCEPWizardInfo->pwszUserName, dwChar+1);
  318. //get the password
  319. if(0==(dwChar=(DWORD)SendDlgItemMessage(hwndDlg, IDC_ACCOUNT_PASSWORD, WM_GETTEXTLENGTH, 0, 0)))
  320. {
  321. idsErr=IDS_PASSWORD_EMPTY;
  322. goto Account_Done;
  323. }
  324. pCEPWizardInfo->pwszPassword=(LPWSTR)malloc(sizeof(WCHAR)*(dwChar+1));
  325. if(NULL==(pCEPWizardInfo->pwszPassword))
  326. goto Account_Done;
  327. *(pCEPWizardInfo->pwszPassword)=L'\0';
  328. GetDlgItemTextU(hwndDlg, IDC_ACCOUNT_PASSWORD, pCEPWizardInfo->pwszPassword, dwChar+1);
  329. //get the confirm
  330. if(0==(dwChar=(DWORD)SendDlgItemMessage(hwndDlg, IDC_ACCOUNT_CONFIRM, WM_GETTEXTLENGTH, 0, 0)))
  331. {
  332. idsErr=IDS_PASSWORD_NO_MATCH;
  333. goto Account_Done;
  334. }
  335. pwszConfirm=(LPWSTR)malloc(sizeof(WCHAR)*(dwChar+1));
  336. if(NULL==pwszConfirm)
  337. goto Account_Done;
  338. GetDlgItemTextU(hwndDlg, IDC_ACCOUNT_CONFIRM, pwszConfirm, dwChar+1);
  339. //Verify the password match
  340. if(0 != wcscmp(pwszConfirm, pCEPWizardInfo->pwszPassword))
  341. {
  342. idsErr=IDS_PASSWORD_NO_MATCH;
  343. goto Account_Done;
  344. }
  345. //Verify the user name are correctly formatted
  346. wszDomain[0]=L'\0';
  347. if(NO_ERROR != CredUIParseUserNameW(
  348. pCEPWizardInfo->pwszUserName,
  349. wszUser,
  350. sizeof(wszUser)/sizeof(WCHAR),
  351. wszDomain,
  352. sizeof(wszDomain)/sizeof(WCHAR)))
  353. {
  354. idsErr=IDS_INVALID_NAME;
  355. goto Account_Done;
  356. }
  357. //Verify the account does exist. Obtain the account's token
  358. //Interactive logon is required on a non-dc machine
  359. if(FALSE == pCEPWizardInfo->fDC)
  360. {
  361. if(!LogonUserW(
  362. wszUser,
  363. wszDomain,
  364. pCEPWizardInfo->pwszPassword,
  365. LOGON32_LOGON_INTERACTIVE,
  366. LOGON32_PROVIDER_DEFAULT,
  367. &(pCEPWizardInfo->hAccountToken)))
  368. {
  369. idsHrErr=IDS_FAIL_LOGON_USER;
  370. goto Account_Done;
  371. }
  372. //do a network logon to obtain the impersonation handle
  373. if(pCEPWizardInfo->hAccountToken)
  374. {
  375. CloseHandle(pCEPWizardInfo->hAccountToken);
  376. pCEPWizardInfo->hAccountToken=NULL;
  377. }
  378. }
  379. //network logon to obtain the token
  380. if(!LogonUserW(
  381. wszUser,
  382. wszDomain,
  383. pCEPWizardInfo->pwszPassword,
  384. LOGON32_LOGON_NETWORK,
  385. LOGON32_PROVIDER_DEFAULT,
  386. &(pCEPWizardInfo->hAccountToken)))
  387. {
  388. idsHrErr=IDS_FAIL_LOGON_USER;
  389. goto Account_Done;
  390. }
  391. //build the account name for IIS_WPG group.
  392. //for a non-DC, it will be localhost\IIS_WPG
  393. //for a DC, it will be domain\IIS_WPG
  394. //get the domain or localhost name
  395. pwszAccount=GetAccountDomainName(pCEPWizardInfo->fDC);
  396. if(NULL==pwszAccount)
  397. {
  398. idsHrErr=IDS_FAIL_FIND_DOMAIN;
  399. goto Account_Done;
  400. }
  401. //build the IIS_WPG account
  402. pwszIIS=(LPWSTR)malloc((wcslen(pwszAccount) + 1 + wcslen(IIS_WPG) + 1)*sizeof(WCHAR));
  403. if(NULL==pwszIIS)
  404. goto Account_Done;
  405. wcscpy(pwszIIS, pwszAccount);
  406. wcscat(pwszIIS, L"\\");
  407. wcscat(pwszIIS, IIS_WPG);
  408. //Obtain the SID for the IIS_WPG group
  409. dwChar=0;
  410. dwDomainChar=0;
  411. LookupAccountNameW(
  412. NULL, //local system
  413. pwszIIS,
  414. NULL,
  415. &dwChar,
  416. NULL,
  417. &dwDomainChar,
  418. &SidName);
  419. pSidIIS=(PSID)malloc(dwChar);
  420. if(NULL==pSidIIS)
  421. goto Account_Done;
  422. pwszDomain=(LPWSTR)malloc(dwDomainChar * sizeof(WCHAR));
  423. if(NULL==pwszDomain)
  424. goto Account_Done;
  425. if(!LookupAccountNameW(
  426. NULL, //local system
  427. pwszIIS,
  428. pSidIIS,
  429. &dwChar,
  430. pwszDomain,
  431. &dwDomainChar,
  432. &SidName))
  433. {
  434. idsHrErr=IDS_FAIL_LOOK_UP;
  435. goto Account_Done;
  436. }
  437. //Verify the account is part of the local IIS_WPG group
  438. if(!CheckTokenMembership(
  439. pCEPWizardInfo->hAccountToken,
  440. pSidIIS,
  441. &fMember))
  442. {
  443. idsHrErr=IDS_FAIL_CHECK_MEMBER;
  444. goto Account_Done;
  445. }
  446. if(FALSE == fMember)
  447. {
  448. idsErr=IDS_NOT_IIS_MEMBER;
  449. goto Account_Done;
  450. }
  451. //on an enterprise CA, verify the account as READ access to the template
  452. if(pCEPWizardInfo->fEnterpriseCA)
  453. {
  454. //make sure that this is an domain account:
  455. //DOMAIN_GROUP_RID_USERS
  456. if(0 != wcslen(wszDomain))
  457. {
  458. dwSize=0;
  459. GetComputerNameExW(ComputerNamePhysicalDnsHostname,
  460. NULL,
  461. &dwSize);
  462. pwszComputerName=(LPWSTR)malloc(dwSize * sizeof(WCHAR));
  463. if(NULL==pwszComputerName)
  464. goto Account_Done;
  465. if(!GetComputerNameExW(ComputerNamePhysicalDnsHostname,
  466. pwszComputerName,
  467. &dwSize))
  468. {
  469. idsHrErr=IDS_FAIL_GET_COMPUTER_NAME;
  470. goto Account_Done;
  471. }
  472. if(0 == _wcsicmp(wszDomain, pwszComputerName))
  473. {
  474. idsErr=IDS_NO_LOCAL_ACCOUNT;
  475. goto Account_Done;
  476. }
  477. }
  478. hr=CAFindCertTypeByName(wszCERTTYPE_IPSEC_INTERMEDIATE_OFFLINE, NULL, CT_ENUM_MACHINE_TYPES, &hCertType);
  479. if(S_OK != hr)
  480. {
  481. idsHrErr=IDS_FAIL_FIND_CERT_TYPE;
  482. goto Account_Done;
  483. }
  484. //get the SD for the template
  485. hr=CACertTypeGetSecurity(hCertType, &pCertTypeSD);
  486. if(S_OK != hr)
  487. {
  488. idsHrErr=IDS_FAIL_FIND_SD_CERT_TYPE;
  489. goto Account_Done;
  490. }
  491. //check the DS_READ Access
  492. dwPSSize=sizeof(ps);
  493. if(!AccessCheck(
  494. pCertTypeSD,
  495. pCEPWizardInfo->hAccountToken,
  496. ACTRL_DS_LIST | ACTRL_DS_READ_PROP,
  497. &GenericMapping,
  498. &ps,
  499. &dwPSSize,
  500. &grantAccess,
  501. &fAccessAllowed))
  502. {
  503. idsHrErr=IDS_FAIL_DETECT_READ_ACCESS;
  504. goto Account_Done;
  505. }
  506. //make sure the account has read access to the template
  507. if(FALSE == fAccessAllowed)
  508. {
  509. idsErr=IDS_NO_READ_ACCESS_TO_TEMPLATE;
  510. goto Account_Done;
  511. }
  512. }
  513. //everything looks good
  514. idsErr=0;
  515. idsHrErr=0;
  516. Account_Done:
  517. if(pwszComputerName)
  518. {
  519. free(pwszComputerName);
  520. }
  521. if(pwszConfirm)
  522. {
  523. free(pwszConfirm);
  524. }
  525. if(pwszAccount)
  526. {
  527. NetApiBufferFree(pwszAccount);
  528. }
  529. if(pwszIIS)
  530. {
  531. free(pwszIIS);
  532. }
  533. if(pwszDomain)
  534. {
  535. free(pwszDomain);
  536. }
  537. if(pSidIIS)
  538. {
  539. free(pSidIIS);
  540. }
  541. if(pCertTypeSD)
  542. {
  543. LocalFree(pCertTypeSD);
  544. }
  545. if(hCertType)
  546. {
  547. CACloseCertType(hCertType);
  548. }
  549. if(0 != idsErr)
  550. {
  551. CEPMessageBox(hwndDlg, idsErr, MB_ICONERROR|MB_OK|MB_APPLMODAL);
  552. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, -1);
  553. }
  554. else
  555. {
  556. if(0 != idsHrErr)
  557. {
  558. if(S_OK == hr)
  559. {
  560. hr=HRESULT_FROM_WIN32(GetLastError());
  561. }
  562. CEPErrorMessageBoxEx(hwndDlg, idsHrErr, hr, MB_ICONERROR|MB_OK|MB_APPLMODAL, IDS_GEN_ERROR_MSG_HR, IDS_GEN_ERROR_MSG);
  563. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, -1);
  564. }
  565. }
  566. break;
  567. default:
  568. return FALSE;
  569. }
  570. break;
  571. default:
  572. return FALSE;
  573. }
  574. return TRUE;
  575. }
  576. //-----------------------------------------------------------------------
  577. //Chanllenge
  578. //-----------------------------------------------------------------------
  579. INT_PTR APIENTRY CEP_Challenge(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
  580. {
  581. CEP_WIZARD_INFO *pCEPWizardInfo=NULL;
  582. PROPSHEETPAGE *pPropSheet=NULL;
  583. switch (msg)
  584. {
  585. case WM_INITDIALOG:
  586. //set the wizard information so that it can be shared
  587. pPropSheet = (PROPSHEETPAGE *) lParam;
  588. pCEPWizardInfo = (CEP_WIZARD_INFO *) (pPropSheet->lParam);
  589. //make sure pCertWizardInfo is a valid pointer
  590. if(NULL==pCEPWizardInfo)
  591. break;
  592. SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pCEPWizardInfo);
  593. SetControlFont(pCEPWizardInfo->hBold, hwndDlg,IDC_BOLD_TITLE);
  594. //by default, we should use Challenge password
  595. SendMessage(GetDlgItem(hwndDlg, IDC_CHALLENGE_CHECK), BM_SETCHECK, BST_CHECKED, 0);
  596. break;
  597. case WM_COMMAND:
  598. break;
  599. case WM_NOTIFY:
  600. switch (((NMHDR FAR *) lParam)->code)
  601. {
  602. case PSN_KILLACTIVE:
  603. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FALSE);
  604. return TRUE;
  605. break;
  606. case PSN_RESET:
  607. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FALSE);
  608. break;
  609. case PSN_SETACTIVE:
  610. PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_NEXT|PSWIZB_BACK);
  611. break;
  612. case PSN_WIZBACK:
  613. if(NULL==(pCEPWizardInfo=(CEP_WIZARD_INFO *)GetWindowLongPtr(hwndDlg, DWLP_USER)))
  614. break;
  615. if(TRUE == (pCEPWizardInfo->fLocalSystem))
  616. {
  617. //skip the account page and goes to the application identity page
  618. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, IDD_APP_ID);
  619. }
  620. break;
  621. case PSN_WIZNEXT:
  622. if(NULL==(pCEPWizardInfo=(CEP_WIZARD_INFO *)GetWindowLongPtr(hwndDlg, DWLP_USER)))
  623. break;
  624. //check for the Challenge password options
  625. if(BST_CHECKED==SendDlgItemMessage(hwndDlg,IDC_CHALLENGE_CHECK, BM_GETCHECK, 0, 0))
  626. pCEPWizardInfo->fPassword=TRUE;
  627. else
  628. pCEPWizardInfo->fPassword=FALSE;
  629. //warn users about the implication of not using a password
  630. if(FALSE == pCEPWizardInfo->fPassword)
  631. {
  632. if(IDNO==CEPMessageBox(hwndDlg, IDS_NO_CHALLENGE_PASSWORD, MB_ICONWARNING|MB_YESNO|MB_APPLMODAL))
  633. {
  634. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, -1);
  635. break;
  636. }
  637. }
  638. if(!EmptyCEPStore())
  639. {
  640. CEPMessageBox(hwndDlg, IDS_EXISTING_RA, MB_ICONINFORMATION|MB_OK|MB_APPLMODAL);
  641. if(IDNO==CEPMessageBox(hwndDlg, IDS_PROCESS_PENDING, MB_ICONQUESTION|MB_YESNO|MB_APPLMODAL))
  642. {
  643. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, -1);
  644. break;
  645. }
  646. }
  647. break;
  648. default:
  649. return FALSE;
  650. }
  651. break;
  652. default:
  653. return FALSE;
  654. }
  655. return TRUE;
  656. }
  657. //-----------------------------------------------------------------------
  658. // Enroll
  659. //-----------------------------------------------------------------------
  660. INT_PTR APIENTRY CEP_Enroll(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
  661. {
  662. CEP_WIZARD_INFO *pCEPWizardInfo=NULL;
  663. PROPSHEETPAGE *pPropSheet=NULL;
  664. DWORD dwIndex=0;
  665. DWORD dwChar=0;
  666. switch (msg)
  667. {
  668. case WM_INITDIALOG:
  669. //set the wizard information so that it can be shared
  670. pPropSheet = (PROPSHEETPAGE *) lParam;
  671. pCEPWizardInfo = (CEP_WIZARD_INFO *) (pPropSheet->lParam);
  672. //make sure pCertWizardInfo is a valid pointer
  673. if(NULL==pCEPWizardInfo)
  674. break;
  675. SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pCEPWizardInfo);
  676. SetControlFont(pCEPWizardInfo->hBold, hwndDlg,IDC_BOLD_TITLE);
  677. //by default, we do not use the advanced enrollment options
  678. SendMessage(GetDlgItem(hwndDlg, IDC_ENORLL_ADV_CHECK), BM_SETCHECK, BST_UNCHECKED, 0);
  679. //preset the country string since we only allow 2 characters
  680. SetDlgItemTextU(hwndDlg, IDC_ENROLL_COUNTRY, L"US");
  681. break;
  682. case WM_COMMAND:
  683. break;
  684. case WM_NOTIFY:
  685. switch (((NMHDR FAR *) lParam)->code)
  686. {
  687. case PSN_KILLACTIVE:
  688. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FALSE);
  689. return TRUE;
  690. break;
  691. case PSN_RESET:
  692. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FALSE);
  693. break;
  694. case PSN_SETACTIVE:
  695. PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_NEXT|PSWIZB_BACK);
  696. if(NULL==(pCEPWizardInfo=(CEP_WIZARD_INFO *)GetWindowLongPtr(hwndDlg, DWLP_USER)))
  697. break;
  698. //if the adv selection is made, it has to stay selected
  699. if(pCEPWizardInfo->fEnrollAdv)
  700. EnableWindow(GetDlgItem(hwndDlg, IDC_ENORLL_ADV_CHECK), FALSE);
  701. break;
  702. case PSN_WIZBACK:
  703. break;
  704. case PSN_WIZNEXT:
  705. if(NULL==(pCEPWizardInfo=(CEP_WIZARD_INFO *)GetWindowLongPtr(hwndDlg, DWLP_USER)))
  706. break;
  707. //gather RA subject informaton
  708. for(dwIndex=0; dwIndex < RA_INFO_COUNT; dwIndex++)
  709. {
  710. if(pCEPWizardInfo->rgpwszName[dwIndex])
  711. {
  712. free(pCEPWizardInfo->rgpwszName[dwIndex]);
  713. pCEPWizardInfo->rgpwszName[dwIndex]=NULL;
  714. }
  715. if(0!=(dwChar=(DWORD)SendDlgItemMessage(hwndDlg,
  716. g_rgRAEnrollInfo[dwIndex].dwIDC,
  717. WM_GETTEXTLENGTH, 0, 0)))
  718. {
  719. pCEPWizardInfo->rgpwszName[dwIndex]=(LPWSTR)malloc(sizeof(WCHAR)*(dwChar+1));
  720. if(NULL!=(pCEPWizardInfo->rgpwszName[dwIndex]))
  721. {
  722. GetDlgItemTextU(hwndDlg, g_rgRAEnrollInfo[dwIndex].dwIDC,
  723. pCEPWizardInfo->rgpwszName[dwIndex],
  724. dwChar+1);
  725. }
  726. }
  727. }
  728. //we require name and company
  729. if((NULL==(pCEPWizardInfo->rgpwszName[0])) ||
  730. (NULL==(pCEPWizardInfo->rgpwszName[2]))
  731. )
  732. {
  733. CEPMessageBox(hwndDlg, IDS_ENROLL_REQUIRE_NAME, MB_ICONERROR|MB_OK|MB_APPLMODAL);
  734. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, -1);
  735. break;
  736. }
  737. //we only allow 2 characeters for the country
  738. if(NULL !=(pCEPWizardInfo->rgpwszName[RA_INFO_COUNT -1]))
  739. {
  740. if(2 < wcslen(pCEPWizardInfo->rgpwszName[RA_INFO_COUNT -1]))
  741. {
  742. CEPMessageBox(hwndDlg, IDS_ENROLL_COUNTRY_TOO_LARGE, MB_ICONERROR|MB_OK|MB_APPLMODAL);
  743. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, -1);
  744. break;
  745. }
  746. }
  747. //check for the advanced options
  748. if(BST_CHECKED==SendDlgItemMessage(hwndDlg,IDC_ENORLL_ADV_CHECK, BM_GETCHECK, 0, 0))
  749. pCEPWizardInfo->fEnrollAdv=TRUE;
  750. else
  751. pCEPWizardInfo->fEnrollAdv=FALSE;
  752. //If the advanced is selected, skip the CSP Page
  753. if(FALSE== pCEPWizardInfo->fEnrollAdv)
  754. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, IDD_COMPLETION);
  755. break;
  756. default:
  757. return FALSE;
  758. }
  759. break;
  760. default:
  761. return FALSE;
  762. }
  763. return TRUE;
  764. }
  765. //-----------------------------------------------------------------------
  766. // CSP
  767. //-----------------------------------------------------------------------
  768. INT_PTR APIENTRY CEP_CSP(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
  769. {
  770. CEP_WIZARD_INFO *pCEPWizardInfo=NULL;
  771. PROPSHEETPAGE *pPropSheet=NULL;
  772. NM_LISTVIEW FAR * pnmv=NULL;
  773. BOOL fSign=FALSE;
  774. int idCombo=0;
  775. switch (msg)
  776. {
  777. case WM_INITDIALOG:
  778. //set the wizard information so that it can be shared
  779. pPropSheet = (PROPSHEETPAGE *) lParam;
  780. pCEPWizardInfo = (CEP_WIZARD_INFO *) (pPropSheet->lParam);
  781. //make sure pCertWizardInfo is a valid pointer
  782. if(NULL==pCEPWizardInfo)
  783. break;
  784. SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pCEPWizardInfo);
  785. SetControlFont(pCEPWizardInfo->hBold, hwndDlg,IDC_BOLD_TITLE);
  786. //populate the CSP list and key length combo box
  787. InitCSPList(hwndDlg, IDC_CSP_SIGN_LIST, TRUE,
  788. pCEPWizardInfo);
  789. InitCSPList(hwndDlg, IDC_CSP_ENCRYPT_LIST, FALSE,
  790. pCEPWizardInfo);
  791. RefreshKeyLengthCombo(hwndDlg,
  792. IDC_CSP_SIGN_LIST,
  793. IDC_CSP_SIGN_COMBO,
  794. TRUE,
  795. pCEPWizardInfo);
  796. RefreshKeyLengthCombo(hwndDlg,
  797. IDC_CSP_ENCRYPT_LIST,
  798. IDC_CSP_ENCRYPT_COMBO,
  799. FALSE,
  800. pCEPWizardInfo);
  801. break;
  802. case WM_COMMAND:
  803. break;
  804. case WM_NOTIFY:
  805. switch (((NMHDR FAR *) lParam)->code)
  806. {
  807. case LVN_ITEMCHANGED:
  808. if(NULL==(pCEPWizardInfo=(CEP_WIZARD_INFO *)GetWindowLongPtr(hwndDlg, DWLP_USER)))
  809. break;
  810. pnmv = (LPNMLISTVIEW) lParam;
  811. if(NULL==pnmv)
  812. break;
  813. if (pnmv->uNewState & LVIS_SELECTED)
  814. {
  815. if(IDC_CSP_SIGN_LIST == (pnmv->hdr).idFrom)
  816. {
  817. fSign=TRUE;
  818. idCombo=IDC_CSP_SIGN_COMBO;
  819. }
  820. else
  821. {
  822. if(IDC_CSP_ENCRYPT_LIST != (pnmv->hdr).idFrom)
  823. break;
  824. fSign=FALSE;
  825. idCombo=IDC_CSP_ENCRYPT_COMBO;
  826. }
  827. RefreshKeyLengthCombo(
  828. hwndDlg,
  829. (int)((pnmv->hdr).idFrom),
  830. idCombo,
  831. fSign,
  832. pCEPWizardInfo);
  833. }
  834. break;
  835. case PSN_KILLACTIVE:
  836. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FALSE);
  837. return TRUE;
  838. break;
  839. case PSN_RESET:
  840. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FALSE);
  841. break;
  842. case PSN_SETACTIVE:
  843. PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_NEXT|PSWIZB_BACK);
  844. break;
  845. case PSN_WIZBACK:
  846. break;
  847. case PSN_WIZNEXT:
  848. if(NULL==(pCEPWizardInfo=(CEP_WIZARD_INFO *)GetWindowLongPtr(hwndDlg, DWLP_USER)))
  849. break;
  850. //get the select CSP and key length
  851. if(!GetSelectedCSP(hwndDlg,
  852. IDC_CSP_SIGN_LIST,
  853. &(pCEPWizardInfo->dwSignProvIndex)))
  854. {
  855. CEPMessageBox(hwndDlg, IDS_SELECT_SIGN_CSP, MB_ICONERROR|MB_OK|MB_APPLMODAL);
  856. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, -1);
  857. break;
  858. }
  859. if(!GetSelectedCSP(hwndDlg,
  860. IDC_CSP_ENCRYPT_LIST,
  861. &(pCEPWizardInfo->dwEncryptProvIndex)))
  862. {
  863. CEPMessageBox(hwndDlg, IDS_SELECT_ENCRYPT_CSP, MB_ICONERROR|MB_OK|MB_APPLMODAL);
  864. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, -1);
  865. break;
  866. }
  867. if(!GetSelectedKeyLength(hwndDlg,
  868. IDC_CSP_SIGN_COMBO,
  869. &(pCEPWizardInfo->dwSignKeyLength)))
  870. {
  871. CEPMessageBox(hwndDlg, IDS_SELECT_SIGN_KEY_LENGTH, MB_ICONERROR|MB_OK|MB_APPLMODAL);
  872. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, -1);
  873. break;
  874. }
  875. if(!GetSelectedKeyLength(hwndDlg,
  876. IDC_CSP_ENCRYPT_COMBO,
  877. &(pCEPWizardInfo->dwEncryptKeyLength)))
  878. {
  879. CEPMessageBox(hwndDlg, IDS_SELECT_ENCRYPT_KEY_LENGTH, MB_ICONERROR|MB_OK|MB_APPLMODAL);
  880. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, -1);
  881. break;
  882. }
  883. break;
  884. default:
  885. return FALSE;
  886. }
  887. break;
  888. default:
  889. return FALSE;
  890. }
  891. return TRUE;
  892. }
  893. //-----------------------------------------------------------------------
  894. //Completion
  895. //-----------------------------------------------------------------------
  896. INT_PTR APIENTRY CEP_Completion(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
  897. {
  898. CEP_WIZARD_INFO *pCEPWizardInfo=NULL;
  899. PROPSHEETPAGE *pPropSheet=NULL;
  900. HWND hwndControl=NULL;
  901. LV_COLUMNW lvC;
  902. HCURSOR hPreCursor=NULL;
  903. HCURSOR hWinPreCursor=NULL;
  904. switch (msg)
  905. {
  906. case WM_INITDIALOG:
  907. //set the wizard information so that it can be shared
  908. pPropSheet = (PROPSHEETPAGE *) lParam;
  909. pCEPWizardInfo = (CEP_WIZARD_INFO *) (pPropSheet->lParam);
  910. //make sure pCertWizardInfo is a valid pointer
  911. if(NULL==pCEPWizardInfo)
  912. break;
  913. SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pCEPWizardInfo);
  914. SetControlFont(pCEPWizardInfo->hBigBold, hwndDlg,IDC_BIG_BOLD_TITLE);
  915. //insert two columns
  916. hwndControl=GetDlgItem(hwndDlg, IDC_COMPLETION_LIST);
  917. memset(&lvC, 0, sizeof(LV_COLUMNW));
  918. lvC.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
  919. lvC.fmt = LVCFMT_LEFT; // Left-align the column.
  920. lvC.cx = 20; // Width of the column, in pixels.
  921. lvC.pszText = L""; // The text for the column.
  922. lvC.iSubItem=0;
  923. if (ListView_InsertColumnU(hwndControl, 0, &lvC) == -1)
  924. break;
  925. //2nd column is the content
  926. memset(&lvC, 0, sizeof(LV_COLUMNW));
  927. lvC.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
  928. lvC.fmt = LVCFMT_LEFT; // Left-align the column.
  929. lvC.cx = 10; //(dwMaxSize+2)*7; // Width of the column, in pixels.
  930. lvC.pszText = L""; // The text for the column.
  931. lvC.iSubItem= 1;
  932. if (ListView_InsertColumnU(hwndControl, 1, &lvC) == -1)
  933. break;
  934. break;
  935. case WM_COMMAND:
  936. break;
  937. case WM_NOTIFY:
  938. switch (((NMHDR FAR *) lParam)->code)
  939. {
  940. case PSN_KILLACTIVE:
  941. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FALSE);
  942. return TRUE;
  943. break;
  944. case PSN_RESET:
  945. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FALSE);
  946. break;
  947. case PSN_SETACTIVE:
  948. PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_BACK|PSWIZB_FINISH);
  949. if(NULL==(pCEPWizardInfo=(CEP_WIZARD_INFO *)GetWindowLongPtr(hwndDlg, DWLP_USER)))
  950. break;
  951. if(hwndControl=GetDlgItem(hwndDlg, IDC_COMPLETION_LIST))
  952. DisplayConfirmation(hwndControl, pCEPWizardInfo);
  953. break;
  954. case PSN_WIZBACK:
  955. if(NULL==(pCEPWizardInfo=(CEP_WIZARD_INFO *)GetWindowLongPtr(hwndDlg, DWLP_USER)))
  956. break;
  957. //skip CSP page if adv is not selected
  958. if(FALSE == pCEPWizardInfo->fEnrollAdv)
  959. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, IDD_ENROLL);
  960. break;
  961. case PSN_WIZFINISH:
  962. if(NULL==(pCEPWizardInfo=(CEP_WIZARD_INFO *)GetWindowLongPtr(hwndDlg, DWLP_USER)))
  963. break;
  964. //overwrite the cursor for this window class
  965. hWinPreCursor=(HCURSOR)SetClassLongPtr(hwndDlg, GCLP_HCURSOR, (LONG_PTR)NULL);
  966. hPreCursor=SetCursor(LoadCursor(NULL, IDC_WAIT));
  967. //do the real setup work
  968. I_DoSetupWork(hwndDlg, pCEPWizardInfo);
  969. //set the cursor back
  970. SetCursor(hPreCursor);
  971. SetWindowLongPtr(hwndDlg, GCLP_HCURSOR, (LONG_PTR)hWinPreCursor);
  972. break;
  973. default:
  974. return FALSE;
  975. }
  976. break;
  977. default:
  978. return FALSE;
  979. }
  980. return TRUE;
  981. }
  982. //--------------------------------------------------------------------------
  983. //
  984. // Helper Functions for the wizard pages
  985. //
  986. //--------------------------------------------------------------------------
  987. //--------------------------------------------------------------------------
  988. //
  989. // CEPGetAccountNameFromPicker
  990. //
  991. //--------------------------------------------------------------------------
  992. BOOL CEPGetAccountNameFromPicker(HWND hwndParent,
  993. IDsObjectPicker *pIDsObjectPicker,
  994. LPWSTR *ppwszSelectedUserSAM)
  995. {
  996. BOOL fResult=FALSE;
  997. BOOL fGotStgMedium = FALSE;
  998. LPWSTR pwszPath=NULL;
  999. DWORD dwIndex =0 ;
  1000. DWORD dwCount=0;
  1001. WCHAR wszWinNT[]=L"WinNT://";
  1002. DWORD dwSize=0;
  1003. LPWSTR pwsz=NULL;
  1004. DWORD cCount=0;
  1005. IDataObject *pdo = NULL;
  1006. PDS_SELECTION_LIST pDsSelList=NULL;
  1007. LPWSTR pwszComputerName=NULL;
  1008. STGMEDIUM stgmedium =
  1009. {
  1010. TYMED_HGLOBAL,
  1011. NULL,
  1012. NULL
  1013. };
  1014. FORMATETC formatetc =
  1015. {
  1016. (CLIPFORMAT)g_cfDsObjectPicker,
  1017. NULL,
  1018. DVASPECT_CONTENT,
  1019. -1,
  1020. TYMED_HGLOBAL
  1021. };
  1022. //input check
  1023. if((NULL == pIDsObjectPicker) || (NULL == ppwszSelectedUserSAM))
  1024. goto CLEANUP;
  1025. *ppwszSelectedUserSAM = NULL;
  1026. if(S_OK != pIDsObjectPicker->InvokeDialog(hwndParent, &pdo))
  1027. goto CLEANUP;
  1028. if(S_OK != pdo->GetData(&formatetc, &stgmedium))
  1029. goto CLEANUP;
  1030. fGotStgMedium = TRUE;
  1031. pDsSelList = (PDS_SELECTION_LIST)GlobalLock(stgmedium.hGlobal);
  1032. if(!pDsSelList)
  1033. goto CLEANUP;
  1034. //detect if this is a domain account
  1035. //local account will be in the format of Winnt://workgroup/machine/foo
  1036. //Get the SAM name
  1037. if((pDsSelList->aDsSelection[0]).pwzADsPath == NULL)
  1038. goto CLEANUP;
  1039. //the ADsPath is in the form of "WinNT://"
  1040. if(wcslen((pDsSelList->aDsSelection[0]).pwzADsPath) <= wcslen(wszWinNT))
  1041. goto CLEANUP;
  1042. if( 0 != _wcsnicmp((pDsSelList->aDsSelection[0]).pwzADsPath, wszWinNT, wcslen(wszWinNT)))
  1043. goto CLEANUP;
  1044. pwsz = ((pDsSelList->aDsSelection[0]).pwzADsPath) + wcslen(wszWinNT);
  1045. while(L'\0' != (*pwsz))
  1046. {
  1047. if(L'/' == (*pwsz))
  1048. {
  1049. cCount++;
  1050. }
  1051. pwsz++;
  1052. }
  1053. if(1 == cCount)
  1054. {
  1055. //domain\administrator have no UPN
  1056. //if((pDsSelList->aDsSelection[0]).pwzUPN != NULL)
  1057. //if(0 != _wcsicmp(L"",(pDsSelList->aDsSelection[0]).pwzUPN))
  1058. pwszPath = ((pDsSelList->aDsSelection[0]).pwzADsPath) + wcslen(wszWinNT);
  1059. *ppwszSelectedUserSAM=(LPWSTR)malloc((wcslen(pwszPath) + 1) * sizeof(WCHAR));
  1060. if(NULL == (*ppwszSelectedUserSAM))
  1061. goto CLEANUP;
  1062. wcscpy(*ppwszSelectedUserSAM, pwszPath);
  1063. //search for the "/" and make it "\". Since the ADsPath is in the form
  1064. //of "WinNT://domain/name". We need the SAM name in the form of
  1065. //domain\name
  1066. dwCount = wcslen(*ppwszSelectedUserSAM);
  1067. for(dwIndex = 0; dwIndex < dwCount; dwIndex++)
  1068. {
  1069. if((*ppwszSelectedUserSAM)[dwIndex] == L'/')
  1070. {
  1071. (*ppwszSelectedUserSAM)[dwIndex] = L'\\';
  1072. break;
  1073. }
  1074. }
  1075. }
  1076. //use the format of localMachine\\account for local account
  1077. if(NULL == (*ppwszSelectedUserSAM))
  1078. {
  1079. if(NULL == (pDsSelList->aDsSelection[0]).pwzName)
  1080. goto CLEANUP;
  1081. //Get the computer name
  1082. dwSize=0;
  1083. GetComputerNameExW(ComputerNamePhysicalDnsHostname,
  1084. NULL,
  1085. &dwSize);
  1086. pwszComputerName=(LPWSTR)malloc(dwSize * sizeof(WCHAR));
  1087. if(NULL==pwszComputerName)
  1088. goto CLEANUP;
  1089. if(!GetComputerNameExW(ComputerNamePhysicalDnsHostname,
  1090. pwszComputerName,
  1091. &dwSize))
  1092. goto CLEANUP;
  1093. *ppwszSelectedUserSAM=(LPWSTR)malloc((wcslen(pwszComputerName) + wcslen((pDsSelList->aDsSelection[0]).pwzName) + wcslen(L"\\") + 1) * sizeof(WCHAR));
  1094. if(NULL == (*ppwszSelectedUserSAM))
  1095. goto CLEANUP;
  1096. wcscpy(*ppwszSelectedUserSAM, pwszComputerName);
  1097. wcscat(*ppwszSelectedUserSAM, L"\\");
  1098. wcscat(*ppwszSelectedUserSAM, (pDsSelList->aDsSelection[0]).pwzName);
  1099. }
  1100. fResult=TRUE;
  1101. CLEANUP:
  1102. if(pwszComputerName)
  1103. free(pwszComputerName);
  1104. if(pDsSelList)
  1105. GlobalUnlock(stgmedium.hGlobal);
  1106. if (TRUE == fGotStgMedium)
  1107. ReleaseStgMedium(&stgmedium);
  1108. if(pdo)
  1109. pdo->Release();
  1110. return fResult;
  1111. }
  1112. //--------------------------------------------------------------------------
  1113. //
  1114. // RefreshKeyLengthCombo
  1115. //
  1116. //--------------------------------------------------------------------------
  1117. BOOL WINAPI RefreshKeyLengthCombo(HWND hwndDlg,
  1118. int idsList,
  1119. int idsCombo,
  1120. BOOL fSign,
  1121. CEP_WIZARD_INFO *pCEPWizardInfo)
  1122. {
  1123. BOOL fResult=FALSE;
  1124. DWORD dwDefaultKeyLength=0;
  1125. DWORD *pdwList=NULL;
  1126. DWORD dwListCount=0;
  1127. DWORD dwMax=0;
  1128. DWORD dwMin=0;
  1129. DWORD dwIndex=0;
  1130. DWORD dwCSPIndex=0;
  1131. CEP_CSP_INFO *pCSPInfo=NULL;
  1132. int iInsertedIndex=0;
  1133. WCHAR wszKeyLength[CEP_KEY_LENGTH_STRING];
  1134. BOOL fSelected=FALSE;
  1135. //get the selected list view item
  1136. if(!GetSelectedCSP(hwndDlg,idsList,&dwCSPIndex))
  1137. goto CLEANUP;
  1138. pCSPInfo= &(pCEPWizardInfo->rgCSPInfo[dwCSPIndex]);
  1139. if(fSign)
  1140. {
  1141. dwDefaultKeyLength=pCSPInfo->dwDefaultSign;
  1142. pdwList=pCSPInfo->pdwSignList;
  1143. dwListCount= pCSPInfo->dwSignCount;
  1144. dwMax=pCSPInfo->dwMaxSign;
  1145. dwMin=pCSPInfo->dwMinSign;
  1146. }
  1147. else
  1148. {
  1149. dwDefaultKeyLength=pCSPInfo->dwDefaultEncrypt;
  1150. pdwList=pCSPInfo->pdwEncryptList;
  1151. dwListCount=pCSPInfo->dwEncryptCount;
  1152. dwMax=pCSPInfo->dwMaxEncrypt;
  1153. dwMin=pCSPInfo->dwMinEncrypt;
  1154. }
  1155. //clear out the combo box
  1156. SendDlgItemMessageU(hwndDlg, idsCombo, CB_RESETCONTENT, 0, 0);
  1157. for(dwIndex=0; dwIndex < dwListCount; dwIndex++)
  1158. {
  1159. if((pdwList[dwIndex] >= dwMin) && (pdwList[dwIndex] <= dwMax))
  1160. {
  1161. _ltow(pdwList[dwIndex], wszKeyLength, 10);
  1162. // 64 bit- will never insert more than 1B entries, so INT is fine
  1163. iInsertedIndex=(int)SendDlgItemMessageU(hwndDlg, idsCombo, CB_ADDSTRING,
  1164. 0, (LPARAM)wszKeyLength);
  1165. if((iInsertedIndex != CB_ERR) && (iInsertedIndex != CB_ERRSPACE))
  1166. {
  1167. SendDlgItemMessage(hwndDlg, idsCombo, CB_SETITEMDATA,
  1168. (WPARAM)iInsertedIndex, (LPARAM)pdwList[dwIndex]);
  1169. if(dwDefaultKeyLength==pdwList[dwIndex])
  1170. {
  1171. SendDlgItemMessageU(hwndDlg, idsCombo, CB_SETCURSEL, iInsertedIndex, 0);
  1172. fSelected=TRUE;
  1173. }
  1174. }
  1175. }
  1176. }
  1177. if(fSelected==FALSE)
  1178. SendDlgItemMessageU(hwndDlg, idsCombo, CB_SETCURSEL, 0, 0);
  1179. fResult=TRUE;
  1180. CLEANUP:
  1181. return fResult;
  1182. }
  1183. //--------------------------------------------------------------------------
  1184. //
  1185. // InitCSPList
  1186. //
  1187. //--------------------------------------------------------------------------
  1188. BOOL WINAPI InitCSPList(HWND hwndDlg,
  1189. int idControl,
  1190. BOOL fSign,
  1191. CEP_WIZARD_INFO *pCEPWizardInfo)
  1192. {
  1193. BOOL fResult=FALSE;
  1194. DWORD dwIndex=0;
  1195. CEP_CSP_INFO *pCSPInfo=NULL;
  1196. int iInsertedIndex=0;
  1197. HWND hwndList=NULL;
  1198. LV_ITEMW lvItem;
  1199. LV_COLUMNW lvC;
  1200. BOOL fSelected=FALSE;
  1201. if(NULL==(hwndList=GetDlgItem(hwndDlg, idControl)))
  1202. goto CLEANUP;
  1203. //insert a column into the list view
  1204. memset(&lvC, 0, sizeof(LV_COLUMNW));
  1205. lvC.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
  1206. lvC.fmt = LVCFMT_LEFT; // Left-align the column.
  1207. lvC.cx = 20; //(dwMaxSize+2)*7; // Width of the column, in pixels.
  1208. lvC.pszText = L""; // The text for the column.
  1209. lvC.iSubItem=0;
  1210. if (-1 == ListView_InsertColumnU(hwndList, 0, &lvC))
  1211. goto CLEANUP;
  1212. // set up the fields in the list view item struct that don't change from item to item
  1213. memset(&lvItem, 0, sizeof(LV_ITEMW));
  1214. lvItem.mask = LVIF_TEXT | LVIF_STATE |LVIF_PARAM ;
  1215. for(dwIndex=0; dwIndex < pCEPWizardInfo->dwCSPCount; dwIndex++)
  1216. {
  1217. fSelected=FALSE;
  1218. pCSPInfo= &(pCEPWizardInfo->rgCSPInfo[dwIndex]);
  1219. if(fSign)
  1220. {
  1221. if(!(pCSPInfo->fSignature))
  1222. continue;
  1223. if(dwIndex==pCEPWizardInfo->dwSignProvIndex)
  1224. fSelected=TRUE;
  1225. }
  1226. else
  1227. {
  1228. if(!(pCSPInfo->fEncryption))
  1229. continue;
  1230. if(dwIndex==pCEPWizardInfo->dwEncryptProvIndex)
  1231. fSelected=TRUE;
  1232. }
  1233. lvItem.iItem=dwIndex;
  1234. lvItem.lParam = (LPARAM)dwIndex;
  1235. lvItem.pszText=pCSPInfo->pwszCSPName;
  1236. iInsertedIndex=ListView_InsertItemU(hwndList, &lvItem);
  1237. if(fSelected)
  1238. {
  1239. ListView_SetItemState(
  1240. hwndList,
  1241. iInsertedIndex,
  1242. LVIS_SELECTED,
  1243. LVIS_SELECTED);
  1244. }
  1245. }
  1246. //make the column autosize
  1247. ListView_SetColumnWidth(hwndList, 0, LVSCW_AUTOSIZE);
  1248. fResult=TRUE;
  1249. CLEANUP:
  1250. return fResult;
  1251. }
  1252. //--------------------------------------------------------------------------
  1253. //
  1254. // GetSelectedCSP
  1255. //
  1256. //--------------------------------------------------------------------------
  1257. BOOL WINAPI GetSelectedCSP(HWND hwndDlg,
  1258. int idControl,
  1259. DWORD *pdwCSPIndex)
  1260. {
  1261. BOOL fResult=FALSE;
  1262. HWND hwndControl=NULL;
  1263. LV_ITEM lvItem;
  1264. int iIndex=0;
  1265. //get the window handle of the list view
  1266. if(NULL==(hwndControl=GetDlgItem(hwndDlg, idControl)))
  1267. goto CLEANUP;
  1268. //now, mark the one that is selected
  1269. if(-1 == (iIndex= ListView_GetNextItem(
  1270. hwndControl,
  1271. -1,
  1272. LVNI_SELECTED
  1273. )))
  1274. goto CLEANUP;
  1275. memset(&lvItem, 0, sizeof(LV_ITEM));
  1276. lvItem.mask=LVIF_PARAM;
  1277. lvItem.iItem=iIndex;
  1278. if(!ListView_GetItem(hwndControl, &lvItem))
  1279. goto CLEANUP;
  1280. // will never have more than 1B CSPs, so this is fine
  1281. *pdwCSPIndex=(DWORD)(lvItem.lParam);
  1282. fResult=TRUE;
  1283. CLEANUP:
  1284. return fResult;
  1285. }
  1286. //--------------------------------------------------------------------------
  1287. //
  1288. // GetSelectedKeyLength
  1289. //
  1290. //--------------------------------------------------------------------------
  1291. BOOL WINAPI GetSelectedKeyLength(HWND hwndDlg,
  1292. int idControl,
  1293. DWORD *pdwKeyLength)
  1294. {
  1295. int iIndex=0;
  1296. BOOL fResult=FALSE;
  1297. iIndex=(int)SendDlgItemMessage(hwndDlg, idControl, CB_GETCURSEL, 0, 0);
  1298. if(CB_ERR==iIndex)
  1299. goto CLEANUP;
  1300. // will never be > 1B bits long, so this is ok
  1301. *pdwKeyLength=(DWORD)SendDlgItemMessage(hwndDlg, idControl, CB_GETITEMDATA, iIndex, 0);
  1302. fResult=TRUE;
  1303. CLEANUP:
  1304. return fResult;
  1305. }
  1306. //--------------------------------------------------------------------------
  1307. //
  1308. // FormatMessageStr
  1309. //
  1310. //--------------------------------------------------------------------------
  1311. int ListView_InsertItemU_IDS(HWND hwndList,
  1312. LV_ITEMW *plvItem,
  1313. UINT idsString,
  1314. LPWSTR pwszText)
  1315. {
  1316. WCHAR wszText[MAX_STRING_SIZE];
  1317. if(pwszText)
  1318. plvItem->pszText=pwszText;
  1319. else
  1320. {
  1321. if(!LoadStringU(g_hModule, idsString, wszText, MAX_STRING_SIZE))
  1322. return -1;
  1323. plvItem->pszText=wszText;
  1324. }
  1325. return ListView_InsertItemU(hwndList, plvItem);
  1326. }
  1327. //-------------------------------------------------------------------------
  1328. //
  1329. // populate the wizards's confirmation page in the order of Challenge,
  1330. // RA informaton, and CSPs
  1331. //
  1332. //-------------------------------------------------------------------------
  1333. void WINAPI DisplayConfirmation(HWND hwndControl,
  1334. CEP_WIZARD_INFO *pCEPWizardInfo)
  1335. {
  1336. WCHAR wszYes[MAX_TITLE_LENGTH];
  1337. DWORD dwIndex=0;
  1338. UINT ids=0;
  1339. BOOL fNewItem=FALSE;
  1340. WCHAR wszLength[CEP_KEY_LENGTH_STRING];
  1341. LV_COLUMNW lvC;
  1342. LV_ITEMW lvItem;
  1343. //delete all the old items in the listView
  1344. ListView_DeleteAllItems(hwndControl);
  1345. //insert row by row
  1346. memset(&lvItem, 0, sizeof(LV_ITEMW));
  1347. // set up the fields in the list view item struct that don't change from item to item
  1348. lvItem.mask = LVIF_TEXT | LVIF_STATE ;
  1349. lvItem.state = 0;
  1350. lvItem.stateMask = 0;
  1351. //*******************************************************************
  1352. //account information
  1353. lvItem.iItem=0;
  1354. lvItem.iSubItem=0;
  1355. ListView_InsertItemU_IDS(hwndControl, &lvItem, IDS_ACCOUNT_INFORMATION, NULL);
  1356. //content
  1357. (lvItem.iSubItem)++;
  1358. if(FALSE == (pCEPWizardInfo->fLocalSystem))
  1359. {
  1360. ListView_SetItemTextU(hwndControl, lvItem.iItem, lvItem.iSubItem, pCEPWizardInfo->pwszUserName);
  1361. }
  1362. else
  1363. {
  1364. if(LoadStringU(g_hModule, IDS_LOCAL_SYSTEM, wszYes, MAX_TITLE_LENGTH))
  1365. ListView_SetItemTextU(hwndControl, lvItem.iItem, lvItem.iSubItem, wszYes);
  1366. }
  1367. //*******************************************************************
  1368. //challenge
  1369. lvItem.iItem++;
  1370. lvItem.iSubItem=0;
  1371. ListView_InsertItemU_IDS(hwndControl, &lvItem, IDS_CHALLENGE_PHRASE, NULL);
  1372. //content
  1373. (lvItem.iSubItem)++;
  1374. if(pCEPWizardInfo->fPassword)
  1375. ids=IDS_YES;
  1376. else
  1377. ids=IDS_NO;
  1378. if(LoadStringU(g_hModule, ids, wszYes, MAX_TITLE_LENGTH))
  1379. ListView_SetItemTextU(hwndControl, lvItem.iItem, lvItem.iSubItem,wszYes);
  1380. //***************************************************************************
  1381. // RA credentials
  1382. lvItem.iItem++;
  1383. lvItem.iSubItem=0;
  1384. ListView_InsertItemU_IDS(hwndControl, &lvItem, IDS_RA_CREDENTIAL, NULL);
  1385. //content
  1386. for(dwIndex=0; dwIndex<RA_INFO_COUNT; dwIndex++)
  1387. {
  1388. if(pCEPWizardInfo->rgpwszName[dwIndex])
  1389. {
  1390. if(TRUE==fNewItem)
  1391. {
  1392. //increase the row
  1393. lvItem.iItem++;
  1394. lvItem.pszText=L"";
  1395. lvItem.iSubItem=0;
  1396. ListView_InsertItemU(hwndControl, &lvItem);
  1397. }
  1398. else
  1399. fNewItem=TRUE;
  1400. lvItem.iSubItem++;
  1401. ListView_SetItemTextU(hwndControl, lvItem.iItem, lvItem.iSubItem, pCEPWizardInfo->rgpwszName[dwIndex]);
  1402. }
  1403. }
  1404. //***************************************************************************
  1405. //CSPInfo
  1406. if(pCEPWizardInfo->fEnrollAdv)
  1407. {
  1408. //signature CSP Name
  1409. lvItem.iItem++;
  1410. lvItem.iSubItem=0;
  1411. ListView_InsertItemU_IDS(hwndControl, &lvItem, IDS_SIGN_CSP, NULL);
  1412. lvItem.iSubItem++;
  1413. ListView_SetItemTextU(hwndControl, lvItem.iItem, lvItem.iSubItem,
  1414. pCEPWizardInfo->rgCSPInfo[pCEPWizardInfo->dwSignProvIndex].pwszCSPName);
  1415. //signaure key length
  1416. lvItem.iItem++;
  1417. lvItem.iSubItem=0;
  1418. ListView_InsertItemU_IDS(hwndControl, &lvItem, IDS_SIGN_KEY_LENGTH, NULL);
  1419. lvItem.iSubItem++;
  1420. _ltow(pCEPWizardInfo->dwSignKeyLength, wszLength, 10);
  1421. ListView_SetItemTextU(hwndControl, lvItem.iItem, lvItem.iSubItem, wszLength);
  1422. //encryption CSP name
  1423. lvItem.iItem++;
  1424. lvItem.iSubItem=0;
  1425. ListView_InsertItemU_IDS(hwndControl, &lvItem, IDS_ENCRYPT_CSP, NULL);
  1426. lvItem.iSubItem++;
  1427. ListView_SetItemTextU(hwndControl, lvItem.iItem, lvItem.iSubItem,
  1428. pCEPWizardInfo->rgCSPInfo[pCEPWizardInfo->dwEncryptProvIndex].pwszCSPName);
  1429. //encryption key length
  1430. lvItem.iItem++;
  1431. lvItem.iSubItem=0;
  1432. ListView_InsertItemU_IDS(hwndControl, &lvItem, IDS_ENCRYPT_KEY_LENGTH, NULL);
  1433. lvItem.iSubItem++;
  1434. _ltow(pCEPWizardInfo->dwEncryptKeyLength, wszLength, 10);
  1435. ListView_SetItemTextU(hwndControl, lvItem.iItem, lvItem.iSubItem, wszLength);
  1436. }
  1437. //autosize the columns
  1438. ListView_SetColumnWidth(hwndControl, 0, LVSCW_AUTOSIZE);
  1439. ListView_SetColumnWidth(hwndControl, 1, LVSCW_AUTOSIZE);
  1440. return;
  1441. }
  1442. //--------------------------------------------------------------------
  1443. //
  1444. // GetServiceWaitPeriod
  1445. //
  1446. // Obtain the value from the registry
  1447. //
  1448. //--------------------------------------------------------------------------
  1449. void GetServiceWaitPeriod(DWORD *pdwServiceWait)
  1450. {
  1451. DWORD cbData=0;
  1452. DWORD dwData=0;
  1453. DWORD dwType=0;
  1454. HKEY hKeyCEP=NULL;
  1455. //set the default value
  1456. *pdwServiceWait=SCEP_SERVICE_WAIT_PERIOD;
  1457. //get the CA's type from the registry
  1458. cbData=sizeof(dwData);
  1459. //we have to have the knowledge of the ca type
  1460. if(ERROR_SUCCESS == RegOpenKeyExU(
  1461. HKEY_LOCAL_MACHINE,
  1462. MSCEP_LOCATION,
  1463. 0,
  1464. KEY_READ,
  1465. &hKeyCEP))
  1466. {
  1467. if(ERROR_SUCCESS == RegQueryValueExU(
  1468. hKeyCEP,
  1469. MSCEP_KEY_SERVICE_WAIT,
  1470. NULL,
  1471. &dwType,
  1472. (BYTE *)&dwData,
  1473. &cbData))
  1474. {
  1475. if ((dwType == REG_DWORD) || (dwType == REG_BINARY))
  1476. {
  1477. *pdwServiceWait=dwData;
  1478. }
  1479. }
  1480. }
  1481. if(hKeyCEP)
  1482. RegCloseKey(hKeyCEP);
  1483. return;
  1484. }
  1485. //--------------------------------------------------------------------
  1486. //
  1487. // Main Function
  1488. //
  1489. //--------------------------------------------------------------------------
  1490. extern "C" int _cdecl wmain(int nArgs, WCHAR ** rgwszArgs)
  1491. {
  1492. BOOL fResult=FALSE;
  1493. UINT idsMsg=IDS_FAIL_INIT_WIZARD;
  1494. HRESULT hr=E_FAIL;
  1495. PROPSHEETPAGEW rgCEPSheet[CEP_PROP_SHEET];
  1496. PROPSHEETHEADERW cepHeader;
  1497. CEP_PAGE_INFO rgCEPPageInfo[CEP_PROP_SHEET]=
  1498. {(LPCWSTR)MAKEINTRESOURCE(IDD_WELCOME), CEP_Welcome,
  1499. (LPCWSTR)MAKEINTRESOURCE(IDD_APP_ID), CEP_App_ID,
  1500. (LPCWSTR)MAKEINTRESOURCE(IDD_ACCOUNT), CEP_Account,
  1501. (LPCWSTR)MAKEINTRESOURCE(IDD_CHALLENGE), CEP_Challenge,
  1502. (LPCWSTR)MAKEINTRESOURCE(IDD_ENROLL), CEP_Enroll,
  1503. (LPCWSTR)MAKEINTRESOURCE(IDD_CSP), CEP_CSP,
  1504. (LPCWSTR)MAKEINTRESOURCE(IDD_COMPLETION), CEP_Completion,
  1505. };
  1506. DWORD dwIndex=0;
  1507. WCHAR wszTitle[MAX_TITLE_LENGTH];
  1508. INT_PTR iReturn=-1;
  1509. ENUM_CATYPES catype;
  1510. DWORD dwWaitCounter=0;
  1511. BOOL fEnterpriseCA=FALSE;
  1512. DSOP_SCOPE_INIT_INFO ScopeInit;
  1513. DSOP_INIT_INFO InitInfo;
  1514. DWORD dwServiceWait=SCEP_SERVICE_WAIT_PERIOD;
  1515. OSVERSIONINFOEXW versionInfo;
  1516. CEP_WIZARD_INFO CEPWizardInfo;
  1517. DSROLE_PRIMARY_DOMAIN_INFO_BASIC *pDomainInfo=NULL;
  1518. memset(rgCEPSheet, 0, sizeof(PROPSHEETPAGEW)*CEP_PROP_SHEET);
  1519. memset(&cepHeader, 0, sizeof(PROPSHEETHEADERW));
  1520. memset(&CEPWizardInfo, 0, sizeof(CEP_WIZARD_INFO));
  1521. if(FAILED(CoInitialize(NULL)))
  1522. return FALSE;
  1523. if(NULL==(g_hModule=GetModuleHandle(NULL)))
  1524. goto CommonReturn;
  1525. if(!IsValidInstallation(&idsMsg))
  1526. goto ErrorReturn;
  1527. //get the wait period for start/stop service account
  1528. GetServiceWaitPeriod(&dwServiceWait);
  1529. if(!IsCaRunning())
  1530. {
  1531. if(S_OK != (hr=CepStartService(CERTSVC_NAME)))
  1532. {
  1533. idsMsg=IDS_NO_CA_RUNNING;
  1534. goto ErrorWithHResultReturn;
  1535. }
  1536. }
  1537. //make sure the CA is up running
  1538. for (dwWaitCounter=0; dwWaitCounter < dwServiceWait; dwWaitCounter++)
  1539. {
  1540. if (!IsCaRunning())
  1541. Sleep(1000);
  1542. else
  1543. break;
  1544. }
  1545. if (dwServiceWait == dwWaitCounter)
  1546. {
  1547. idsMsg=IDS_CAN_NOT_START_CA;
  1548. goto ErrorWithHResultReturn;
  1549. }
  1550. //make sure we have the correct admin rights based on the CA type
  1551. if(S_OK != (hr=GetCaType(&catype)))
  1552. {
  1553. idsMsg=IDS_FAIL_GET_CA_TYPE;
  1554. goto ErrorWithHResultReturn;
  1555. }
  1556. //some cisco routers only work with root CA
  1557. if((ENUM_ENTERPRISE_ROOTCA != catype) && (ENUM_STANDALONE_ROOTCA != catype))
  1558. {
  1559. if(IDNO==CEPMessageBox(NULL, IDS_CAN_NOT_ROOT_CA, MB_ICONWARNING|MB_YESNO|MB_APPLMODAL))
  1560. {
  1561. fResult=FALSE;
  1562. goto CommonReturn;
  1563. }
  1564. }
  1565. //for either Enteprise CA or Standalone CA, the user has to be the local machine admin
  1566. // check for machine admin
  1567. if(!IsUserInAdminGroup(FALSE))
  1568. {
  1569. idsMsg=IDS_NOT_MACHINE_ADMIN;
  1570. goto ErrorReturn;
  1571. }
  1572. if (ENUM_ENTERPRISE_ROOTCA==catype || ENUM_ENTERPRISE_SUBCA==catype)
  1573. {
  1574. fEnterpriseCA=TRUE;
  1575. // check for enterprise admin
  1576. if(!IsUserInAdminGroup(TRUE))
  1577. {
  1578. idsMsg=IDS_NOT_ENT_ADMIN;
  1579. goto ErrorReturn;
  1580. }
  1581. }
  1582. //everything looks good. We start the wizard page
  1583. if(!CEPWizardInit())
  1584. goto ErrorWithWin32Return;
  1585. CEPWizardInfo.fEnrollAdv=FALSE;
  1586. CEPWizardInfo.fPassword=FALSE;
  1587. CEPWizardInfo.fEnterpriseCA=fEnterpriseCA;
  1588. CEPWizardInfo.fDC=FALSE;
  1589. CEPWizardInfo.fDomain=TRUE; //defeult to assume the machine is on a domain
  1590. CEPWizardInfo.dwServiceWait=dwServiceWait;
  1591. //detect if the machine is a DC
  1592. versionInfo.dwOSVersionInfoSize = sizeof(versionInfo);
  1593. if(GetVersionEx(reinterpret_cast<OSVERSIONINFOW *>(&versionInfo)))
  1594. {
  1595. CEPWizardInfo.fDC = (versionInfo.wProductType == VER_NT_DOMAIN_CONTROLLER);
  1596. }
  1597. //detect if the machine is on a domain
  1598. if(ERROR_SUCCESS != DsRoleGetPrimaryDomainInformation(
  1599. NULL,
  1600. DsRolePrimaryDomainInfoBasic,
  1601. (PBYTE*)&pDomainInfo))
  1602. {
  1603. idsMsg=IDS_FAIL_DOMAIN_INFO;
  1604. goto ErrorReturn;
  1605. }
  1606. if((DsRole_RoleStandaloneWorkstation == (pDomainInfo->MachineRole)) ||
  1607. (DsRole_RoleStandaloneServer == (pDomainInfo->MachineRole))
  1608. )
  1609. {
  1610. CEPWizardInfo.fDomain=FALSE;
  1611. }
  1612. //initialize the object picker object
  1613. //init for the user selection dialogue
  1614. memset(&ScopeInit, 0, sizeof(DSOP_SCOPE_INIT_INFO));
  1615. memset(&InitInfo, 0, sizeof(InitInfo));
  1616. ScopeInit.cbSize = sizeof(DSOP_SCOPE_INIT_INFO);
  1617. //only domain account for enterprise CA
  1618. if(fEnterpriseCA)
  1619. {
  1620. ScopeInit.flType = DSOP_SCOPE_TYPE_ENTERPRISE_DOMAIN|DSOP_SCOPE_TYPE_GLOBAL_CATALOG;
  1621. }
  1622. else
  1623. {
  1624. ScopeInit.flType = DSOP_SCOPE_TYPE_ENTERPRISE_DOMAIN|DSOP_SCOPE_TYPE_GLOBAL_CATALOG|DSOP_SCOPE_TYPE_TARGET_COMPUTER;
  1625. }
  1626. ScopeInit.flScope = DSOP_SCOPE_FLAG_WANT_PROVIDER_WINNT; //this will give us the SAM name for the user
  1627. ScopeInit.FilterFlags.flDownlevel = DSOP_DOWNLEVEL_FILTER_USERS;
  1628. ScopeInit.FilterFlags.Uplevel.flBothModes = DSOP_FILTER_USERS;
  1629. InitInfo.cbSize = sizeof(InitInfo);
  1630. InitInfo.pwzTargetComputer = NULL; // NULL == local machine
  1631. InitInfo.cDsScopeInfos = 1;
  1632. InitInfo.aDsScopeInfos = &ScopeInit;
  1633. InitInfo.flOptions = 0; //we are doing single select
  1634. //create the COM object
  1635. if(S_OK != (hr=CoCreateInstance
  1636. (CLSID_DsObjectPicker,
  1637. NULL,
  1638. CLSCTX_INPROC_SERVER,
  1639. IID_IDsObjectPicker,
  1640. (void **) &(CEPWizardInfo.pIDsObjectPicker))))
  1641. {
  1642. idsMsg=IDS_FAIL_GET_OBJECT_PICKER;
  1643. goto ErrorWithHResultReturn;
  1644. }
  1645. if(S_OK != (hr=CEPWizardInfo.pIDsObjectPicker->Initialize(&InitInfo)))
  1646. {
  1647. idsMsg=IDS_FAIL_GET_OBJECT_PICKER;
  1648. goto ErrorWithHResultReturn;
  1649. }
  1650. //initialize the CSP information
  1651. if(!CEPGetCSPInformation(&CEPWizardInfo))
  1652. {
  1653. idsMsg=IDS_FAIL_GET_CSP_INFO;
  1654. goto ErrorWithWin32Return;
  1655. }
  1656. for(dwIndex=0; dwIndex<RA_INFO_COUNT; dwIndex++)
  1657. {
  1658. CEPWizardInfo.rgpwszName[dwIndex]=NULL;
  1659. }
  1660. if(!SetupFonts(
  1661. g_hModule,
  1662. NULL,
  1663. &(CEPWizardInfo.hBigBold),
  1664. &(CEPWizardInfo.hBold)))
  1665. goto ErrorReturn;
  1666. for(dwIndex=0; dwIndex<CEP_PROP_SHEET; dwIndex++)
  1667. {
  1668. rgCEPSheet[dwIndex].dwSize=sizeof(rgCEPSheet[dwIndex]);
  1669. rgCEPSheet[dwIndex].hInstance=g_hModule;
  1670. rgCEPSheet[dwIndex].pszTemplate=rgCEPPageInfo[dwIndex].pszTemplate;
  1671. rgCEPSheet[dwIndex].pfnDlgProc=rgCEPPageInfo[dwIndex].pfnDlgProc;
  1672. rgCEPSheet[dwIndex].lParam=(LPARAM)&CEPWizardInfo;
  1673. }
  1674. //set up the header information
  1675. cepHeader.dwSize=sizeof(cepHeader);
  1676. cepHeader.dwFlags=PSH_PROPSHEETPAGE | PSH_WIZARD | PSH_NOAPPLYNOW;
  1677. cepHeader.hwndParent=NULL;
  1678. cepHeader.hInstance=g_hModule;
  1679. if(LoadStringU(g_hModule, IDS_WIZARD_CAPTION, wszTitle, sizeof(wszTitle)/sizeof(wszTitle[0])))
  1680. cepHeader.pszCaption=wszTitle;
  1681. cepHeader.nPages=CEP_PROP_SHEET;
  1682. cepHeader.nStartPage=0;
  1683. cepHeader.ppsp=rgCEPSheet;
  1684. //create the wizard
  1685. iReturn = PropertySheetU(&cepHeader);
  1686. if(-1 == iReturn)
  1687. goto ErrorWithWin32Return;
  1688. if(0 == iReturn)
  1689. {
  1690. //cancel button is pushed. We return FALSE so that
  1691. //the reboot will not happen.
  1692. fResult=FALSE;
  1693. goto CommonReturn;
  1694. }
  1695. fResult=TRUE;
  1696. CommonReturn:
  1697. if(pDomainInfo)
  1698. {
  1699. DsRoleFreeMemory(pDomainInfo);
  1700. }
  1701. FreeCEPWizardInfo(&CEPWizardInfo);
  1702. CoUninitialize();
  1703. return fResult;
  1704. ErrorReturn:
  1705. fResult=FALSE;
  1706. CEPMessageBox(NULL, idsMsg, MB_ICONERROR|MB_OK|MB_APPLMODAL);
  1707. goto CommonReturn;
  1708. ErrorWithHResultReturn:
  1709. fResult=FALSE;
  1710. CEPErrorMessageBox(NULL, idsMsg, hr, MB_ICONERROR|MB_OK|MB_APPLMODAL);
  1711. goto CommonReturn;
  1712. ErrorWithWin32Return:
  1713. fResult=FALSE;
  1714. hr=HRESULT_FROM_WIN32(GetLastError());
  1715. CEPErrorMessageBox(NULL, idsMsg, hr, MB_ICONERROR|MB_OK|MB_APPLMODAL);
  1716. goto CommonReturn;
  1717. }
  1718. //**********************************************************************
  1719. //
  1720. // Helper functions
  1721. //
  1722. //**********************************************************************
  1723. //-----------------------------------------------------------------------
  1724. //
  1725. // I_DoSetupWork
  1726. //
  1727. // we are ready to do the real work
  1728. //-----------------------------------------------------------------------
  1729. BOOL WINAPI I_DoSetupWork(HWND hWnd, CEP_WIZARD_INFO *pCEPWizardInfo)
  1730. {
  1731. BOOL fResult=FALSE;
  1732. UINT idsMsg=IDS_FAIL_INIT_WIZARD;
  1733. HRESULT hr=E_FAIL;
  1734. DWORD dwWaitCounter=0;
  1735. DWORD dwIndex=0;
  1736. BOOL bStart=FALSE;
  1737. DWORD dwSize=0;
  1738. WCHAR wszTitle[MAX_TITLE_LENGTH];
  1739. DWORD cbUserInfo = 0;
  1740. PTOKEN_USER pUserInfo = NULL;
  1741. LPWSTR pwszRADN=NULL;
  1742. LPWSTR pwszComputerName=NULL;
  1743. LPWSTR pwszText=NULL;
  1744. //************************************************************************************
  1745. //delete all existing CEP certificates
  1746. if(!RemoveRACertificates())
  1747. {
  1748. idsMsg=IDS_FAIL_DELETE_RA;
  1749. goto ErrorWithWin32Return;
  1750. }
  1751. //************************************************************************************
  1752. //CEP policy registry
  1753. if(!UpdateCEPRegistry(pCEPWizardInfo->fPassword,
  1754. pCEPWizardInfo->fEnterpriseCA))
  1755. {
  1756. idsMsg=IDS_FAIL_UPDATE_REGISTRY;
  1757. goto ErrorWithWin32Return;
  1758. }
  1759. //************************************************************************************
  1760. // Add the virtual root
  1761. if(S_OK != (hr=AddVDir(pCEPWizardInfo->fDC, CEP_DIR_NAME, SCEP_APPLICATION_POOL, pCEPWizardInfo->fLocalSystem, pCEPWizardInfo->pwszUserName, pCEPWizardInfo->pwszPassword)))
  1762. {
  1763. idsMsg=IDS_FAIL_ADD_VROOT;
  1764. goto ErrorWithHResultReturn;
  1765. }
  1766. //************************************************************************************
  1767. // Stop and Start W3SVC service for the change to take effect
  1768. CepStopService(pCEPWizardInfo->dwServiceWait,IIS_NAME, &bStart);
  1769. if(S_OK != (hr=CepStartService(IIS_NAME)))
  1770. {
  1771. idsMsg=IDS_FAIL_START_IIS;
  1772. goto ErrorWithHResultReturn;
  1773. }
  1774. //make sure the w3svc is up running
  1775. for (dwWaitCounter=0; dwWaitCounter < pCEPWizardInfo->dwServiceWait; dwWaitCounter++)
  1776. {
  1777. if (!IsServiceRunning(IIS_NAME))
  1778. Sleep(1000);
  1779. else
  1780. break;
  1781. }
  1782. if (pCEPWizardInfo->dwServiceWait == dwWaitCounter)
  1783. {
  1784. idsMsg=IDS_FAIL_START_IIS;
  1785. goto ErrorWithHResultReturn;
  1786. }
  1787. //************************************************************************************
  1788. //Get the security ID for the account
  1789. //get the account's SID
  1790. if(FALSE == (pCEPWizardInfo->fLocalSystem))
  1791. {
  1792. if(NULL == pCEPWizardInfo->hAccountToken)
  1793. {
  1794. idsMsg=IDS_FAIL_SID_FROM_ACCOUNT;
  1795. hr=E_INVALIDARG;
  1796. goto ErrorWithHResultReturn;
  1797. }
  1798. GetTokenInformation(pCEPWizardInfo->hAccountToken, TokenUser, NULL, 0, &cbUserInfo);
  1799. if(cbUserInfo == 0)
  1800. {
  1801. idsMsg=IDS_FAIL_SID_FROM_ACCOUNT;
  1802. goto ErrorWithWin32Return;
  1803. }
  1804. pUserInfo = (PTOKEN_USER)LocalAlloc(LPTR, cbUserInfo);
  1805. if(pUserInfo == NULL)
  1806. {
  1807. idsMsg=IDS_FAIL_SID_FROM_ACCOUNT;
  1808. hr=E_OUTOFMEMORY;
  1809. goto ErrorWithHResultReturn;
  1810. }
  1811. if(!GetTokenInformation(pCEPWizardInfo->hAccountToken, TokenUser, pUserInfo, cbUserInfo, &cbUserInfo))
  1812. {
  1813. idsMsg=IDS_FAIL_SID_FROM_ACCOUNT;
  1814. goto ErrorWithWin32Return;
  1815. }
  1816. }
  1817. //************************************************************************************
  1818. //Update the certificate template and its ACLs for enterprise CA
  1819. if (pCEPWizardInfo->fEnterpriseCA)
  1820. {
  1821. // get the templates and permisisons right
  1822. if(S_OK != (hr=DoCertSrvEnterpriseChanges(pCEPWizardInfo->fLocalSystem ? NULL : (SID *)((pUserInfo->User).Sid))))
  1823. {
  1824. idsMsg=IDS_FAIL_ADD_TEMPLATE;
  1825. goto ErrorWithHResultReturn;
  1826. }
  1827. }
  1828. //************************************************************************************
  1829. //Enroll for the RA certificate
  1830. //build the name in the form of L"C=US;S=Washington;CN=TestSetupUtil"
  1831. pwszRADN=(LPWSTR)malloc(sizeof(WCHAR));
  1832. if(NULL==pwszRADN)
  1833. {
  1834. idsMsg=IDS_NO_MEMORY;
  1835. goto ErrorReturn;
  1836. }
  1837. *pwszRADN=L'\0';
  1838. for(dwIndex=0; dwIndex<RA_INFO_COUNT; dwIndex++)
  1839. {
  1840. if((pCEPWizardInfo->rgpwszName)[dwIndex])
  1841. {
  1842. if(0 != wcslen(pwszRADN))
  1843. wcscat(pwszRADN, L";");
  1844. pwszRADN=(LPWSTR)realloc(pwszRADN,
  1845. sizeof(WCHAR) * (wcslen(pwszRADN) +
  1846. wcslen((pCEPWizardInfo->rgpwszName)[dwIndex]) +
  1847. wcslen(L";") +
  1848. wcslen(g_rgRAEnrollInfo[dwIndex].pwszPreFix) +
  1849. 1));
  1850. if(NULL==pwszRADN)
  1851. {
  1852. idsMsg=IDS_NO_MEMORY;
  1853. goto ErrorReturn;
  1854. }
  1855. wcscat(pwszRADN,g_rgRAEnrollInfo[dwIndex].pwszPreFix);
  1856. wcscat(pwszRADN,(pCEPWizardInfo->rgpwszName)[dwIndex]);
  1857. }
  1858. }
  1859. if(S_OK != (hr=EnrollForRACertificates(
  1860. pwszRADN,
  1861. (pCEPWizardInfo->rgCSPInfo)[pCEPWizardInfo->dwSignProvIndex].pwszCSPName,
  1862. (pCEPWizardInfo->rgCSPInfo)[pCEPWizardInfo->dwSignProvIndex].dwCSPType,
  1863. pCEPWizardInfo->dwSignKeyLength,
  1864. (pCEPWizardInfo->rgCSPInfo)[pCEPWizardInfo->dwEncryptProvIndex].pwszCSPName,
  1865. (pCEPWizardInfo->rgCSPInfo)[pCEPWizardInfo->dwEncryptProvIndex].dwCSPType,
  1866. pCEPWizardInfo->dwEncryptKeyLength,
  1867. pCEPWizardInfo->fLocalSystem ? NULL : (SID *)((pUserInfo->User).Sid))))
  1868. {
  1869. idsMsg=IDS_FAIL_ENROLL_RA_CERT;
  1870. goto ErrorWithHResultReturn;
  1871. }
  1872. //************************************************************************************
  1873. //CA policy registry
  1874. CepStopService(pCEPWizardInfo->dwServiceWait, CERTSVC_NAME, &bStart);
  1875. if(S_OK != (hr=DoCertSrvRegChanges(FALSE)))
  1876. {
  1877. idsMsg=IDS_FAIL_UPDATE_CERTSVC;
  1878. goto ErrorWithHResultReturn;
  1879. }
  1880. if(S_OK != (hr=CepStartService(CERTSVC_NAME)))
  1881. {
  1882. idsMsg=IDS_FAIL_START_CERTSVC;
  1883. goto ErrorWithHResultReturn;
  1884. }
  1885. //make sure the CA is up running
  1886. for (dwWaitCounter=0; dwWaitCounter < pCEPWizardInfo->dwServiceWait; dwWaitCounter++)
  1887. {
  1888. if (!IsCaRunning())
  1889. Sleep(1000);
  1890. else
  1891. break;
  1892. }
  1893. if (pCEPWizardInfo->dwServiceWait == dwWaitCounter)
  1894. {
  1895. idsMsg=IDS_CAN_NOT_START_CA;
  1896. goto ErrorWithHResultReturn;
  1897. }
  1898. //************************************************************************************
  1899. //Add the EventLog Source
  1900. if(S_OK != AddLogSourceToRegistry(L"%SystemRoot%\\System32\\Certsrv\\Mscep\\mscep.dll"))
  1901. {
  1902. idsMsg=IDS_FAIL_REG_EVENT_LOG;
  1903. goto ErrorWithHResultReturn;
  1904. }
  1905. //************************************************************************************
  1906. //success
  1907. //inform the user of the password location and URL
  1908. dwSize=0;
  1909. GetComputerNameExW(ComputerNamePhysicalDnsHostname,
  1910. NULL,
  1911. &dwSize);
  1912. pwszComputerName=(LPWSTR)malloc(dwSize * sizeof(WCHAR));
  1913. if(NULL==pwszComputerName)
  1914. {
  1915. idsMsg=IDS_NO_MEMORY;
  1916. goto ErrorReturn;
  1917. }
  1918. if(!GetComputerNameExW(ComputerNamePhysicalDnsHostname,
  1919. pwszComputerName,
  1920. &dwSize))
  1921. {
  1922. idsMsg=IDS_FAIL_GET_COMPUTER_NAME;
  1923. goto ErrorWithWin32Return;
  1924. }
  1925. if(!FormatMessageUnicode(&pwszText, IDS_CEP_SUCCESS_INFO, pwszComputerName, CEP_DIR_NAME, CEP_DLL_NAME))
  1926. {
  1927. idsMsg=IDS_NO_MEMORY;
  1928. goto ErrorWithWin32Return;
  1929. }
  1930. wszTitle[0]=L'\0';
  1931. LoadStringU(g_hModule, IDS_WIZARD_CAPTION, wszTitle, sizeof(wszTitle)/sizeof(wszTitle[0]));
  1932. MessageBoxU(hWnd, pwszText, wszTitle, MB_OK | MB_APPLMODAL);
  1933. fResult=TRUE;
  1934. CommonReturn:
  1935. if(pUserInfo)
  1936. {
  1937. LocalFree(pUserInfo);
  1938. }
  1939. if(pwszText)
  1940. LocalFree((HLOCAL)pwszText);
  1941. if(pwszComputerName)
  1942. free(pwszComputerName);
  1943. if(pwszRADN)
  1944. free(pwszRADN);
  1945. return fResult;
  1946. ErrorReturn:
  1947. fResult=FALSE;
  1948. CEPMessageBox(hWnd, idsMsg, MB_ICONERROR|MB_OK|MB_APPLMODAL);
  1949. goto CommonReturn;
  1950. ErrorWithHResultReturn:
  1951. fResult=FALSE;
  1952. CEPErrorMessageBox(hWnd, idsMsg, hr, MB_ICONERROR|MB_OK|MB_APPLMODAL);
  1953. goto CommonReturn;
  1954. ErrorWithWin32Return:
  1955. fResult=FALSE;
  1956. hr=HRESULT_FROM_WIN32(GetLastError());
  1957. CEPErrorMessageBox(hWnd, idsMsg, hr, MB_ICONERROR|MB_OK|MB_APPLMODAL);
  1958. goto CommonReturn;
  1959. }
  1960. //-----------------------------------------------------------------------
  1961. //
  1962. // CEPGetCSPInformation
  1963. //
  1964. // We initialize the following members of CEP_WIZARD_INFO:
  1965. //
  1966. // CEP_CSP_INFO *rgCSPInfo;
  1967. // DWORD dwCSPCount;
  1968. // DWORD dwSignProvIndex;
  1969. // DWORD dwSignKeySize;
  1970. // DWORD dwEncryptProvIndex;
  1971. // DWORD dwEncryptKeySize;
  1972. //
  1973. //
  1974. // typedef struct _CEP_CSP_INFO
  1975. //{
  1976. // LPWSTR pwszCSPName;
  1977. // DWORD dwCSPType;
  1978. // BOOL fSignature;
  1979. // BOOL fExchange;
  1980. // DWORD dwMaxSign; //Max key length of signature
  1981. // DWORD dwMinSign; //Min key length of signature
  1982. // DWORD dwDefaultSign; //default key length of signature
  1983. // DWORD dwMaxEncrypt;
  1984. // DWORD dwMinEncrypt;
  1985. // DWORD dwDefaultEncrypt;
  1986. // DWORD *pdwSignList; //the table of possible signing key length
  1987. // DWORD dwSignCount; //the count of entries in the table
  1988. // DWORD *pdwEncryptList;
  1989. // DWORD dwEncryptCount;
  1990. //}CEP_CSP_INFO;
  1991. //
  1992. //
  1993. //------------------------------------------------------------------------
  1994. BOOL WINAPI CEPGetCSPInformation(CEP_WIZARD_INFO *pCEPWizardInfo)
  1995. {
  1996. BOOL fResult=FALSE;
  1997. DWORD dwCSPIndex=0;
  1998. DWORD dwProviderType=0;
  1999. DWORD cbSize=0;
  2000. DWORD dwFlags=0;
  2001. DWORD dwIndex=0;
  2002. int iDefaultSignature=-1;
  2003. int iDefaultEncryption=-1;
  2004. PROV_ENUMALGS_EX paramData;
  2005. CEP_CSP_INFO *pCSPInfo=NULL;
  2006. HCRYPTPROV hProv = NULL;
  2007. //enum all the providers on the system
  2008. while(CryptEnumProvidersU(
  2009. dwCSPIndex,
  2010. NULL,
  2011. 0,
  2012. &dwProviderType,
  2013. NULL,
  2014. &cbSize))
  2015. {
  2016. pCSPInfo=(CEP_CSP_INFO *)malloc(sizeof(CEP_CSP_INFO));
  2017. if(NULL == pCSPInfo)
  2018. goto MemoryErr;
  2019. memset(pCSPInfo, 0, sizeof(CEP_CSP_INFO));
  2020. pCSPInfo->pwszCSPName=(LPWSTR)malloc(cbSize);
  2021. if(NULL==(pCSPInfo->pwszCSPName))
  2022. goto MemoryErr;
  2023. //get the CSP name and the type
  2024. if(!CryptEnumProvidersU(
  2025. dwCSPIndex,
  2026. NULL,
  2027. 0,
  2028. &(pCSPInfo->dwCSPType),
  2029. pCSPInfo->pwszCSPName,
  2030. &cbSize))
  2031. goto TryNext;
  2032. if(!CryptAcquireContextU(&hProv,
  2033. NULL,
  2034. pCSPInfo->pwszCSPName,
  2035. pCSPInfo->dwCSPType,
  2036. CRYPT_VERIFYCONTEXT))
  2037. goto TryNext;
  2038. //get the max/min of key length for both signature and encryption
  2039. dwFlags=CRYPT_FIRST;
  2040. cbSize=sizeof(paramData);
  2041. memset(&paramData, 0, sizeof(PROV_ENUMALGS_EX));
  2042. while(CryptGetProvParam(
  2043. hProv,
  2044. PP_ENUMALGS_EX,
  2045. (BYTE *) &paramData,
  2046. &cbSize,
  2047. dwFlags))
  2048. {
  2049. if (ALG_CLASS_SIGNATURE == GET_ALG_CLASS(paramData.aiAlgid))
  2050. {
  2051. pCSPInfo->fSignature=TRUE;
  2052. pCSPInfo->dwMaxSign = paramData.dwMaxLen;
  2053. pCSPInfo->dwMinSign = paramData.dwMinLen;
  2054. }
  2055. if (ALG_CLASS_KEY_EXCHANGE == GET_ALG_CLASS(paramData.aiAlgid))
  2056. {
  2057. pCSPInfo->fEncryption=TRUE;
  2058. pCSPInfo->dwMaxEncrypt = paramData.dwMaxLen;
  2059. pCSPInfo->dwMinEncrypt = paramData.dwMinLen;
  2060. }
  2061. dwFlags=0;
  2062. cbSize=sizeof(paramData);
  2063. memset(&paramData, 0, sizeof(PROV_ENUMALGS_EX));
  2064. }
  2065. //the min/max has to within the limit
  2066. if(pCSPInfo->fSignature)
  2067. {
  2068. if(pCSPInfo->dwMaxSign < g_rgdwSmallKeyLength[0])
  2069. pCSPInfo->fSignature=FALSE;
  2070. if(pCSPInfo->dwMinSign > g_rgdwKeyLength[g_dwKeyLengthCount-1])
  2071. pCSPInfo->fSignature=FALSE;
  2072. }
  2073. if(pCSPInfo->fEncryption)
  2074. {
  2075. if(pCSPInfo->dwMaxEncrypt < g_rgdwSmallKeyLength[0])
  2076. pCSPInfo->fEncryption=FALSE;
  2077. if(pCSPInfo->dwMinEncrypt > g_rgdwKeyLength[g_dwKeyLengthCount-1])
  2078. pCSPInfo->fEncryption=FALSE;
  2079. }
  2080. if((FALSE == pCSPInfo->fEncryption) && (FALSE==pCSPInfo->fSignature))
  2081. goto TryNext;
  2082. //decide the default key length
  2083. for(dwIndex=0; dwIndex<g_dwDefaultKeyCount; dwIndex++)
  2084. {
  2085. if((pCSPInfo->fSignature) && (0==pCSPInfo->dwDefaultSign))
  2086. {
  2087. if((g_rgdwDefaultKey[dwIndex] >= pCSPInfo->dwMinSign) &&
  2088. (g_rgdwDefaultKey[dwIndex] <= pCSPInfo->dwMaxSign)
  2089. )
  2090. pCSPInfo->dwDefaultSign=g_rgdwDefaultKey[dwIndex];
  2091. }
  2092. if((pCSPInfo->fEncryption) && (0==pCSPInfo->dwDefaultEncrypt))
  2093. {
  2094. if((g_rgdwDefaultKey[dwIndex] >= pCSPInfo->dwMinEncrypt) &&
  2095. (g_rgdwDefaultKey[dwIndex] <= pCSPInfo->dwMaxEncrypt)
  2096. )
  2097. pCSPInfo->dwDefaultEncrypt=g_rgdwDefaultKey[dwIndex];
  2098. }
  2099. }
  2100. //make sure that we have find a default
  2101. if((pCSPInfo->fSignature) && (0==pCSPInfo->dwDefaultSign))
  2102. goto TryNext;
  2103. if((pCSPInfo->fEncryption) && (0==pCSPInfo->dwDefaultEncrypt))
  2104. goto TryNext;
  2105. //decide the display list
  2106. if(pCSPInfo->fSignature)
  2107. {
  2108. if(pCSPInfo->dwMaxSign <= g_rgdwSmallKeyLength[g_dwSmallKeyLengthCount-1])
  2109. {
  2110. pCSPInfo->pdwSignList=g_rgdwSmallKeyLength;
  2111. pCSPInfo->dwSignCount=g_dwSmallKeyLengthCount;
  2112. }
  2113. else
  2114. {
  2115. pCSPInfo->pdwSignList=g_rgdwKeyLength;
  2116. pCSPInfo->dwSignCount=g_dwKeyLengthCount;
  2117. }
  2118. }
  2119. if(pCSPInfo->fEncryption)
  2120. {
  2121. if(pCSPInfo->dwMaxEncrypt <= g_rgdwSmallKeyLength[g_dwSmallKeyLengthCount-1])
  2122. {
  2123. pCSPInfo->pdwEncryptList=g_rgdwSmallKeyLength;
  2124. pCSPInfo->dwEncryptCount=g_dwSmallKeyLengthCount;
  2125. }
  2126. else
  2127. {
  2128. pCSPInfo->pdwEncryptList=g_rgdwKeyLength;
  2129. pCSPInfo->dwEncryptCount=g_dwKeyLengthCount;
  2130. }
  2131. }
  2132. //the CSP looks good
  2133. (pCEPWizardInfo->dwCSPCount)++;
  2134. //realloc to mapped to LocalRealloc which does not take NULL
  2135. if(1 == pCEPWizardInfo->dwCSPCount)
  2136. pCEPWizardInfo->rgCSPInfo=(CEP_CSP_INFO *)malloc(sizeof(CEP_CSP_INFO));
  2137. else
  2138. pCEPWizardInfo->rgCSPInfo=(CEP_CSP_INFO *)realloc(pCEPWizardInfo->rgCSPInfo,
  2139. (pCEPWizardInfo->dwCSPCount) * sizeof(CEP_CSP_INFO));
  2140. if(NULL==pCEPWizardInfo->rgCSPInfo)
  2141. {
  2142. pCEPWizardInfo->dwCSPCount=0;
  2143. goto MemoryErr;
  2144. }
  2145. memcpy(&(pCEPWizardInfo->rgCSPInfo[(pCEPWizardInfo->dwCSPCount)-1]),
  2146. pCSPInfo, sizeof(CEP_CSP_INFO));
  2147. free(pCSPInfo);
  2148. pCSPInfo=NULL;
  2149. //we default to use RSA_FULL
  2150. if(0 == _wcsicmp(pCEPWizardInfo->rgCSPInfo[pCEPWizardInfo->dwCSPCount-1].pwszCSPName,
  2151. MS_DEF_PROV_W))
  2152. {
  2153. if(pCEPWizardInfo->rgCSPInfo[pCEPWizardInfo->dwCSPCount-1].fSignature)
  2154. {
  2155. iDefaultSignature=pCEPWizardInfo->dwCSPCount-1;
  2156. }
  2157. if(pCEPWizardInfo->rgCSPInfo[pCEPWizardInfo->dwCSPCount-1].fEncryption)
  2158. {
  2159. iDefaultEncryption=pCEPWizardInfo->dwCSPCount-1;
  2160. }
  2161. }
  2162. TryNext:
  2163. cbSize=0;
  2164. dwCSPIndex++;
  2165. if(pCSPInfo)
  2166. {
  2167. if(pCSPInfo->pwszCSPName)
  2168. free(pCSPInfo->pwszCSPName);
  2169. free(pCSPInfo);
  2170. }
  2171. pCSPInfo=NULL;
  2172. if(hProv)
  2173. CryptReleaseContext(hProv, 0);
  2174. hProv=NULL;
  2175. }
  2176. //we need to have some valid data
  2177. if((0==pCEPWizardInfo->dwCSPCount) || (NULL==pCEPWizardInfo->rgCSPInfo))
  2178. goto InvalidArgErr;
  2179. //get the default CSP selection
  2180. if(-1 != iDefaultSignature)
  2181. pCEPWizardInfo->dwSignProvIndex=iDefaultSignature;
  2182. else
  2183. {
  2184. //find the 1st signature CSP
  2185. for(dwIndex=0; dwIndex < pCEPWizardInfo->dwCSPCount; dwIndex++)
  2186. {
  2187. if(pCEPWizardInfo->rgCSPInfo[dwIndex].fSignature)
  2188. {
  2189. pCEPWizardInfo->dwSignProvIndex=dwIndex;
  2190. break;
  2191. }
  2192. //we do no have signature CSPs
  2193. if(dwIndex == pCEPWizardInfo->dwCSPCount)
  2194. goto InvalidArgErr;
  2195. }
  2196. }
  2197. pCEPWizardInfo->dwSignKeyLength=pCEPWizardInfo->rgCSPInfo[pCEPWizardInfo->dwSignProvIndex].dwDefaultSign;
  2198. if(-1 != iDefaultEncryption)
  2199. pCEPWizardInfo->dwEncryptProvIndex=iDefaultEncryption;
  2200. else
  2201. {
  2202. //find the 1st exchange CSP
  2203. for(dwIndex=0; dwIndex < pCEPWizardInfo->dwCSPCount; dwIndex++)
  2204. {
  2205. if(pCEPWizardInfo->rgCSPInfo[dwIndex].fEncryption)
  2206. {
  2207. pCEPWizardInfo->dwEncryptProvIndex=dwIndex;
  2208. break;
  2209. }
  2210. //we do no have encryption CSPs
  2211. if(dwIndex == pCEPWizardInfo->dwCSPCount)
  2212. goto InvalidArgErr;
  2213. }
  2214. }
  2215. pCEPWizardInfo->dwEncryptKeyLength=pCEPWizardInfo->rgCSPInfo[pCEPWizardInfo->dwEncryptProvIndex].dwDefaultEncrypt;
  2216. fResult=TRUE;
  2217. CommonReturn:
  2218. return fResult;
  2219. ErrorReturn:
  2220. if(pCSPInfo)
  2221. {
  2222. if(pCSPInfo->pwszCSPName)
  2223. free(pCSPInfo->pwszCSPName);
  2224. free(pCSPInfo);
  2225. }
  2226. if(hProv)
  2227. CryptReleaseContext(hProv, 0);
  2228. if(pCEPWizardInfo->rgCSPInfo)
  2229. {
  2230. for(dwIndex=0; dwIndex < pCEPWizardInfo->dwCSPCount; dwIndex++)
  2231. {
  2232. if(pCEPWizardInfo->rgCSPInfo[dwIndex].pwszCSPName)
  2233. free(pCEPWizardInfo->rgCSPInfo[dwIndex].pwszCSPName);
  2234. }
  2235. free(pCEPWizardInfo->rgCSPInfo);
  2236. }
  2237. pCEPWizardInfo->dwCSPCount=0;
  2238. pCEPWizardInfo->rgCSPInfo=NULL;
  2239. fResult=FALSE;
  2240. goto CommonReturn;
  2241. SET_ERROR(MemoryErr, E_OUTOFMEMORY);
  2242. SET_ERROR(InvalidArgErr, E_INVALIDARG);
  2243. }
  2244. //-----------------------------------------------------------------------
  2245. //
  2246. // UpdateCEPRegistry
  2247. //
  2248. //------------------------------------------------------------------------
  2249. BOOL WINAPI UpdateCEPRegistry(BOOL fPassword, BOOL fEnterpriseCA)
  2250. {
  2251. BOOL fResult=FALSE;
  2252. DWORD dwDisposition=0;
  2253. LPWSTR pwszReg[]={MSCEP_REFRESH_LOCATION,
  2254. MSCEP_PASSWORD_LOCATION,
  2255. MSCEP_PASSWORD_MAX_LOCATION,
  2256. MSCEP_PASSWORD_VALIDITY_LOCATION,
  2257. MSCEP_CACHE_REQUEST_LOCATION,
  2258. MSCEP_CATYPE_LOCATION};
  2259. DWORD dwRegCount=0;
  2260. DWORD dwRegIndex=0;
  2261. HKEY hKey=NULL;
  2262. //we delete all existing CEP related registry keys
  2263. dwRegCount=sizeof(pwszReg)/sizeof(pwszReg[0]);
  2264. for(dwRegIndex=0; dwRegIndex < dwRegCount; dwRegIndex++)
  2265. {
  2266. RegDeleteKeyU(HKEY_LOCAL_MACHINE, pwszReg[dwRegIndex]);
  2267. }
  2268. //password
  2269. if (ERROR_SUCCESS != RegCreateKeyExU(
  2270. HKEY_LOCAL_MACHINE,
  2271. MSCEP_PASSWORD_LOCATION,
  2272. 0,
  2273. NULL,
  2274. REG_OPTION_NON_VOLATILE,
  2275. KEY_WRITE,
  2276. NULL,
  2277. &hKey,
  2278. &dwDisposition))
  2279. goto RegErr;
  2280. if(fPassword)
  2281. dwDisposition=1;
  2282. else
  2283. dwDisposition=0;
  2284. if(ERROR_SUCCESS != RegSetValueExU(
  2285. hKey,
  2286. MSCEP_KEY_PASSWORD,
  2287. 0,
  2288. REG_DWORD,
  2289. (BYTE *)&dwDisposition,
  2290. sizeof(dwDisposition)))
  2291. goto RegErr;
  2292. if(hKey)
  2293. RegCloseKey(hKey);
  2294. hKey=NULL;
  2295. //caType
  2296. dwDisposition=0;
  2297. if (ERROR_SUCCESS != RegCreateKeyExU(
  2298. HKEY_LOCAL_MACHINE,
  2299. MSCEP_CATYPE_LOCATION,
  2300. 0,
  2301. NULL,
  2302. REG_OPTION_NON_VOLATILE,
  2303. KEY_WRITE,
  2304. NULL,
  2305. &hKey,
  2306. &dwDisposition))
  2307. goto RegErr;
  2308. if(fEnterpriseCA)
  2309. dwDisposition=1;
  2310. else
  2311. dwDisposition=0;
  2312. if(ERROR_SUCCESS != RegSetValueExU(
  2313. hKey,
  2314. MSCEP_KEY_CATYPE,
  2315. 0,
  2316. REG_DWORD,
  2317. (BYTE *)&dwDisposition,
  2318. sizeof(dwDisposition)))
  2319. goto RegErr;
  2320. fResult=TRUE;
  2321. CommonReturn:
  2322. if(hKey)
  2323. RegCloseKey(hKey);
  2324. return fResult;
  2325. ErrorReturn:
  2326. fResult=FALSE;
  2327. goto CommonReturn;
  2328. TRACE_ERROR(RegErr);
  2329. }
  2330. //-----------------------------------------------------------------------
  2331. //
  2332. // EmptyCEPStore
  2333. //
  2334. //------------------------------------------------------------------------
  2335. BOOL WINAPI EmptyCEPStore()
  2336. {
  2337. BOOL fResult=TRUE;
  2338. HCERTSTORE hCEPStore=NULL;
  2339. PCCERT_CONTEXT pCurCert=NULL;
  2340. if(NULL == (hCEPStore=CertOpenStore(CERT_STORE_PROV_SYSTEM_W,
  2341. ENCODE_TYPE,
  2342. NULL,
  2343. CERT_SYSTEM_STORE_LOCAL_MACHINE | CERT_STORE_READONLY_FLAG | CERT_STORE_OPEN_EXISTING_FLAG,
  2344. CEP_STORE_NAME)))
  2345. return TRUE;
  2346. if(NULL != (pCurCert=CertEnumCertificatesInStore(hCEPStore, NULL)))
  2347. {
  2348. CertFreeCertificateContext(pCurCert);
  2349. fResult=FALSE;
  2350. }
  2351. CertCloseStore(hCEPStore, 0);
  2352. return fResult;
  2353. }
  2354. //-----------------------------------------------------------------------
  2355. //
  2356. // RemoveRACertificates
  2357. //
  2358. //------------------------------------------------------------------------
  2359. BOOL WINAPI RemoveRACertificates()
  2360. {
  2361. PCCERT_CONTEXT pCurCert=NULL;
  2362. PCCERT_CONTEXT pPreCert=NULL;
  2363. PCCERT_CONTEXT pDupCert=NULL;
  2364. BOOL fResult=TRUE;
  2365. HCERTSTORE hCEPStore=NULL;
  2366. if(hCEPStore=CertOpenStore(CERT_STORE_PROV_SYSTEM_W,
  2367. ENCODE_TYPE,
  2368. NULL,
  2369. CERT_SYSTEM_STORE_LOCAL_MACHINE | CERT_STORE_OPEN_EXISTING_FLAG,
  2370. CEP_STORE_NAME))
  2371. {
  2372. while(pCurCert=CertEnumCertificatesInStore(hCEPStore,
  2373. pPreCert))
  2374. {
  2375. if(pDupCert=CertDuplicateCertificateContext(pCurCert))
  2376. {
  2377. if(!CertDeleteCertificateFromStore(pDupCert))
  2378. {
  2379. fResult=FALSE;
  2380. }
  2381. pDupCert=NULL;
  2382. }
  2383. else
  2384. fResult=FALSE;
  2385. pPreCert=pCurCert;
  2386. }
  2387. CertCloseStore(hCEPStore, 0);
  2388. }
  2389. return fResult;
  2390. }
  2391. //-----------------------------------------------------------------------
  2392. //
  2393. // FreeCEPWizardInfo
  2394. //
  2395. //------------------------------------------------------------------------
  2396. void WINAPI FreeCEPWizardInfo(CEP_WIZARD_INFO *pCEPWizardInfo)
  2397. {
  2398. DWORD dwIndex=0;
  2399. if(pCEPWizardInfo)
  2400. {
  2401. DestroyFonts(pCEPWizardInfo->hBigBold,
  2402. pCEPWizardInfo->hBold);
  2403. for(dwIndex=0; dwIndex<RA_INFO_COUNT; dwIndex++)
  2404. {
  2405. if(pCEPWizardInfo->rgpwszName[dwIndex])
  2406. free(pCEPWizardInfo->rgpwszName[dwIndex]);
  2407. }
  2408. if(pCEPWizardInfo->rgCSPInfo)
  2409. {
  2410. for(dwIndex=0; dwIndex < pCEPWizardInfo->dwCSPCount; dwIndex++)
  2411. {
  2412. if(pCEPWizardInfo->rgCSPInfo[dwIndex].pwszCSPName)
  2413. free(pCEPWizardInfo->rgCSPInfo[dwIndex].pwszCSPName);
  2414. }
  2415. free(pCEPWizardInfo->rgCSPInfo);
  2416. }
  2417. if(pCEPWizardInfo->pwszUserName)
  2418. {
  2419. free(pCEPWizardInfo->pwszUserName);
  2420. }
  2421. if(pCEPWizardInfo->pwszPassword)
  2422. {
  2423. SecureZeroMemory(pCEPWizardInfo->pwszPassword, sizeof(WCHAR) * wcslen(pCEPWizardInfo->pwszPassword));
  2424. free(pCEPWizardInfo->pwszPassword);
  2425. }
  2426. if(pCEPWizardInfo->hAccountToken)
  2427. {
  2428. CloseHandle(pCEPWizardInfo->hAccountToken);
  2429. }
  2430. if(pCEPWizardInfo->pIDsObjectPicker)
  2431. {
  2432. (pCEPWizardInfo->pIDsObjectPicker)->Release();
  2433. }
  2434. memset(pCEPWizardInfo, 0, sizeof(CEP_WIZARD_INFO));
  2435. }
  2436. }
  2437. //-----------------------------------------------------------------------
  2438. //
  2439. // CEPWizardInit
  2440. //
  2441. //------------------------------------------------------------------------
  2442. BOOL WINAPI CEPWizardInit()
  2443. {
  2444. INITCOMMONCONTROLSEX initcomm = {
  2445. sizeof(initcomm), ICC_NATIVEFNTCTL_CLASS | ICC_LISTVIEW_CLASSES
  2446. };
  2447. return InitCommonControlsEx(&initcomm);
  2448. }
  2449. //-----------------------------------------------------------------------
  2450. //
  2451. // IsValidInstallation
  2452. //
  2453. //------------------------------------------------------------------------
  2454. BOOL WINAPI IsValidInstallation(UINT *pidsMsg)
  2455. {
  2456. if(!IsNT5())
  2457. {
  2458. *pidsMsg=IDS_NO_NT5;
  2459. return FALSE;
  2460. }
  2461. if(!IsIISInstalled())
  2462. {
  2463. *pidsMsg=IDS_NO_IIS;
  2464. return FALSE;
  2465. }
  2466. if(!IsGoodCaInstalled())
  2467. {
  2468. *pidsMsg=IDS_NO_GOOD_CA;
  2469. return FALSE;
  2470. }
  2471. return TRUE;
  2472. }
  2473. //-----------------------------------------------------------------------
  2474. //
  2475. // CEPErrorMessageBox
  2476. //
  2477. //------------------------------------------------------------------------
  2478. int WINAPI CEPErrorMessageBox(
  2479. HWND hWnd,
  2480. UINT idsReason,
  2481. HRESULT hr,
  2482. UINT uType
  2483. )
  2484. {
  2485. return CEPErrorMessageBoxEx(hWnd,
  2486. idsReason,
  2487. hr,
  2488. uType,
  2489. IDS_CEP_ERROR_MSG_HR,
  2490. IDS_CEP_ERROR_MSG);
  2491. }
  2492. //-----------------------------------------------------------------------
  2493. //
  2494. // CEPErrorMessageBoxEx
  2495. //
  2496. //------------------------------------------------------------------------
  2497. int WINAPI CEPErrorMessageBoxEx(
  2498. HWND hWnd,
  2499. UINT idsReason,
  2500. HRESULT hr,
  2501. UINT uType,
  2502. UINT idsFormat1,
  2503. UINT idsFormat2
  2504. )
  2505. {
  2506. WCHAR wszReason[MAX_STRING_SIZE];
  2507. WCHAR wszCaption[MAX_STRING_SIZE];
  2508. UINT intReturn=0;
  2509. LPWSTR pwszText=NULL;
  2510. LPWSTR pwszErrorMsg=NULL;
  2511. if(!LoadStringU(g_hModule, IDS_MEG_CAPTION, wszCaption, sizeof(wszCaption)/sizeof(WCHAR)))
  2512. goto CLEANUP;
  2513. if(!LoadStringU(g_hModule, idsReason, wszReason, sizeof(wszReason)/sizeof(WCHAR)))
  2514. goto CLEANUP;
  2515. if(!FAILED(hr))
  2516. hr=E_FAIL;
  2517. //using W version because this is a NT5 only function call
  2518. if(FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER |
  2519. FORMAT_MESSAGE_FROM_SYSTEM |
  2520. FORMAT_MESSAGE_IGNORE_INSERTS,
  2521. NULL,
  2522. hr,
  2523. MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
  2524. (LPWSTR) &pwszErrorMsg,
  2525. 0,
  2526. NULL))
  2527. {
  2528. if(!FormatMessageUnicode(&pwszText, idsFormat1, wszReason, pwszErrorMsg))
  2529. goto CLEANUP;
  2530. }
  2531. else
  2532. {
  2533. if(!FormatMessageUnicode(&pwszText, idsFormat2, wszReason))
  2534. goto CLEANUP;
  2535. }
  2536. intReturn=MessageBoxU(hWnd, pwszText, wszCaption, uType);
  2537. CLEANUP:
  2538. if(pwszText)
  2539. LocalFree((HLOCAL)pwszText);
  2540. if(pwszErrorMsg)
  2541. LocalFree((HLOCAL)pwszErrorMsg);
  2542. return intReturn;
  2543. }
  2544. //-----------------------------------------------------------------------
  2545. //
  2546. // CEPMessageBox
  2547. //
  2548. //------------------------------------------------------------------------
  2549. int WINAPI CEPMessageBox(
  2550. HWND hWnd,
  2551. UINT idsText,
  2552. UINT uType
  2553. )
  2554. {
  2555. WCHAR wszText[MAX_STRING_SIZE];
  2556. WCHAR wszCaption[MAX_STRING_SIZE];
  2557. UINT intReturn=0;
  2558. if(!LoadStringU(g_hModule, IDS_MEG_CAPTION, wszCaption, sizeof(wszCaption)/sizeof(WCHAR)))
  2559. return 0;
  2560. if(!LoadStringU(g_hModule, idsText, wszText, sizeof(wszText)/sizeof(WCHAR)))
  2561. return 0;
  2562. intReturn=MessageBoxU(hWnd, wszText, wszCaption, uType);
  2563. return intReturn;
  2564. }
  2565. //--------------------------------------------------------------------------
  2566. //
  2567. // SetControlFont
  2568. //
  2569. //--------------------------------------------------------------------------
  2570. void WINAPI SetControlFont(
  2571. IN HFONT hFont,
  2572. IN HWND hwnd,
  2573. IN INT nId
  2574. )
  2575. {
  2576. if( hFont )
  2577. {
  2578. HWND hwndControl = GetDlgItem(hwnd, nId);
  2579. if( hwndControl )
  2580. {
  2581. SetWindowFont(hwndControl, hFont, TRUE);
  2582. }
  2583. }
  2584. }
  2585. //--------------------------------------------------------------------------
  2586. //
  2587. // SetupFonts
  2588. //
  2589. //--------------------------------------------------------------------------
  2590. BOOL WINAPI SetupFonts(
  2591. IN HINSTANCE hInstance,
  2592. IN HWND hwnd,
  2593. IN HFONT *pBigBoldFont,
  2594. IN HFONT *pBoldFont
  2595. )
  2596. {
  2597. //
  2598. // Create the fonts we need based on the dialog font
  2599. //
  2600. NONCLIENTMETRICS ncm = {0};
  2601. ncm.cbSize = sizeof(ncm);
  2602. if(!SystemParametersInfo(SPI_GETNONCLIENTMETRICS, 0, &ncm, 0))
  2603. return FALSE;
  2604. LOGFONT BigBoldLogFont = ncm.lfMessageFont;
  2605. LOGFONT BoldLogFont = ncm.lfMessageFont;
  2606. //
  2607. // Create Big Bold Font and Bold Font
  2608. //
  2609. BigBoldLogFont.lfWeight = FW_BOLD;
  2610. BoldLogFont.lfWeight = FW_BOLD;
  2611. INT BigBoldFontSize = 12;
  2612. HDC hdc = GetDC( hwnd );
  2613. if( hdc )
  2614. {
  2615. BigBoldLogFont.lfHeight = 0 - (GetDeviceCaps(hdc,LOGPIXELSY) * BigBoldFontSize / 72);
  2616. *pBigBoldFont = CreateFontIndirect(&BigBoldLogFont);
  2617. *pBoldFont = CreateFontIndirect(&BoldLogFont);
  2618. ReleaseDC(hwnd,hdc);
  2619. if(*pBigBoldFont && *pBoldFont)
  2620. return TRUE;
  2621. else
  2622. {
  2623. if( *pBigBoldFont )
  2624. {
  2625. DeleteObject(*pBigBoldFont);
  2626. *pBigBoldFont=NULL;
  2627. }
  2628. if( *pBoldFont )
  2629. {
  2630. DeleteObject(*pBoldFont);
  2631. *pBoldFont=NULL;
  2632. }
  2633. return FALSE;
  2634. }
  2635. }
  2636. return FALSE;
  2637. }
  2638. //--------------------------------------------------------------------------
  2639. //
  2640. // DestroyFonts
  2641. //
  2642. //--------------------------------------------------------------------------
  2643. void WINAPI DestroyFonts(
  2644. IN HFONT hBigBoldFont,
  2645. IN HFONT hBoldFont
  2646. )
  2647. {
  2648. if( hBigBoldFont )
  2649. {
  2650. DeleteObject( hBigBoldFont );
  2651. }
  2652. if( hBoldFont )
  2653. {
  2654. DeleteObject( hBoldFont );
  2655. }
  2656. }
  2657. //--------------------------------------------------------------------------
  2658. //
  2659. // FormatMessageUnicode
  2660. //
  2661. //--------------------------------------------------------------------------
  2662. BOOL WINAPI FormatMessageUnicode(LPWSTR *ppwszFormat,UINT ids,...)
  2663. {
  2664. // get format string from resources
  2665. WCHAR wszFormat[1000];
  2666. va_list argList;
  2667. DWORD cbMsg=0;
  2668. BOOL fResult=FALSE;
  2669. HRESULT hr=S_OK;
  2670. if(NULL == ppwszFormat)
  2671. goto InvalidArgErr;
  2672. if(!LoadStringU(g_hModule, ids, wszFormat, sizeof(wszFormat)/sizeof(WCHAR)))
  2673. goto LoadStringError;
  2674. // format message into requested buffer
  2675. va_start(argList, ids);
  2676. cbMsg = FormatMessageU(
  2677. FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_STRING,
  2678. wszFormat,
  2679. 0, // dwMessageId
  2680. 0, // dwLanguageId
  2681. (LPWSTR) (ppwszFormat),
  2682. 0, // minimum size to allocate
  2683. &argList);
  2684. va_end(argList);
  2685. if(!cbMsg)
  2686. goto FormatMessageError;
  2687. fResult=TRUE;
  2688. CommonReturn:
  2689. return fResult;
  2690. ErrorReturn:
  2691. fResult=FALSE;
  2692. goto CommonReturn;
  2693. TRACE_ERROR(LoadStringError);
  2694. TRACE_ERROR(FormatMessageError);
  2695. SET_ERROR(InvalidArgErr, E_INVALIDARG);
  2696. }
  2697. //--------------------------------------------------------------------------
  2698. //
  2699. // AddLogSourceToRegistry
  2700. //
  2701. //--------------------------------------------------------------------------
  2702. HRESULT WINAPI AddLogSourceToRegistry(LPWSTR pwszMsgDLL)
  2703. {
  2704. DWORD dwError=ERROR_SUCCESS;
  2705. DWORD dwData=0;
  2706. WCHAR const *pwszRegPath = L"SYSTEM\\CurrentControlSet\\Services\\EventLog\\Application\\";
  2707. WCHAR NameBuf[MAX_STRING_SIZE];
  2708. HKEY hkey = NULL;
  2709. wcscpy(NameBuf, pwszRegPath);
  2710. wcscat(NameBuf, MSCEP_EVENT_LOG);
  2711. // Create a new key for our application
  2712. if(ERROR_SUCCESS != RegOpenKey(HKEY_LOCAL_MACHINE, NameBuf, &hkey))
  2713. {
  2714. if(ERROR_SUCCESS != (dwError = RegCreateKey(HKEY_LOCAL_MACHINE, NameBuf, &hkey)))
  2715. goto CLEANUP;
  2716. }
  2717. // Add the Event-ID message-file name to the subkey
  2718. dwError = RegSetValueEx(
  2719. hkey,
  2720. L"EventMessageFile",
  2721. 0,
  2722. REG_EXPAND_SZ,
  2723. (const BYTE *) pwszMsgDLL,
  2724. (wcslen(pwszMsgDLL) + 1) * sizeof(WCHAR));
  2725. if(ERROR_SUCCESS != dwError)
  2726. goto CLEANUP;
  2727. // Set the supported types flags and add it to the subkey
  2728. dwData = EVENTLOG_ERROR_TYPE |
  2729. EVENTLOG_WARNING_TYPE |
  2730. EVENTLOG_INFORMATION_TYPE;
  2731. dwError = RegSetValueEx(
  2732. hkey,
  2733. L"TypesSupported",
  2734. 0,
  2735. REG_DWORD,
  2736. (LPBYTE) &dwData,
  2737. sizeof(DWORD));
  2738. if(ERROR_SUCCESS != dwError)
  2739. goto CLEANUP;
  2740. dwError=ERROR_SUCCESS;
  2741. CLEANUP:
  2742. if (NULL != hkey)
  2743. {
  2744. RegCloseKey(hkey);
  2745. }
  2746. return(HRESULT_FROM_WIN32(dwError));
  2747. }
  2748. LPWSTR
  2749. GetAccountDomainName(BOOL fDC)
  2750. /*++
  2751. Routine Description:
  2752. Returns the name of the account domain for this machine.
  2753. For workstatations, the account domain is the netbios computer name.
  2754. For DCs, the account domain is the netbios domain name.
  2755. Arguments:
  2756. None.
  2757. Return Values:
  2758. Returns a pointer to the name. The name should be free using NetApiBufferFree.
  2759. NULL - on error.
  2760. --*/
  2761. {
  2762. DWORD WinStatus;
  2763. LPWSTR AllocatedName = NULL;
  2764. //
  2765. // If this machine is a domain controller,
  2766. // get the domain name.
  2767. //
  2768. if ( fDC )
  2769. {
  2770. WinStatus = NetpGetDomainName( &AllocatedName );
  2771. if ( WinStatus != NO_ERROR )
  2772. {
  2773. SetLastError(WinStatus);
  2774. return NULL;
  2775. }
  2776. //
  2777. // Otherwise, the 'account domain' is the computername
  2778. //
  2779. }
  2780. else
  2781. {
  2782. WinStatus = NetpGetComputerName( &AllocatedName );
  2783. if ( WinStatus != NO_ERROR )
  2784. {
  2785. SetLastError(WinStatus);
  2786. return NULL;
  2787. }
  2788. }
  2789. return AllocatedName;
  2790. }