Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

7145 lines
194 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1997 - 1999
  6. //
  7. // File: wizpage.cpp
  8. //
  9. // Contents: Wizard page construction and presentation functions to be used
  10. // by the OCM driver code.
  11. //
  12. // History: 04/16/97 JerryK Fixed/Changed/Unmangled
  13. // 0/8/97 XTan major structure change
  14. //
  15. //----------------------------------------------------------------------------
  16. #include "pch.cpp"
  17. #pragma hdrstop
  18. // ** System Includes **
  19. #include <prsht.h>
  20. #include <commdlg.h>
  21. #include <sddl.h>
  22. // ** Application Includes **
  23. #include "cryptui.h"
  24. #include "csdisp.h"
  25. #include "csprop.h"
  26. #include "cspenum.h"
  27. #include "usecert.h"
  28. #include "wizpage.h"
  29. #include "cscsp.h"
  30. #include "clibres.h"
  31. #include "certmsg.h"
  32. #include "websetup.h"
  33. #include "dssetup.h"
  34. #include "setupids.h"
  35. #include "tfc.h"
  36. //defines
  37. #define __dwFILE__ __dwFILE_OCMSETUP_WIZPAGE_CPP__
  38. #define dwWIZDISABLE -2
  39. #define dwWIZBACK -1
  40. #define dwWIZACTIVE 0
  41. #define dwWIZNEXT 1
  42. #define C_CSPHASNOKEYMINMAX -1
  43. #define MAX_KEYLENGTHEDIT 128
  44. #define MAX_KEYLENGTHDIGIT 5
  45. #define wszOLDCASTOREPREFIX L"CA_"
  46. #define _ReturnIfWizError(hr) \
  47. { \
  48. if (S_OK != (hr)) \
  49. { \
  50. CSILOG((hr), IDS_LOG_WIZ_PAGE_ERROR, NULL, NULL, NULL); \
  51. _PrintError(hr, "CertSrv Wizard error"); \
  52. return TRUE; \
  53. } \
  54. }
  55. #define _GetCompDataOrReturnIfError(pComp, hDlg) \
  56. (PER_COMPONENT_DATA*)GetWindowLongPtr((hDlg), DWLP_USER); \
  57. if (NULL == (pComp) || S_OK != (pComp)->hrContinue) \
  58. { \
  59. return TRUE; \
  60. }
  61. #define _GetCompDataOrReturn(pComp, hDlg) \
  62. (PER_COMPONENT_DATA*)GetWindowLongPtr((hDlg), DWLP_USER); \
  63. if (NULL == (pComp)) \
  64. { \
  65. return TRUE; \
  66. }
  67. #define _DisableWizDisplayIfError(pComp, hDlg) \
  68. if (S_OK != (pComp)->hrContinue) \
  69. { \
  70. CSILOG((pComp)->hrContinue, IDS_LOG_DISABLE_WIZ_PAGE, NULL, NULL, NULL); \
  71. SetWindowLongPtr((hDlg), DWLP_MSGRESULT, -1); \
  72. }
  73. //--------------------------------------------------------------------
  74. struct FAKEPROGRESSINFO {
  75. HANDLE hStopEvent;
  76. CRITICAL_SECTION csTimeSync;
  77. BOOL fCSInit;
  78. DWORD dwSecsRemaining;
  79. HWND hwndProgBar;
  80. };
  81. struct KEYGENPROGRESSINFO {
  82. HWND hDlg; // wizard page window
  83. PER_COMPONENT_DATA * pComp; // setup data
  84. };
  85. KEYGENPROGRESSINFO g_KeyGenInfo = {
  86. NULL, //hDlg
  87. NULL, //pComp
  88. };
  89. BOOL g_fAllowUnicodeStrEncoding = FALSE;
  90. // ** Prototypes/Forward Declarations **
  91. LRESULT CALLBACK
  92. IdInfoNameEditFilterHook(HWND, UINT, WPARAM, LPARAM);
  93. __inline VOID
  94. SetEditFocusAndSelect(
  95. IN HWND hwnd,
  96. IN DWORD indexStart,
  97. IN DWORD indexEnd)
  98. {
  99. SetFocus(hwnd);
  100. SendMessage(hwnd, EM_SETSEL, indexStart, indexEnd);
  101. }
  102. // fix for 160324 - NT4->Whistler upgrade:
  103. // cannot reinstall CA w/ same cert as instructions tell us to do
  104. //
  105. // Upgrade NT4->Whistler is not supported but old CA key and cert can be reused
  106. // But NT4 used to install CA certs in a separate store (CA_MACHINENAME) so we
  107. // need to move the cert to root store so it can be validated.
  108. HRESULT CopyNT4CACertToRootStore(CASERVERSETUPINFO *pServer)
  109. {
  110. HRESULT hr;
  111. WCHAR wszOldCAStore[MAX_PATH];
  112. HCERTSTORE hOldStore = NULL;
  113. HCERTSTORE hRootStore = NULL;
  114. CERT_RDN_ATTR rdnAttr = { szOID_COMMON_NAME, CERT_RDN_ANY_TYPE,};
  115. CERT_RDN rdn = { 1, &rdnAttr };
  116. DWORD cCA = 0;
  117. CERT_CONTEXT const *pCACert;
  118. CERT_CONTEXT const *pCACertKeep = NULL; // needn't free
  119. DWORD dwFlags;
  120. ENUM_CATYPES CATypeDummy;
  121. CERT_CONTEXT const **ppCACertKeep = NULL;
  122. CRYPT_KEY_PROV_INFO keyProvInfo;
  123. DWORD IndexCA;
  124. DWORD *pIndex = NULL;
  125. DWORD i = 0;
  126. ZeroMemory(&keyProvInfo, sizeof(keyProvInfo));
  127. // form old ca store name
  128. // !!! NT4 uses different sanitize, how do we build it correctly?
  129. wcscpy(wszOldCAStore, wszOLDCASTOREPREFIX);
  130. wcscat(wszOldCAStore, pServer->pwszSanitizedName);
  131. // open old CA store
  132. hOldStore = CertOpenStore(
  133. CERT_STORE_PROV_SYSTEM_W,
  134. X509_ASN_ENCODING,
  135. NULL, // hProv
  136. CERT_STORE_OPEN_EXISTING_FLAG |
  137. CERT_STORE_READONLY_FLAG |
  138. CERT_SYSTEM_STORE_LOCAL_MACHINE,
  139. wszOldCAStore);
  140. if (NULL == hOldStore)
  141. {
  142. hr = myHLastError();
  143. _JumpError(hr, error, "CertOpenStore");
  144. }
  145. // find CA cert, old ca common name always same as ca name
  146. rdnAttr.Value.pbData = (BYTE *) pServer->pwszCACommonName;
  147. rdnAttr.Value.cbData = 0;
  148. pCACert = NULL;
  149. do
  150. {
  151. pCACert = CertFindCertificateInStore(
  152. hOldStore,
  153. X509_ASN_ENCODING,
  154. CERT_UNICODE_IS_RDN_ATTRS_FLAG |
  155. CERT_CASE_INSENSITIVE_IS_RDN_ATTRS_FLAG,
  156. CERT_FIND_SUBJECT_ATTR,
  157. &rdn,
  158. pCACert);
  159. if (NULL != pCACert)
  160. {
  161. // find one
  162. if (NULL == ppCACertKeep)
  163. {
  164. ppCACertKeep = (CERT_CONTEXT const **)LocalAlloc(LMEM_FIXED,
  165. (cCA + 1) * sizeof(CERT_CONTEXT const *));
  166. _JumpIfOutOfMemory(hr, error, ppCACertKeep);
  167. }
  168. else
  169. {
  170. CERT_CONTEXT const ** ppTemp;
  171. ppTemp = (CERT_CONTEXT const **)LocalReAlloc(
  172. ppCACertKeep,
  173. (cCA + 1) * sizeof(CERT_CONTEXT const *),
  174. LMEM_MOVEABLE);
  175. _JumpIfOutOfMemory(hr, error, ppTemp);
  176. ppCACertKeep = ppTemp;
  177. }
  178. // keep current
  179. ppCACertKeep[cCA] = CertDuplicateCertificateContext(pCACert);
  180. if (NULL == ppCACertKeep[cCA])
  181. {
  182. hr = myHLastError();
  183. _JumpError(hr, error, "CertDuplicateCertificate");
  184. }
  185. ++cCA;
  186. }
  187. } while (NULL != pCACert);
  188. if (1 > cCA)
  189. {
  190. // no ca cert
  191. hr = E_INVALIDARG;
  192. _JumpError(hr, error, "no ca cert");
  193. }
  194. // assume 1st one
  195. pCACertKeep = ppCACertKeep[0];
  196. if (1 < cCA)
  197. {
  198. DWORD cCA2 = cCA;
  199. BOOL fMatch;
  200. // have multi ca certs with the same cn
  201. // because sp4 doesn't reg ca serial # so need to decide which one
  202. // once the correct one is found, reg its serial #
  203. // build an index
  204. pIndex = (DWORD*)LocalAlloc(LMEM_FIXED, cCA * sizeof(DWORD));
  205. _JumpIfOutOfMemory(hr, error, pIndex);
  206. i = 0;
  207. for (pIndex[i] = i; i < cCA; ++i);
  208. // try to compare with public key
  209. // in case ca cert doesn't have kpi which is the case for v10
  210. // so try base rsa
  211. hr = csiFillKeyProvInfo(
  212. pServer->pwszSanitizedName,
  213. pServer->pCSPInfo->pwszProvName,
  214. pServer->pCSPInfo->dwProvType,
  215. TRUE, // always machine keyset
  216. &keyProvInfo);
  217. if (S_OK == hr)
  218. {
  219. cCA2 = 0;
  220. for (i = 0; i < cCA; ++i)
  221. {
  222. hr = myVerifyPublicKey(
  223. ppCACertKeep[i],
  224. FALSE,
  225. &keyProvInfo,
  226. NULL,
  227. &fMatch);
  228. if (S_OK != hr)
  229. {
  230. continue;
  231. }
  232. if (fMatch)
  233. {
  234. // found one match with current public key from container
  235. pIndex[cCA2] = i;
  236. ++cCA2;
  237. }
  238. }
  239. }
  240. // compare all ca certs and pick one has most recent NotAfter
  241. pCACertKeep = ppCACertKeep[pIndex[0]];
  242. for (i = 1; i < cCA2; ++i)
  243. {
  244. if (0 < CompareFileTime(
  245. &ppCACertKeep[pIndex[i]]->pCertInfo->NotAfter,
  246. &pCACertKeep->pCertInfo->NotAfter))
  247. {
  248. // update
  249. pCACertKeep = ppCACertKeep[pIndex[i]];
  250. }
  251. }
  252. }
  253. // if get here, must find ca cert
  254. CSASSERT(NULL != pCACertKeep);
  255. // add cert to root store
  256. hRootStore = CertOpenStore(
  257. CERT_STORE_PROV_SYSTEM_W,
  258. X509_ASN_ENCODING,
  259. NULL, // hProv
  260. CERT_SYSTEM_STORE_LOCAL_MACHINE,
  261. wszROOT_CERTSTORE);
  262. if (NULL == hRootStore)
  263. {
  264. hr = myHLastError();
  265. _JumpError(hr, error, "CertOpenStore");
  266. }
  267. if(!CertAddCertificateContextToStore(
  268. hRootStore,
  269. pCACertKeep,
  270. CERT_STORE_ADD_NEW,
  271. NULL))
  272. {
  273. hr = myHLastError();
  274. _JumpError(hr, error, "CertAddCertificateContextToStore");
  275. }
  276. error:
  277. csiFreeKeyProvInfo(&keyProvInfo);
  278. for (i = 0; i < cCA; ++i)
  279. {
  280. CertFreeCertificateContext(ppCACertKeep[i]);
  281. }
  282. if (NULL != hOldStore)
  283. {
  284. CertCloseStore(hOldStore, CERT_CLOSE_STORE_CHECK_FLAG);
  285. }
  286. if (NULL != hRootStore)
  287. {
  288. CertCloseStore(hRootStore, CERT_CLOSE_STORE_CHECK_FLAG);
  289. }
  290. return hr;
  291. }
  292. //--------------------------------------------------------------------
  293. // Clear the key container name to indicate that we must generate a new key.
  294. void
  295. ClearKeyContainerName(CASERVERSETUPINFO *pServer)
  296. {
  297. if (NULL!=pServer->pwszKeyContainerName) {
  298. // Delete the key container if this is a new one
  299. if (pServer->fDeletableNewKey) {
  300. // Delete the key container. Ignore any errors.
  301. HCRYPTPROV hProv=NULL;
  302. myCertSrvCryptAcquireContext(
  303. &hProv,
  304. pServer->pwszKeyContainerName,
  305. pServer->pCSPInfo->pwszProvName,
  306. pServer->pCSPInfo->dwProvType,
  307. CRYPT_DELETEKEYSET,
  308. pServer->pCSPInfo->fMachineKeyset);
  309. if (NULL!=hProv) {
  310. CryptReleaseContext(hProv, 0);
  311. }
  312. pServer->fDeletableNewKey=FALSE;
  313. }
  314. // Clear the key container name, to indicate that we must generate a new key.
  315. LocalFree(pServer->pwszKeyContainerName);
  316. LocalFree(pServer->pwszDesanitizedKeyContainerName);
  317. pServer->pwszKeyContainerName=NULL;
  318. pServer->pwszDesanitizedKeyContainerName=NULL;
  319. // if we were using an existing cert, we are not anymore
  320. ClearExistingCertToUse(pServer);
  321. } else {
  322. // if there was no key, there couldn't be a existing cert.
  323. CSASSERT(NULL==pServer->pccExistingCert);
  324. // key container name is already clear
  325. }
  326. }
  327. //--------------------------------------------------------------------
  328. // Set both the real key container name and the display key container name
  329. HRESULT
  330. SetKeyContainerName(
  331. CASERVERSETUPINFO *pServer,
  332. const WCHAR * pwszKeyContainerName)
  333. {
  334. HRESULT hr;
  335. // get rid of any previous names
  336. ClearKeyContainerName(pServer);
  337. // set the real key container name
  338. pServer->pwszKeyContainerName = (WCHAR *) LocalAlloc(
  339. LMEM_FIXED,
  340. sizeof(WCHAR) * (wcslen(pwszKeyContainerName) + 1));
  341. _JumpIfOutOfMemory(hr, error, pServer->pwszKeyContainerName);
  342. wcscpy(pServer->pwszKeyContainerName, pwszKeyContainerName);
  343. // set the display key container name
  344. hr = myRevertSanitizeName(
  345. pServer->pwszKeyContainerName,
  346. &pServer->pwszDesanitizedKeyContainerName);
  347. _JumpIfError(hr, error, "myRevertSanitizeName");
  348. // Must validate the key again when the selected key changes
  349. pServer->fValidatedHashAndKey = FALSE;
  350. CSILOG(
  351. hr,
  352. IDS_ILOG_KEYCONTAINERNAME,
  353. pServer->pwszKeyContainerName,
  354. pServer->pwszDesanitizedKeyContainerName,
  355. NULL);
  356. error:
  357. return hr;
  358. }
  359. HRESULT
  360. UpdateDomainAndUserName(
  361. IN HWND hwnd,
  362. IN OUT PER_COMPONENT_DATA *pComp);
  363. BOOL
  364. CertConfirmCancel(
  365. HWND hwnd,
  366. PER_COMPONENT_DATA *pComp)
  367. {
  368. HRESULT hr;
  369. CSASSERT(NULL != pComp);
  370. if (!(*pComp->HelperRoutines.ConfirmCancelRoutine)(hwnd))
  371. {
  372. SetWindowLongPtr(hwnd, DWLP_MSGRESULT, TRUE);
  373. return TRUE;
  374. }
  375. hr = CancelCertsrvInstallation(hwnd, pComp);
  376. _PrintIfError(hr, "CancelCertsrvInstallation");
  377. return FALSE;
  378. }
  379. HRESULT
  380. StartWizardPageEditControls(
  381. IN HWND hDlg,
  382. IN OUT PAGESTRINGS *pPageStrings)
  383. {
  384. HRESULT hr;
  385. for ( ; NULL != pPageStrings->ppwszString; pPageStrings++)
  386. {
  387. SendMessage(
  388. GetDlgItem(hDlg, pPageStrings->idControl),
  389. WM_SETTEXT,
  390. 0,
  391. (LPARAM) *pPageStrings->ppwszString);
  392. }
  393. hr = S_OK;
  394. //error:
  395. return hr;
  396. }
  397. HRESULT
  398. FinishWizardPageEditControls(
  399. IN HWND hDlg,
  400. IN OUT PAGESTRINGS *pPageStrings)
  401. {
  402. HRESULT hr;
  403. for ( ; NULL != pPageStrings->ppwszString; pPageStrings++)
  404. {
  405. WCHAR *pwszString = NULL;
  406. hr = myUIGetWindowText(
  407. GetDlgItem(hDlg, pPageStrings->idControl),
  408. &pwszString);
  409. _JumpIfError(hr, error, "myUIGetWindowText");
  410. if (NULL != *pPageStrings->ppwszString)
  411. {
  412. // free old one
  413. LocalFree(*pPageStrings->ppwszString);
  414. *pPageStrings->ppwszString = NULL;
  415. }
  416. *pPageStrings->ppwszString = pwszString;
  417. CSILOG(S_OK, pPageStrings->idLog, pwszString, NULL, NULL);
  418. }
  419. hr = S_OK;
  420. error:
  421. return hr;
  422. }
  423. //+------------------------------------------------------------------------
  424. // Function: WizPageSetTextLimits
  425. //
  426. // Synopsis: Sets text input limits for the text controls of a dlg page.
  427. //-------------------------------------------------------------------------
  428. HRESULT
  429. WizPageSetTextLimits(
  430. HWND hDlg,
  431. IN OUT PAGESTRINGS *pPageStrings)
  432. {
  433. HRESULT hr;
  434. for ( ; NULL != pPageStrings->ppwszString; pPageStrings++)
  435. {
  436. SendDlgItemMessage(
  437. hDlg,
  438. pPageStrings->idControl,
  439. EM_SETLIMITTEXT,
  440. (WPARAM) pPageStrings->cchMax,
  441. (LPARAM) 0);
  442. }
  443. hr = S_OK;
  444. //error:
  445. return hr;
  446. }
  447. // check optional or mac length in edit field
  448. // if any invalid, focus on the edit field, select all
  449. HRESULT
  450. ValidateTextField(
  451. HINSTANCE hInstance,
  452. BOOL fUnattended,
  453. HWND hDlg,
  454. LPTSTR pszTestString,
  455. DWORD nUBValue,
  456. int nMsgBoxNullStringErrID,
  457. int nMsgBoxLenStringErrID,
  458. int nControlID)
  459. {
  460. HRESULT hr = E_INVALIDARG;
  461. HWND hwndCtrl = NULL;
  462. BOOL fIsEmpty;
  463. fIsEmpty = (NULL == pszTestString) || (L'\0' == pszTestString[0]);
  464. if (fIsEmpty)
  465. {
  466. if (0 != nMsgBoxNullStringErrID) // non optional
  467. {
  468. // edit field can't be empty
  469. CertWarningMessageBox(
  470. hInstance,
  471. fUnattended,
  472. hDlg,
  473. nMsgBoxNullStringErrID,
  474. 0,
  475. NULL);
  476. if (!fUnattended)
  477. {
  478. hwndCtrl = GetDlgItem(hDlg, nControlID); // Get offending ctrl
  479. }
  480. goto error;
  481. }
  482. goto done;
  483. }
  484. // the following may not be necessary because edit field set to max limit
  485. if (wcslen(pszTestString) > nUBValue) // Make sure it's not too long
  486. {
  487. CertWarningMessageBox(
  488. hInstance,
  489. fUnattended,
  490. hDlg,
  491. nMsgBoxLenStringErrID,
  492. 0,
  493. NULL);
  494. if (!fUnattended)
  495. {
  496. hwndCtrl = GetDlgItem(hDlg, nControlID);
  497. }
  498. goto error;
  499. }
  500. done:
  501. hr = S_OK;
  502. error:
  503. if (!fUnattended && NULL != hwndCtrl)
  504. {
  505. SetEditFocusAndSelect(hwndCtrl, 0, -1);
  506. }
  507. return hr;
  508. }
  509. HRESULT
  510. WizardPageValidation(
  511. IN HINSTANCE hInstance,
  512. IN BOOL fUnattended,
  513. IN HWND hDlg,
  514. IN PAGESTRINGS *pPageStrings)
  515. {
  516. HRESULT hr;
  517. for ( ; NULL != pPageStrings->ppwszString; pPageStrings++)
  518. {
  519. hr = ValidateTextField(
  520. hInstance,
  521. fUnattended,
  522. hDlg,
  523. *pPageStrings->ppwszString,
  524. pPageStrings->cchMax,
  525. pPageStrings->idMsgBoxNullString,
  526. pPageStrings->idMsgBoxLenString,
  527. pPageStrings->idControl);
  528. _JumpIfError(hr, error, "invalid edit field");
  529. }
  530. hr = S_OK;
  531. error:
  532. return hr;
  533. }
  534. #define KEYGEN_GENERATE_KEY 60 // estimated seconds to gen key
  535. #define KEYGEN_PROTECT_KEY 60 // estimated seconds to acl key
  536. #define KEYGEN_TEST_HASH 2 // estimated seconds to acl key
  537. //--------------------------------------------------------------------
  538. // Fake progress by incrementing a progress bar every second
  539. DWORD WINAPI
  540. KeyGenFakeProgressThread(
  541. LPVOID lpParameter)
  542. {
  543. FAKEPROGRESSINFO * pFakeProgressInfo=(FAKEPROGRESSINFO *)lpParameter;
  544. // Wait for the stop signal for 1 second.
  545. while (WAIT_TIMEOUT==WaitForSingleObject(pFakeProgressInfo->hStopEvent, 1000)) {
  546. // See if we can send another tick to the progress bar
  547. if(pFakeProgressInfo->fCSInit)
  548. {
  549. EnterCriticalSection(&pFakeProgressInfo->csTimeSync);
  550. if (pFakeProgressInfo->dwSecsRemaining>0) {
  551. // move one step (one second)
  552. SendMessage(pFakeProgressInfo->hwndProgBar, PBM_DELTAPOS, 1, 0);
  553. pFakeProgressInfo->dwSecsRemaining--;
  554. }
  555. LeaveCriticalSection(&pFakeProgressInfo->csTimeSync);
  556. }
  557. }
  558. // We were signaled, so stop.
  559. return 0; // return value ignored
  560. }
  561. //--------------------------------------------------------------------
  562. // Generate a new key and test the hash algorithm
  563. DWORD WINAPI
  564. GenerateKeyThread(
  565. LPVOID lpParameter)
  566. {
  567. HRESULT hr = S_OK;
  568. WCHAR * pwszMsg;
  569. FAKEPROGRESSINFO fpi;
  570. KEYGENPROGRESSINFO * pKeyGenInfo=(KEYGENPROGRESSINFO *)lpParameter;
  571. PER_COMPONENT_DATA * pComp=pKeyGenInfo->pComp;
  572. CASERVERSETUPINFO * pServer=pComp->CA.pServer;
  573. HWND hwndProgBar=GetDlgItem(pKeyGenInfo->hDlg, IDC_KEYGEN_PROGRESS);
  574. HWND hwndText=GetDlgItem(pKeyGenInfo->hDlg, IDC_KEYGEN_PROGRESS_TEXT);
  575. int iErrMsg=0; // error msg id
  576. const WCHAR * pwszErrMsgData = L"";
  577. // variables that must be cleaned up
  578. fpi.hStopEvent=NULL;
  579. HANDLE hFakeProgressThread=NULL;
  580. HCRYPTPROV hProv=NULL;
  581. fpi.fCSInit = FALSE;
  582. __try
  583. {
  584. InitializeCriticalSection(&fpi.csTimeSync);
  585. fpi.fCSInit = TRUE;
  586. }
  587. __except(hr = myHEXCEPTIONCODE(), EXCEPTION_EXECUTE_HANDLER)
  588. {
  589. }
  590. _JumpIfError(hr, error, "InitializeCriticalSection");
  591. // STEP 0:
  592. // initialize the fake-progress thread
  593. // set up the structure for the fake-progress thread
  594. fpi.hStopEvent=CreateEvent(
  595. NULL, // security
  596. FALSE, // manual reset?
  597. FALSE, // signaled?
  598. NULL); // name
  599. if (NULL==fpi.hStopEvent) {
  600. hr = myHLastError();
  601. _JumpError(hr, error, "CreateEvent");
  602. }
  603. fpi.hwndProgBar=hwndProgBar;
  604. fpi.dwSecsRemaining=0; // Initially, the thread has no work to do.
  605. // start the fake-progress thread
  606. DWORD dwThreadID; // ignored
  607. hFakeProgressThread=CreateThread(
  608. NULL, // security
  609. 0, // stack
  610. KeyGenFakeProgressThread,
  611. (void *)&fpi,
  612. 0, // flags
  613. &dwThreadID);
  614. if (NULL==hFakeProgressThread) {
  615. hr = myHLastError();
  616. _JumpError(hr, error, "CreateThread");
  617. }
  618. if (NULL==pServer->pwszKeyContainerName) {
  619. // STEP 1:
  620. // Generate a key
  621. // set the status
  622. hr = myLoadRCString(pComp->hInstance, IDS_KEYGEN_GENERATING, &pwszMsg);
  623. _JumpIfError(hr, error, "myLoadRCString");
  624. SetWindowText(hwndText, pwszMsg);
  625. LocalFree(pwszMsg);
  626. SendMessage(hwndProgBar, PBM_SETPOS, (WPARAM)0, 0);
  627. if(fpi.fCSInit)
  628. {
  629. EnterCriticalSection(&fpi.csTimeSync);
  630. fpi.dwSecsRemaining = KEYGEN_GENERATE_KEY;
  631. LeaveCriticalSection(&fpi.csTimeSync);
  632. }
  633. // generate key
  634. hr = csiGenerateKeysOnly(
  635. pServer->pwszSanitizedName,
  636. pServer->pCSPInfo->pwszProvName,
  637. pServer->pCSPInfo->dwProvType,
  638. pServer->pCSPInfo->fMachineKeyset,
  639. pServer->dwKeyLength,
  640. pComp->fUnattended,
  641. &hProv,
  642. &iErrMsg);
  643. if (S_OK != hr)
  644. {
  645. pwszErrMsgData=pServer->pwszSanitizedName;
  646. pServer->fKeyGenFailed = TRUE;
  647. _JumpError(hr, error, "csiGenerateKeysOnly");
  648. }
  649. pServer->fKeyGenFailed = FALSE;
  650. // now set this as the existing key
  651. SetKeyContainerName(pServer, pServer->pwszSanitizedName);
  652. pServer->fDeletableNewKey=TRUE;
  653. // STEP 2:
  654. // Set the ACLs
  655. // set the status
  656. hr = myLoadRCString(pComp->hInstance, IDS_KEYGEN_PROTECTING, &pwszMsg);
  657. _JumpIfError(hr, error, "myLoadRCString");
  658. SetWindowText(hwndText, pwszMsg);
  659. LocalFree(pwszMsg);
  660. if(fpi.fCSInit)
  661. {
  662. EnterCriticalSection(&fpi.csTimeSync);
  663. SendMessage(hwndProgBar, PBM_SETPOS, (WPARAM)KEYGEN_GENERATE_KEY, 0);
  664. fpi.dwSecsRemaining=KEYGEN_PROTECT_KEY;
  665. LeaveCriticalSection(&fpi.csTimeSync);
  666. }
  667. // set the ACLs
  668. hr = csiSetKeyContainerSecurity(hProv);
  669. if (S_OK!=hr) {
  670. iErrMsg=IDS_ERR_KEYSECURITY;
  671. pwszErrMsgData=pServer->pwszKeyContainerName;
  672. _JumpError(hr, error, "csiSetKeyContainerSecurity");
  673. }
  674. } // <- end if (NULL==pServer->pwszKeyContainerName)
  675. if (FALSE==pServer->fValidatedHashAndKey) {
  676. // STEP 3:
  677. // Test the hash algorithm and key set
  678. // set the status
  679. hr = myLoadRCString(pComp->hInstance, IDS_KEYGEN_TESTINGHASHANDKEY, &pwszMsg);
  680. _JumpIfError(hr, error, "myLoadRCString");
  681. SetWindowText(hwndText, pwszMsg);
  682. LocalFree(pwszMsg);
  683. if(fpi.fCSInit)
  684. {
  685. EnterCriticalSection(&fpi.csTimeSync);
  686. SendMessage(hwndProgBar, PBM_SETPOS, (WPARAM)KEYGEN_GENERATE_KEY+KEYGEN_PROTECT_KEY, 0);
  687. fpi.dwSecsRemaining=KEYGEN_TEST_HASH;
  688. LeaveCriticalSection(&fpi.csTimeSync);
  689. }
  690. // test the hash and keyset
  691. hr = myValidateHashForSigning(
  692. pServer->pwszKeyContainerName,
  693. pServer->pCSPInfo->pwszProvName,
  694. pServer->pCSPInfo->dwProvType,
  695. pServer->pCSPInfo->fMachineKeyset,
  696. NULL,
  697. pServer->pHashInfo->idAlg);
  698. if (S_OK!=hr) {
  699. if (NTE_BAD_KEY_STATE==hr || //all the errors with KEY in them
  700. NTE_NO_KEY==hr ||
  701. NTE_BAD_PUBLIC_KEY==hr ||
  702. NTE_BAD_KEYSET==hr ||
  703. NTE_KEYSET_NOT_DEF==hr ||
  704. NTE_KEYSET_ENTRY_BAD==hr ||
  705. NTE_BAD_KEYSET_PARAM==hr) {
  706. // Bad keyset (eg, not AT_SIGNATURE) - force user to pick another
  707. iErrMsg=IDS_KEY_INVALID;
  708. pwszErrMsgData=pServer->pwszKeyContainerName;
  709. } else {
  710. // Bad hash algorithm - force user to pick another
  711. iErrMsg=IDS_ERR_INVALIDHASH;
  712. pwszErrMsgData=pServer->pHashInfo->pwszName;
  713. }
  714. _JumpError(hr, error, "myValidateHashForSigning");
  715. }
  716. // mark this hash as validated
  717. pServer->fValidatedHashAndKey=TRUE;
  718. }
  719. // STEP 3:
  720. // Go to the next page
  721. // set the status, so the user sees the bar go all the way.
  722. if(fpi.fCSInit)
  723. {
  724. EnterCriticalSection(&fpi.csTimeSync);
  725. SendMessage(hwndProgBar, PBM_SETPOS, (WPARAM)KEYGEN_GENERATE_KEY+KEYGEN_PROTECT_KEY+KEYGEN_TEST_HASH, 0);
  726. fpi.dwSecsRemaining=0;
  727. LeaveCriticalSection(&fpi.csTimeSync);
  728. }
  729. error:
  730. // clean up after the false-progress thread
  731. if (NULL!=hFakeProgressThread) {
  732. CSASSERT(NULL!=fpi.hStopEvent);
  733. // tell the progress thread to stop
  734. if (FALSE==SetEvent(fpi.hStopEvent)) {
  735. _PrintError(myHLastError(), "SetEvent");
  736. } else {
  737. // wait for it to stop
  738. WaitForSingleObject(hFakeProgressThread, INFINITE);
  739. }
  740. CloseHandle(hFakeProgressThread);
  741. }
  742. if(fpi.fCSInit)
  743. {
  744. DeleteCriticalSection(&fpi.csTimeSync);
  745. }
  746. if (NULL!=fpi.hStopEvent) {
  747. CloseHandle(fpi.hStopEvent);
  748. }
  749. if (NULL!=hProv) {
  750. CryptReleaseContext(hProv, 0);
  751. }
  752. // show an error message if we need to
  753. if (0!=iErrMsg) {
  754. CertWarningMessageBox(
  755. pComp->hInstance,
  756. pComp->fUnattended,
  757. pKeyGenInfo->hDlg,
  758. iErrMsg,
  759. hr,
  760. pwszErrMsgData);
  761. }
  762. pServer->LastWiz=ENUM_WIZ_KEYGEN;
  763. if (S_OK==hr) {
  764. // go to next page
  765. PropSheet_PressButton(GetParent(pKeyGenInfo->hDlg), PSBTN_NEXT);
  766. } else {
  767. // go back
  768. PropSheet_PressButton(GetParent(pKeyGenInfo->hDlg), PSBTN_BACK);
  769. }
  770. return 0; // return value ignored
  771. }
  772. //--------------------------------------------------------------------
  773. // Start the KeyGen wizard page
  774. HRESULT
  775. HandleKeyGenWizActive(
  776. HWND hDlg,
  777. PER_COMPONENT_DATA *pComp,
  778. KEYGENPROGRESSINFO *pKeyGenInfo)
  779. {
  780. HRESULT hr = S_OK;
  781. // Suppress this wizard page if
  782. // we are going backwards, or
  783. // we've already seen an error, or
  784. // we are not installing the server,
  785. // or the key exists and the hash has been checked.
  786. if (ENUM_WIZ_STORE == pComp->CA.pServer->LastWiz ||
  787. !(IS_SERVER_INSTALL & pComp->dwInstallStatus) ||
  788. (NULL != pComp->CA.pServer->pwszKeyContainerName &&
  789. pComp->CA.pServer->fValidatedHashAndKey)) {
  790. // skip/disable page
  791. CSILOGDWORD(IDS_KEYGEN_TITLE, dwWIZDISABLE);
  792. SetWindowLongPtr(hDlg, DWLP_MSGRESULT, -1);
  793. }
  794. else
  795. {
  796. // set progress bar parameters: range, step, and position
  797. // set them now so the user will never see a full bar if this is the second visit.
  798. HWND hwndProgBar=GetDlgItem(hDlg, IDC_KEYGEN_PROGRESS);
  799. SendMessage(hwndProgBar, PBM_SETRANGE, 0,
  800. MAKELPARAM(0, KEYGEN_GENERATE_KEY+KEYGEN_PROTECT_KEY+KEYGEN_TEST_HASH));
  801. SendMessage(hwndProgBar, PBM_SETSTEP, (WPARAM)1, 0);
  802. SendMessage(hwndProgBar, PBM_SETPOS, (WPARAM)0, 0);
  803. // init info for keygen thread
  804. pKeyGenInfo->hDlg=hDlg;
  805. pKeyGenInfo->pComp=pComp;
  806. // start the key gen thread
  807. DWORD dwThreadID; // ignored
  808. HANDLE hKeyGenThread=CreateThread(
  809. NULL, // security
  810. 0, // stack
  811. GenerateKeyThread,
  812. (void *)pKeyGenInfo,
  813. 0, // flags
  814. &dwThreadID);
  815. if (NULL==hKeyGenThread) {
  816. hr = myHLastError();
  817. _JumpError(hr, error, "CreateThread");
  818. }
  819. CloseHandle(hKeyGenThread);
  820. }
  821. error:
  822. return hr;
  823. }
  824. //+------------------------------------------------------------------------
  825. // Function: WizKeyGenPageDlgProc(. . . .)
  826. //
  827. // Synopsis: Dialog procedure for keygen wiz-page
  828. //-------------------------------------------------------------------------
  829. INT_PTR
  830. WizKeyGenPageDlgProc(HWND hDlg, UINT iMsg, WPARAM wParam, LPARAM lParam)
  831. {
  832. HWND hwndCtrl;
  833. PER_COMPONENT_DATA *pComp = NULL;
  834. switch(iMsg)
  835. {
  836. case WM_INITDIALOG:
  837. // point to component data
  838. SetWindowLongPtr(hDlg, DWLP_USER,
  839. (ULONG_PTR)((PROPSHEETPAGE*)lParam)->lParam);
  840. pComp = (PER_COMPONENT_DATA*)(ULONG_PTR)((PROPSHEETPAGE*)lParam)->lParam;
  841. _ReturnIfWizError(pComp->hrContinue);
  842. break;
  843. case WM_COMMAND:
  844. break;
  845. case WM_NOTIFY:
  846. switch (((NMHDR FAR *) lParam)->code)
  847. {
  848. case PSN_KILLACTIVE:
  849. break;
  850. case PSN_RESET:
  851. break;
  852. case PSN_QUERYCANCEL:
  853. pComp = _GetCompDataOrReturnIfError(pComp, hDlg);
  854. return CertConfirmCancel(hDlg, pComp);
  855. break;
  856. case PSN_SETACTIVE:
  857. CSILOGDWORD(IDS_KEYGEN_TITLE, dwWIZACTIVE);
  858. PropSheet_SetWizButtons(GetParent(hDlg), 0);
  859. pComp = _GetCompDataOrReturn(pComp, hDlg);
  860. _DisableWizDisplayIfError(pComp, hDlg);
  861. _ReturnIfWizError(pComp->hrContinue);
  862. pComp->hrContinue=HandleKeyGenWizActive(hDlg, pComp, &g_KeyGenInfo);
  863. _ReturnIfWizError(pComp->hrContinue);
  864. break;
  865. case PSN_WIZBACK:
  866. CSILOGDWORD(IDS_KEYGEN_TITLE, dwWIZBACK);
  867. break;
  868. case PSN_WIZNEXT:
  869. CSILOGDWORD(IDS_KEYGEN_TITLE, dwWIZNEXT);
  870. break;
  871. default:
  872. return FALSE;
  873. }
  874. break;
  875. default:
  876. return FALSE;
  877. }
  878. return TRUE;
  879. }
  880. HRESULT
  881. ValidateESERestrictions(
  882. IN WCHAR const *pwszDirectory)
  883. {
  884. HRESULT hr;
  885. HANDLE hFile = INVALID_HANDLE_VALUE;
  886. HANDLE hFileA = INVALID_HANDLE_VALUE;
  887. WCHAR *pwszPath = NULL;
  888. char *pszPath = NULL;
  889. WCHAR *pwsz;
  890. char *psz;
  891. DWORD cwcbs;
  892. DWORD cchbs;
  893. hr = myBuildPathAndExt(pwszDirectory, L"certocm.tmp", NULL, &pwszPath);
  894. _JumpIfError(hr, error, "myBuildPathAndExt");
  895. if (!ConvertWszToSz(&pszPath, pwszPath, -1))
  896. {
  897. hr = E_OUTOFMEMORY;
  898. _JumpError(hr, error, "ConvertWszToSz")
  899. }
  900. pwsz = pwszPath;
  901. cwcbs = 0;
  902. while (TRUE)
  903. {
  904. pwsz = wcschr(pwsz, L'\\');
  905. if (NULL == pwsz)
  906. {
  907. break;
  908. }
  909. pwsz++;
  910. cwcbs++;
  911. }
  912. psz = pszPath;
  913. cchbs = 0;
  914. while (TRUE)
  915. {
  916. psz = strchr(psz, '\\');
  917. if (NULL == psz)
  918. {
  919. break;
  920. }
  921. psz++;
  922. cchbs++;
  923. }
  924. if (cchbs != cwcbs)
  925. {
  926. hr = E_INVALIDARG;
  927. _JumpError(hr, error, "backslash count")
  928. }
  929. hFile = CreateFile(
  930. pwszPath,
  931. GENERIC_WRITE,
  932. FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
  933. NULL, // security
  934. OPEN_ALWAYS,
  935. FILE_ATTRIBUTE_NORMAL,
  936. NULL); // template
  937. if (INVALID_HANDLE_VALUE == hFile)
  938. {
  939. hr = myHLastError();
  940. _JumpErrorStr(hr, error, "CreateFile", pwszPath);
  941. }
  942. hFileA = CreateFileA(
  943. pszPath,
  944. GENERIC_READ,
  945. FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
  946. NULL, // security
  947. OPEN_EXISTING,
  948. FILE_ATTRIBUTE_NORMAL,
  949. NULL); // template
  950. if (INVALID_HANDLE_VALUE == hFileA)
  951. {
  952. hr = myHLastError();
  953. _JumpErrorStr(hr, error, pszPath, L"CreateFileA");
  954. }
  955. CSASSERT(S_OK == hr);
  956. error:
  957. if (INVALID_HANDLE_VALUE != hFileA)
  958. {
  959. CloseHandle(hFileA); // close before below delete
  960. }
  961. if (NULL != pszPath)
  962. {
  963. LocalFree(pszPath);
  964. }
  965. if (NULL != pwszPath)
  966. {
  967. if (INVALID_HANDLE_VALUE != hFile)
  968. {
  969. CloseHandle(hFile); // close before delete
  970. DeleteFile(pwszPath);
  971. }
  972. LocalFree(pwszPath);
  973. }
  974. return(hr);
  975. }
  976. //+-------------------------------------------------------------------------
  977. // Function: check if a database edit field
  978. //--------------------------------------------------------------------------
  979. BOOL
  980. ValidateAndCreateDirField(
  981. HINSTANCE hInstance,
  982. BOOL fUnattended,
  983. HWND hDlg,
  984. WCHAR *pwszDirectory,
  985. BOOL fDefaultDir,
  986. int iMsgNotFullPath,
  987. BOOL *pfExist,
  988. BOOL *pfIsUNC)
  989. {
  990. BOOL fRet = FALSE;
  991. DWORD dwPathFlag = 0;
  992. HRESULT hr;
  993. *pfExist = TRUE;
  994. // check edit field
  995. if (!myIsFullPath(pwszDirectory, &dwPathFlag))
  996. {
  997. CertWarningMessageBox(
  998. hInstance,
  999. fUnattended,
  1000. hDlg,
  1001. iMsgNotFullPath,
  1002. 0,
  1003. pwszDirectory);
  1004. goto error;
  1005. }
  1006. // set the UNC check
  1007. *pfIsUNC = (dwPathFlag == UNC_PATH);
  1008. if (MAX_PATH - 1 < wcslen(pwszDirectory))
  1009. {
  1010. WCHAR wszMsg[256 + MAX_PATH];
  1011. WCHAR *pwszFormat = NULL;
  1012. hr = myLoadRCString(hInstance,
  1013. IDS_STORELOC_PATHTOOLONG,
  1014. &pwszFormat);
  1015. _JumpIfError(hr, error, "myLoadRCString");
  1016. swprintf(wszMsg, pwszFormat, pwszDirectory, MAX_PATH-1);
  1017. CertWarningMessageBox(
  1018. hInstance,
  1019. fUnattended,
  1020. hDlg,
  1021. 0,
  1022. 0,
  1023. wszMsg);
  1024. LocalFree(pwszFormat);
  1025. goto error;
  1026. }
  1027. if (DE_DIREXISTS != DirExists(pwszDirectory))
  1028. {
  1029. if (*pfIsUNC)
  1030. {
  1031. CertWarningMessageBox(
  1032. hInstance,
  1033. fUnattended,
  1034. hDlg,
  1035. IDS_STORELOC_UNCMUSTEXIST,
  1036. 0,
  1037. pwszDirectory);
  1038. goto error;
  1039. }
  1040. else
  1041. {
  1042. if (!fDefaultDir)
  1043. {
  1044. // confirm and create outside
  1045. *pfExist = FALSE;
  1046. goto done;
  1047. }
  1048. // try to create default dir
  1049. hr = myCreateNestedDirectories(pwszDirectory);
  1050. _JumpIfError(hr, error, "myCreateNestedDirectories");
  1051. }
  1052. }
  1053. done:
  1054. fRet = TRUE;
  1055. error:
  1056. return fRet;
  1057. }
  1058. //+---------------------------------------------------------------------------
  1059. // Description: set MS Base CSP as default csp otherwise 1st one
  1060. //----------------------------------------------------------------------------
  1061. HRESULT
  1062. DetermineDefaultCSP(CASERVERSETUPINFO *pServer)
  1063. {
  1064. HRESULT hr;
  1065. CSP_INFO *pCSPInfo = NULL;
  1066. // select 1st if no MSBase
  1067. pServer->pCSPInfo = pServer->pCSPInfoList;
  1068. if (NULL == pServer->pDefaultCSPInfo)
  1069. {
  1070. goto done;
  1071. }
  1072. // check all csps
  1073. pCSPInfo = pServer->pCSPInfoList;
  1074. while (NULL != pCSPInfo)
  1075. {
  1076. if (NULL != pCSPInfo->pwszProvName)
  1077. {
  1078. if (0 == wcscmp(pCSPInfo->pwszProvName,
  1079. pServer->pDefaultCSPInfo->pwszProvName) &&
  1080. pCSPInfo->dwProvType == pServer->pDefaultCSPInfo->dwProvType)
  1081. {
  1082. // change to default
  1083. pServer->pCSPInfo = pCSPInfo;
  1084. break;
  1085. }
  1086. }
  1087. pCSPInfo = pCSPInfo->next;
  1088. }
  1089. done:
  1090. hr = S_OK;
  1091. //error:
  1092. return hr;
  1093. }
  1094. //+---------------------------------------------------------------------------
  1095. // Description: set SHA as default hash alg. otherwise 1st one
  1096. //----------------------------------------------------------------------------
  1097. HRESULT
  1098. DetermineDefaultHash(CASERVERSETUPINFO *pServer)
  1099. {
  1100. CSP_HASH *pHashInfo = NULL;
  1101. HRESULT hr;
  1102. if ((NULL == pServer) || (NULL == pServer->pCSPInfo))
  1103. return E_POINTER;
  1104. // select 1st if no default match
  1105. pServer->pHashInfo = pServer->pCSPInfo->pHashList;
  1106. // search list
  1107. pHashInfo = pServer->pCSPInfo->pHashList;
  1108. while (NULL != pHashInfo)
  1109. {
  1110. if (pHashInfo->idAlg == pServer->pDefaultHashInfo->idAlg)
  1111. {
  1112. //change to default
  1113. pServer->pHashInfo = pHashInfo;
  1114. break;
  1115. }
  1116. pHashInfo = pHashInfo->next;
  1117. }
  1118. // Must validate the hash again when the selected hash changes
  1119. pServer->fValidatedHashAndKey = FALSE;
  1120. hr = S_OK;
  1121. //error:
  1122. return hr;
  1123. }
  1124. HRESULT
  1125. UpdateCADescription(
  1126. HWND hDlg,
  1127. PER_COMPONENT_DATA *pComp)
  1128. {
  1129. int ids;
  1130. WCHAR *pwszDesc = NULL;
  1131. HRESULT hr;
  1132. switch (pComp->CA.pServer->CAType)
  1133. {
  1134. case ENUM_STANDALONE_ROOTCA:
  1135. ids = IDS_CATYPE_DES_STANDALONE_ROOTCA;
  1136. break;
  1137. case ENUM_STANDALONE_SUBCA:
  1138. ids = IDS_CATYPE_DES_STANDALONE_SUBCA;
  1139. break;
  1140. case ENUM_ENTERPRISE_ROOTCA:
  1141. ids = IDS_CATYPE_DES_ENTERPRISE_ROOTCA;
  1142. break;
  1143. case ENUM_ENTERPRISE_SUBCA:
  1144. ids = IDS_CATYPE_DES_ENTERPRISE_SUBCA;
  1145. break;
  1146. }
  1147. // load description from resource
  1148. hr = myLoadRCString(pComp->hInstance, ids, &pwszDesc);
  1149. _JumpIfError(hr, error, "myLoadRCString");
  1150. // change text
  1151. SetWindowText(GetDlgItem(hDlg, IDC_CATYPE_CA_DESCRIPTION), pwszDesc);
  1152. hr = S_OK;
  1153. error:
  1154. if (NULL != pwszDesc)
  1155. {
  1156. LocalFree(pwszDesc);
  1157. }
  1158. return hr;
  1159. }
  1160. HRESULT
  1161. InitCATypeWizControls(
  1162. HWND hDlg,
  1163. PER_COMPONENT_DATA *pComp)
  1164. {
  1165. HRESULT hr;
  1166. int idc;
  1167. CASERVERSETUPINFO *pServer = pComp->CA.pServer;
  1168. EnableWindow(GetDlgItem(hDlg, IDC_CATYPE_ENT_ROOT_CA), pServer->fUseDS);
  1169. EnableWindow(GetDlgItem(hDlg, IDC_CATYPE_ENT_SUB_CA), pServer->fUseDS);
  1170. ShowWindow(GetDlgItem(hDlg, IDC_CATYPE_DESCRIPTION_ENTERPRISE),
  1171. !pServer->fUseDS);
  1172. EnableWindow(GetDlgItem(hDlg, IDC_CATYPE_STAND_ROOT_CA), TRUE);
  1173. EnableWindow(GetDlgItem(hDlg, IDC_CATYPE_STAND_SUB_CA), TRUE);
  1174. if (pServer->fUseDS)
  1175. {
  1176. if (ENUM_ENTERPRISE_SUBCA == pServer->CAType)
  1177. {
  1178. idc = IDC_CATYPE_ENT_SUB_CA;
  1179. }
  1180. else
  1181. {
  1182. idc = IDC_CATYPE_ENT_ROOT_CA;
  1183. }
  1184. }
  1185. else
  1186. {
  1187. idc = IDC_CATYPE_STAND_ROOT_CA;
  1188. }
  1189. SendMessage(GetDlgItem(hDlg, idc), BM_CLICK, (WPARAM)0, (LPARAM)0);
  1190. hr= UpdateCADescription(hDlg, pComp);
  1191. _JumpIfError(hr, error, "UpdateCADescription");
  1192. hr = S_OK;
  1193. error:
  1194. return hr;
  1195. }
  1196. BOOL
  1197. IsRadioControlChecked(HWND hwnd)
  1198. {
  1199. BOOL checked = FALSE;
  1200. if (BST_CHECKED == SendMessage(hwnd, BM_GETCHECK, (WPARAM)0, (LPARAM)0))
  1201. {
  1202. checked = TRUE;
  1203. }
  1204. return checked;
  1205. }
  1206. HRESULT
  1207. HandleAdvanceChange(HWND hDlg, CASERVERSETUPINFO *pServer)
  1208. {
  1209. HRESULT hr;
  1210. if (!pServer->fAdvance)
  1211. {
  1212. // if not advance, clear all advance flags
  1213. pServer->fPreserveDB = FALSE;
  1214. ClearExistingCertToUse(pServer);
  1215. }
  1216. hr = S_OK;
  1217. //error:
  1218. return hr;
  1219. }
  1220. HRESULT
  1221. HandleCATypeChange(
  1222. IN HWND hDlg,
  1223. IN PER_COMPONENT_DATA *pComp,
  1224. IN ENUM_CATYPES eNewType)
  1225. {
  1226. HRESULT hr;
  1227. BOOL bCertOK;
  1228. CASERVERSETUPINFO * pServer=pComp->CA.pServer;
  1229. pServer->CAType = eNewType;
  1230. pServer->dwKeyLength = IsRootCA(pServer->CAType)?
  1231. CA_DEFAULT_KEY_LENGTH_ROOT:
  1232. CA_DEFAULT_KEY_LENGTH_SUB;
  1233. hr=UpdateCADescription(hDlg, pComp);
  1234. _JumpIfError(hr, error, "UpdateCADescription");
  1235. // make sure that if we are using an existing cert, we didn't make it invalid.
  1236. if (NULL!=pServer->pccExistingCert) {
  1237. hr=IsCertSelfSignedForCAType(pServer, pServer->pccExistingCert, &bCertOK);
  1238. _JumpIfError(hr, error, "UpdateCADescription");
  1239. if (FALSE==bCertOK) {
  1240. // can't use this cert with this CA type.
  1241. ClearExistingCertToUse(pServer);
  1242. }
  1243. }
  1244. hr = S_OK;
  1245. error:
  1246. return hr;
  1247. }
  1248. HRESULT
  1249. HandleCATypeWizActive(
  1250. HWND hDlg,
  1251. PER_COMPONENT_DATA *pComp)
  1252. {
  1253. HRESULT hr;
  1254. // first of all, get install status
  1255. hr = UpdateSubComponentInstallStatus(wszCERTSRVSECTION, wszSERVERSECTION, pComp);
  1256. _JumpIfError(hr, error, "UpdateSubComponentInstallStatus");
  1257. hr = UpdateSubComponentInstallStatus(wszCERTSRVSECTION, wszCLIENTSECTION, pComp);
  1258. _JumpIfError(hr, error, "UpdateSubComponentInstallStatus");
  1259. // Suppress this wizard page if
  1260. // we've already seen an error, or
  1261. // we are not installing the server.
  1262. if (!(IS_SERVER_INSTALL & pComp->dwInstallStatus) )
  1263. {
  1264. // disable page
  1265. CSILOGDWORD(IDS_CATYPE_TITLE, dwWIZDISABLE);
  1266. SetWindowLongPtr(hDlg, DWLP_MSGRESULT, -1);
  1267. goto done;
  1268. }
  1269. done:
  1270. hr = S_OK;
  1271. error:
  1272. return hr;
  1273. }
  1274. //+------------------------------------------------------------------------
  1275. // Function: WizCATypePageDlgProc(. . . .)
  1276. //
  1277. // Synopsis: Dialog procedure for CA Type wiz-page
  1278. //-------------------------------------------------------------------------
  1279. INT_PTR
  1280. WizCATypePageDlgProc(
  1281. HWND hDlg,
  1282. UINT iMsg,
  1283. WPARAM wParam,
  1284. LPARAM lParam)
  1285. {
  1286. PER_COMPONENT_DATA *pComp = NULL;
  1287. switch (iMsg)
  1288. {
  1289. case WM_INITDIALOG:
  1290. // point to component data
  1291. SetWindowLongPtr(hDlg, DWLP_USER,
  1292. (ULONG_PTR)((PROPSHEETPAGE*)lParam)->lParam);
  1293. pComp = (PER_COMPONENT_DATA*)(ULONG_PTR)((PROPSHEETPAGE*)lParam)->lParam;
  1294. _ReturnIfWizError(pComp->hrContinue);
  1295. pComp->hrContinue = InitCATypeWizControls(hDlg, pComp);
  1296. _ReturnIfWizError(pComp->hrContinue);
  1297. break;
  1298. case WM_COMMAND:
  1299. switch (LOWORD(wParam))
  1300. {
  1301. case IDC_CATYPE_STAND_ROOT_CA:
  1302. if (IsRadioControlChecked((HWND)lParam))
  1303. {
  1304. pComp = _GetCompDataOrReturnIfError(pComp, hDlg);
  1305. pComp->hrContinue = HandleCATypeChange(hDlg,
  1306. pComp, ENUM_STANDALONE_ROOTCA);
  1307. _ReturnIfWizError(pComp->hrContinue);
  1308. }
  1309. break;
  1310. case IDC_CATYPE_STAND_SUB_CA:
  1311. if (IsRadioControlChecked((HWND)lParam))
  1312. {
  1313. pComp = _GetCompDataOrReturnIfError(pComp, hDlg);
  1314. pComp->hrContinue = HandleCATypeChange(hDlg,
  1315. pComp, ENUM_STANDALONE_SUBCA);
  1316. _ReturnIfWizError(pComp->hrContinue);
  1317. }
  1318. break;
  1319. case IDC_CATYPE_ENT_ROOT_CA:
  1320. if (IsRadioControlChecked((HWND)lParam))
  1321. {
  1322. pComp = _GetCompDataOrReturnIfError(pComp, hDlg);
  1323. pComp->hrContinue = HandleCATypeChange(hDlg,
  1324. pComp, ENUM_ENTERPRISE_ROOTCA);
  1325. _ReturnIfWizError(pComp->hrContinue);
  1326. }
  1327. break;
  1328. case IDC_CATYPE_ENT_SUB_CA:
  1329. if (IsRadioControlChecked((HWND)lParam))
  1330. {
  1331. pComp = _GetCompDataOrReturnIfError(pComp, hDlg);
  1332. pComp->hrContinue = HandleCATypeChange(hDlg,
  1333. pComp, ENUM_ENTERPRISE_SUBCA);
  1334. _ReturnIfWizError(pComp->hrContinue);
  1335. }
  1336. break;
  1337. case IDC_CATYPE_CHECK_ADVANCE:
  1338. pComp = _GetCompDataOrReturnIfError(pComp, hDlg);
  1339. pComp->CA.pServer->fAdvance = !pComp->CA.pServer->fAdvance;
  1340. pComp->hrContinue = HandleAdvanceChange(hDlg, pComp->CA.pServer);
  1341. _ReturnIfWizError(pComp->hrContinue);
  1342. break;
  1343. }
  1344. break;
  1345. case WM_NOTIFY:
  1346. switch (((NMHDR FAR *) lParam)->code)
  1347. {
  1348. case PSN_KILLACTIVE:
  1349. break;
  1350. case PSN_RESET:
  1351. break;
  1352. case PSN_QUERYCANCEL:
  1353. pComp = _GetCompDataOrReturnIfError(pComp, hDlg);
  1354. return CertConfirmCancel(hDlg, pComp);
  1355. break;
  1356. case PSN_SETACTIVE:
  1357. CSILOGDWORD(IDS_CATYPE_TITLE, dwWIZACTIVE);
  1358. PropSheet_SetWizButtons(GetParent(hDlg), PSWIZB_BACK|PSWIZB_NEXT);
  1359. pComp = _GetCompDataOrReturn(pComp, hDlg);
  1360. _DisableWizDisplayIfError(pComp, hDlg);
  1361. _ReturnIfWizError(pComp->hrContinue);
  1362. pComp->hrContinue = HandleCATypeWizActive(hDlg, pComp);
  1363. _ReturnIfWizError(pComp->hrContinue);
  1364. break;
  1365. case PSN_WIZBACK:
  1366. CSILOGDWORD(IDS_CATYPE_TITLE, dwWIZBACK);
  1367. pComp = _GetCompDataOrReturnIfError(pComp, hDlg);
  1368. pComp->CA.pServer->LastWiz = ENUM_WIZ_CATYPE;
  1369. break;
  1370. case PSN_WIZNEXT:
  1371. CSILOGDWORD(IDS_CATYPE_TITLE, dwWIZNEXT);
  1372. pComp = _GetCompDataOrReturnIfError(pComp, hDlg);
  1373. pComp->CA.pServer->LastWiz = ENUM_WIZ_CATYPE;
  1374. CSILOGDWORD(IDS_LOG_CATYPE, pComp->CA.pServer->CAType);
  1375. pComp->hrContinue = InitNameFields(pComp->CA.pServer);
  1376. _ReturnIfWizError(pComp->hrContinue);
  1377. break;
  1378. default:
  1379. return FALSE;
  1380. }
  1381. break;
  1382. default:
  1383. return FALSE;
  1384. }
  1385. return TRUE;
  1386. }
  1387. //+---------------------------------------------------------------------------
  1388. // Description: display existing keys from list
  1389. //----------------------------------------------------------------------------
  1390. HRESULT
  1391. ShowExistingKey(
  1392. IN HWND hDlg,
  1393. KEY_LIST *pKeyList)
  1394. {
  1395. HRESULT hr;
  1396. KEY_LIST *pKey = pKeyList;
  1397. HWND hKeyList = GetDlgItem(hDlg, IDC_ADVANCE_KEYLIST);
  1398. LRESULT nItem;
  1399. LRESULT lr;
  1400. WCHAR *pwszDeSanitize = NULL;
  1401. while (NULL != pKey)
  1402. {
  1403. if (NULL != pKey->pwszName)
  1404. {
  1405. if (NULL != pwszDeSanitize)
  1406. {
  1407. LocalFree(pwszDeSanitize);
  1408. pwszDeSanitize = NULL;
  1409. }
  1410. hr = myRevertSanitizeName(pKey->pwszName, &pwszDeSanitize);
  1411. _JumpIfError(hr, error, "myRevertSanitizeName");
  1412. nItem = (INT)SendMessage(
  1413. hKeyList,
  1414. LB_ADDSTRING,
  1415. (WPARAM) 0,
  1416. (LPARAM) pwszDeSanitize);
  1417. if (LB_ERR == nItem)
  1418. {
  1419. hr = myHLastError();
  1420. _JumpError(hr, error, "SendMessage");
  1421. }
  1422. lr = (INT)SendMessage(
  1423. hKeyList,
  1424. LB_SETITEMDATA,
  1425. (WPARAM) nItem,
  1426. (LPARAM) pKey->pwszName);
  1427. if (LB_ERR == lr)
  1428. {
  1429. hr = myHLastError();
  1430. _JumpError(hr, error, "SendMessage");
  1431. }
  1432. }
  1433. pKey = pKey->next;
  1434. }
  1435. if (NULL != pKeyList)
  1436. {
  1437. // choose the 1st one as default
  1438. lr = (INT)SendMessage(hKeyList, LB_SETCURSEL, (WPARAM) 0, (LPARAM) 0);
  1439. if (LB_ERR == lr)
  1440. {
  1441. hr = myHLastError();
  1442. _JumpError(hr, error, "SendMessage");
  1443. }
  1444. }
  1445. hr = S_OK;
  1446. error:
  1447. if (NULL != pwszDeSanitize)
  1448. {
  1449. LocalFree(pwszDeSanitize);
  1450. }
  1451. return hr;
  1452. }
  1453. //+---------------------------------------------------------------------------
  1454. // Description: hilight an item by matched data
  1455. //----------------------------------------------------------------------------
  1456. HRESULT
  1457. HilightItemInList(HWND hDlg, int id, VOID const *pData, BOOL fString)
  1458. {
  1459. HWND hListCtrl = GetDlgItem(hDlg, id);
  1460. LRESULT iItem;
  1461. LRESULT count;
  1462. VOID *pItemData;
  1463. HRESULT hr = NTE_NOT_FOUND;
  1464. // find item
  1465. if (fString)
  1466. {
  1467. iItem = (INT)SendMessage(
  1468. hListCtrl,
  1469. LB_FINDSTRING,
  1470. (WPARAM) 0,
  1471. (LPARAM) pData);
  1472. if (LB_ERR == iItem)
  1473. {
  1474. _JumpError(hr, error, "SendMessage");
  1475. }
  1476. hr = S_OK;
  1477. }
  1478. else
  1479. {
  1480. count = (INT)SendMessage(hListCtrl, LB_GETCOUNT, (WPARAM)0, (LPARAM)0);
  1481. for (iItem = 0; iItem < count; ++iItem)
  1482. {
  1483. pItemData = (VOID*)SendMessage(hListCtrl, LB_GETITEMDATA,
  1484. (WPARAM)iItem, (LPARAM)0);
  1485. if (pItemData == pData)
  1486. {
  1487. hr = S_OK;
  1488. break;
  1489. }
  1490. }
  1491. }
  1492. if (S_OK != hr)
  1493. {
  1494. _JumpError(hr, error, "not found");
  1495. }
  1496. // hilight it
  1497. SendMessage(hListCtrl, LB_SETCURSEL, (WPARAM)iItem, (LPARAM)0);
  1498. hr = S_OK;
  1499. error:
  1500. return hr;
  1501. }
  1502. HRESULT
  1503. ShowAllCSP(
  1504. HWND hDlg,
  1505. CSP_INFO *pCSPInfo)
  1506. {
  1507. HWND hCSPList = GetDlgItem(hDlg, IDC_ADVANCE_CSPLIST);
  1508. LRESULT nItem;
  1509. // list all of csps
  1510. while (pCSPInfo)
  1511. {
  1512. if (pCSPInfo->pwszProvName)
  1513. {
  1514. nItem = (INT)SendMessage(hCSPList, LB_ADDSTRING,
  1515. (WPARAM)0, (LPARAM)pCSPInfo->pwszProvName);
  1516. SendMessage(hCSPList, LB_SETITEMDATA,
  1517. (WPARAM)nItem, (LPARAM)pCSPInfo);
  1518. }
  1519. pCSPInfo = pCSPInfo->next;
  1520. }
  1521. return S_OK;
  1522. }
  1523. HRESULT
  1524. ShowAllHash(
  1525. HWND hDlg,
  1526. CSP_HASH *pHashInfo)
  1527. {
  1528. HWND hHashList = GetDlgItem(hDlg, IDC_ADVANCE_HASHLIST);
  1529. LRESULT nItem;
  1530. // remove hash of previous csp from list
  1531. while (SendMessage(hHashList, LB_GETCOUNT,
  1532. (WPARAM)0, (LPARAM)0))
  1533. {
  1534. SendMessage(hHashList, LB_DELETESTRING,
  1535. (WPARAM)0, (LPARAM)0);
  1536. }
  1537. // list all hash
  1538. while (NULL != pHashInfo)
  1539. {
  1540. if (NULL != pHashInfo->pwszName)
  1541. {
  1542. nItem = (INT)SendMessage(hHashList, LB_ADDSTRING,
  1543. (WPARAM)0, (LPARAM)pHashInfo->pwszName);
  1544. SendMessage(hHashList, LB_SETITEMDATA,
  1545. (WPARAM)nItem, (LPARAM)pHashInfo);
  1546. }
  1547. pHashInfo = pHashInfo->next;
  1548. }
  1549. return S_OK;
  1550. }
  1551. //--------------------------------------------------------------------
  1552. HRESULT
  1553. UpdateUseCertCheckbox(
  1554. HWND hDlg,
  1555. CASERVERSETUPINFO *pServer)
  1556. {
  1557. HRESULT hr;
  1558. BOOL bUsingExistingCert;
  1559. if (NULL==pServer->pccExistingCert) {
  1560. bUsingExistingCert=FALSE;
  1561. } else {
  1562. bUsingExistingCert=TRUE;
  1563. }
  1564. // check "use cert" control
  1565. SendMessage(GetDlgItem(hDlg, IDC_ADVANCE_USECERTCHECK),
  1566. BM_SETCHECK,
  1567. (WPARAM)(bUsingExistingCert?BST_CHECKED:BST_UNCHECKED),
  1568. (LPARAM)0);
  1569. // enable the "View Cert" button if necessary
  1570. EnableWindow(GetDlgItem(hDlg, IDC_ADVANCE_VIEWCERT), bUsingExistingCert);
  1571. // we will match the hash alg used by the cert, if possible
  1572. hr=HilightItemInList(hDlg, IDC_ADVANCE_HASHLIST,
  1573. pServer->pHashInfo, FALSE);
  1574. _JumpIfError(hr, error, "HilightItemInList");
  1575. hr=S_OK;
  1576. error:
  1577. return hr;
  1578. }
  1579. HRESULT
  1580. FindCertificateByKeyWithWaitCursor(
  1581. IN CASERVERSETUPINFO *pServer,
  1582. OUT CERT_CONTEXT const **ppccCert)
  1583. {
  1584. HRESULT hr;
  1585. HCURSOR hPrevCur = SetCursor(LoadCursor(NULL, IDC_WAIT));
  1586. hr = FindCertificateByKey(pServer, ppccCert);
  1587. SetCursor(hPrevCur);
  1588. _JumpIfError(hr, error, "FindCertificateByKey");
  1589. error:
  1590. return(hr);
  1591. }
  1592. //--------------------------------------------------------------------
  1593. // handle the "Use existing Cert" checkbox
  1594. HRESULT
  1595. HandleUseCertCheckboxChange(
  1596. HWND hDlg,
  1597. CASERVERSETUPINFO *pServer)
  1598. {
  1599. HRESULT hr;
  1600. CERT_CONTEXT const * pccCert;
  1601. if(pServer->pwszFullCADN)
  1602. {
  1603. LocalFree(pServer->pwszFullCADN);
  1604. pServer->pwszFullCADN = NULL;
  1605. }
  1606. // is the checkbox checked or unchecked?
  1607. if (BST_CHECKED==IsDlgButtonChecked(hDlg, IDC_ADVANCE_USECERTCHECK)) {
  1608. // checkbox was just checked, so we previously were not using an existing cert
  1609. CSASSERT(NULL==pServer->pccExistingCert);
  1610. // Find the existing cert for this key
  1611. hr = FindCertificateByKeyWithWaitCursor(pServer, &pccCert);
  1612. _JumpIfError(hr, error, "FindCertificateByKeyWithWaitCursor");
  1613. // use it
  1614. hr=SetExistingCertToUse(pServer, pccCert);
  1615. _JumpIfError(hr, error, "SetExistingCertToUse");
  1616. } else {
  1617. // checkbox was just unchecked, so we previously were using an existing cert.
  1618. CSASSERT(NULL!=pServer->pccExistingCert);
  1619. // stop using the cert
  1620. ClearExistingCertToUse(pServer);
  1621. }
  1622. hr = UpdateUseCertCheckbox(hDlg, pServer);
  1623. _JumpIfError(hr, error, "UpdateUseCertCheckbox");
  1624. error:
  1625. return hr;
  1626. }
  1627. //----------------------------------------------------------------------------
  1628. // Hilight the current key - don't use HilightItemInList because we
  1629. // must use string-compare on the data portion, and HilightItemInList does not
  1630. // support this.
  1631. HRESULT
  1632. HilightKeyInList(HWND hDlg, CASERVERSETUPINFO * pServer)
  1633. {
  1634. HWND hListCtrl=GetDlgItem(hDlg, IDC_ADVANCE_KEYLIST);
  1635. LRESULT nIndex;
  1636. LRESULT nTotNames;
  1637. WCHAR * pwszKeyContainerName;
  1638. HRESULT hr = NTE_NOT_FOUND;
  1639. nTotNames=(INT)SendMessage(hListCtrl, LB_GETCOUNT, (WPARAM)0, (LPARAM)0);
  1640. for (nIndex=0; nIndex<nTotNames; nIndex++) {
  1641. pwszKeyContainerName=(WCHAR *)SendMessage(hListCtrl, LB_GETITEMDATA, (WPARAM)nIndex, (LPARAM)0);
  1642. if (0==wcscmp(pwszKeyContainerName, pServer->pwszKeyContainerName)) {
  1643. SendMessage(hListCtrl, LB_SETCURSEL, (WPARAM)nIndex, (LPARAM)0);
  1644. hr = S_OK;
  1645. break;
  1646. }
  1647. }
  1648. if (S_OK != hr)
  1649. {
  1650. // can lead to dead wiz pages
  1651. CSILOG(
  1652. hr,
  1653. IDS_LOG_KEY_NOT_FOUND_IN_LIST,
  1654. pServer->pwszKeyContainerName,
  1655. NULL,
  1656. NULL);
  1657. _PrintErrorStr(hr, "not found", pServer->pwszKeyContainerName);
  1658. }
  1659. hr = S_OK;
  1660. //error:
  1661. return hr;
  1662. }
  1663. //--------------------------------------------------------------------
  1664. HRESULT
  1665. UpdateKeySelection(
  1666. HWND hDlg,
  1667. CASERVERSETUPINFO *pServer)
  1668. {
  1669. HRESULT hr;
  1670. BOOL bAvailableExistingCert = FALSE;
  1671. CERT_CONTEXT const * pccCert;
  1672. // if we have an existing key, make sure it is the one hilighted
  1673. // in the list and check for coresponding certs.
  1674. if (NULL!=pServer->pwszKeyContainerName) {
  1675. // hilight key
  1676. hr = HilightKeyInList(hDlg, pServer);
  1677. _JumpIfError(hr, error, "HilightKeyInList");
  1678. if (NULL!=pServer->pccExistingCert) {
  1679. // we are using an existing cert, so it better exist!
  1680. bAvailableExistingCert = TRUE;
  1681. } else {
  1682. // see if there is an existing cert for this key
  1683. hr = FindCertificateByKeyWithWaitCursor(pServer, &pccCert);
  1684. if (S_OK==hr) {
  1685. CertFreeCertificateContext(pccCert);
  1686. bAvailableExistingCert = TRUE;
  1687. } else {
  1688. // only other return is 'not found'
  1689. CSASSERT(CRYPT_E_NOT_FOUND==hr);
  1690. }
  1691. }
  1692. } else {
  1693. // no key selected, can't have an existing cert
  1694. }
  1695. // enable/disable reuse cert...
  1696. EnableWindow(GetDlgItem(hDlg, IDC_ADVANCE_USECERTCHECK), bAvailableExistingCert);
  1697. hr = UpdateUseCertCheckbox(hDlg, pServer);
  1698. _JumpIfError(hr, error, "UpdateUseCertCheckbox");
  1699. error:
  1700. return hr;
  1701. }
  1702. //--------------------------------------------------------------------
  1703. HRESULT
  1704. UpdateUseKeyCheckbox(
  1705. HWND hDlg,
  1706. CASERVERSETUPINFO *pServer)
  1707. {
  1708. HRESULT hr;
  1709. BOOL bReuseKey;
  1710. if (NULL==pServer->pwszKeyContainerName) {
  1711. // we are creating a new key
  1712. bReuseKey=FALSE;
  1713. } else {
  1714. // we are using an existing key
  1715. bReuseKey=TRUE;
  1716. }
  1717. // check/uncheck the checkbox depending upon whether we are reusing a key
  1718. SendDlgItemMessage(hDlg,
  1719. IDC_ADVANCE_USEKEYCHECK,
  1720. BM_SETCHECK,
  1721. (WPARAM)(bReuseKey?BST_CHECKED:BST_UNCHECKED),
  1722. (LPARAM)0);
  1723. // enable the key list if we are reusing a key
  1724. EnableWindow(GetDlgItem(hDlg, IDC_ADVANCE_KEYLIST), bReuseKey);
  1725. // disable the key length box if we are reusing a key
  1726. EnableWindow(GetDlgItem(hDlg, IDC_ADVANCE_KEY_LENGTH), !bReuseKey);
  1727. hr = UpdateKeySelection(hDlg, pServer);
  1728. _JumpIfError(hr, error, "UpdateKeySelection");
  1729. error:
  1730. return hr;
  1731. }
  1732. //+---------------------------------------------------------------------------
  1733. // Description: update hash alg. list if csp selection changes
  1734. //----------------------------------------------------------------------------
  1735. HRESULT
  1736. UpdateHashList(
  1737. HWND hDlg,
  1738. CASERVERSETUPINFO *pServer)
  1739. {
  1740. HRESULT hr;
  1741. // load new hash list
  1742. hr = ShowAllHash(hDlg, pServer->pCSPInfo->pHashList);
  1743. _JumpIfError(hr, error, "ShowAllHash");
  1744. hr = HilightItemInList(hDlg, IDC_ADVANCE_HASHLIST,
  1745. pServer->pHashInfo, FALSE);
  1746. _JumpIfError(hr, error, "HilightItemInList");
  1747. hr = S_OK;
  1748. error:
  1749. return hr;
  1750. }
  1751. //+---------------------------------------------------------------------------
  1752. // Description: update key list if csp selection changes
  1753. //----------------------------------------------------------------------------
  1754. HRESULT
  1755. UpdateKeyList(
  1756. HWND hDlg,
  1757. CASERVERSETUPINFO *pServer)
  1758. {
  1759. HRESULT hr;
  1760. HWND hKeyList;
  1761. CSP_HASH *pHashInfo = NULL;
  1762. int nItem;
  1763. HCURSOR hPrevCur;
  1764. // remove keys of previous csp from list
  1765. hKeyList = GetDlgItem(hDlg, IDC_ADVANCE_KEYLIST);
  1766. while (SendMessage(hKeyList, LB_GETCOUNT, (WPARAM) 0, (LPARAM) 0))
  1767. {
  1768. SendMessage(hKeyList, LB_DELETESTRING, (WPARAM) 0, (LPARAM) 0);
  1769. }
  1770. // update key list with new CSP
  1771. if (NULL != pServer->pKeyList)
  1772. {
  1773. csiFreeKeyList(pServer->pKeyList);
  1774. }
  1775. hPrevCur = SetCursor(LoadCursor(NULL, IDC_WAIT));
  1776. hr = csiGetKeyList(
  1777. pServer->pCSPInfo->dwProvType,
  1778. pServer->pCSPInfo->pwszProvName,
  1779. pServer->pCSPInfo->fMachineKeyset,
  1780. FALSE, // fSilent
  1781. &pServer->pKeyList);
  1782. SetCursor(hPrevCur);
  1783. if (S_OK != hr)
  1784. {
  1785. _PrintError(hr, "csiGetKeyList");
  1786. // don't fail setup if only no key update
  1787. //goto done;
  1788. }
  1789. // show keys
  1790. if (NULL != pServer->pKeyList)
  1791. {
  1792. hr = ShowExistingKey(hDlg, pServer->pKeyList);
  1793. _JumpIfError(hr, error, "ShowExistingKey");
  1794. }
  1795. if (NULL == pServer->pKeyList) {
  1796. // no existing key for the csp, so disable "use existing key" checkbox
  1797. EnableWindow(GetDlgItem(hDlg, IDC_ADVANCE_USEKEYCHECK), FALSE);
  1798. CSASSERT(NULL==pServer->pwszKeyContainerName);
  1799. } else {
  1800. EnableWindow(GetDlgItem(hDlg, IDC_ADVANCE_USEKEYCHECK), TRUE);
  1801. }
  1802. hr = UpdateUseKeyCheckbox(hDlg, pServer);
  1803. _JumpIfError(hr, error, "UpdateUseKeyCheckbox");
  1804. //done:
  1805. hr = S_OK;
  1806. error:
  1807. return(hr);
  1808. }
  1809. DWORD g_adwKeyLengths[] =
  1810. {
  1811. 512,
  1812. 1024,
  1813. 2048,
  1814. 4096,
  1815. };
  1816. DWORD g_adwKeyLengthsSmall[] =
  1817. {
  1818. 128,
  1819. 256,
  1820. 512,
  1821. 1024,
  1822. };
  1823. HRESULT
  1824. AddPredefinedKeyLength
  1825. (
  1826. HWND hwnd,
  1827. DWORD dwKeyLength)
  1828. {
  1829. HRESULT hr;
  1830. WCHAR wszKeyLength[MAX_KEYLENGTHDIGIT + 1];
  1831. WCHAR const *pwszKeyLength;
  1832. LRESULT nIndex;
  1833. CSASSERT(0 != dwKeyLength);
  1834. wsprintf(wszKeyLength, L"%u", dwKeyLength);
  1835. pwszKeyLength = wszKeyLength;
  1836. nIndex = (INT)SendMessage(hwnd, CB_ADDSTRING, (WPARAM)0, (LPARAM)pwszKeyLength);
  1837. if (CB_ERR == nIndex)
  1838. {
  1839. hr = E_INVALIDARG;
  1840. _JumpError(hr, error, "SendMessage(CB_ADDSTRING)");
  1841. }
  1842. SendMessage(hwnd, CB_SETITEMDATA, (WPARAM)nIndex, (LPARAM)dwKeyLength);
  1843. hr = S_OK;
  1844. error:
  1845. return hr;
  1846. }
  1847. HRESULT
  1848. ShowAllKeyLength(
  1849. HWND hDlg,
  1850. CASERVERSETUPINFO *pServer)
  1851. {
  1852. HRESULT hr;
  1853. HWND hwndCtrl = GetDlgItem(hDlg, IDC_ADVANCE_KEY_LENGTH);
  1854. WCHAR wszKeyLength[MAX_KEYLENGTHDIGIT + 1];
  1855. DWORD *pdw;
  1856. DWORD *pdwEnd;
  1857. // remove existing key length list
  1858. while (SendMessage(hwndCtrl, CB_GETCOUNT, (WPARAM) 0, (LPARAM) 0))
  1859. {
  1860. SendMessage(hwndCtrl, CB_DELETESTRING, (WPARAM) 0, (LPARAM) 0);
  1861. }
  1862. CSASSERT(0 != pServer->dwKeyLength);
  1863. if(pServer->dwKeyLength > pServer->dwKeyLenMax)
  1864. {
  1865. pServer->dwKeyLength=pServer->dwKeyLenMax;
  1866. }
  1867. wsprintf(wszKeyLength, L"%u", pServer->dwKeyLength);
  1868. SetWindowText(hwndCtrl, wszKeyLength);
  1869. pdw = g_adwKeyLengths;
  1870. pdwEnd = &g_adwKeyLengths[ARRAYSIZE(g_adwKeyLengths)];
  1871. if (C_CSPHASNOKEYMINMAX != pServer->dwKeyLenMin &&
  1872. C_CSPHASNOKEYMINMAX != pServer->dwKeyLenMax &&
  1873. g_adwKeyLengthsSmall[ARRAYSIZE(g_adwKeyLengthsSmall) - 1] >=
  1874. pServer->dwKeyLenMax)
  1875. {
  1876. pdw = g_adwKeyLengthsSmall;
  1877. pdwEnd = &g_adwKeyLengthsSmall[ARRAYSIZE(g_adwKeyLengthsSmall)];
  1878. }
  1879. // show new key length list
  1880. for ( ; pdw < pdwEnd; pdw++)
  1881. {
  1882. if (0 == *pdw ||
  1883. ((C_CSPHASNOKEYMINMAX != pServer->dwKeyLenMin &&
  1884. *pdw >= pServer->dwKeyLenMin) &&
  1885. (C_CSPHASNOKEYMINMAX != pServer->dwKeyLenMax &&
  1886. *pdw <= pServer->dwKeyLenMax)) )
  1887. {
  1888. hr = AddPredefinedKeyLength(hwndCtrl, *pdw);
  1889. _JumpIfError(hr, error, "AddPredefinedKeyLength");
  1890. }
  1891. }
  1892. hr = S_OK;
  1893. error:
  1894. return hr;
  1895. }
  1896. HRESULT
  1897. UpdateKeyLengthMinMax(
  1898. HWND hDlg,
  1899. CASERVERSETUPINFO *pServer)
  1900. {
  1901. HRESULT hr;
  1902. HCRYPTPROV hProv = NULL;
  1903. CSP_INFO *pCSPInfo = pServer->pCSPInfo;
  1904. PROV_ENUMALGS_EX paramData;
  1905. DWORD cbData;
  1906. DWORD dwFlags;
  1907. // default that csp doesn't support PP_ENUMALGS_EX
  1908. pServer->dwKeyLenMin = C_CSPHASNOKEYMINMAX;
  1909. pServer->dwKeyLenMax = C_CSPHASNOKEYMINMAX;
  1910. // determine the min and max key length for selected csp
  1911. if (!myCertSrvCryptAcquireContext(
  1912. &hProv,
  1913. NULL,
  1914. pCSPInfo->pwszProvName,
  1915. pCSPInfo->dwProvType,
  1916. CRYPT_VERIFYCONTEXT,
  1917. FALSE))
  1918. {
  1919. hr = myHLastError();
  1920. if (NULL != hProv)
  1921. {
  1922. hProv = NULL;
  1923. _PrintError(hr, "CSP returns a non-null handle");
  1924. }
  1925. _JumpErrorStr(hr, error, "myCertSrvCryptAcquireContext", pCSPInfo->pwszProvName);
  1926. }
  1927. dwFlags = CRYPT_FIRST;
  1928. while (TRUE)
  1929. {
  1930. cbData = sizeof(paramData);
  1931. if (!CryptGetProvParam(
  1932. hProv,
  1933. PP_ENUMALGS_EX,
  1934. (BYTE *) &paramData,
  1935. &cbData,
  1936. dwFlags))
  1937. {
  1938. hr = myHLastError();
  1939. if (HRESULT_FROM_WIN32(ERROR_NO_MORE_ITEMS) == hr)
  1940. {
  1941. // out of for loop
  1942. break;
  1943. }
  1944. _JumpError(hr, error, "CryptGetProvParam");
  1945. }
  1946. if (ALG_CLASS_SIGNATURE == GET_ALG_CLASS(paramData.aiAlgid))
  1947. {
  1948. pServer->dwKeyLenMin = paramData.dwMinLen;
  1949. pServer->dwKeyLenMax = paramData.dwMaxLen;
  1950. break;
  1951. }
  1952. dwFlags = 0;
  1953. }
  1954. error:
  1955. hr = ShowAllKeyLength(hDlg, pServer);
  1956. _PrintIfError(hr, "ShowAllKeyLength");
  1957. if (NULL != hProv)
  1958. {
  1959. CryptReleaseContext(hProv, 0);
  1960. }
  1961. return(S_OK);
  1962. }
  1963. HRESULT
  1964. InitializeKeyLengthControl(HWND hDlg)
  1965. {
  1966. HWND hwndCtrl = GetDlgItem(hDlg, IDC_ADVANCE_KEY_LENGTH);
  1967. // set digit length
  1968. SendMessage(
  1969. hwndCtrl,
  1970. CB_LIMITTEXT,
  1971. (WPARAM) MAX_KEYLENGTHDIGIT,
  1972. (LPARAM) 0);
  1973. return S_OK;
  1974. }
  1975. //--------------------------------------------------------------------
  1976. HRESULT
  1977. HandleKeySelectionChange(
  1978. HWND hDlg,
  1979. CASERVERSETUPINFO *pServer,
  1980. BOOL fUpdate)
  1981. {
  1982. HRESULT hr;
  1983. HWND hKeyList = GetDlgItem(hDlg, IDC_ADVANCE_KEYLIST);
  1984. WCHAR * pwszKeyContainerName;
  1985. CERT_CONTEXT const * pccCert;
  1986. LRESULT nItem = (INT)SendMessage(
  1987. hKeyList,
  1988. LB_GETCURSEL,
  1989. (WPARAM) 0,
  1990. (LPARAM) 0);
  1991. CSASSERT(LB_ERR!=nItem);
  1992. pwszKeyContainerName = (WCHAR *) SendMessage(
  1993. hKeyList,
  1994. LB_GETITEMDATA,
  1995. (WPARAM) nItem,
  1996. (LPARAM) 0);
  1997. CSASSERT(NULL!=pwszKeyContainerName);
  1998. // Only change is this is a different selection
  1999. if (NULL==pServer->pwszKeyContainerName ||
  2000. 0!=wcscmp(pwszKeyContainerName, pServer->pwszKeyContainerName)) {
  2001. // Set the container name to match what the user picked.
  2002. BOOL fKeyListChange=pServer->fDeletableNewKey;
  2003. hr = SetKeyContainerName(pServer, pwszKeyContainerName);
  2004. _JumpIfError(hr, error, "SetKeyContainerName");
  2005. // see if there is an existing cert for this key
  2006. hr = FindCertificateByKeyWithWaitCursor(pServer, &pccCert);
  2007. if (S_OK==hr) {
  2008. // Yes there is. By default, use it.
  2009. hr=SetExistingCertToUse(pServer, pccCert);
  2010. _JumpIfError(hr, error, "SetExistingCertToUse");
  2011. } else {
  2012. // only other return is 'not found'
  2013. CSASSERT(CRYPT_E_NOT_FOUND==hr);
  2014. }
  2015. // check to see if our caller wants us to update.
  2016. // our caller may want to do the update himself.
  2017. if (fUpdate) {
  2018. // perform the minimum necessary update
  2019. if (fKeyListChange) {
  2020. hr = UpdateKeyList(hDlg, pServer);
  2021. _JumpIfError(hr, error, "UpdateKeyList");
  2022. } else {
  2023. hr = UpdateKeySelection(hDlg, pServer);
  2024. _JumpIfError(hr, error, "UpdateKeySelection");
  2025. }
  2026. }
  2027. }
  2028. hr=S_OK;
  2029. error:
  2030. return hr;
  2031. }
  2032. //--------------------------------------------------------------------
  2033. // handle the "Use existing Key" checkbox
  2034. HRESULT
  2035. HandleUseKeyCheckboxChange(
  2036. HWND hDlg,
  2037. CASERVERSETUPINFO *pServer)
  2038. {
  2039. HRESULT hr;
  2040. static bool fNT4CertCopiedAlready = false;
  2041. if(pServer->pwszFullCADN)
  2042. {
  2043. LocalFree(pServer->pwszFullCADN);
  2044. pServer->pwszFullCADN = NULL;
  2045. }
  2046. if(pServer->pwszCACommonName)
  2047. {
  2048. LocalFree(pServer->pwszCACommonName);
  2049. pServer->pwszCACommonName = NULL;
  2050. }
  2051. if(pServer->pwszDNSuffix)
  2052. {
  2053. LocalFree(pServer->pwszDNSuffix);
  2054. pServer->pwszDNSuffix = NULL;
  2055. }
  2056. // is the checkbox checked or unchecked?
  2057. if (BST_CHECKED==IsDlgButtonChecked(hDlg, IDC_ADVANCE_USEKEYCHECK)) {
  2058. // checkbox was just checked, so we previously did not have a chosen key.
  2059. CSASSERT(NULL==pServer->pwszKeyContainerName);
  2060. hr = HandleKeySelectionChange(hDlg, pServer, FALSE); // don't update, because we need to update too.
  2061. _JumpIfError(hr, error, "HandleKeySelectionChange");
  2062. hr = UpdateUseKeyCheckbox(hDlg, pServer);
  2063. _JumpIfError(hr, error, "UpdateUseKeyCheckbox");
  2064. } else {
  2065. // checkbox was just unchecked, so we previously had a chosen key..
  2066. CSASSERT(NULL!=pServer->pwszKeyContainerName);
  2067. BOOL fKeyListChange=pServer->fDeletableNewKey;
  2068. ClearKeyContainerName(pServer);
  2069. // perform the minimum necessary update
  2070. if (fKeyListChange) {
  2071. hr = UpdateKeyList(hDlg, pServer);
  2072. _JumpIfError(hr, error, "UpdateKeyList");
  2073. } else {
  2074. hr = UpdateUseKeyCheckbox(hDlg, pServer);
  2075. _JumpIfError(hr, error, "UpdateUseKeyCheckbox");
  2076. }
  2077. hr = InitNameFields(pServer);
  2078. _JumpIfError(hr, error, "InitNameFields");
  2079. }
  2080. error:
  2081. return hr;
  2082. }
  2083. //--------------------------------------------------------------------
  2084. HRESULT
  2085. UpdateCSPSelection(
  2086. HWND hDlg,
  2087. CASERVERSETUPINFO *pServer)
  2088. {
  2089. HRESULT hr;
  2090. bool fInteractiveOff;
  2091. if (NULL == pServer->pCSPInfo)
  2092. {
  2093. hr = E_POINTER;
  2094. _JumpError(hr, error, "NULL pCSPInfo");
  2095. }
  2096. // hilight current CSP
  2097. hr = HilightItemInList(hDlg,
  2098. IDC_ADVANCE_CSPLIST,
  2099. pServer->pCSPInfo->pwszProvName,
  2100. TRUE);
  2101. _JumpIfError(hr, error, "HilightItemInList");
  2102. hr = UpdateHashList(hDlg, pServer);
  2103. _JumpIfError(hr, error, "UpdateHashList");
  2104. hr = UpdateKeyLengthMinMax(hDlg, pServer);
  2105. _JumpIfError(hr, error, "UpdateKeyLengthMinMax");
  2106. hr = UpdateKeyList(hDlg, pServer);
  2107. _JumpIfError(hr, error, "UpdateKeyList");
  2108. // Update "interact with desktop" flag. For default CSP
  2109. // we turn it off, otherwise turn it on.
  2110. CSASSERT(pServer->pCSPInfo &&
  2111. pServer->pDefaultCSPInfo&&
  2112. pServer->pCSPInfo->pwszProvName &&
  2113. pServer->pDefaultCSPInfo->pwszProvName);
  2114. fInteractiveOff =
  2115. (0 == wcscmp(pServer->pCSPInfo->pwszProvName,
  2116. pServer->pDefaultCSPInfo->pwszProvName) &&
  2117. (pServer->pCSPInfo->dwProvType == pServer->pDefaultCSPInfo->dwProvType));
  2118. SendMessage(
  2119. GetDlgItem(hDlg, IDC_ADVANCE_INTERACTIVECHECK),
  2120. BM_SETCHECK,
  2121. (WPARAM)(fInteractiveOff?BST_UNCHECKED:BST_CHECKED),
  2122. (LPARAM)0);
  2123. hr = S_OK;
  2124. error:
  2125. return hr;
  2126. }
  2127. //--------------------------------------------------------------------
  2128. HRESULT
  2129. HandleCSPSelectionChange(
  2130. HWND hDlg,
  2131. CASERVERSETUPINFO *pServer)
  2132. {
  2133. HRESULT hr = S_OK;
  2134. HWND hCSPList;
  2135. LRESULT nItem;
  2136. CSP_INFO * pCSPInfo;
  2137. // get current csp
  2138. hCSPList = GetDlgItem(hDlg, IDC_ADVANCE_CSPLIST);
  2139. nItem = (INT)SendMessage(hCSPList, LB_GETCURSEL,
  2140. (WPARAM)0, (LPARAM)0);
  2141. pCSPInfo = (CSP_INFO *)SendMessage(hCSPList,
  2142. LB_GETITEMDATA, (WPARAM)nItem, (LPARAM)0);
  2143. // only change if this is a different selection
  2144. if (pCSPInfo->dwProvType!=pServer->pCSPInfo->dwProvType ||
  2145. 0!=wcscmp(pCSPInfo->pwszProvName, pServer->pCSPInfo->pwszProvName)) {
  2146. // Must create a new key if the CSP changes
  2147. ClearKeyContainerName(pServer);
  2148. pServer->pCSPInfo=pCSPInfo;
  2149. hr = DetermineDefaultHash(pServer);
  2150. _JumpIfError(hr, error, "DetermineDefaultHash");
  2151. hr = UpdateCSPSelection(hDlg, pServer);
  2152. _JumpIfError(hr, error, "UpdateCSPSelection");
  2153. }
  2154. error:
  2155. return hr;
  2156. }
  2157. // Update cascade:
  2158. //
  2159. // UpdateCSPSelection
  2160. // |-UpdateHashList
  2161. // |-UpdateKeyLengthMinMax
  2162. // \-UpdateKeyList
  2163. // \-UpdateUseKeyCheckbox
  2164. // \-UpdateKeySelection
  2165. // \-UpdateUseCertCheckbox
  2166. HRESULT
  2167. InitAdvanceWizPageControls(
  2168. HWND hDlg,
  2169. CASERVERSETUPINFO *pServer)
  2170. {
  2171. HRESULT hr;
  2172. EnableWindow(GetDlgItem(hDlg, IDC_ADVANCE_INTERACTIVECHECK), TRUE);
  2173. hr = S_OK;
  2174. //error:
  2175. return hr;
  2176. }
  2177. HRESULT
  2178. HandleHashSelectionChange(
  2179. HWND hDlg,
  2180. CASERVERSETUPINFO *pServer)
  2181. {
  2182. HRESULT hr;
  2183. HWND hHashList = GetDlgItem(hDlg, IDC_ADVANCE_HASHLIST);
  2184. LRESULT nItem = (INT)SendMessage(
  2185. hHashList,
  2186. LB_GETCURSEL,
  2187. (WPARAM) 0,
  2188. (LPARAM) 0);
  2189. pServer->pHashInfo = (CSP_HASH*)SendMessage(
  2190. hHashList,
  2191. LB_GETITEMDATA,
  2192. (WPARAM) nItem,
  2193. (LPARAM) 0);
  2194. // Must validate the hash again when the selected hash changes
  2195. pServer->fValidatedHashAndKey = FALSE;
  2196. hr = S_OK;
  2197. //error:
  2198. return hr;
  2199. }
  2200. HRESULT
  2201. HandleKeyLengthSelectionChange(
  2202. HWND hDlg,
  2203. CASERVERSETUPINFO *pServer)
  2204. {
  2205. HRESULT hr;
  2206. HWND hwndCtrl = GetDlgItem(hDlg, IDC_ADVANCE_KEY_LENGTH);
  2207. LRESULT nItem = (INT)SendMessage(hwndCtrl, CB_GETCURSEL,
  2208. (WPARAM)0, (LPARAM)0);
  2209. pServer->dwKeyLength = (DWORD)SendMessage(hwndCtrl,
  2210. CB_GETITEMDATA,
  2211. (WPARAM)nItem, (LPARAM)0);
  2212. // If key length chenges, we must not have created a key yet.
  2213. CSASSERT(NULL==pServer->pwszKeyContainerName);
  2214. hr = S_OK;
  2215. //error:
  2216. return hr;
  2217. }
  2218. // remove any non-numeric chars except default string
  2219. HRESULT
  2220. HandleKeyLengthEditChange(
  2221. HWND hwndComboBox)
  2222. {
  2223. HRESULT hr;
  2224. WCHAR wszKeyLength[MAX_KEYLENGTHEDIT];
  2225. int index = 0; // index for new #
  2226. int posi = 0; // current position
  2227. wszKeyLength[0] = L'\0'; // PREFIX says initialize
  2228. GetWindowText(hwndComboBox, wszKeyLength, ARRAYSIZE(wszKeyLength));
  2229. // remove non-numeric chars
  2230. while (L'\0' != wszKeyLength[posi])
  2231. {
  2232. if (iswdigit(wszKeyLength[posi]))
  2233. {
  2234. // take digit
  2235. wszKeyLength[index] = wszKeyLength[posi];
  2236. ++index;
  2237. }
  2238. ++posi;
  2239. }
  2240. if (index != posi)
  2241. {
  2242. // null terminator
  2243. wszKeyLength[index] = L'\0';
  2244. // update
  2245. SetWindowText(hwndComboBox, wszKeyLength);
  2246. // point to end
  2247. SendMessage(hwndComboBox, CB_SETEDITSEL, (WPARAM)0,
  2248. MAKELPARAM((index), (index)) );
  2249. }
  2250. hr = S_OK;
  2251. //error:
  2252. return hr;
  2253. }
  2254. HRESULT
  2255. HandleImportPFXButton(
  2256. HWND hDlg,
  2257. PER_COMPONENT_DATA *pComp)
  2258. {
  2259. HRESULT hr;
  2260. CASERVERSETUPINFO *pServer = pComp->CA.pServer;
  2261. hr = ImportPFXAndUpdateCSPInfo(hDlg, pComp);
  2262. _PrintIfError(hr, "ImportPFXAndUpdateCSPInfo");
  2263. // ignore error and force update anyway.
  2264. hr = UpdateCSPSelection(hDlg, pServer);
  2265. _JumpIfError(hr, error, "UpdateCSPSelection");
  2266. hr = S_OK;
  2267. error:
  2268. return hr;
  2269. }
  2270. HRESULT
  2271. HandleAdvanceWizNext(
  2272. HWND hDlg,
  2273. PER_COMPONENT_DATA *pComp)
  2274. {
  2275. HRESULT hr;
  2276. WCHAR wszKeyLength[MAX_KEYLENGTHEDIT];
  2277. CASERVERSETUPINFO *pServer = pComp->CA.pServer;
  2278. HWND hwndCtrl = GetDlgItem(hDlg, IDC_ADVANCE_KEY_LENGTH);
  2279. BOOL fDontNext = FALSE;
  2280. WCHAR wszKeyRange[2*MAX_KEYLENGTHDIGIT + 4]; //"(xxxx,xxxx)" format
  2281. WCHAR *pwszKeyRange = NULL; //don't free just a pointer
  2282. int dwKeyLength;
  2283. int idMsg;
  2284. BOOL fValidDigitString;
  2285. if (NULL == pServer->pwszKeyContainerName)
  2286. {
  2287. GetWindowText(hwndCtrl, wszKeyLength, ARRAYSIZE(wszKeyLength));
  2288. dwKeyLength = myWtoI(wszKeyLength, &fValidDigitString);
  2289. if (0 > dwKeyLength)
  2290. {
  2291. idMsg = IDS_ADVANCE_NEGATIVEKEYLENGTH;
  2292. fDontNext = TRUE;
  2293. }
  2294. else if (!fValidDigitString)
  2295. {
  2296. idMsg = IDS_ADVANCE_INVALIDKEYLENGTH;
  2297. fDontNext = TRUE;
  2298. }
  2299. else if ( (C_CSPHASNOKEYMINMAX != pServer->dwKeyLenMin &&
  2300. (DWORD)dwKeyLength < pServer->dwKeyLenMin) ||
  2301. (C_CSPHASNOKEYMINMAX != pServer->dwKeyLenMax &&
  2302. (DWORD)dwKeyLength > pServer->dwKeyLenMax) )
  2303. {
  2304. swprintf(wszKeyRange, L"(%ld, %ld)",
  2305. pServer->dwKeyLenMin, pServer->dwKeyLenMax);
  2306. pwszKeyRange = wszKeyRange;
  2307. idMsg = IDS_ADVANCE_KEYLENGTHOUTOFRANGE;
  2308. fDontNext = TRUE;
  2309. }
  2310. if (fDontNext)
  2311. {
  2312. CertWarningMessageBox(
  2313. pComp->hInstance,
  2314. pComp->fUnattended,
  2315. hDlg,
  2316. idMsg,
  2317. 0,
  2318. pwszKeyRange);
  2319. SetEditFocusAndSelect(hwndCtrl, 0, -1);
  2320. goto done;
  2321. }
  2322. // take the length
  2323. pServer->dwKeyLength = dwKeyLength;
  2324. }
  2325. else
  2326. {
  2327. // use existing key
  2328. if (NULL==pServer->pccExistingCert)
  2329. {
  2330. // If reusing a key but not a cert, make the common name match the key name
  2331. if (NULL != pServer->pwszCACommonName)
  2332. {
  2333. // free old
  2334. LocalFree(pServer->pwszCACommonName);
  2335. pServer->pwszCACommonName = NULL;
  2336. }
  2337. pServer->pwszCACommonName = (WCHAR*) LocalAlloc(LPTR,
  2338. (wcslen(pServer->pwszDesanitizedKeyContainerName) + 1) * sizeof(WCHAR));
  2339. _JumpIfOutOfMemory(hr, error, pServer->pwszCACommonName);
  2340. wcscpy(pServer->pwszCACommonName, pServer->pwszDesanitizedKeyContainerName);
  2341. hr = InitNameFields(pServer);
  2342. _JumpIfError(hr, error, "InitNameFields");
  2343. } else {
  2344. // If reusing a cert, make all the ID fields match the cert
  2345. // use idinfo from signing cert
  2346. hr = DetermineExistingCAIdInfo(pServer, NULL);
  2347. if (S_OK != hr)
  2348. {
  2349. CertWarningMessageBox(
  2350. pComp->hInstance,
  2351. pComp->fUnattended,
  2352. hDlg,
  2353. IDS_ERR_ANALYSIS_CA,
  2354. hr,
  2355. NULL);
  2356. _PrintError(hr, "DetermineExistingCAIdInfo");
  2357. fDontNext = TRUE;
  2358. goto done;
  2359. }
  2360. }
  2361. }
  2362. // get "interactive service" check box state
  2363. pServer->fInteractiveService =
  2364. (BST_CHECKED ==
  2365. SendMessage(GetDlgItem(hDlg, IDC_ADVANCE_INTERACTIVECHECK),
  2366. BM_GETCHECK, (WPARAM)0, (LPARAM)0))?
  2367. TRUE:FALSE;
  2368. // update hash oid
  2369. if (NULL != pServer->pszAlgId)
  2370. {
  2371. // free old
  2372. LocalFree(pServer->pszAlgId);
  2373. }
  2374. hr = myGetSigningOID(
  2375. NULL, // hProv
  2376. pServer->pCSPInfo->pwszProvName,
  2377. pServer->pCSPInfo->dwProvType,
  2378. pServer->pHashInfo->idAlg,
  2379. &(pServer->pszAlgId));
  2380. if (S_OK != hr)
  2381. {
  2382. CertWarningMessageBox(
  2383. pComp->hInstance,
  2384. pComp->fUnattended,
  2385. hDlg,
  2386. IDS_ERR_UNSUPPORTEDHASH,
  2387. hr,
  2388. NULL);
  2389. fDontNext = TRUE;
  2390. goto done;
  2391. }
  2392. done:
  2393. if (fDontNext)
  2394. {
  2395. SetWindowLongPtr(hDlg, DWLP_MSGRESULT, TRUE); // forbid
  2396. }
  2397. else
  2398. {
  2399. pServer->LastWiz = ENUM_WIZ_ADVANCE;
  2400. }
  2401. hr = S_OK;
  2402. error:
  2403. return hr;
  2404. }
  2405. HRESULT
  2406. HandleAdvanceWizActive(
  2407. HWND hDlg,
  2408. PER_COMPONENT_DATA *pComp)
  2409. {
  2410. HRESULT hr;
  2411. CASERVERSETUPINFO *pServer = pComp->CA.pServer;
  2412. // Suppress this wizard page if
  2413. // we've already seen an error, or
  2414. // the advanced option was not selected, or
  2415. // we are not installing the server.
  2416. if (!pServer->fAdvance ||
  2417. !(IS_SERVER_INSTALL & pComp->dwInstallStatus) )
  2418. {
  2419. // disable page
  2420. CSILOGDWORD(IDS_ADVANCE_TITLE, dwWIZDISABLE);
  2421. SetWindowLongPtr(hDlg, DWLP_MSGRESULT, -1);
  2422. goto done;
  2423. }
  2424. if (NULL == pServer->pCSPInfoList)
  2425. {
  2426. // construct CSP info list
  2427. HCURSOR hPrevCur = SetCursor(LoadCursor(NULL, IDC_WAIT));
  2428. hr = GetCSPInfoList(&pServer->pCSPInfoList);
  2429. SetCursor(hPrevCur);
  2430. _JumpIfError(hr, error, "GetCSPInfoList");
  2431. // show all csps
  2432. hr = ShowAllCSP(hDlg, pServer->pCSPInfoList);
  2433. _JumpIfError(hr, error, "ShowAllCSP");
  2434. // determine default csp
  2435. hr = DetermineDefaultCSP(pServer);
  2436. _JumpIfError(hr, error, "DetermineDefaultCSP");
  2437. hr = DetermineDefaultHash(pServer);
  2438. _JumpIfError(hr, error, "DetermineDefaultHash");
  2439. hr = InitializeKeyLengthControl(hDlg);
  2440. _JumpIfError(hr, error, "InitializeKeyLengthControl");
  2441. }
  2442. hr = UpdateCSPSelection(hDlg, pServer);
  2443. _JumpIfError(hr, error, "UpdateCSPSelection");
  2444. done:
  2445. hr = S_OK;
  2446. error:
  2447. return hr;
  2448. }
  2449. HRESULT
  2450. HandleViewCertButton(
  2451. HWND hDlg,
  2452. PER_COMPONENT_DATA *pComp)
  2453. {
  2454. HRESULT hr;
  2455. CRYPTUI_VIEWCERTIFICATE_STRUCTW viewCert;
  2456. CASERVERSETUPINFO *pServer = pComp->CA.pServer;
  2457. CSASSERT(NULL!=pServer->pwszKeyContainerName &&
  2458. NULL!=pServer->pccExistingCert);
  2459. ZeroMemory(&viewCert, sizeof(CRYPTUI_VIEWCERTIFICATE_STRUCTW));
  2460. viewCert.hwndParent = hDlg;
  2461. viewCert.dwSize = sizeof(viewCert);
  2462. viewCert.pCertContext = CertDuplicateCertificateContext(pServer->pccExistingCert);
  2463. if (NULL == viewCert.pCertContext)
  2464. {
  2465. hr = myHLastError();
  2466. _JumpError(hr, error, "CertDuplicateCertificateContext");
  2467. }
  2468. // viewCert.rghStores = &pServer->hMyStore;
  2469. // viewCert.cStores = 1;
  2470. viewCert.dwFlags = CRYPTUI_DONT_OPEN_STORES;
  2471. if (!CryptUIDlgViewCertificateW(&viewCert, NULL))
  2472. {
  2473. hr = myHLastError();
  2474. _PrintError(hr, "CryptUIDlgViewCertificate");
  2475. }
  2476. hr = S_OK;
  2477. error:
  2478. if (NULL != viewCert.pCertContext)
  2479. {
  2480. CertFreeCertificateContext(viewCert.pCertContext);
  2481. }
  2482. return hr;
  2483. }
  2484. //+------------------------------------------------------------------------
  2485. //
  2486. // Function: WizAdvancedPageDlgProc(. . . .)
  2487. //
  2488. // Synopsis: Dialog procedure for advanced configuration OCM wizard.
  2489. //
  2490. // Arguments: [hDlg]
  2491. // [iMsg]
  2492. // [wParam]
  2493. // [lParam] ... the usual.
  2494. //
  2495. // Returns: BOOL dlg proc result.
  2496. //
  2497. //-------------------------------------------------------------------------
  2498. INT_PTR
  2499. WizAdvancedPageDlgProc(HWND hDlg, UINT iMsg, WPARAM wParam, LPARAM lParam)
  2500. {
  2501. PER_COMPONENT_DATA *pComp = NULL;
  2502. switch (iMsg)
  2503. {
  2504. case WM_INITDIALOG:
  2505. // point to component data
  2506. SetWindowLongPtr(hDlg, DWLP_USER,
  2507. (LONG)((PROPSHEETPAGE*)lParam)->lParam);
  2508. pComp = (PER_COMPONENT_DATA*)((PROPSHEETPAGE*)lParam)->lParam;
  2509. _ReturnIfWizError(pComp->hrContinue);
  2510. pComp->hrContinue = InitAdvanceWizPageControls(hDlg, pComp->CA.pServer);
  2511. _ReturnIfWizError(pComp->hrContinue);
  2512. break;
  2513. case WM_COMMAND:
  2514. switch (LOWORD(wParam))
  2515. {
  2516. case IDC_ADVANCE_CSPLIST:
  2517. switch (HIWORD(wParam))
  2518. {
  2519. case LBN_SELCHANGE:
  2520. pComp = _GetCompDataOrReturnIfError(pComp, hDlg);
  2521. pComp->hrContinue = HandleCSPSelectionChange(hDlg,
  2522. pComp->CA.pServer);
  2523. _ReturnIfWizError(pComp->hrContinue);
  2524. break;
  2525. default:
  2526. break;
  2527. }
  2528. break;
  2529. case IDC_ADVANCE_HASHLIST:
  2530. switch (HIWORD(wParam))
  2531. {
  2532. case LBN_SELCHANGE:
  2533. pComp = _GetCompDataOrReturnIfError(pComp, hDlg);
  2534. pComp->hrContinue = HandleHashSelectionChange(hDlg,
  2535. pComp->CA.pServer);
  2536. _ReturnIfWizError(pComp->hrContinue);
  2537. break;
  2538. }
  2539. break;
  2540. case IDC_ADVANCE_KEYLIST:
  2541. switch (HIWORD(wParam))
  2542. {
  2543. case LBN_SELCHANGE:
  2544. pComp = _GetCompDataOrReturnIfError(pComp, hDlg);
  2545. pComp->hrContinue = HandleKeySelectionChange(hDlg,
  2546. pComp->CA.pServer, TRUE);
  2547. _ReturnIfWizError(pComp->hrContinue);
  2548. break;
  2549. }
  2550. break;
  2551. case IDC_ADVANCE_USEKEYCHECK:
  2552. pComp = _GetCompDataOrReturnIfError(pComp, hDlg);
  2553. pComp->hrContinue = HandleUseKeyCheckboxChange(hDlg,
  2554. pComp->CA.pServer);
  2555. _ReturnIfWizError(pComp->hrContinue);
  2556. break;
  2557. case IDC_ADVANCE_USECERTCHECK:
  2558. pComp = _GetCompDataOrReturnIfError(pComp, hDlg);
  2559. pComp->hrContinue = HandleUseCertCheckboxChange(hDlg,
  2560. pComp->CA.pServer);
  2561. _ReturnIfWizError(pComp->hrContinue);
  2562. break;
  2563. case IDC_ADVANCE_KEY_LENGTH:
  2564. switch (HIWORD(wParam))
  2565. {
  2566. case CBN_SELCHANGE:
  2567. pComp = _GetCompDataOrReturnIfError(pComp, hDlg);
  2568. pComp->hrContinue = HandleKeyLengthSelectionChange(hDlg,
  2569. pComp->CA.pServer);
  2570. _ReturnIfWizError(pComp->hrContinue);
  2571. break;
  2572. case CBN_EDITCHANGE:
  2573. pComp = _GetCompDataOrReturnIfError(pComp, hDlg);
  2574. pComp->hrContinue = HandleKeyLengthEditChange(
  2575. (HWND)lParam);
  2576. _ReturnIfWizError(pComp->hrContinue);
  2577. break;
  2578. }
  2579. break;
  2580. case IDC_ADVANCE_IMPORT:
  2581. pComp = _GetCompDataOrReturnIfError(pComp, hDlg);
  2582. pComp->hrContinue = HandleImportPFXButton(hDlg, pComp);
  2583. _ReturnIfWizError(pComp->hrContinue);
  2584. break;
  2585. case IDC_ADVANCE_VIEWCERT:
  2586. pComp = _GetCompDataOrReturnIfError(pComp, hDlg);
  2587. pComp->hrContinue = HandleViewCertButton(hDlg, pComp);
  2588. _ReturnIfWizError(pComp->hrContinue);
  2589. break;
  2590. default:
  2591. return FALSE;
  2592. }
  2593. break;
  2594. case WM_NOTIFY:
  2595. switch (((NMHDR FAR*) lParam)->code)
  2596. {
  2597. case PSN_KILLACTIVE:
  2598. break;
  2599. case PSN_RESET:
  2600. break;
  2601. case PSN_QUERYCANCEL:
  2602. pComp = _GetCompDataOrReturnIfError(pComp, hDlg);
  2603. return CertConfirmCancel(hDlg, pComp);
  2604. break;
  2605. case PSN_SETACTIVE:
  2606. CSILOGDWORD(IDS_ADVANCE_TITLE, dwWIZACTIVE);
  2607. PropSheet_SetWizButtons(GetParent(hDlg), PSWIZB_BACK|PSWIZB_NEXT);
  2608. pComp = _GetCompDataOrReturn(pComp, hDlg);
  2609. _DisableWizDisplayIfError(pComp, hDlg);
  2610. _ReturnIfWizError(pComp->hrContinue);
  2611. pComp->hrContinue = HandleAdvanceWizActive(hDlg, pComp);
  2612. _ReturnIfWizError(pComp->hrContinue);
  2613. break;
  2614. case PSN_WIZBACK:
  2615. CSILOGDWORD(IDS_ADVANCE_TITLE, dwWIZBACK);
  2616. break;
  2617. case PSN_WIZNEXT:
  2618. DWORD fReuseCert;
  2619. pComp = _GetCompDataOrReturnIfError(pComp, hDlg);
  2620. fReuseCert = NULL != pComp->CA.pServer->pccExistingCert;
  2621. CSILOG(
  2622. S_OK,
  2623. IDS_LOG_KEYNAME,
  2624. pComp->CA.pServer->pwszKeyContainerName,
  2625. pComp->CA.pServer->pwszDesanitizedKeyContainerName,
  2626. &fReuseCert);
  2627. CSILOGDWORD(IDS_ADVANCE_TITLE, dwWIZNEXT);
  2628. pComp->hrContinue = HandleAdvanceWizNext(hDlg, pComp);
  2629. _ReturnIfWizError(pComp->hrContinue);
  2630. break;
  2631. default:
  2632. return FALSE;
  2633. }
  2634. break;
  2635. default:
  2636. return FALSE;
  2637. }
  2638. return TRUE;
  2639. }
  2640. HRESULT
  2641. EnableSharedFolderControls(HWND hDlg, BOOL fUseSharedFolder)
  2642. {
  2643. EnableWindow(GetDlgItem(hDlg, IDC_STORE_EDIT_SHAREDFOLDER), fUseSharedFolder);
  2644. EnableWindow(GetDlgItem(hDlg, IDC_STORE_SHAREDBROWSE), fUseSharedFolder);
  2645. if (fUseSharedFolder)
  2646. {
  2647. SetEditFocusAndSelect(GetDlgItem(hDlg, IDC_STORE_EDIT_SHAREDFOLDER), 0, -1);
  2648. }
  2649. return S_OK;
  2650. }
  2651. HRESULT
  2652. StorePageValidation(
  2653. HWND hDlg,
  2654. PER_COMPONENT_DATA *pComp,
  2655. BOOL *pfDontNext)
  2656. {
  2657. HRESULT hr;
  2658. UINT uiFocus = 0;
  2659. WCHAR *pwszDefaultDBDir = NULL;
  2660. WCHAR *pwszDefaultSF = NULL;
  2661. LPWSTR pwszPrompt = NULL;
  2662. LPWSTR pwszComputerName = NULL;
  2663. BOOL fExistSF = TRUE;
  2664. BOOL fExistDB = TRUE;
  2665. BOOL fExistLog = TRUE;
  2666. BOOL fDefaultDir;
  2667. BOOL fIsUNC, fIsSharedFolderUNC;
  2668. WCHAR wszNotExistingDir[3 * MAX_PATH];
  2669. BOOL fUseSharedFolder;
  2670. CASERVERSETUPINFO *pServer = pComp->CA.pServer;
  2671. *pfDontNext = FALSE;
  2672. // get shared folder check state
  2673. if (pComp->fUnattended)
  2674. {
  2675. CSASSERT(NULL != pServer->pwszSharedFolder);
  2676. fUseSharedFolder = TRUE; // unattended always use shared folder
  2677. }
  2678. else
  2679. {
  2680. fUseSharedFolder = (BST_CHECKED == SendMessage(
  2681. GetDlgItem(hDlg, IDC_STORE_USE_SHAREDFOLDER),
  2682. BM_GETCHECK, 0, 0));
  2683. }
  2684. if (NULL != pServer->pwszSharedFolder)
  2685. {
  2686. fDefaultDir = TRUE;
  2687. hr = GetDefaultSharedFolder(&pwszDefaultSF);
  2688. _JumpIfError(hr, error, "GetDefaultSharedFolder");
  2689. // make sure case insensitive
  2690. if (0 != lstrcmpiW(pwszDefaultSF, pServer->pwszSharedFolder))
  2691. {
  2692. fDefaultDir = FALSE;
  2693. }
  2694. if (!ValidateAndCreateDirField(
  2695. pComp->hInstance,
  2696. pComp->fUnattended,
  2697. hDlg,
  2698. pServer->pwszSharedFolder,
  2699. fDefaultDir,
  2700. IDS_WRN_STORELOC_SHAREDFOLDER_FULLPATH,
  2701. &fExistSF,
  2702. &fIsSharedFolderUNC))
  2703. {
  2704. uiFocus = IDC_STORE_EDIT_SHAREDFOLDER;
  2705. *pfDontNext = TRUE;
  2706. goto done;
  2707. }
  2708. }
  2709. else if (fUseSharedFolder)
  2710. {
  2711. // the case to enforce shared folder but edit field is empty
  2712. CertWarningMessageBox(
  2713. pComp->hInstance,
  2714. pComp->fUnattended,
  2715. hDlg,
  2716. IDS_WRN_STORELOC_SHAREDFOLDER_FULLPATH,
  2717. 0,
  2718. L"");
  2719. uiFocus = IDC_STORE_EDIT_SHAREDFOLDER;
  2720. *pfDontNext = TRUE;
  2721. goto done;
  2722. }
  2723. fDefaultDir = TRUE;
  2724. hr = GetDefaultDBDirectory(pComp, &pwszDefaultDBDir);
  2725. _JumpIfError(hr, error, "GetDefaultDBDirectory");
  2726. // make sure case insensitive
  2727. if (0 != lstrcmpiW(pwszDefaultDBDir, pServer->pwszDBDirectory))
  2728. {
  2729. fDefaultDir = FALSE;
  2730. }
  2731. if (!ValidateAndCreateDirField(
  2732. pComp->hInstance,
  2733. pComp->fUnattended,
  2734. hDlg,
  2735. pServer->pwszDBDirectory,
  2736. fDefaultDir,
  2737. IDS_WRN_STORELOC_DB_FULLPATH,
  2738. &fExistDB,
  2739. &fIsUNC))
  2740. {
  2741. uiFocus = IDC_STORE_EDIT_DB;
  2742. *pfDontNext = TRUE;
  2743. goto done;
  2744. }
  2745. fDefaultDir = TRUE;
  2746. // remember default log dir is the same as db
  2747. if (0 != lstrcmpiW(pwszDefaultDBDir, pServer->pwszLogDirectory))
  2748. {
  2749. fDefaultDir = FALSE;
  2750. }
  2751. if (!ValidateAndCreateDirField(
  2752. pComp->hInstance,
  2753. pComp->fUnattended,
  2754. hDlg,
  2755. pServer->pwszLogDirectory,
  2756. fDefaultDir,
  2757. IDS_WRN_STORELOC_LOG_FULLPATH,
  2758. &fExistLog,
  2759. &fIsUNC))
  2760. {
  2761. uiFocus = IDC_STORE_EDIT_LOG;
  2762. *pfDontNext = TRUE;
  2763. goto done;
  2764. }
  2765. wszNotExistingDir[0] = '\0'; // empty string
  2766. if (!fExistSF)
  2767. {
  2768. wcscat(wszNotExistingDir, pServer->pwszSharedFolder);
  2769. }
  2770. if (!fExistDB)
  2771. {
  2772. if ('\0' != wszNotExistingDir[0])
  2773. {
  2774. wcscat(wszNotExistingDir, L"\n");
  2775. }
  2776. wcscat(wszNotExistingDir, pServer->pwszDBDirectory);
  2777. }
  2778. if (!fExistLog)
  2779. {
  2780. if ('\0' != wszNotExistingDir[0])
  2781. {
  2782. wcscat(wszNotExistingDir, L"\n");
  2783. }
  2784. wcscat(wszNotExistingDir, pServer->pwszLogDirectory);
  2785. }
  2786. if ('\0' != wszNotExistingDir[0])
  2787. {
  2788. // skip confirm in unattended mode
  2789. if (!pComp->fUnattended)
  2790. {
  2791. // confirm all here
  2792. if (IDYES != CertMessageBox(
  2793. pComp->hInstance,
  2794. pComp->fUnattended,
  2795. hDlg,
  2796. IDS_ASK_CREATE_DIRECTORY,
  2797. 0,
  2798. MB_YESNO |
  2799. MB_ICONWARNING |
  2800. CMB_NOERRFROMSYS,
  2801. wszNotExistingDir) )
  2802. {
  2803. if (!fExistSF)
  2804. {
  2805. uiFocus = IDC_STORE_EDIT_SHAREDFOLDER;
  2806. }
  2807. else if (!fExistDB)
  2808. {
  2809. uiFocus = IDC_STORE_EDIT_DB;
  2810. }
  2811. else if (!fExistLog)
  2812. {
  2813. uiFocus = IDC_STORE_EDIT_LOG;
  2814. }
  2815. *pfDontNext = TRUE;
  2816. goto done;
  2817. }
  2818. }
  2819. if (!fExistSF)
  2820. {
  2821. hr = myCreateNestedDirectories(pServer->pwszSharedFolder);
  2822. if (S_OK != hr)
  2823. {
  2824. CertWarningMessageBox(pComp->hInstance,
  2825. pComp->fUnattended,
  2826. hDlg,
  2827. IDS_ERR_CREATE_DIR,
  2828. hr,
  2829. pServer->pwszSharedFolder);
  2830. uiFocus = IDC_STORE_EDIT_SHAREDFOLDER;
  2831. *pfDontNext = TRUE;
  2832. goto done;
  2833. }
  2834. }
  2835. if (!fExistDB)
  2836. {
  2837. hr = myCreateNestedDirectories(pServer->pwszDBDirectory);
  2838. if (S_OK != hr)
  2839. {
  2840. CertWarningMessageBox(pComp->hInstance,
  2841. pComp->fUnattended,
  2842. hDlg,
  2843. IDS_ERR_CREATE_DIR,
  2844. hr,
  2845. pServer->pwszDBDirectory);
  2846. uiFocus = IDC_STORE_EDIT_DB;
  2847. *pfDontNext = TRUE;
  2848. goto done;
  2849. }
  2850. }
  2851. if (!fExistLog)
  2852. {
  2853. hr = myCreateNestedDirectories(pServer->pwszLogDirectory);
  2854. if (S_OK != hr)
  2855. {
  2856. CertWarningMessageBox(pComp->hInstance,
  2857. pComp->fUnattended,
  2858. hDlg,
  2859. IDS_ERR_CREATE_DIR,
  2860. hr,
  2861. pServer->pwszLogDirectory);
  2862. uiFocus = IDC_STORE_EDIT_LOG;
  2863. *pfDontNext = TRUE;
  2864. goto done;
  2865. }
  2866. }
  2867. }
  2868. hr = ValidateESERestrictions(pServer->pwszDBDirectory);
  2869. if (S_OK != hr)
  2870. {
  2871. CertWarningMessageBox(
  2872. pComp->hInstance,
  2873. pComp->fUnattended,
  2874. hDlg,
  2875. IDS_WRN_DBSPECIALCHARACTERS,
  2876. hr,
  2877. pServer->pwszDBDirectory);
  2878. uiFocus = IDC_STORE_EDIT_DB;
  2879. *pfDontNext = TRUE;
  2880. goto done;
  2881. }
  2882. hr = ValidateESERestrictions(pServer->pwszLogDirectory);
  2883. if (S_OK != hr)
  2884. {
  2885. CertWarningMessageBox(
  2886. pComp->hInstance,
  2887. pComp->fUnattended,
  2888. hDlg,
  2889. IDS_WRN_DBSPECIALCHARACTERS,
  2890. hr,
  2891. pServer->pwszLogDirectory);
  2892. uiFocus = IDC_STORE_EDIT_LOG;
  2893. *pfDontNext = TRUE;
  2894. goto done;
  2895. }
  2896. CSASSERT(!*pfDontNext);
  2897. // directory creation done; now analyze for UNC, sharepath
  2898. if (NULL != pServer->pwszSharedFolder)
  2899. {
  2900. // if not UNC, prompt to change to UNC
  2901. if (!fIsSharedFolderUNC)
  2902. {
  2903. #define UNCPATH_TEMPLATE L"\\\\%ws\\" wszCERTCONFIGSHARENAME
  2904. hr = myAddShare(
  2905. wszCERTCONFIGSHARENAME,
  2906. myLoadResourceString(IDS_CERTCONFIG_FOLDERDESCR),
  2907. pServer->pwszSharedFolder,
  2908. TRUE, // overwrite
  2909. NULL);
  2910. _JumpIfError(hr, done, "myAddShare");
  2911. // get the local machine name
  2912. WCHAR wszUNCPath[MAX_PATH + ARRAYSIZE(UNCPATH_TEMPLATE)]; // "machine" + UNCPATH_TEMPLATE
  2913. hr = myGetMachineDnsName(&pwszComputerName);
  2914. _JumpIfError(hr, done, "myGetMachineDnsName");
  2915. // create UNC path
  2916. swprintf(wszUNCPath, UNCPATH_TEMPLATE, pwszComputerName);
  2917. // only convert to UNC if this thing is shared
  2918. LocalFree(pServer->pwszSharedFolder);
  2919. pServer->pwszSharedFolder = (LPWSTR)LocalAlloc(LMEM_FIXED,
  2920. WSZ_BYTECOUNT(wszUNCPath));
  2921. _JumpIfOutOfMemory(hr, error, pServer->pwszSharedFolder);
  2922. wcscpy(pServer->pwszSharedFolder, wszUNCPath);
  2923. } // else, user typed in an already-shared UNC path
  2924. }
  2925. done:
  2926. hr = S_OK;
  2927. error:
  2928. if (NULL != pwszDefaultDBDir)
  2929. LocalFree(pwszDefaultDBDir);
  2930. if (NULL != pwszDefaultSF)
  2931. LocalFree(pwszDefaultSF);
  2932. if (NULL != pwszPrompt)
  2933. LocalFree(pwszPrompt);
  2934. if (NULL != pwszComputerName)
  2935. LocalFree(pwszComputerName);
  2936. if (!pComp->fUnattended && uiFocus != 0 && *pfDontNext)
  2937. {
  2938. SetEditFocusAndSelect(GetDlgItem(hDlg, uiFocus), 0, -1);
  2939. }
  2940. return hr;
  2941. }
  2942. HRESULT
  2943. StoreDBShareValidation(
  2944. IN HWND hDlg,
  2945. IN PER_COMPONENT_DATA *pComp,
  2946. IN WCHAR const *pwszDir,
  2947. IN BOOL fDB, //db dir vs. log dir
  2948. OUT BOOL *pfDontNext)
  2949. {
  2950. HRESULT hr;
  2951. WCHAR *pwszDefaultLogDir = NULL;
  2952. BOOL fDefaultLogPath;
  2953. WCHAR *pwszFileInUse = NULL;
  2954. BOOL fFilesExist;
  2955. static BOOL s_fOverwriteDB = FALSE;
  2956. static BOOL s_fOverwriteLog = FALSE;
  2957. BOOL *pfOverwrite = fDB ? &s_fOverwriteDB : &s_fOverwriteLog;
  2958. // init
  2959. *pfDontNext = FALSE;
  2960. // get default log path which is the same as db
  2961. hr = GetDefaultDBDirectory(pComp, &pwszDefaultLogDir);
  2962. _JumpIfError(hr, error, "GetDefaultDBDirectory");
  2963. fDefaultLogPath = (0 == lstrcmpi(pwszDir, pwszDefaultLogDir));
  2964. hr = myDoDBFilesExistInDir(pwszDir, &fFilesExist, &pwszFileInUse);
  2965. _JumpIfError(hr, error, "myDoDBFilesExistInDir");
  2966. if (NULL != pwszFileInUse)
  2967. {
  2968. CertWarningMessageBox(
  2969. pComp->hInstance,
  2970. pComp->fUnattended,
  2971. hDlg,
  2972. IDS_WRN_DBFILEINUSE,
  2973. 0,
  2974. pwszFileInUse);
  2975. *pfDontNext = TRUE;
  2976. goto done;
  2977. }
  2978. if (!pComp->CA.pServer->fPreserveDB &&
  2979. fFilesExist &&
  2980. !*pfOverwrite &&
  2981. !fDefaultLogPath)
  2982. {
  2983. // log file exists in non-default dir
  2984. if (IDYES != CertMessageBox(
  2985. pComp->hInstance,
  2986. pComp->fUnattended,
  2987. hDlg,
  2988. IDS_WRN_STORELOC_EXISTINGDB,
  2989. 0,
  2990. MB_YESNO |
  2991. MB_DEFBUTTON2 |
  2992. MB_ICONWARNING |
  2993. CMB_NOERRFROMSYS,
  2994. pwszDir))
  2995. {
  2996. *pfDontNext = TRUE;
  2997. goto done;
  2998. }
  2999. // warn only once
  3000. *pfOverwrite = TRUE;
  3001. }
  3002. done:
  3003. if (*pfDontNext)
  3004. {
  3005. // set focus
  3006. SetEditFocusAndSelect(GetDlgItem(hDlg, IDC_STORE_EDIT_LOG), 0, -1);
  3007. }
  3008. hr = S_OK;
  3009. error:
  3010. if (NULL != pwszFileInUse)
  3011. {
  3012. LocalFree(pwszFileInUse);
  3013. }
  3014. if (NULL != pwszDefaultLogDir)
  3015. {
  3016. LocalFree(pwszDefaultLogDir);
  3017. }
  3018. return hr;
  3019. }
  3020. HRESULT
  3021. FinishDirectoryBrowse(
  3022. HWND hDlg,
  3023. int idEdit)
  3024. {
  3025. HRESULT hr = S_FALSE;
  3026. WCHAR dirInitName[MAX_PATH];
  3027. WCHAR dirName[MAX_PATH];
  3028. GetWindowText(GetDlgItem(hDlg, idEdit), dirInitName, MAX_PATH);
  3029. if (BrowseForDirectory(
  3030. GetParent(hDlg),
  3031. dirInitName,
  3032. dirName,
  3033. MAX_PATH,
  3034. NULL,
  3035. TRUE))
  3036. {
  3037. SetDlgItemText(hDlg, idEdit, dirName);
  3038. hr = S_OK;
  3039. }
  3040. return hr;
  3041. }
  3042. HRESULT
  3043. HookStorePageStrings(
  3044. HWND hDlg,
  3045. PAGESTRINGS *pPageString,
  3046. CASERVERSETUPINFO *pServer)
  3047. {
  3048. HRESULT hr;
  3049. for ( ; 0 != pPageString->idControl; pPageString++)
  3050. {
  3051. switch (pPageString->idControl)
  3052. {
  3053. case IDC_STORE_EDIT_SHAREDFOLDER:
  3054. pPageString->ppwszString = &(pServer->pwszSharedFolder);
  3055. break;
  3056. case IDC_STORE_EDIT_DB:
  3057. pPageString->ppwszString = &(pServer->pwszDBDirectory);
  3058. break;
  3059. case IDC_STORE_EDIT_LOG:
  3060. pPageString->ppwszString = &(pServer->pwszLogDirectory);
  3061. break;
  3062. default:
  3063. hr = E_INVALIDARG;
  3064. _JumpError(hr, error, "Internal error");
  3065. break;
  3066. }
  3067. }
  3068. hr = S_OK;
  3069. error:
  3070. return hr;
  3071. }
  3072. HRESULT
  3073. InitStoreWizControls(
  3074. HWND hDlg,
  3075. PAGESTRINGS *pPageString,
  3076. CASERVERSETUPINFO *pServer)
  3077. {
  3078. HRESULT hr;
  3079. // now make page strings complete
  3080. hr = HookStorePageStrings(hDlg, pPageString, pServer);
  3081. _JumpIfError(hr, error, "HookStorePageStrings");
  3082. SendDlgItemMessage(hDlg,
  3083. IDC_STORE_USE_SHAREDFOLDER,
  3084. BM_SETCHECK,
  3085. (WPARAM)((NULL != pServer->pwszSharedFolder) ?
  3086. BST_CHECKED : BST_UNCHECKED),
  3087. (LPARAM)0);
  3088. if (!pServer->fUseDS && (NULL != pServer->pwszSharedFolder))
  3089. {
  3090. // no DS, disable shared folder check to force it
  3091. EnableWindow(GetDlgItem(hDlg, IDC_STORE_USE_SHAREDFOLDER), FALSE);
  3092. }
  3093. hr = StartWizardPageEditControls(hDlg, pPageString);
  3094. _JumpIfError(hr, error, "StartWizardPageEditControls");
  3095. hr = S_OK;
  3096. error:
  3097. return hr;
  3098. }
  3099. HRESULT
  3100. HandlePreservingDB(
  3101. HWND hDlg,
  3102. PER_COMPONENT_DATA *pComp)
  3103. {
  3104. HRESULT hr;
  3105. CASERVERSETUPINFO *pServer = pComp->CA.pServer;
  3106. HWND hwndSF = GetDlgItem(hDlg, IDC_STORE_EDIT_SHAREDFOLDER);
  3107. HWND hwndDB = GetDlgItem(hDlg, IDC_STORE_EDIT_DB);
  3108. HWND hwndLog = GetDlgItem(hDlg, IDC_STORE_EDIT_LOG);
  3109. BOOL fEnable = TRUE;
  3110. BOOL fEnableSharedFolder = TRUE;
  3111. WCHAR *pwszExistingSharedFolder = NULL;
  3112. WCHAR *pwszExistingDBDirectory = NULL;
  3113. WCHAR *pwszExistingLogDirectory = NULL;
  3114. if (pServer->fPreserveDB)
  3115. {
  3116. if (!pServer->fUNCPathNotFound)
  3117. {
  3118. // get shared folder path
  3119. hr = myGetCertRegStrValue(NULL, NULL, NULL,
  3120. wszREGDIRECTORY, &pwszExistingSharedFolder);
  3121. if (hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND))
  3122. {
  3123. // optional value
  3124. hr = S_OK;
  3125. pwszExistingSharedFolder = NULL;
  3126. }
  3127. _JumpIfError(hr, error, "myGetCertRegStrValue");
  3128. fEnableSharedFolder = FALSE;
  3129. }
  3130. else
  3131. {
  3132. pwszExistingSharedFolder = pServer->pwszSharedFolder;
  3133. }
  3134. // get existing db path
  3135. hr = myGetCertRegStrValue(NULL, NULL, NULL,
  3136. wszREGDBDIRECTORY, &pwszExistingDBDirectory);
  3137. _JumpIfError(hr, error, "myGetCertRegStrValue");
  3138. hr = myGetCertRegStrValue(NULL, NULL, NULL,
  3139. wszREGDBLOGDIRECTORY, &pwszExistingLogDirectory);
  3140. _JumpIfError(hr, error, "myGetCertRegStrValue");
  3141. // fill edit fields
  3142. SetWindowText(hwndSF, pwszExistingSharedFolder);
  3143. SetWindowText(hwndDB, pwszExistingDBDirectory);
  3144. SetWindowText(hwndLog, pwszExistingLogDirectory);
  3145. // disable them
  3146. fEnable = FALSE;
  3147. }
  3148. EnableWindow(hwndSF, fEnableSharedFolder);
  3149. EnableWindow(hwndDB, fEnable);
  3150. EnableWindow(hwndLog, fEnable);
  3151. hr = S_OK;
  3152. error:
  3153. if (NULL != pwszExistingSharedFolder &&
  3154. pwszExistingSharedFolder != pServer->pwszSharedFolder)
  3155. {
  3156. LocalFree(pwszExistingSharedFolder);
  3157. }
  3158. if (NULL != pwszExistingDBDirectory)
  3159. {
  3160. LocalFree(pwszExistingDBDirectory);
  3161. }
  3162. if (NULL != pwszExistingLogDirectory)
  3163. {
  3164. LocalFree(pwszExistingLogDirectory);
  3165. }
  3166. return hr;
  3167. }
  3168. HRESULT
  3169. HandleStoreWizActive(
  3170. HWND hDlg,
  3171. PER_COMPONENT_DATA *pComp,
  3172. PAGESTRINGS *pPageString)
  3173. {
  3174. HRESULT hr;
  3175. HWND hwndDB;
  3176. BOOL fEnableKeepDB = FALSE;
  3177. CASERVERSETUPINFO *pServer = pComp->CA.pServer;
  3178. // Suppress this wizard page if
  3179. // we've already seen an error, or
  3180. // we are not installing the server.
  3181. if (!(IS_SERVER_INSTALL & pComp->dwInstallStatus) )
  3182. {
  3183. // disable page
  3184. CSILOGDWORD(IDS_STORE_TITLE, dwWIZDISABLE);
  3185. SetWindowLongPtr(hDlg, DWLP_MSGRESULT, -1);
  3186. goto done;
  3187. }
  3188. CSASSERT(NULL != pServer->pwszKeyContainerName);
  3189. hwndDB = GetDlgItem(hDlg, IDC_STORE_KEEPDB);
  3190. if (NULL != pServer->pccExistingCert)
  3191. {
  3192. // determine existing db status
  3193. hr = myDoDBFilesExist(
  3194. pServer->pwszSanitizedName,
  3195. &fEnableKeepDB,
  3196. NULL);
  3197. _JumpIfError(hr, error, "myDoDBFilesExist");
  3198. }
  3199. else
  3200. {
  3201. // can't use db
  3202. pServer->fPreserveDB = FALSE;
  3203. SendMessage(hwndDB, BM_SETCHECK, (WPARAM)BST_UNCHECKED, (LPARAM)0);
  3204. HandlePreservingDB(hDlg, pComp);
  3205. }
  3206. // enable/disable the control
  3207. EnableSharedFolderControls(hDlg, NULL != pServer->pwszSharedFolder);
  3208. EnableWindow(hwndDB, fEnableKeepDB);
  3209. done:
  3210. hr = S_OK;
  3211. error:
  3212. return hr;
  3213. }
  3214. HRESULT
  3215. HandleStoreWizNextOrBack(
  3216. HWND hDlg,
  3217. PAGESTRINGS *pPageString,
  3218. PER_COMPONENT_DATA *pComp,
  3219. int iWizBN)
  3220. {
  3221. HRESULT hr;
  3222. HWND hwndCtrl = NULL;
  3223. WCHAR *pwszFile = NULL;
  3224. WCHAR const *pwszCertName;
  3225. CASERVERSETUPINFO *pServer = pComp->CA.pServer;
  3226. BOOL fDontNext = FALSE;
  3227. BOOL fGoBack = FALSE;
  3228. BOOL fUseSharedFolder;
  3229. HCURSOR hPrevCur;
  3230. hr = FinishWizardPageEditControls(hDlg, pPageString);
  3231. _JumpIfError(hr, error, "FinishWizardPageEditControls");
  3232. if (PSN_WIZBACK == iWizBN)
  3233. {
  3234. goto done;
  3235. }
  3236. // make sure at least one way to publish ca
  3237. CSASSERT(NULL != pServer->pwszSharedFolder || pComp->CA.pServer->fUseDS);
  3238. // get shared folder check state
  3239. fUseSharedFolder = (BST_CHECKED == SendMessage(
  3240. GetDlgItem(hDlg, IDC_STORE_USE_SHAREDFOLDER),
  3241. BM_GETCHECK, 0, 0));
  3242. if (!fUseSharedFolder && NULL != pServer->pwszSharedFolder)
  3243. {
  3244. //don't collect shared folder from edit control
  3245. LocalFree(pServer->pwszSharedFolder);
  3246. pServer->pwszSharedFolder = NULL;
  3247. }
  3248. hPrevCur = SetCursor(LoadCursor(NULL, IDC_WAIT));
  3249. hr = StorePageValidation(hDlg, pComp, &fDontNext);
  3250. SetCursor(hPrevCur);
  3251. _JumpIfError(hr, error, "StorePageValidation");
  3252. if (fDontNext)
  3253. {
  3254. goto done;
  3255. }
  3256. // validate existing db sharing here
  3257. hr = StoreDBShareValidation(
  3258. hDlg,
  3259. pComp,
  3260. pComp->CA.pServer->pwszDBDirectory,
  3261. TRUE, //db dir
  3262. &fDontNext);
  3263. _JumpIfError(hr, error, "StoreDBShareValidation");
  3264. if (fDontNext)
  3265. {
  3266. goto done;
  3267. }
  3268. if (0 != lstrcmpi(
  3269. pComp->CA.pServer->pwszDBDirectory,
  3270. pComp->CA.pServer->pwszLogDirectory))
  3271. {
  3272. hr = StoreDBShareValidation(
  3273. hDlg,
  3274. pComp,
  3275. pComp->CA.pServer->pwszLogDirectory,
  3276. FALSE, //log dir
  3277. &fDontNext);
  3278. _JumpIfError(hr, error, "StoreDBShareValidation");
  3279. if (fDontNext)
  3280. {
  3281. goto done;
  3282. }
  3283. }
  3284. hr = myBuildPathAndExt(
  3285. pComp->CA.pServer->pwszDBDirectory,
  3286. pServer->pwszSanitizedName,
  3287. wszDBFILENAMEEXT,
  3288. &pwszFile);
  3289. _JumpIfError(hr, error, "myBuildPathAndExt");
  3290. // make sure path fits
  3291. if (MAX_PATH <= wcslen(pwszFile))
  3292. {
  3293. // pop up warning
  3294. CertWarningMessageBox(
  3295. pComp->hInstance,
  3296. pComp->fUnattended,
  3297. hDlg,
  3298. IDS_PATH_TOO_LONG_CANAME,
  3299. S_OK,
  3300. pwszFile);
  3301. // make it go back
  3302. fGoBack = TRUE;
  3303. fDontNext = TRUE;
  3304. goto done;
  3305. }
  3306. LocalFree(pwszFile);
  3307. pwszFile = NULL;
  3308. hr = myBuildPathAndExt(
  3309. pComp->CA.pServer->pwszLogDirectory,
  3310. TEXT(szDBBASENAMEPARM) L"00000",
  3311. wszLOGFILENAMEEXT,
  3312. &pwszFile);
  3313. _JumpIfError(hr, error, "myBuildPathAndExt");
  3314. // make sure path fits
  3315. if (MAX_PATH <= wcslen(pwszFile))
  3316. {
  3317. // pop up warning
  3318. CertWarningMessageBox(
  3319. pComp->hInstance,
  3320. pComp->fUnattended,
  3321. hDlg,
  3322. IDS_PATH_TOO_LONG_DIRECTORY,
  3323. S_OK,
  3324. pwszFile);
  3325. SetEditFocusAndSelect(GetDlgItem(hDlg, IDC_STORE_EDIT_LOG), 0, -1);
  3326. fDontNext = TRUE;
  3327. goto done;
  3328. }
  3329. LocalFree(pwszFile);
  3330. pwszFile = NULL;
  3331. hr = csiBuildCACertFileName(
  3332. pComp->hInstance,
  3333. hDlg,
  3334. pComp->fUnattended,
  3335. pServer->pwszSharedFolder,
  3336. pServer->pwszSanitizedName,
  3337. L".crt",
  3338. 0, // CANAMEIDTOICERT(pServer->dwCertNameId),
  3339. &pwszFile);
  3340. _JumpIfError(hr, error, "csiBuildCACertFileName");
  3341. // make sure path fit
  3342. if (MAX_PATH <= wcslen(pwszFile) + cwcSUFFIXMAX)
  3343. {
  3344. // pop up warning
  3345. CertWarningMessageBox(
  3346. pComp->hInstance,
  3347. pComp->fUnattended,
  3348. hDlg,
  3349. IDS_PATH_TOO_LONG_CANAME,
  3350. S_OK,
  3351. pwszFile);
  3352. // make it go back
  3353. fGoBack = TRUE;
  3354. fDontNext = TRUE;
  3355. goto done;
  3356. }
  3357. if (NULL != pServer->pwszCACertFile)
  3358. {
  3359. // free old one
  3360. LocalFree(pServer->pwszCACertFile);
  3361. }
  3362. pServer->pwszCACertFile = pwszFile;
  3363. pwszFile = NULL;
  3364. if (IsRootCA(pServer->CAType))
  3365. {
  3366. hPrevCur = SetCursor(LoadCursor(NULL, IDC_WAIT));
  3367. hr = StartAndStopService(pComp->hInstance,
  3368. pComp->fUnattended,
  3369. hDlg,
  3370. wszW3SVCNAME,
  3371. TRUE,
  3372. TRUE, // confirmation
  3373. IDS_STOP_W3SVC,
  3374. &g_fW3SvcRunning);
  3375. SetCursor(hPrevCur);
  3376. if (S_OK != hr)
  3377. {
  3378. if (E_ABORT == hr)
  3379. {
  3380. fDontNext = TRUE;
  3381. goto done;
  3382. }
  3383. _JumpError(hr, error, "StartAndStopService");
  3384. }
  3385. }
  3386. done:
  3387. if (fDontNext)
  3388. {
  3389. SetWindowLongPtr(hDlg, DWLP_MSGRESULT, TRUE); // forbid
  3390. if (fGoBack)
  3391. {
  3392. PropSheet_PressButton(GetParent(hDlg), PSBTN_BACK);
  3393. pServer->LastWiz = ENUM_WIZ_STORE;
  3394. }
  3395. }
  3396. else
  3397. {
  3398. // continue to next
  3399. pServer->LastWiz = ENUM_WIZ_STORE;
  3400. }
  3401. hr = S_OK;
  3402. error:
  3403. if (NULL != pwszFile)
  3404. {
  3405. LocalFree(pwszFile);
  3406. }
  3407. return hr;
  3408. }
  3409. HRESULT
  3410. HandleUseSharedFolder(
  3411. IN HWND hDlg,
  3412. IN OUT PER_COMPONENT_DATA *pComp)
  3413. {
  3414. HRESULT hr;
  3415. // get shared folder check state
  3416. BOOL fUseSharedFolder = (BST_CHECKED == SendMessage(
  3417. GetDlgItem(hDlg, IDC_STORE_USE_SHAREDFOLDER),
  3418. BM_GETCHECK, 0, 0));
  3419. if (!fUseSharedFolder && !pComp->CA.pServer->fUseDS)
  3420. {
  3421. // must check at least one, force unchange
  3422. fUseSharedFolder = TRUE;
  3423. SendDlgItemMessage(hDlg, IDC_STORE_USE_SHAREDFOLDER,
  3424. BM_SETCHECK, (WPARAM)BST_CHECKED, (LPARAM)0);
  3425. }
  3426. hr = EnableSharedFolderControls(hDlg, fUseSharedFolder);
  3427. // _JumpIfError(hr, error, "EnableSharedFolderControls");
  3428. _PrintIfError(hr, "EnableSharedFolderControls");
  3429. // hr = S_OK;
  3430. //error:
  3431. return hr;
  3432. }
  3433. //+------------------------------------------------------------------------
  3434. // Function: WizStorePageDlgProc(. . . .)
  3435. //
  3436. // Synopsis: Dialog procedure for storage location
  3437. //-------------------------------------------------------------------------
  3438. INT_PTR
  3439. WizStorePageDlgProc(HWND hDlg, UINT iMsg, WPARAM wParam, LPARAM lParam)
  3440. {
  3441. PER_COMPONENT_DATA *pComp = NULL;
  3442. // keep scope of following array inside
  3443. static PAGESTRINGS saStoreString[] =
  3444. {
  3445. {
  3446. IDC_STORE_EDIT_SHAREDFOLDER,
  3447. IDS_LOG_SHAREDFOLDER,
  3448. 0,
  3449. 0,
  3450. MAX_PATH,
  3451. NULL,
  3452. },
  3453. {
  3454. IDC_STORE_EDIT_DB,
  3455. IDS_LOG_DBDIR,
  3456. 0,
  3457. 0,
  3458. MAX_PATH,
  3459. NULL,
  3460. },
  3461. {
  3462. IDC_STORE_EDIT_LOG,
  3463. IDS_LOG_DBLOGDIR,
  3464. 0,
  3465. 0,
  3466. MAX_PATH,
  3467. NULL,
  3468. },
  3469. // you need to add code in HookStoreStrings if adding more...
  3470. {
  3471. 0,
  3472. 0,
  3473. 0,
  3474. 0,
  3475. 0,
  3476. NULL,
  3477. }
  3478. };
  3479. switch(iMsg)
  3480. {
  3481. case WM_INITDIALOG:
  3482. // point to component data
  3483. SetWindowLongPtr(hDlg, DWLP_USER,
  3484. (LONG)((PROPSHEETPAGE*)lParam)->lParam);
  3485. pComp = (PER_COMPONENT_DATA*)((PROPSHEETPAGE*)lParam)->lParam;
  3486. _ReturnIfWizError(pComp->hrContinue);
  3487. pComp->hrContinue = InitStoreWizControls(hDlg, saStoreString, pComp->CA.pServer);
  3488. _ReturnIfWizError(pComp->hrContinue);
  3489. break;
  3490. case WM_COMMAND:
  3491. switch (LOWORD(wParam))
  3492. {
  3493. case IDC_STORE_USE_SHAREDFOLDER:
  3494. pComp = _GetCompDataOrReturnIfError(pComp, hDlg);
  3495. pComp->hrContinue = HandleUseSharedFolder(hDlg, pComp);
  3496. _ReturnIfWizError(pComp->hrContinue);
  3497. break;
  3498. case IDC_STORE_KEEPDB:
  3499. pComp = _GetCompDataOrReturnIfError(pComp, hDlg);
  3500. pComp->CA.pServer->fPreserveDB = !pComp->CA.pServer->fPreserveDB;
  3501. pComp->hrContinue = HandlePreservingDB(hDlg, pComp);
  3502. _ReturnIfWizError(pComp->hrContinue);
  3503. break;
  3504. case IDC_STORE_SHAREDBROWSE:
  3505. FinishDirectoryBrowse(hDlg, IDC_STORE_EDIT_SHAREDFOLDER);
  3506. break;
  3507. case IDC_STORE_DBBROWSE:
  3508. FinishDirectoryBrowse(hDlg, IDC_STORE_EDIT_DB);
  3509. break;
  3510. case IDC_STORE_LOGBROWSE:
  3511. FinishDirectoryBrowse(hDlg, IDC_STORE_EDIT_LOG);
  3512. break;
  3513. }
  3514. break;
  3515. case WM_NOTIFY:
  3516. switch (((NMHDR FAR *) lParam)->code)
  3517. {
  3518. case PSN_KILLACTIVE:
  3519. break;
  3520. case PSN_RESET:
  3521. break;
  3522. case PSN_QUERYCANCEL:
  3523. pComp = _GetCompDataOrReturnIfError(pComp, hDlg);
  3524. return CertConfirmCancel(hDlg, pComp);
  3525. break;
  3526. case PSN_SETACTIVE:
  3527. CSILOGDWORD(IDS_STORE_TITLE, dwWIZACTIVE);
  3528. PropSheet_SetWizButtons(GetParent(hDlg), PSWIZB_BACK|PSWIZB_NEXT);
  3529. pComp = _GetCompDataOrReturn(pComp, hDlg);
  3530. _DisableWizDisplayIfError(pComp, hDlg);
  3531. _ReturnIfWizError(pComp->hrContinue);
  3532. pComp->hrContinue = HandleStoreWizActive(hDlg, pComp,
  3533. saStoreString);
  3534. _ReturnIfWizError(pComp->hrContinue);
  3535. break;
  3536. case PSN_WIZBACK:
  3537. CSILOGDWORD(IDS_STORE_TITLE, dwWIZBACK);
  3538. pComp = _GetCompDataOrReturnIfError(pComp, hDlg);
  3539. pComp->hrContinue = HandleStoreWizNextOrBack(hDlg,
  3540. saStoreString, pComp, PSN_WIZBACK);
  3541. _ReturnIfWizError(pComp->hrContinue);
  3542. break;
  3543. case PSN_WIZNEXT:
  3544. CSILOGDWORD(IDS_STORE_TITLE, dwWIZNEXT);
  3545. pComp = _GetCompDataOrReturnIfError(pComp, hDlg);
  3546. pComp->hrContinue = HandleStoreWizNextOrBack(hDlg,
  3547. saStoreString, pComp, PSN_WIZNEXT);
  3548. _ReturnIfWizError(pComp->hrContinue);
  3549. break;
  3550. default:
  3551. return FALSE;
  3552. }
  3553. break;
  3554. default:
  3555. return FALSE;
  3556. }
  3557. return TRUE;
  3558. }
  3559. HRESULT
  3560. EnableCARequestControls(
  3561. HWND hDlg,
  3562. PER_COMPONENT_DATA *pComp)
  3563. {
  3564. HRESULT hr;
  3565. CASERVERSETUPINFO *pServer = pComp->CA.pServer;
  3566. // Online req
  3567. EnableWindow(GetDlgItem(hDlg, IDC_CAREQUEST_CANAME),
  3568. !pServer->fSaveRequestAsFile);
  3569. EnableWindow(GetDlgItem(hDlg, IDC_CAREQUEST_COMPUTERNAME),
  3570. !pServer->fSaveRequestAsFile);
  3571. EnableWindow(GetDlgItem(hDlg, IDC_CAREQUEST_CA_BROWSE),
  3572. !pServer->fSaveRequestAsFile && pServer->fCAsExist);
  3573. EnableWindow(GetDlgItem(hDlg, IDC_CAREQUEST_CNLABEL),
  3574. !pServer->fSaveRequestAsFile);
  3575. EnableWindow(GetDlgItem(hDlg, IDC_CAREQUEST_PCALABEL),
  3576. !pServer->fSaveRequestAsFile);
  3577. // File req
  3578. EnableWindow(GetDlgItem(hDlg, IDC_CAREQUEST_FILE),
  3579. pServer->fSaveRequestAsFile);
  3580. EnableWindow(GetDlgItem(hDlg, IDC_CAREQUEST_FILE_BROWSE),
  3581. pServer->fSaveRequestAsFile);
  3582. EnableWindow(GetDlgItem(hDlg, IDC_CAREQUEST_FILELABEL),
  3583. pServer->fSaveRequestAsFile);
  3584. if (pServer->fSaveRequestAsFile)
  3585. {
  3586. SetFocus(GetDlgItem(hDlg, IDC_CAREQUEST_FILE));
  3587. }
  3588. else
  3589. {
  3590. SetFocus(GetDlgItem(hDlg, IDC_CAREQUEST_CANAME));
  3591. }
  3592. hr = S_OK;
  3593. //error:
  3594. return hr;
  3595. }
  3596. HRESULT
  3597. BuildRequestFileName(
  3598. IN WCHAR const *pwszCACertFile,
  3599. OUT WCHAR **ppwszRequestFile)
  3600. {
  3601. #define wszREQEXT L".req"
  3602. HRESULT hr;
  3603. WCHAR const *pwszStart;
  3604. WCHAR const *pwszEnd;
  3605. WCHAR *pwszRequestFile = NULL;
  3606. CSASSERT(NULL != pwszCACertFile);
  3607. // derive request file name
  3608. pwszStart = pwszCACertFile;
  3609. pwszEnd = wcsrchr(pwszStart, L'.');
  3610. if (pwszEnd == NULL)
  3611. {
  3612. // set to end of entire string -- no '.' found
  3613. pwszEnd = &pwszStart[wcslen(pwszStart)];
  3614. }
  3615. pwszRequestFile = (WCHAR*)LocalAlloc(LMEM_FIXED,
  3616. (SAFE_SUBTRACT_POINTERS(pwszEnd, pwszStart) +
  3617. wcslen(wszREQEXT) + 1) * sizeof(WCHAR));
  3618. _JumpIfOutOfMemory(hr, error, pwszRequestFile);
  3619. CopyMemory(pwszRequestFile, pwszStart,
  3620. SAFE_SUBTRACT_POINTERS(pwszEnd, pwszStart) * sizeof(WCHAR));
  3621. wcscpy(pwszRequestFile + SAFE_SUBTRACT_POINTERS(pwszEnd, pwszStart), wszREQEXT);
  3622. // return
  3623. *ppwszRequestFile = pwszRequestFile;
  3624. pwszRequestFile = NULL;
  3625. hr = S_OK;
  3626. error:
  3627. if (NULL != pwszRequestFile)
  3628. {
  3629. LocalFree(pwszRequestFile);
  3630. }
  3631. return hr;
  3632. }
  3633. HRESULT
  3634. StartCARequestPage(
  3635. HWND hDlg,
  3636. PAGESTRINGS *pPageString,
  3637. CASERVERSETUPINFO *pServer)
  3638. {
  3639. HRESULT hr;
  3640. if (NULL == pServer->pwszRequestFile)
  3641. {
  3642. hr = BuildRequestFileName(
  3643. pServer->pwszCACertFile,
  3644. &pServer->pwszRequestFile);
  3645. _JumpIfError(hr, error, "BuildRequestFileName");
  3646. }
  3647. hr = StartWizardPageEditControls(hDlg, pPageString);
  3648. _JumpIfError(hr, error, "StartWizardPageEditControls");
  3649. hr = S_OK;
  3650. error:
  3651. return hr;
  3652. }
  3653. HRESULT
  3654. GetRequestFileName(
  3655. HWND hDlg,
  3656. PER_COMPONENT_DATA *pComp)
  3657. {
  3658. HRESULT hr;
  3659. WCHAR *pwszFileIn = NULL;
  3660. WCHAR *pwszFileOut = NULL;
  3661. HWND hCtrl = GetDlgItem(hDlg, IDC_CAREQUEST_FILE);
  3662. hr = myUIGetWindowText(hCtrl, &pwszFileIn);
  3663. _JumpIfError(hr, error, "myUIGetWindowText");
  3664. hr = myGetSaveFileName(
  3665. hDlg,
  3666. pComp->hInstance,
  3667. IDS_REQUEST_SAVE_TITLE,
  3668. IDS_REQUEST_FILE_FILTER,
  3669. IDS_REQUEST_FILE_DEFEXT,
  3670. OFN_PATHMUSTEXIST | OFN_OVERWRITEPROMPT,
  3671. pwszFileIn,
  3672. &pwszFileOut);
  3673. _JumpIfError(hr, error, "myGetSaveFileName");
  3674. if (NULL != pwszFileOut)
  3675. {
  3676. SetWindowText(hCtrl, pwszFileOut);
  3677. }
  3678. hr = S_OK;
  3679. error:
  3680. if (NULL != pwszFileOut)
  3681. {
  3682. LocalFree(pwszFileOut);
  3683. }
  3684. if (NULL != pwszFileIn)
  3685. {
  3686. LocalFree(pwszFileIn);
  3687. }
  3688. return hr;
  3689. }
  3690. HRESULT
  3691. HookCARequestPageStrings(
  3692. HWND hDlg,
  3693. PAGESTRINGS *pPageString,
  3694. CASERVERSETUPINFO *pServer)
  3695. {
  3696. HRESULT hr;
  3697. for ( ; 0 != pPageString->idControl; pPageString++)
  3698. {
  3699. switch (pPageString->idControl)
  3700. {
  3701. case IDC_CAREQUEST_CANAME:
  3702. pPageString->ppwszString = &(pServer->pwszParentCAName);
  3703. break;
  3704. case IDC_CAREQUEST_COMPUTERNAME:
  3705. pPageString->ppwszString = &(pServer->pwszParentCAMachine);
  3706. break;
  3707. case IDC_CAREQUEST_FILE:
  3708. pPageString->ppwszString = &(pServer->pwszRequestFile);
  3709. break;
  3710. default:
  3711. hr = E_INVALIDARG;
  3712. _JumpError(hr, error, "Internal error");
  3713. break;
  3714. }
  3715. }
  3716. hr = S_OK;
  3717. error:
  3718. return hr;
  3719. }
  3720. CERTSRVUICASELECTION g_CARequestUICASelection =
  3721. {NULL, NULL, NULL, NULL, NULL, ENUM_UNKNOWN_CA, false};
  3722. HRESULT
  3723. InitCARequestWizControls(
  3724. HWND hDlg,
  3725. PAGESTRINGS *pSubmitPageString,
  3726. PAGESTRINGS *pFilePageString,
  3727. PER_COMPONENT_DATA *pComp)
  3728. {
  3729. HRESULT hr;
  3730. CASERVERSETUPINFO *pServer = pComp->CA.pServer;
  3731. HWND hwndCtrl;
  3732. // now make page strings complete
  3733. hr = HookCARequestPageStrings(hDlg, pSubmitPageString, pServer);
  3734. _JumpIfError(hr, error, "HookCARequestPageStrings");
  3735. hr = HookCARequestPageStrings(hDlg, pFilePageString, pServer);
  3736. _JumpIfError(hr, error, "HookCARequestPageStrings");
  3737. if (!(SETUPOP_STANDALONE & pComp->Flags))
  3738. {
  3739. // nt base setup
  3740. // disable online submit
  3741. EnableWindow(GetDlgItem(hDlg, IDC_CAREQUEST_SUBMITTOCA), FALSE);
  3742. SendMessage(GetDlgItem(hDlg, IDC_CAREQUEST_SUBMITTOCA),
  3743. BM_SETCHECK,
  3744. (WPARAM) BST_UNCHECKED,
  3745. (LPARAM) 0);
  3746. // only save as file
  3747. pServer->fSaveRequestAsFile = TRUE;
  3748. SendMessage(GetDlgItem(hDlg, IDC_CAREQUEST_SAVETOFILE),
  3749. BM_SETCHECK,
  3750. (WPARAM) BST_CHECKED,
  3751. (LPARAM) 0);
  3752. }
  3753. else
  3754. {
  3755. // set online submit as default
  3756. pServer->fSaveRequestAsFile = FALSE;
  3757. SendMessage(GetDlgItem(hDlg, IDC_CAREQUEST_SUBMITTOCA),
  3758. BM_CLICK,
  3759. (WPARAM) 0,
  3760. (LPARAM) 0);
  3761. hr = myInitUICASelectionControls(
  3762. &g_CARequestUICASelection,
  3763. pComp->hInstance,
  3764. hDlg,
  3765. GetDlgItem(hDlg, IDC_CAREQUEST_CA_BROWSE),
  3766. GetDlgItem(hDlg, IDC_CAREQUEST_COMPUTERNAME),
  3767. GetDlgItem(hDlg, IDC_CAREQUEST_CANAME),
  3768. csiIsAnyDSCAAvailable(),
  3769. &pServer->fCAsExist);
  3770. _JumpIfError(hr, error, "myInitUICASelectionControls");
  3771. }
  3772. hr = S_OK;
  3773. error:
  3774. return hr;
  3775. }
  3776. HRESULT
  3777. HandleCARequestWizActive(
  3778. HWND hDlg,
  3779. PAGESTRINGS *pPageString,
  3780. PER_COMPONENT_DATA *pComp)
  3781. {
  3782. HRESULT hr;
  3783. DWORD dwCACount;
  3784. CRYPTUI_CA_CONTEXT const *pCAContext = NULL;
  3785. CASERVERSETUPINFO *pServer = pComp->CA.pServer;
  3786. BOOL fMatchAll = IsEverythingMatched(pServer);
  3787. // Suppress this wizard page if
  3788. // we've already seen an error, or
  3789. // we are not installing the server, or
  3790. // we are not installing a subordinate, or
  3791. // the advanced page already selected a matching key and cert
  3792. if (!(IS_SERVER_INSTALL & pComp->dwInstallStatus) ||
  3793. IsRootCA(pServer->CAType) ||
  3794. fMatchAll)
  3795. {
  3796. // disable page
  3797. CSILOGDWORD(IDS_CAREQUEST_TITLE, dwWIZDISABLE);
  3798. SetWindowLongPtr(hDlg, DWLP_MSGRESULT, -1);
  3799. goto done;
  3800. }
  3801. EnableCARequestControls(hDlg, pComp);
  3802. hr = StartCARequestPage(hDlg, pPageString, pServer);
  3803. _JumpIfError(hr, error, "StartCARequestPage");
  3804. done:
  3805. hr = S_OK;
  3806. error:
  3807. if (NULL != pCAContext)
  3808. {
  3809. CryptUIDlgFreeCAContext(pCAContext);
  3810. }
  3811. return hr;
  3812. }
  3813. HRESULT
  3814. ConvertEditControlFullFilePath(
  3815. HWND hEdtCtrl)
  3816. {
  3817. HRESULT hr;
  3818. WCHAR *pwszPath = NULL;
  3819. WCHAR wszFullPath[MAX_PATH];
  3820. WCHAR *pwszNotUsed;
  3821. DWORD dwSize = 0;
  3822. hr = myUIGetWindowText(hEdtCtrl, &pwszPath);
  3823. _JumpIfError(hr, error, "myUIGetWindowText");
  3824. if (NULL == pwszPath)
  3825. {
  3826. // empty path, done
  3827. goto done;
  3828. }
  3829. dwSize = GetFullPathName(pwszPath,
  3830. ARRAYSIZE(wszFullPath),
  3831. wszFullPath,
  3832. &pwszNotUsed);
  3833. CSASSERT(ARRAYSIZE(wszFullPath) > dwSize);
  3834. if (0 == dwSize)
  3835. {
  3836. hr = myHLastError();
  3837. _JumpError(hr, error, "GetFullPathName");
  3838. }
  3839. // get full path, set it back to edit control
  3840. SetWindowText(hEdtCtrl, wszFullPath);
  3841. done:
  3842. hr = S_OK;
  3843. error:
  3844. if (NULL != pwszPath)
  3845. {
  3846. LocalFree(pwszPath);
  3847. }
  3848. return hr;
  3849. }
  3850. HRESULT
  3851. HandleCARequestWizNextOrBack(
  3852. HWND hDlg,
  3853. PAGESTRINGS *pPageString,
  3854. PER_COMPONENT_DATA *pComp,
  3855. int iWizBN)
  3856. {
  3857. HRESULT hr;
  3858. CASERVERSETUPINFO *pServer = pComp->CA.pServer;
  3859. BOOL fDontNext = FALSE;
  3860. BOOL fValid;
  3861. if (pServer->fSaveRequestAsFile)
  3862. {
  3863. // convert request file to full path
  3864. hr = ConvertEditControlFullFilePath(
  3865. GetDlgItem(hDlg, IDC_CAREQUEST_FILE));
  3866. _JumpIfError(hr, error, "ConvertEditControlFullFilePath");
  3867. CSASSERT(pServer->pwszSanitizedName);
  3868. CSASSERT(pServer->pwszKeyContainerName);
  3869. hr = mySetCertRegStrValue(
  3870. pServer->pwszSanitizedName,
  3871. NULL,
  3872. NULL,
  3873. wszREGREQUESTKEYCONTAINER,
  3874. pServer->pwszKeyContainerName);
  3875. _JumpIfErrorStr(hr, error, "mySetCertRegStrValue", wszREGREQUESTKEYCONTAINER);
  3876. }
  3877. hr = FinishWizardPageEditControls(hDlg, pPageString);
  3878. _JumpIfError(hr, error, "FinishWizardPageEditControls");
  3879. if (PSN_WIZBACK == iWizBN)
  3880. {
  3881. goto done;
  3882. }
  3883. if (!pServer->fSaveRequestAsFile && NULL==pServer->pccExistingCert)
  3884. {
  3885. // online case
  3886. hr = myUICASelectionValidation(&g_CARequestUICASelection, &fValid);
  3887. _JumpIfError(hr, error, "myUICASelectionValidation");
  3888. if (!fValid)
  3889. {
  3890. fDontNext = TRUE;
  3891. goto done;
  3892. }
  3893. }
  3894. hr = WizardPageValidation(pComp->hInstance, pComp->fUnattended,
  3895. hDlg, pPageString);
  3896. if (S_OK != hr)
  3897. {
  3898. fDontNext = TRUE;
  3899. goto done;
  3900. }
  3901. if (pServer->fSaveRequestAsFile)
  3902. {
  3903. // validate dir path existance of the request file
  3904. WCHAR *pwszLastSlash = wcsrchr(pServer->pwszRequestFile, L'\\');
  3905. CSASSERT(NULL != pwszLastSlash);
  3906. if (NULL != pwszLastSlash)
  3907. {
  3908. // make request file path into a dir path
  3909. pwszLastSlash[0] = L'\0';
  3910. if (DE_DIREXISTS != DirExists(pServer->pwszRequestFile) ||
  3911. L'\0' == pwszLastSlash[1])
  3912. {
  3913. // bring request file path back
  3914. pwszLastSlash[0] = L'\\';
  3915. CertWarningMessageBox(
  3916. pComp->hInstance,
  3917. pComp->fUnattended,
  3918. hDlg,
  3919. IDS_CAREQUEST_REQUESTFILEPATH_MUSTEXIST,
  3920. 0,
  3921. pServer->pwszRequestFile);
  3922. SetEditFocusAndSelect(GetDlgItem(hDlg, IDC_CAREQUEST_FILE), 0, -1);
  3923. fDontNext = TRUE;
  3924. goto done;
  3925. }
  3926. // bring request file path back
  3927. pwszLastSlash[0] = L'\\';
  3928. }
  3929. // Fail if a directory with the same name already exists
  3930. if(DE_DIREXISTS == DirExists(pServer->pwszRequestFile))
  3931. {
  3932. CertWarningMessageBox(
  3933. pComp->hInstance,
  3934. pComp->fUnattended,
  3935. hDlg,
  3936. IDS_CAREQUEST_REQUESTFILEPATH_DIREXISTS,
  3937. 0,
  3938. pServer->pwszRequestFile);
  3939. SetEditFocusAndSelect(GetDlgItem(hDlg, IDC_CAREQUEST_FILE), 0, -1);
  3940. fDontNext = TRUE;
  3941. goto done;
  3942. }
  3943. }
  3944. hr = StartAndStopService(pComp->hInstance,
  3945. pComp->fUnattended,
  3946. hDlg,
  3947. wszW3SVCNAME,
  3948. TRUE,
  3949. TRUE,
  3950. IDS_STOP_W3SVC,
  3951. &g_fW3SvcRunning);
  3952. if (S_OK != hr)
  3953. {
  3954. if (E_ABORT == hr)
  3955. {
  3956. fDontNext = TRUE;
  3957. goto done;
  3958. }
  3959. _JumpError(hr, error, "StartAndStopService");
  3960. }
  3961. done:
  3962. if (fDontNext)
  3963. {
  3964. SetWindowLongPtr(hDlg, DWLP_MSGRESULT, TRUE); // forbid
  3965. }
  3966. else
  3967. {
  3968. pServer->LastWiz = ENUM_WIZ_REQUEST;
  3969. }
  3970. hr = S_OK;
  3971. error:
  3972. return hr;
  3973. }
  3974. //+------------------------------------------------------------------------
  3975. // Function: WizCARequestPageDlgProc(. . . .)
  3976. //
  3977. // Synopsis: Dialog procedure for CA Request wiz-page
  3978. //-------------------------------------------------------------------------
  3979. INT_PTR
  3980. WizCARequestPageDlgProc(HWND hDlg, UINT iMsg, WPARAM wParam, LPARAM lParam)
  3981. {
  3982. PAGESTRINGS *pPageString;
  3983. PER_COMPONENT_DATA *pComp = NULL;
  3984. static BOOL s_fComputerChange = FALSE;
  3985. // keep the following in local scope
  3986. static PAGESTRINGS saCARequestSubmit[] =
  3987. {
  3988. {
  3989. IDC_CAREQUEST_COMPUTERNAME,
  3990. IDS_LOG_COMPUTER,
  3991. IDS_COMPUTERNULLSTRERR,
  3992. IDS_COMPUTERLENSTRERR,
  3993. MAX_PATH,
  3994. NULL,
  3995. },
  3996. {
  3997. IDC_CAREQUEST_CANAME,
  3998. IDS_LOG_CANAME,
  3999. IDS_CANULLSTRERR,
  4000. IDS_CALENSTRERR,
  4001. cchCOMMONNAMEMAX,
  4002. NULL,
  4003. },
  4004. // add more code in HookCARequestPageStrings if you add
  4005. {
  4006. 0,
  4007. 0,
  4008. 0,
  4009. 0,
  4010. 0,
  4011. NULL
  4012. }
  4013. };
  4014. static PAGESTRINGS saCARequestFile[] =
  4015. {
  4016. {
  4017. IDC_CAREQUEST_FILE,
  4018. IDS_LOG_REQUESTFILE,
  4019. IDS_REQUESTFILENULLSTRERR,
  4020. IDS_REQUESTFILELENSTRERR,
  4021. MAX_PATH,
  4022. NULL,
  4023. },
  4024. // add more code in HookCARequestPageStrings if you add
  4025. {
  4026. 0,
  4027. 0,
  4028. 0,
  4029. 0,
  4030. 0,
  4031. NULL,
  4032. }
  4033. };
  4034. switch(iMsg)
  4035. {
  4036. case WM_INITDIALOG:
  4037. // point to component data
  4038. SetWindowLongPtr(hDlg, DWLP_USER,
  4039. (ULONG_PTR)((PROPSHEETPAGE*)lParam)->lParam);
  4040. pComp = (PER_COMPONENT_DATA*)(ULONG_PTR)((PROPSHEETPAGE*)lParam)->lParam;
  4041. _ReturnIfWizError(pComp->hrContinue);
  4042. pComp->hrContinue = InitCARequestWizControls(hDlg,
  4043. saCARequestSubmit,
  4044. saCARequestFile,
  4045. pComp);
  4046. _ReturnIfWizError(pComp->hrContinue);
  4047. break;
  4048. case WM_COMMAND:
  4049. switch (LOWORD(wParam))
  4050. {
  4051. case IDC_CAREQUEST_SAVETOFILE:
  4052. pComp = _GetCompDataOrReturnIfError(pComp, hDlg);
  4053. pComp->CA.pServer->fSaveRequestAsFile = TRUE;
  4054. pComp->hrContinue = EnableCARequestControls(hDlg, pComp);
  4055. _ReturnIfWizError(pComp->hrContinue);
  4056. break;
  4057. case IDC_CAREQUEST_SUBMITTOCA:
  4058. pComp = _GetCompDataOrReturnIfError(pComp, hDlg);
  4059. pComp->CA.pServer->fSaveRequestAsFile = FALSE;
  4060. pComp->hrContinue = EnableCARequestControls(hDlg, pComp);
  4061. _ReturnIfWizError(pComp->hrContinue);
  4062. break;
  4063. case IDC_CAREQUEST_CA_BROWSE:
  4064. pComp = _GetCompDataOrReturnIfError(pComp, hDlg);
  4065. pComp->hrContinue = myUICAHandleCABrowseButton(
  4066. &g_CARequestUICASelection,
  4067. csiIsAnyDSCAAvailable(),
  4068. IDS_CA_PICKER_TITLE,
  4069. IDS_CA_PICKER_PROMPT,
  4070. NULL);
  4071. _ReturnIfWizError(pComp->hrContinue);
  4072. break;
  4073. case IDC_CAREQUEST_FILE_BROWSE:
  4074. pComp = _GetCompDataOrReturnIfError(pComp, hDlg);
  4075. pComp->hrContinue = GetRequestFileName(hDlg, pComp);
  4076. _ReturnIfWizError(pComp->hrContinue);
  4077. break;
  4078. case IDC_CAREQUEST_CANAME:
  4079. pComp = _GetCompDataOrReturnIfError(pComp, hDlg);
  4080. pComp->hrContinue = myUICAHandleCAListDropdown(
  4081. (int)HIWORD(wParam), // notification
  4082. &g_CARequestUICASelection,
  4083. &s_fComputerChange);
  4084. _ReturnIfWizError(pComp->hrContinue);
  4085. break;
  4086. case IDC_CAREQUEST_COMPUTERNAME:
  4087. switch ((int)HIWORD(wParam))
  4088. {
  4089. case EN_CHANGE: // edit changed
  4090. s_fComputerChange = TRUE;
  4091. break;
  4092. }
  4093. break;
  4094. }
  4095. break;
  4096. case WM_NOTIFY:
  4097. switch (((NMHDR FAR *) lParam)->code)
  4098. {
  4099. case PSN_KILLACTIVE:
  4100. break;
  4101. case PSN_RESET:
  4102. break;
  4103. case PSN_QUERYCANCEL:
  4104. pComp = _GetCompDataOrReturnIfError(pComp, hDlg);
  4105. return CertConfirmCancel(hDlg, pComp);
  4106. break;
  4107. case PSN_SETACTIVE:
  4108. CSILOGDWORD(IDS_CAREQUEST_TITLE, dwWIZACTIVE);
  4109. pComp = _GetCompDataOrReturn(pComp, hDlg);
  4110. PropSheet_SetWizButtons(GetParent(hDlg), PSWIZB_BACK|PSWIZB_NEXT);
  4111. _DisableWizDisplayIfError(pComp, hDlg);
  4112. _ReturnIfWizError(pComp->hrContinue);
  4113. pComp->hrContinue = HandleCARequestWizActive(hDlg,
  4114. saCARequestFile, pComp);
  4115. _ReturnIfWizError(pComp->hrContinue);
  4116. break;
  4117. case PSN_WIZBACK:
  4118. CSILOGDWORD(IDS_CAREQUEST_TITLE, dwWIZBACK);
  4119. pComp = _GetCompDataOrReturnIfError(pComp, hDlg);
  4120. pPageString = saCARequestSubmit;
  4121. if (pComp->CA.pServer->fSaveRequestAsFile)
  4122. {
  4123. pPageString = saCARequestFile;
  4124. }
  4125. pComp->hrContinue = HandleCARequestWizNextOrBack(hDlg,
  4126. pPageString, pComp, PSN_WIZBACK);
  4127. _ReturnIfWizError(pComp->hrContinue);
  4128. break;
  4129. case PSN_WIZNEXT:
  4130. CSILOGDWORD(IDS_CAREQUEST_TITLE, dwWIZNEXT);
  4131. pComp = _GetCompDataOrReturnIfError(pComp, hDlg);
  4132. pPageString = saCARequestSubmit;
  4133. if (pComp->CA.pServer->fSaveRequestAsFile)
  4134. {
  4135. pPageString = saCARequestFile;
  4136. }
  4137. pComp->hrContinue = HandleCARequestWizNextOrBack(hDlg,
  4138. pPageString, pComp, PSN_WIZNEXT);
  4139. _ReturnIfWizError(pComp->hrContinue);
  4140. break;
  4141. default:
  4142. return FALSE;
  4143. }
  4144. break;
  4145. default:
  4146. return FALSE;
  4147. }
  4148. return TRUE;
  4149. }
  4150. HRESULT
  4151. HookClientPageStrings(
  4152. HWND hDlg,
  4153. PAGESTRINGS *pPageString,
  4154. CAWEBCLIENTSETUPINFO *pClient)
  4155. {
  4156. HRESULT hr;
  4157. for ( ; 0 != pPageString->idControl; pPageString++)
  4158. {
  4159. switch (pPageString->idControl)
  4160. {
  4161. case IDC_CLIENT_COMPUTERNAME:
  4162. pPageString->ppwszString = &(pClient->pwszWebCAMachine);
  4163. break;
  4164. default:
  4165. hr = E_INVALIDARG;
  4166. _JumpError(hr, error, "Internal error");
  4167. break;
  4168. }
  4169. }
  4170. hr = S_OK;
  4171. error:
  4172. return hr;
  4173. }
  4174. CERTSRVUICASELECTION g_WebClientUICASelection =
  4175. {NULL, NULL, NULL, NULL, NULL, ENUM_UNKNOWN_CA, true};
  4176. HRESULT
  4177. InitClientWizControls(
  4178. HWND hDlg,
  4179. PAGESTRINGS *pPageString,
  4180. PER_COMPONENT_DATA *pComp)
  4181. {
  4182. HRESULT hr;
  4183. BOOL fCAsExist;
  4184. CAWEBCLIENTSETUPINFO *pClient = pComp->CA.pClient;
  4185. hr = HookClientPageStrings(hDlg, pPageString, pClient);
  4186. _JumpIfError(hr, error, "HookClientPageStrings");
  4187. hr = WizPageSetTextLimits(hDlg, pPageString);
  4188. _JumpIfError(hr, error, "WizPageSetTextLimits");
  4189. pClient->fUseDS = FALSE;
  4190. if (IsDSAvailable())
  4191. {
  4192. pClient->fUseDS = csiIsAnyDSCAAvailable();
  4193. }
  4194. hr = myInitUICASelectionControls(
  4195. &g_WebClientUICASelection,
  4196. pComp->hInstance,
  4197. hDlg,
  4198. GetDlgItem(hDlg, IDC_CLIENT_BROWSECNFG),
  4199. GetDlgItem(hDlg, IDC_CLIENT_COMPUTERNAME),
  4200. GetDlgItem(hDlg, IDC_CLIENT_CANAME),
  4201. pClient->fUseDS,
  4202. &fCAsExist);
  4203. _JumpIfError(hr, error, "myInitUICASelectionControls");
  4204. hr = S_OK;
  4205. error:
  4206. return hr;
  4207. }
  4208. HRESULT
  4209. GetCAConfigInfo(
  4210. HWND hDlg,
  4211. PER_COMPONENT_DATA *pComp)
  4212. {
  4213. HRESULT hr = S_OK;
  4214. CAWEBCLIENTSETUPINFO *pClient = pComp->CA.pClient;
  4215. // free old shared folder always
  4216. if (NULL != pClient->pwszSharedFolder)
  4217. {
  4218. // free old
  4219. LocalFree(pClient->pwszSharedFolder);
  4220. pClient->pwszSharedFolder = NULL;
  4221. }
  4222. hr = myUICAHandleCABrowseButton(
  4223. &g_WebClientUICASelection,
  4224. pClient->fUseDS,
  4225. IDS_CONFIG_PICKER_TITLE,
  4226. IDS_CONFIG_PICKER_PROMPT,
  4227. &pClient->pwszSharedFolder);
  4228. _JumpIfError(hr, error, "myUICAHandleCABrowseButton");
  4229. error:
  4230. return hr;
  4231. }
  4232. HRESULT
  4233. HandleClientWizNextOrBack(
  4234. HWND hDlg,
  4235. PAGESTRINGS *pPageString,
  4236. PER_COMPONENT_DATA *pComp,
  4237. int iWizBN)
  4238. {
  4239. HWND hwndCtrl;
  4240. HRESULT hr;
  4241. CAWEBCLIENTSETUPINFO *pClient = pComp->CA.pClient;
  4242. BOOL fDontNext = FALSE;
  4243. WCHAR *pwszCAName = NULL;
  4244. WCHAR *pwszSanitizedCAName;
  4245. int nItem;
  4246. int len;
  4247. BOOL fValid;
  4248. BOOL fCoInit = FALSE;
  4249. // CAINFO *pCAInfo = NULL;
  4250. HCURSOR hPrevCur;
  4251. hr = FinishWizardPageEditControls(hDlg, pPageString);
  4252. _JumpIfError(hr, error, "FinishWizardPageEditControls");
  4253. if (PSN_WIZBACK == iWizBN)
  4254. {
  4255. goto done;
  4256. }
  4257. hr = myUICASelectionValidation(&g_WebClientUICASelection, &fValid);
  4258. _JumpIfError(hr, error, "myUICASelectionValidation");
  4259. if (!fValid)
  4260. {
  4261. fDontNext = TRUE;
  4262. goto done;
  4263. }
  4264. // at this point, g_WebClientUICASelection.CAType is guaranteed to be filled in
  4265. hr = WizardPageValidation(pComp->hInstance, pComp->fUnattended,
  4266. hDlg, pPageString);
  4267. if (S_OK != hr)
  4268. {
  4269. fDontNext = TRUE;
  4270. goto done;
  4271. }
  4272. hr = myUIGetWindowText(GetDlgItem(hDlg, IDC_CLIENT_CANAME), &pwszCAName);
  4273. _JumpIfError(hr, error, "myUIGetWindowText");
  4274. CSASSERT(NULL != pwszCAName);
  4275. if (NULL != pClient->pwszWebCAName)
  4276. {
  4277. // free old one
  4278. LocalFree(pClient->pwszWebCAName);
  4279. }
  4280. pClient->pwszWebCAName = pwszCAName;
  4281. pwszCAName = NULL;
  4282. hr = mySanitizeName(pClient->pwszWebCAName, &pwszSanitizedCAName);
  4283. _JumpIfError(hr, error, "mySanitizeName");
  4284. if (NULL != pClient->pwszSanitizedWebCAName)
  4285. {
  4286. // free old one
  4287. LocalFree(pClient->pwszSanitizedWebCAName);
  4288. }
  4289. pClient->pwszSanitizedWebCAName = pwszSanitizedCAName;
  4290. // pClient->WebCAType = pCAInfo->CAType;
  4291. pClient->WebCAType = g_WebClientUICASelection.CAType;
  4292. hr = StartAndStopService(pComp->hInstance,
  4293. pComp->fUnattended,
  4294. hDlg,
  4295. wszW3SVCNAME,
  4296. TRUE,
  4297. TRUE,
  4298. IDS_STOP_W3SVC,
  4299. &g_fW3SvcRunning);
  4300. if (S_OK != hr)
  4301. {
  4302. if (E_ABORT == hr)
  4303. {
  4304. fDontNext = TRUE;
  4305. goto done;
  4306. }
  4307. _JumpError(hr, error, "StartAndStopService");
  4308. }
  4309. done:
  4310. hr = S_OK;
  4311. error:
  4312. if (fCoInit)
  4313. {
  4314. CoUninitialize();
  4315. }
  4316. if (fDontNext)
  4317. {
  4318. SetWindowLongPtr(hDlg, DWLP_MSGRESULT, TRUE); // forbid
  4319. }
  4320. if (NULL != pwszCAName)
  4321. {
  4322. LocalFree(pwszCAName);
  4323. }
  4324. // if (NULL != pCAInfo)
  4325. {
  4326. // LocalFree(pCAInfo);
  4327. }
  4328. return hr;
  4329. }
  4330. HRESULT
  4331. HandleClientWizActive(
  4332. HWND hDlg,
  4333. PER_COMPONENT_DATA *pComp,
  4334. PAGESTRINGS *pPageString)
  4335. {
  4336. HRESULT hr;
  4337. // Suppress this wizard page if
  4338. // we've already seen an error, or
  4339. // the server is or will be installed, or
  4340. // the client isn't or won't be installed, or
  4341. // ther will be no change in client and server install states.
  4342. if ((IS_SERVER_ENABLED & pComp->dwInstallStatus) ||
  4343. !(IS_CLIENT_ENABLED & pComp->dwInstallStatus) ||
  4344. !((IS_CLIENT_CHANGE | IS_SERVER_CHANGE) & pComp->dwInstallStatus))
  4345. {
  4346. // disable page
  4347. CSILOGDWORD(IDS_CLIENT_TITLE, dwWIZDISABLE);
  4348. SetWindowLongPtr(hDlg, DWLP_MSGRESULT, -1);
  4349. goto done;
  4350. }
  4351. // load id info
  4352. hr = StartWizardPageEditControls(hDlg, pPageString);
  4353. _JumpIfError(hr, error, "StartWizardPageEditControls");
  4354. done:
  4355. hr = S_OK;
  4356. error:
  4357. return hr;
  4358. }
  4359. //+------------------------------------------------------------------------
  4360. // Function: WizClientPageDlgProc(. . . .)
  4361. //
  4362. // Synopsis: Dialog procedure for CA Client wiz-page
  4363. //-------------------------------------------------------------------------
  4364. INT_PTR
  4365. WizClientPageDlgProc(HWND hDlg, UINT iMsg, WPARAM wParam, LPARAM lParam)
  4366. {
  4367. PER_COMPONENT_DATA *pComp = NULL;
  4368. static BOOL s_fComputerChange = FALSE;
  4369. static PAGESTRINGS saClientPageString[] =
  4370. {
  4371. {
  4372. IDC_CLIENT_COMPUTERNAME,
  4373. IDS_LOG_COMPUTER,
  4374. IDS_CLIENT_NOCOMPUTER,
  4375. IDS_COMPUTERLENSTRERR,
  4376. MAX_PATH,
  4377. NULL,
  4378. },
  4379. // you need to add code in HookClientPageStrings if adding more...
  4380. {
  4381. 0,
  4382. 0,
  4383. 0,
  4384. 0,
  4385. 0,
  4386. NULL
  4387. }
  4388. };
  4389. switch(iMsg)
  4390. {
  4391. case WM_INITDIALOG:
  4392. // point to component data
  4393. SetWindowLongPtr(hDlg, DWLP_USER,
  4394. (LONG)((PROPSHEETPAGE*)lParam)->lParam);
  4395. pComp = (PER_COMPONENT_DATA*)((PROPSHEETPAGE*)lParam)->lParam;
  4396. _ReturnIfWizError(pComp->hrContinue);
  4397. pComp->hrContinue = InitClientWizControls(hDlg,
  4398. saClientPageString, pComp);
  4399. _ReturnIfWizError(pComp->hrContinue);
  4400. break;
  4401. case WM_COMMAND:
  4402. switch (LOWORD(wParam))
  4403. {
  4404. case IDC_CLIENT_BROWSECNFG:
  4405. pComp = _GetCompDataOrReturnIfError(pComp, hDlg);
  4406. pComp->hrContinue = GetCAConfigInfo(hDlg, pComp);
  4407. _ReturnIfWizError(pComp->hrContinue);
  4408. break;
  4409. case IDC_CLIENT_CANAME:
  4410. pComp = _GetCompDataOrReturnIfError(pComp, hDlg);
  4411. pComp->hrContinue = myUICAHandleCAListDropdown(
  4412. (int)HIWORD(wParam),
  4413. &g_WebClientUICASelection,
  4414. &s_fComputerChange);
  4415. _ReturnIfWizError(pComp->hrContinue);
  4416. break;
  4417. case IDC_CLIENT_COMPUTERNAME:
  4418. switch ((int)HIWORD(wParam))
  4419. {
  4420. case EN_CHANGE: // edit change
  4421. s_fComputerChange = TRUE;
  4422. break;
  4423. }
  4424. break;
  4425. }
  4426. break;
  4427. case WM_NOTIFY:
  4428. switch (((NMHDR FAR *) lParam)->code)
  4429. {
  4430. case PSN_KILLACTIVE:
  4431. break;
  4432. case PSN_RESET:
  4433. break;
  4434. case PSN_QUERYCANCEL:
  4435. pComp = _GetCompDataOrReturnIfError(pComp, hDlg);
  4436. return CertConfirmCancel(hDlg, pComp);
  4437. break;
  4438. case PSN_SETACTIVE:
  4439. CSILOGDWORD(IDS_CLIENT_TITLE, dwWIZACTIVE);
  4440. PropSheet_SetWizButtons(GetParent(hDlg), PSWIZB_BACK|PSWIZB_NEXT);
  4441. pComp = _GetCompDataOrReturn(pComp, hDlg);
  4442. _DisableWizDisplayIfError(pComp, hDlg);
  4443. _ReturnIfWizError(pComp->hrContinue);
  4444. pComp->hrContinue = HandleClientWizActive(hDlg, pComp, saClientPageString);
  4445. _ReturnIfWizError(pComp->hrContinue);
  4446. break;
  4447. case PSN_WIZBACK:
  4448. CSILOGDWORD(IDS_CLIENT_TITLE, dwWIZBACK);
  4449. pComp = _GetCompDataOrReturnIfError(pComp, hDlg);
  4450. // enable back
  4451. SetWindowLongPtr(hDlg, DWLP_MSGRESULT, 0);
  4452. pComp->hrContinue = HandleClientWizNextOrBack(hDlg,
  4453. saClientPageString, pComp, PSN_WIZBACK);
  4454. _ReturnIfWizError(pComp->hrContinue);
  4455. break;
  4456. case PSN_WIZNEXT:
  4457. CSILOGDWORD(IDS_CLIENT_TITLE, dwWIZNEXT);
  4458. pComp = _GetCompDataOrReturnIfError(pComp, hDlg);
  4459. pComp->hrContinue = HandleClientWizNextOrBack(hDlg,
  4460. saClientPageString, pComp, PSN_WIZNEXT);
  4461. _ReturnIfWizError(pComp->hrContinue);
  4462. break;
  4463. default:
  4464. return FALSE;
  4465. }
  4466. break;
  4467. default:
  4468. return FALSE;
  4469. }
  4470. return TRUE;
  4471. }
  4472. static CFont s_cBigBoldFont;
  4473. static BOOL s_fBigBoldFont;
  4474. BOOL ocmWiz97SetupFonts(HWND hwnd)
  4475. {
  4476. BOOL bReturn = FALSE;
  4477. //
  4478. // Create the fonts we need based on the dialog font
  4479. //
  4480. NONCLIENTMETRICS ncm = {0};
  4481. ncm.cbSize = sizeof (ncm);
  4482. SystemParametersInfo (SPI_GETNONCLIENTMETRICS, 0, &ncm, 0);
  4483. LOGFONT BigBoldLogFont = ncm.lfMessageFont;
  4484. //
  4485. // Create Big Bold Font and Bold Font
  4486. //
  4487. BigBoldLogFont.lfWeight = FW_BOLD;
  4488. WCHAR largeFontSizeString[24];
  4489. INT largeFontSize;
  4490. //
  4491. // Load size and name from resources, since these may change
  4492. // from locale to locale based on the size of the system font, etc.
  4493. //
  4494. if ( !::LoadString (g_hInstance, IDS_LARGEFONTNAME,
  4495. BigBoldLogFont.lfFaceName, LF_FACESIZE) )
  4496. {
  4497. CSASSERT (0);
  4498. lstrcpy (BigBoldLogFont.lfFaceName, L"MS Shell Dlg");
  4499. }
  4500. if ( ::LoadStringW (g_hInstance, IDS_LARGEFONTSIZE,
  4501. largeFontSizeString, ARRAYSIZE(largeFontSizeString)) )
  4502. {
  4503. largeFontSize = wcstoul (largeFontSizeString, NULL, 10);
  4504. }
  4505. else
  4506. {
  4507. CSASSERT (0);
  4508. largeFontSize = 12;
  4509. }
  4510. HDC hdc = GetDC(hwnd);
  4511. if (hdc)
  4512. {
  4513. BigBoldLogFont.lfHeight = 0 - (GetDeviceCaps(hdc, LOGPIXELSY) * largeFontSize / 72);
  4514. BOOL bBigBold = s_cBigBoldFont.CreateFontIndirect (&BigBoldLogFont);
  4515. ReleaseDC(hwnd, hdc);
  4516. if ( bBigBold )
  4517. bReturn = TRUE;
  4518. }
  4519. return bReturn;
  4520. }
  4521. HFONT ocmWiz97GetBigBoldFont(HWND hwnd)
  4522. {
  4523. if (FALSE == s_fBigBoldFont)
  4524. {
  4525. if (!ocmWiz97SetupFonts(hwnd))
  4526. return NULL;
  4527. s_fBigBoldFont = TRUE;
  4528. }
  4529. return s_cBigBoldFont;
  4530. }
  4531. //+------------------------------------------------------------------------
  4532. // Function: WizWelcomePageDlgProc(. . . .)
  4533. //
  4534. // Synopsis: Dialog procedure welcome wiz-page
  4535. //-------------------------------------------------------------------------
  4536. INT_PTR
  4537. WizWelcomePageDlgProc(HWND hDlg, UINT iMsg, WPARAM wParam, LPARAM lParam)
  4538. {
  4539. PER_COMPONENT_DATA *pComp = NULL;
  4540. HFONT hf;
  4541. switch(iMsg)
  4542. {
  4543. case WM_INITDIALOG:
  4544. // point to component data
  4545. SetWindowLongPtr(hDlg, DWLP_USER,
  4546. (LONG)((PROPSHEETPAGE*)lParam)->lParam);
  4547. pComp = (PER_COMPONENT_DATA*)((PROPSHEETPAGE*)lParam)->lParam;
  4548. // set wizard 97 fonts
  4549. hf = ocmWiz97GetBigBoldFont(hDlg);
  4550. if (NULL != hf)
  4551. SendMessage(GetDlgItem(hDlg, IDC_TEXT_BIGBOLD), WM_SETFONT, (WPARAM)hf, MAKELPARAM(TRUE, 0));
  4552. _ReturnIfWizError(pComp->hrContinue);
  4553. break;
  4554. case WM_NOTIFY:
  4555. switch (((NMHDR FAR *) lParam)->code)
  4556. {
  4557. case PSN_SETACTIVE:
  4558. // disable back button
  4559. PropSheet_SetWizButtons(GetParent(hDlg), PSWIZB_NEXT);
  4560. pComp = _GetCompDataOrReturn(pComp, hDlg);
  4561. _DisableWizDisplayIfError(pComp, hDlg);
  4562. _ReturnIfWizError(pComp->hrContinue);
  4563. break;
  4564. default:
  4565. return FALSE;
  4566. }
  4567. break;
  4568. default:
  4569. return FALSE;
  4570. }
  4571. return TRUE;
  4572. }
  4573. //+------------------------------------------------------------------------
  4574. // Function: WizFinalPageDlgProc(. . . .)
  4575. //
  4576. // Synopsis: Dialog procedure final wiz-page
  4577. //-------------------------------------------------------------------------
  4578. INT_PTR
  4579. WizFinalPageDlgProc(HWND hDlg, UINT iMsg, WPARAM wParam, LPARAM lParam)
  4580. {
  4581. PER_COMPONENT_DATA *pComp = NULL;
  4582. HFONT hf;
  4583. switch(iMsg)
  4584. {
  4585. case WM_INITDIALOG:
  4586. // point to component data
  4587. SetWindowLongPtr(hDlg, DWLP_USER,
  4588. (LONG)((PROPSHEETPAGE*)lParam)->lParam);
  4589. pComp = (PER_COMPONENT_DATA*)((PROPSHEETPAGE*)lParam)->lParam;
  4590. hf = ocmWiz97GetBigBoldFont(hDlg);
  4591. if (NULL != hf)
  4592. SendMessage(GetDlgItem(hDlg,IDC_TEXT_BIGBOLD), WM_SETFONT, (WPARAM)hf, MAKELPARAM(TRUE, 0));
  4593. _ReturnIfWizError(pComp->hrContinue);
  4594. break;
  4595. case WM_NOTIFY:
  4596. switch (((NMHDR FAR *) lParam)->code)
  4597. {
  4598. case PSN_SETACTIVE:
  4599. // enable finish button
  4600. PropSheet_SetWizButtons(GetParent(hDlg), PSWIZB_FINISH);
  4601. pComp = _GetCompDataOrReturn(pComp, hDlg);
  4602. // always display final wiz page
  4603. if (S_OK != pComp->hrContinue)
  4604. {
  4605. WCHAR *pwszFail = NULL;
  4606. HRESULT hr2 = myLoadRCString(
  4607. pComp->hInstance,
  4608. IDS_FINAL_ERROR_TEXT,
  4609. &pwszFail);
  4610. if (S_OK == hr2)
  4611. {
  4612. SetWindowText(GetDlgItem(hDlg, IDC_FINAL_STATUS),
  4613. pwszFail);
  4614. LocalFree(pwszFail);
  4615. }
  4616. else
  4617. {
  4618. // well, use hard code string
  4619. SetWindowText(GetDlgItem(hDlg, IDC_FINAL_STATUS),
  4620. L"Certificate Services Installation failed");
  4621. _PrintError(hr2, "myLoadRCString");
  4622. }
  4623. }
  4624. _ReturnIfWizError(pComp->hrContinue);
  4625. break;
  4626. default:
  4627. return FALSE;
  4628. }
  4629. break;
  4630. default:
  4631. return FALSE;
  4632. }
  4633. return TRUE;
  4634. }
  4635. // Map table for dialog template resource IDs and dialog proc pointers
  4636. WIZPAGERESENTRY aWizPageResources[] =
  4637. {
  4638. IDD_WIZCATYPEPAGE, WizCATypePageDlgProc,
  4639. IDS_CATYPE_TITLE, IDS_CATYPE_SUBTITLE,
  4640. IDD_WIZADVANCEDPAGE, WizAdvancedPageDlgProc,
  4641. IDS_ADVANCE_TITLE, IDS_ADVANCE_SUBTITLE,
  4642. IDD_WIZIDINFOPAGE, WizIdInfoPageDlgProc,
  4643. IDS_IDINFO_TITLE, IDS_IDINFO_SUBTITLE,
  4644. IDD_WIZKEYGENPAGE, WizKeyGenPageDlgProc,
  4645. IDS_KEYGEN_TITLE, IDS_KEYGEN_SUBTITLE,
  4646. IDD_WIZSTOREPAGE, WizStorePageDlgProc,
  4647. IDS_STORE_TITLE, IDS_STORE_SUBTITLE,
  4648. IDD_WIZCAREQUESTPAGE, WizCARequestPageDlgProc,
  4649. IDS_CAREQUEST_TITLE, IDS_CAREQUEST_SUBTITLE,
  4650. IDD_WIZCLIENTPAGE, WizClientPageDlgProc,
  4651. IDS_CLIENT_TITLE, IDS_CLIENT_SUBTITLE,
  4652. };
  4653. #define NUM_SERVERWIZPAGES sizeof(aWizPageResources)/sizeof(WIZPAGERESENTRY)
  4654. HRESULT
  4655. CreateCertsrvWizPage(
  4656. IN PER_COMPONENT_DATA *pComp,
  4657. IN int idTitle,
  4658. IN int idSubTitle,
  4659. IN int idDlgResource,
  4660. IN DLGPROC fnDlgProc,
  4661. IN BOOL fWelcomeFinal,
  4662. OUT HPROPSHEETPAGE *phPage)
  4663. {
  4664. HRESULT hr;
  4665. PROPSHEETPAGE Page;
  4666. WCHAR *pwszTitle = NULL;
  4667. WCHAR *pwszSubTitle = NULL;
  4668. // init
  4669. ZeroMemory(&Page, sizeof(PROPSHEETPAGE));
  4670. // construct page info
  4671. // Set titles
  4672. Page.dwFlags = PSP_DEFAULT;
  4673. if (fWelcomeFinal)
  4674. Page.dwFlags |= PSP_HIDEHEADER;
  4675. if (-1 != idTitle)
  4676. {
  4677. hr = myLoadRCString(pComp->hInstance,
  4678. idTitle,
  4679. &pwszTitle);
  4680. _JumpIfError(hr, error, "Internal Error");
  4681. Page.pszHeaderTitle = pwszTitle;
  4682. Page.dwFlags |= PSP_USEHEADERTITLE;
  4683. }
  4684. if (-1 != idSubTitle)
  4685. {
  4686. hr = myLoadRCString(pComp->hInstance,
  4687. idSubTitle,
  4688. &pwszSubTitle);
  4689. _JumpIfError(hr, error, "Internal Error");
  4690. Page.pszHeaderSubTitle = pwszSubTitle;
  4691. Page.dwFlags |= PSP_USEHEADERSUBTITLE;
  4692. }
  4693. // Set the basic property sheet data
  4694. Page.dwSize = sizeof(PROPSHEETPAGE); // + sizeof(MYWIZPAGE);
  4695. // Set up module and resource dependent data
  4696. Page.hInstance = pComp->hInstance;
  4697. Page.pszTemplate = MAKEINTRESOURCE(idDlgResource);
  4698. Page.pfnDlgProc = fnDlgProc;
  4699. Page.pfnCallback = NULL;
  4700. Page.pcRefParent = NULL;
  4701. Page.pszIcon = NULL;
  4702. Page.pszTitle = NULL;
  4703. Page.lParam = (LPARAM)pComp; // pass this to wizpage handlers
  4704. // Create the page
  4705. *phPage = CreatePropertySheetPage(&Page);
  4706. _JumpIfOutOfMemory(hr, error, *phPage);
  4707. hr = S_OK;
  4708. error:
  4709. if (NULL != pwszTitle)
  4710. {
  4711. LocalFree(pwszTitle);
  4712. }
  4713. if (NULL != pwszSubTitle)
  4714. {
  4715. LocalFree(pwszSubTitle);
  4716. }
  4717. return hr;
  4718. }
  4719. //+------------------------------------------------------------------------
  4720. //
  4721. // Function: DoPageRequest(. . . .)
  4722. //
  4723. // Synopsis: Handler for the OC_REQUEST_PAGES notification.
  4724. //
  4725. // Effects: Ponies up the pages for the OCM driven wizard to display.
  4726. //
  4727. // Arguments: [ComponentId] ID String for the component.
  4728. // [WhichOnes] Type specifier for requested pages.
  4729. // [SetupPages] Structure to receive page handles.
  4730. //
  4731. // Returns: DWORD count of pages returned or -1 (MAXDWORD) in case of
  4732. // failure; in this case SetLastError() will provide extended
  4733. // error information.
  4734. //
  4735. // History: 04/16/97 JerryK Unmangled
  4736. // 08/97 XTan major structure change
  4737. //
  4738. //-------------------------------------------------------------------------
  4739. DWORD
  4740. DoPageRequest(
  4741. IN PER_COMPONENT_DATA *pComp,
  4742. IN WIZPAGERESENTRY *pWizPageResources,
  4743. IN DWORD dwWizPageNum,
  4744. IN WizardPagesType WhichOnes,
  4745. IN OUT PSETUP_REQUEST_PAGES SetupPages)
  4746. {
  4747. DWORD dwPageNum = MAXDWORD;
  4748. HRESULT hr;
  4749. DWORD i;
  4750. if (pComp->fUnattended)
  4751. {
  4752. // don't create wiz page if unattended
  4753. return 0;
  4754. }
  4755. // handle welcome page
  4756. if (pComp->fPostBase && WizPagesWelcome == WhichOnes)
  4757. {
  4758. if (1 > SetupPages->MaxPages)
  4759. {
  4760. // ask ocm allocate enough pages
  4761. return 1; // only welcome, 1 page
  4762. }
  4763. hr = CreateCertsrvWizPage(
  4764. pComp,
  4765. IDS_WELCOME_TITLE, // title,
  4766. -1, // no sub-title
  4767. IDD_WIZWELCOMEPAGE,
  4768. WizWelcomePageDlgProc,
  4769. TRUE,
  4770. &SetupPages->Pages[0]);
  4771. _JumpIfError(hr, error, "CreateCertsrvWizPage");
  4772. return 1; // create 1 page
  4773. }
  4774. // handle final page
  4775. if (pComp->fPostBase && WizPagesFinal == WhichOnes)
  4776. {
  4777. if (1 > SetupPages->MaxPages)
  4778. {
  4779. // ask ocm allocate enough pages
  4780. return 1; // only final, 1 page
  4781. }
  4782. hr = CreateCertsrvWizPage(
  4783. pComp,
  4784. IDS_FINAL_TITLE, // title,
  4785. -1, // no sub-title
  4786. IDD_WIZFINALPAGE,
  4787. WizFinalPageDlgProc,
  4788. TRUE,
  4789. &SetupPages->Pages[0]);
  4790. _JumpIfError(hr, error, "CreateCertsrvWizPage");
  4791. return 1; // create 1 page
  4792. }
  4793. // from now on, we should only handle post net wiz pages
  4794. if (WizPagesPostnet != WhichOnes)
  4795. {
  4796. // ignore all others except postnet pages
  4797. return 0;
  4798. }
  4799. if (dwWizPageNum > SetupPages->MaxPages)
  4800. {
  4801. // OCM didn't allocate enough for pages, return # and ask more
  4802. return dwWizPageNum;
  4803. }
  4804. // Create the property sheet pages for the wizard
  4805. for (i = 0; i < dwWizPageNum; i++)
  4806. {
  4807. hr = CreateCertsrvWizPage(
  4808. pComp,
  4809. pWizPageResources[i].idTitle, // title,
  4810. pWizPageResources[i].idSubTitle, // sub-title
  4811. pWizPageResources[i].idResource,
  4812. pWizPageResources[i].fnDlgProc,
  4813. FALSE,
  4814. &SetupPages->Pages[i]);
  4815. _JumpIfError(hr, error, "CreateCertsrvWizPage");
  4816. }
  4817. dwPageNum = dwWizPageNum;
  4818. error:
  4819. return dwPageNum;
  4820. }
  4821. DWORD
  4822. myDoPageRequest(
  4823. IN PER_COMPONENT_DATA *pComp,
  4824. IN WizardPagesType WhichOnes,
  4825. IN OUT PSETUP_REQUEST_PAGES SetupPages)
  4826. {
  4827. pComp->CA.pServer->LastWiz = ENUM_WIZ_UNKNOWN;
  4828. return DoPageRequest(pComp,
  4829. aWizPageResources,
  4830. NUM_SERVERWIZPAGES,
  4831. WhichOnes,
  4832. SetupPages);
  4833. }
  4834. //+-------------------------------------------------------------------------
  4835. //
  4836. // Function: DirExists()
  4837. //
  4838. // Synopsis: Determines whether or not a directory already exists.
  4839. //
  4840. // Arguments: [pszTestFileName] -- Name of directory to test for.
  4841. //
  4842. // Returns: FALSE -- Directory doesn't exist
  4843. // DE_DIREXISTS -- Directory exists
  4844. // DE_NAMEINUSE -- Name in use by non-directory entity
  4845. //
  4846. // History: 10/23/96 JerryK Created
  4847. //
  4848. //--------------------------------------------------------------------------
  4849. int
  4850. DirExists(LPTSTR pszTestFileName)
  4851. {
  4852. DWORD dwFileAttrs;
  4853. int nRetVal;
  4854. // Get file attributes
  4855. dwFileAttrs = GetFileAttributes(pszTestFileName);
  4856. if (0xFFFFFFFF == dwFileAttrs) // Error code from GetFileAttributes
  4857. {
  4858. nRetVal = FALSE; // Couldn't open file
  4859. }
  4860. else if (dwFileAttrs & FILE_ATTRIBUTE_DIRECTORY)
  4861. {
  4862. nRetVal = DE_DIREXISTS; // Directory already exists
  4863. }
  4864. else
  4865. {
  4866. nRetVal = DE_NAMEINUSE; // Name in use by non-directory entity
  4867. }
  4868. return nRetVal;
  4869. }
  4870. BOOL
  4871. IsEverythingMatched(CASERVERSETUPINFO *pServer)
  4872. {
  4873. return pServer->fAdvance &&
  4874. (NULL!=pServer->pwszKeyContainerName) &&
  4875. NULL!=pServer->pccExistingCert;
  4876. }
  4877. //====================================================================
  4878. //
  4879. // CA info code
  4880. //
  4881. //
  4882. //====================================================================
  4883. WNDPROC g_pfnValidityWndProcs;
  4884. WNDPROC g_pfnIdInfoWndProcs;
  4885. HRESULT
  4886. GetValidityEditCount(
  4887. HWND hDlg,
  4888. DWORD *pdwPeriodCount)
  4889. {
  4890. HRESULT hr;
  4891. WCHAR *pwszPeriodCount = NULL;
  4892. BOOL fValidDigitString;
  4893. // init to 0
  4894. *pdwPeriodCount = 0;
  4895. hr = myUIGetWindowText(GetDlgItem(hDlg, IDC_IDINFO_EDIT_VALIDITYCOUNT),
  4896. &pwszPeriodCount);
  4897. _JumpIfError(hr, error, "myUIGetWindowText");
  4898. if (NULL != pwszPeriodCount)
  4899. {
  4900. *pdwPeriodCount = myWtoI(pwszPeriodCount, &fValidDigitString);
  4901. }
  4902. hr = S_OK;
  4903. error:
  4904. if (NULL != pwszPeriodCount)
  4905. {
  4906. LocalFree(pwszPeriodCount);
  4907. }
  4908. return hr;
  4909. }
  4910. HRESULT
  4911. UpdateExpirationDate(
  4912. HWND hDlg,
  4913. CASERVERSETUPINFO *pServer)
  4914. {
  4915. HRESULT hr;
  4916. WCHAR *pwszExpiration = NULL;
  4917. hr = GetValidityEditCount(hDlg, &pServer->dwValidityPeriodCount);
  4918. _JumpIfError(hr, error, "GetValidityEditCount");
  4919. if (0 < pServer->dwValidityPeriodCount)
  4920. {
  4921. if(!pServer->pccExistingCert)
  4922. {
  4923. GetSystemTimeAsFileTime(&pServer->NotBefore);
  4924. pServer->NotAfter = pServer->NotBefore;
  4925. myMakeExprDateTime(
  4926. &pServer->NotAfter,
  4927. pServer->dwValidityPeriodCount,
  4928. pServer->enumValidityPeriod);
  4929. }
  4930. hr = myGMTFileTimeToWszLocalTime(
  4931. &pServer->NotAfter,
  4932. FALSE,
  4933. &pwszExpiration);
  4934. _JumpIfError(hr, error, "myGMTFileTimeToWszLocalTime");
  4935. if (!SetWindowText(GetDlgItem(hDlg, IDC_IDINFO_EXPIRATION),
  4936. pwszExpiration))
  4937. {
  4938. hr = myHLastError();
  4939. _JumpError(hr, error, "SetWindowText");
  4940. }
  4941. }
  4942. hr = S_OK;
  4943. error:
  4944. if (NULL != pwszExpiration)
  4945. {
  4946. LocalFree(pwszExpiration);
  4947. }
  4948. return hr;
  4949. }
  4950. HRESULT
  4951. AddValidityString(
  4952. IN HINSTANCE hInstance,
  4953. const HWND hList,
  4954. const int ids,
  4955. ENUM_PERIOD enumValidityPeriod)
  4956. {
  4957. HRESULT hr;
  4958. WCHAR *pwsz = NULL;
  4959. LRESULT nIndex;
  4960. hr = myLoadRCString(hInstance, ids, &pwsz);
  4961. _JumpIfError(hr, error, "myLoadRCString");
  4962. // add string
  4963. nIndex = (INT)SendMessage(hList, CB_ADDSTRING, (WPARAM)0, (LPARAM)pwsz);
  4964. if (CB_ERR == nIndex)
  4965. {
  4966. hr = E_INVALIDARG;
  4967. _JumpError(hr, error, "SendMessage(CB_ADDSTRING)");
  4968. }
  4969. // set data
  4970. nIndex = (INT)SendMessage(hList, CB_SETITEMDATA, (WPARAM)nIndex, (LPARAM)enumValidityPeriod);
  4971. if (CB_ERR == nIndex)
  4972. {
  4973. hr = E_INVALIDARG;
  4974. _JumpError(hr, error, "SendMessage(CB_ADDSTRING)");
  4975. }
  4976. hr = S_OK;
  4977. error:
  4978. if (NULL != pwsz)
  4979. {
  4980. LocalFree(pwsz);
  4981. }
  4982. return hr;
  4983. }
  4984. HRESULT
  4985. SelectValidityString(
  4986. PER_COMPONENT_DATA *pComp,
  4987. HWND hList,
  4988. ENUM_PERIOD enumValidityPeriod)
  4989. {
  4990. HRESULT hr;
  4991. WCHAR *pwsz = NULL;
  4992. LRESULT nIndex;
  4993. LRESULT lr;
  4994. int id;
  4995. switch (enumValidityPeriod)
  4996. {
  4997. case ENUM_PERIOD_YEARS:
  4998. id = IDS_VALIDITY_YEAR;
  4999. break;
  5000. case ENUM_PERIOD_MONTHS:
  5001. id = IDS_VALIDITY_MONTH;
  5002. break;
  5003. case ENUM_PERIOD_WEEKS:
  5004. id = IDS_VALIDITY_WEEK;
  5005. break;
  5006. case ENUM_PERIOD_DAYS:
  5007. id = IDS_VALIDITY_DAY;
  5008. break;
  5009. default:
  5010. hr = E_INVALIDARG;
  5011. _JumpError(hr, error, "Invalid validity period enum");
  5012. break;
  5013. }
  5014. hr = myLoadRCString(pComp->hInstance, id, &pwsz);
  5015. _JumpIfError(hr, error, "myLoadRCString");
  5016. nIndex = (INT)SendMessage(hList, CB_FINDSTRING, (WPARAM)0, (LPARAM)pwsz);
  5017. if (CB_ERR == nIndex)
  5018. {
  5019. hr = E_INVALIDARG;
  5020. _JumpError(hr, error, "SendMessage(CB_FINDSTRING)");
  5021. }
  5022. lr = (INT)SendMessage(hList, CB_SETCURSEL, (WPARAM)nIndex, (LPARAM)0);
  5023. if (CB_ERR == lr)
  5024. {
  5025. hr = E_INVALIDARG;
  5026. _JumpError(hr, error, "SendMessage(CB_FINDSTRING)");
  5027. }
  5028. lr = (INT)SendMessage(hList, CB_GETITEMDATA, (WPARAM)nIndex, (LPARAM)0);
  5029. if (CB_ERR == lr)
  5030. {
  5031. hr = E_INVALIDARG;
  5032. _JumpError(hr, error, "SendMessage(CB_FINDSTRING)");
  5033. }
  5034. pComp->CA.pServer->enumValidityPeriod = (ENUM_PERIOD)lr;
  5035. hr = S_OK;
  5036. error:
  5037. if (pwsz)
  5038. LocalFree(pwsz);
  5039. return hr;
  5040. }
  5041. HRESULT
  5042. DetermineKeyExistence(
  5043. CSP_INFO *pCSPInfo,
  5044. WCHAR *pwszKeyName)
  5045. {
  5046. HRESULT hr;
  5047. HCRYPTPROV hProv = NULL;
  5048. if (!myCertSrvCryptAcquireContext(
  5049. &hProv,
  5050. pwszKeyName,
  5051. pCSPInfo->pwszProvName,
  5052. pCSPInfo->dwProvType,
  5053. CRYPT_SILENT,
  5054. TRUE))
  5055. {
  5056. hr = myHLastError();
  5057. goto error;
  5058. }
  5059. hr = S_OK;
  5060. error:
  5061. if (NULL != hProv)
  5062. {
  5063. CryptReleaseContext(hProv, 0);
  5064. }
  5065. return hr;
  5066. }
  5067. LRESULT CALLBACK
  5068. ValidityEditFilterHook(
  5069. HWND hwnd,
  5070. UINT iMsg,
  5071. WPARAM wParam,
  5072. LPARAM lParam)
  5073. {
  5074. int ret;
  5075. BOOL fUpdate = FALSE;
  5076. LRESULT lr;
  5077. CASERVERSETUPINFO *pServer = (CASERVERSETUPINFO*)GetWindowLongPtr(hwnd, GWLP_USERDATA);
  5078. switch(iMsg)
  5079. {
  5080. case WM_CHAR:
  5081. fUpdate = TRUE;
  5082. if (!iswdigit((TCHAR) wParam))
  5083. {
  5084. if (VK_BACK != (int)wParam)
  5085. {
  5086. // ignore the key
  5087. MessageBeep(0xFFFFFFFF);
  5088. return 0;
  5089. }
  5090. }
  5091. break;
  5092. case WM_KEYDOWN:
  5093. if (VK_DELETE == (int)wParam)
  5094. {
  5095. // validity is changed
  5096. fUpdate = TRUE;
  5097. }
  5098. break;
  5099. }
  5100. lr = CallWindowProc(
  5101. g_pfnValidityWndProcs,
  5102. hwnd,
  5103. iMsg,
  5104. wParam,
  5105. lParam);
  5106. if (fUpdate)
  5107. {
  5108. UpdateExpirationDate(GetParent(hwnd), pServer);
  5109. }
  5110. return lr;
  5111. }
  5112. HRESULT MakeNullStringEmpty(LPWSTR *ppwszStr)
  5113. {
  5114. if(!*ppwszStr)
  5115. return myDupString(L"", ppwszStr);
  5116. return S_OK;
  5117. }
  5118. HRESULT
  5119. HideAndShowMachineDNControls(
  5120. HWND hDlg,
  5121. CASERVERSETUPINFO *pServer)
  5122. {
  5123. HRESULT hr;
  5124. LPCWSTR pcwszDNSuffix;
  5125. hr = MakeNullStringEmpty(&pServer->pwszFullCADN);
  5126. _JumpIfError(hr, error, "MakeNullStringEmpty");
  5127. hr = MakeNullStringEmpty(&pServer->pwszCACommonName);
  5128. _JumpIfError(hr, error, "MakeNullStringEmpty");
  5129. hr = MakeNullStringEmpty(&pServer->pwszDNSuffix);
  5130. _JumpIfError(hr, error, "MakeNullStringEmpty");
  5131. SetDlgItemText(hDlg, IDC_IDINFO_NAMEEDIT, pServer->pwszCACommonName);
  5132. SetDlgItemText(hDlg, IDC_IDINFO_DNSUFFIXEDIT, pServer->pwszDNSuffix);
  5133. SetDlgItemText(hDlg, IDC_IDINFO_NAMEPREVIEW, pServer->pwszFullCADN);
  5134. // name preview is never editable
  5135. // EnableWindow(GetDlgItem(hDlg, IDC_IDINFO_NAMEPREVIEW), FALSE);
  5136. SendDlgItemMessage(hDlg, IDC_IDINFO_NAMEPREVIEW, EM_SETREADONLY, TRUE, 0);
  5137. // if we're in reuse cert mode, we can't edit the DNs
  5138. if (NULL != pServer->pccExistingCert)
  5139. {
  5140. // EnableWindow(GetDlgItem(hDlg, IDC_IDINFO_NAMEEDIT), FALSE);
  5141. // EnableWindow(GetDlgItem(hDlg, IDC_IDINFO_DNSUFFIXEDIT), FALSE);
  5142. SendDlgItemMessage(hDlg, IDC_IDINFO_NAMEEDIT, EM_SETREADONLY, TRUE, 0);
  5143. SendDlgItemMessage(hDlg, IDC_IDINFO_DNSUFFIXEDIT, EM_SETREADONLY, TRUE, 0);
  5144. }
  5145. else
  5146. {
  5147. // set the defaults again
  5148. // and re-enable everything else
  5149. // EnableWindow(GetDlgItem(hDlg, IDC_IDINFO_NAMEEDIT), TRUE);
  5150. // EnableWindow(GetDlgItem(hDlg, IDC_IDINFO_DNSUFFIXEDIT), TRUE);
  5151. SendDlgItemMessage(hDlg, IDC_IDINFO_NAMEEDIT, EM_SETREADONLY, FALSE, 0);
  5152. SendDlgItemMessage(hDlg, IDC_IDINFO_DNSUFFIXEDIT, EM_SETREADONLY, FALSE, 0);
  5153. // SendDlgItemMessage(hDlg, IDC_IDINFO_NAMEPREVIEW, EM_SETREADONLY, FALSE, 0);
  5154. }
  5155. hr = S_OK;
  5156. error:
  5157. return hr;
  5158. }
  5159. HRESULT InitNameFields(CASERVERSETUPINFO *pServer)
  5160. {
  5161. HRESULT hr;
  5162. CAutoLPWSTR pwsz;
  5163. const WCHAR *pwszFirstDCComponent = L"";
  5164. if(pServer->pccExistingCert)
  5165. {
  5166. }
  5167. else
  5168. {
  5169. if(!pServer->pwszCACommonName)
  5170. {
  5171. // avoid null name
  5172. hr = myDupString(L"", &pServer->pwszCACommonName);
  5173. _JumpIfError(hr, error, "myDupString");
  5174. }
  5175. hr = myGetComputerObjectName(NameFullyQualifiedDN, &pwsz);
  5176. _PrintIfError(hr, "myGetComputerObjectName");
  5177. if (S_OK == hr && pwsz != NULL)
  5178. {
  5179. pwszFirstDCComponent = wcsstr(pwsz, L"DC=");
  5180. }
  5181. if(pServer->pwszDNSuffix)
  5182. {
  5183. LocalFree(pServer->pwszDNSuffix);
  5184. pServer->pwszDNSuffix = NULL;
  5185. }
  5186. if(!pwszFirstDCComponent)
  5187. {
  5188. pwszFirstDCComponent = L"";
  5189. }
  5190. hr = myDupString(pwszFirstDCComponent, &pServer->pwszDNSuffix);
  5191. _JumpIfError(hr, error, "myDupString");
  5192. if(pServer->pwszFullCADN)
  5193. {
  5194. LocalFree(pServer->pwszFullCADN);
  5195. pServer->pwszFullCADN = NULL;
  5196. }
  5197. hr = BuildFullDN(
  5198. pServer->pwszCACommonName,
  5199. pwszFirstDCComponent,
  5200. &pServer->pwszFullCADN);
  5201. _JumpIfError(hr, error, "BuildFullDN");
  5202. }
  5203. error:
  5204. return hr;
  5205. }
  5206. // Builds full DN "CN=CAName,DistinguishedName" where CAName and DistinguishedName
  5207. // could be empty or NULL;
  5208. HRESULT BuildFullDN(
  5209. OPTIONAL LPCWSTR pcwszCAName,
  5210. OPTIONAL LPCWSTR pcwszDNSuffix,
  5211. LPWSTR* ppwszFullDN)
  5212. {
  5213. HRESULT hr = S_OK;
  5214. DWORD cBytes = 4; // 4 chars for leading "CN=" plus null terminator
  5215. CSASSERT(ppwszFullDN);
  5216. if(!EmptyString(pcwszCAName))
  5217. cBytes += wcslen(pcwszCAName);
  5218. if(!EmptyString(pcwszDNSuffix))
  5219. cBytes += wcslen(pcwszDNSuffix)+1; // comma
  5220. cBytes *= sizeof(WCHAR);
  5221. *ppwszFullDN = (LPWSTR) LocalAlloc(LMEM_FIXED, cBytes);
  5222. _JumpIfAllocFailed(*ppwszFullDN, error);
  5223. wcscpy(*ppwszFullDN, L"CN=");
  5224. if(!EmptyString(pcwszCAName))
  5225. {
  5226. wcscat(*ppwszFullDN, pcwszCAName);
  5227. }
  5228. if(!EmptyString(pcwszDNSuffix))
  5229. {
  5230. wcscat(*ppwszFullDN, L",");
  5231. wcscat(*ppwszFullDN, pcwszDNSuffix);
  5232. }
  5233. error:
  5234. return hr;
  5235. }
  5236. HRESULT
  5237. EnableValidityControls(HWND hDlg, BOOL fEnabled)
  5238. {
  5239. EnableWindow(GetDlgItem(hDlg, IDC_IDINFO_COMBO_VALIDITYSTRING), fEnabled);
  5240. EnableWindow(GetDlgItem(hDlg, IDC_IDINFO_EDIT_VALIDITYCOUNT), fEnabled);
  5241. return S_OK;
  5242. }
  5243. HRESULT
  5244. HideAndShowValidityControls(
  5245. HWND hDlg,
  5246. ENUM_CATYPES CAType)
  5247. {
  5248. // default to root ca
  5249. int showValidity = SW_SHOW;
  5250. int showHelp = SW_HIDE;
  5251. BOOL fEnableLabel = TRUE;
  5252. if (IsSubordinateCA(CAType))
  5253. {
  5254. showValidity = SW_HIDE;
  5255. showHelp = SW_SHOW;
  5256. fEnableLabel = FALSE;
  5257. }
  5258. ShowWindow(GetDlgItem(hDlg, IDC_IDINFO_DETERMINEDBYPCA), showHelp);
  5259. ShowWindow(GetDlgItem(hDlg, IDC_IDINFO_EDIT_VALIDITYCOUNT), showValidity);
  5260. ShowWindow(GetDlgItem(hDlg, IDC_IDINFO_COMBO_VALIDITYSTRING), showValidity);
  5261. ShowWindow(GetDlgItem(hDlg, IDC_IDINFO_EXPIRATION_LABEL), showValidity);
  5262. ShowWindow(GetDlgItem(hDlg, IDC_IDINFO_EXPIRATION), showValidity);
  5263. EnableWindow(GetDlgItem(hDlg, IDC_IDINFO_VPLABEL), fEnableLabel);
  5264. return S_OK;
  5265. }
  5266. HRESULT
  5267. InitValidityControls(
  5268. HWND hDlg,
  5269. PER_COMPONENT_DATA *pComp)
  5270. {
  5271. HRESULT hr;
  5272. HWND hwndCtrl = GetDlgItem(hDlg, IDC_IDINFO_COMBO_VALIDITYSTRING);
  5273. ENUM_PERIOD enumValidityPeriod = ENUM_PERIOD_YEARS;
  5274. WCHAR *pwsz = NULL;
  5275. CASERVERSETUPINFO *pServer = pComp->CA.pServer;
  5276. // load validity help text
  5277. hr = myLoadRCString(pComp->hInstance, IDS_IDINFO_DETERMINEDBYPCA, &pwsz);
  5278. _JumpIfError(hr, error, "LoadString");
  5279. if (!SetWindowText(GetDlgItem(hDlg, IDC_IDINFO_DETERMINEDBYPCA), pwsz))
  5280. {
  5281. hr = myHLastError();
  5282. _JumpError(hr, error, "SetWindowText");
  5283. }
  5284. // load validity period strings
  5285. hr = AddValidityString(pComp->hInstance, hwndCtrl, IDS_VALIDITY_YEAR,
  5286. ENUM_PERIOD_YEARS);
  5287. _JumpIfError(hr, error, "AddValidityString");
  5288. hr = AddValidityString(pComp->hInstance, hwndCtrl, IDS_VALIDITY_MONTH,
  5289. ENUM_PERIOD_MONTHS);
  5290. _JumpIfError(hr, error, "AddValidityString");
  5291. hr = AddValidityString(pComp->hInstance, hwndCtrl, IDS_VALIDITY_WEEK,
  5292. ENUM_PERIOD_WEEKS);
  5293. _JumpIfError(hr, error, "AddValidityString");
  5294. hr = AddValidityString(pComp->hInstance, hwndCtrl, IDS_VALIDITY_DAY,
  5295. ENUM_PERIOD_DAYS);
  5296. _JumpIfError(hr, error, "AddValidityString");
  5297. hr = S_OK;
  5298. error:
  5299. if (NULL != pwsz)
  5300. {
  5301. LocalFree(pwsz);
  5302. }
  5303. return hr;
  5304. }
  5305. HRESULT
  5306. EnableMatchedCertIdInfoEditFields(HWND hDlg, BOOL fEnable)
  5307. {
  5308. HRESULT hr;
  5309. EnableValidityControls(hDlg, fEnable);
  5310. hr = S_OK;
  5311. //error:
  5312. return hr;
  5313. }
  5314. HRESULT
  5315. WizIdInfoPageSetHooks(HWND hDlg, PER_COMPONENT_DATA *pComp)
  5316. {
  5317. HRESULT hr;
  5318. CSASSERT (NULL != pComp);
  5319. // CA Name filter proc
  5320. g_pfnIdInfoWndProcs =
  5321. (WNDPROC) SetWindowLongPtr(
  5322. GetDlgItem(hDlg, IDC_IDINFO_NAMEEDIT),
  5323. GWLP_WNDPROC,
  5324. (LPARAM)IdInfoNameEditFilterHook);
  5325. if (0 == g_pfnIdInfoWndProcs)
  5326. {
  5327. hr = myHLastError();
  5328. _JumpError(hr, error, "SetWindowLongPtr");
  5329. }
  5330. SetLastError(0);
  5331. if (0 == SetWindowLongPtr(
  5332. GetDlgItem(hDlg, IDC_IDINFO_NAMEEDIT),
  5333. GWLP_USERDATA,
  5334. (LPARAM)pComp->CA.pServer))
  5335. {
  5336. hr = myHLastError(); // might return S_OK
  5337. _JumpIfError(hr, error, "SetWindowLongPtr USERDATA");
  5338. }
  5339. hr = S_OK;
  5340. error:
  5341. return hr;
  5342. }
  5343. HRESULT
  5344. HandleValidityStringChange(
  5345. HWND hDlg,
  5346. CASERVERSETUPINFO *pServer)
  5347. {
  5348. HRESULT hr;
  5349. LRESULT nItem;
  5350. LRESULT lr;
  5351. HWND hwndCtrl = GetDlgItem(hDlg, IDC_IDINFO_COMBO_VALIDITYSTRING);
  5352. if (NULL == hwndCtrl)
  5353. {
  5354. hr = E_INVALIDARG;
  5355. _JumpError(hr, error, "Internal Error");
  5356. }
  5357. nItem = (INT)SendMessage(hwndCtrl, CB_GETCURSEL, (WPARAM)0, (LPARAM)0);
  5358. if (CB_ERR == nItem)
  5359. {
  5360. hr = E_INVALIDARG;
  5361. _JumpError(hr, error, "Internal Error");
  5362. }
  5363. lr = (INT)SendMessage(hwndCtrl, CB_GETITEMDATA, (WPARAM)nItem, (LPARAM)0);
  5364. if (CB_ERR == nItem)
  5365. {
  5366. hr = E_INVALIDARG;
  5367. _JumpError(hr, error, "Internal Error");
  5368. }
  5369. pServer->enumValidityPeriod = (ENUM_PERIOD)lr;
  5370. hr = UpdateExpirationDate(hDlg, pServer);
  5371. _JumpIfError(hr, error, "UpdateExpirationDate");
  5372. hr = S_OK;
  5373. error:
  5374. return hr;
  5375. }
  5376. HRESULT
  5377. HookIdInfoPageStrings(
  5378. HWND hDlg,
  5379. PAGESTRINGS *pPageString,
  5380. CASERVERSETUPINFO *pServer)
  5381. {
  5382. HRESULT hr;
  5383. for ( ; 0 != pPageString->idControl; pPageString++)
  5384. {
  5385. switch (pPageString->idControl)
  5386. {
  5387. case IDC_IDINFO_NAMEEDIT:
  5388. pPageString->ppwszString = &(pServer->pwszCACommonName);
  5389. break;
  5390. case IDC_IDINFO_EDIT_VALIDITYCOUNT:
  5391. pPageString->ppwszString = &(pServer->pwszValidityPeriodCount);
  5392. break;
  5393. default:
  5394. hr = E_INVALIDARG;
  5395. _JumpError(hr, error, "Internal error");
  5396. break;
  5397. }
  5398. }
  5399. hr = S_OK;
  5400. error:
  5401. return hr;
  5402. }
  5403. HRESULT
  5404. InitIdInfoWizControls(
  5405. HWND hDlg,
  5406. PAGESTRINGS *pIdPageString,
  5407. PER_COMPONENT_DATA *pComp)
  5408. {
  5409. HRESULT hr;
  5410. HWND hwndCtrl;
  5411. CASERVERSETUPINFO *pServer = pComp->CA.pServer;
  5412. // now make page strings complete
  5413. hr = HookIdInfoPageStrings(hDlg, pIdPageString, pServer);
  5414. _JumpIfError(hr, error, "HookIdInfoPageStrings");
  5415. hr = WizPageSetTextLimits(hDlg, pIdPageString);
  5416. _JumpIfError(hr, error, "WizPageSetTextLimits");
  5417. hr = WizIdInfoPageSetHooks(hDlg, pComp);
  5418. _JumpIfError(hr, error, "WizIdInfoPageSetHooks");
  5419. hr = InitValidityControls(hDlg, pComp);
  5420. _JumpIfError(hr, error, "InitValidityControls");
  5421. if (!IsSubordinateCA(pServer->CAType))
  5422. {
  5423. hwndCtrl = GetDlgItem(hDlg, IDC_IDINFO_EDIT_VALIDITYCOUNT);
  5424. g_pfnValidityWndProcs = (WNDPROC)SetWindowLongPtr(hwndCtrl,
  5425. GWLP_WNDPROC, (LPARAM)ValidityEditFilterHook);
  5426. if (NULL == g_pfnValidityWndProcs)
  5427. {
  5428. hr = myHLastError();
  5429. _JumpError(hr, error, "SetWindowLongPtr");
  5430. }
  5431. // pass data
  5432. SetWindowLongPtr(hwndCtrl, GWLP_USERDATA, (ULONG_PTR)pServer);
  5433. }
  5434. hr = S_OK;
  5435. error:
  5436. return hr;
  5437. }
  5438. HRESULT
  5439. UpdateValidityMaxDigits(
  5440. BOOL fMatchAll,
  5441. PAGESTRINGS *pIdPageString)
  5442. {
  5443. HRESULT hr;
  5444. for (; 0 != pIdPageString; pIdPageString++)
  5445. {
  5446. if (IDC_IDINFO_EDIT_VALIDITYCOUNT == pIdPageString->idControl)
  5447. {
  5448. pIdPageString->cchMax = fMatchAll? UB_VALIDITY_ANY : UB_VALIDITY;
  5449. break;
  5450. }
  5451. }
  5452. hr = S_OK;
  5453. //error:
  5454. return hr;
  5455. }
  5456. HRESULT
  5457. HandleIdInfoWizActive(
  5458. HWND hDlg,
  5459. PER_COMPONENT_DATA *pComp,
  5460. PAGESTRINGS *pIdPageString)
  5461. {
  5462. HRESULT hr;
  5463. WCHAR wszValidity[20];
  5464. CASERVERSETUPINFO *pServer = pComp->CA.pServer;
  5465. ENUM_PERIOD enumValidityPeriod = pServer->enumValidityPeriod;
  5466. BOOL fMatchAll;
  5467. // Suppress this wizard page if
  5468. // we've already seen an error, or
  5469. // we are not installing the server.
  5470. if (!(IS_SERVER_INSTALL & pComp->dwInstallStatus) )
  5471. {
  5472. // disable page
  5473. CSILOGDWORD(IDS_IDINFO_TITLE, dwWIZDISABLE);
  5474. SetWindowLongPtr(hDlg, DWLP_MSGRESULT, -1);
  5475. goto done;
  5476. }
  5477. if (ENUM_WIZ_STORE == pServer->LastWiz)
  5478. {
  5479. // if back from ca request, reset
  5480. g_fAllowUnicodeStrEncoding = FALSE;
  5481. }
  5482. if (pServer->fAdvance &&
  5483. ENUM_WIZ_KEYGEN == pServer->LastWiz &&
  5484. (pServer->fKeyGenFailed || pServer->fValidatedHashAndKey) )
  5485. {
  5486. // key gen failed and go back
  5487. PropSheet_PressButton(GetParent(hDlg), PSBTN_BACK);
  5488. }
  5489. if (!pServer->fAdvance && ENUM_WIZ_CATYPE == pServer->LastWiz)
  5490. {
  5491. hr = LoadDefaultAdvanceAttributes(pServer);
  5492. _JumpIfError(hr, error, "LoadDefaultAdvanceAttributes");
  5493. }
  5494. hr = HideAndShowValidityControls(hDlg, pServer->CAType);
  5495. _JumpIfError(hr, error, "HideAndShowValidityControls");
  5496. hr = HideAndShowMachineDNControls(hDlg, pServer);
  5497. _JumpIfError(hr, error, "HideAndShowMachineDNControls");
  5498. // load id info
  5499. hr = StartWizardPageEditControls(hDlg, pIdPageString);
  5500. _JumpIfError(hr, error, "StartWizardPageEditControls");
  5501. hr = EnableMatchedCertIdInfoEditFields(hDlg, TRUE);
  5502. _JumpIfError(hr, error, "EnableMatchedCertIdInfoEditFields");
  5503. // default
  5504. wsprintf(wszValidity, L"%u", pServer->dwValidityPeriodCount);
  5505. fMatchAll = IsEverythingMatched(pServer);
  5506. if (fMatchAll)
  5507. {
  5508. enumValidityPeriod = ENUM_PERIOD_DAYS;
  5509. wsprintf(wszValidity, L"%u", pServer->lExistingValidity);
  5510. hr = EnableMatchedCertIdInfoEditFields(hDlg, FALSE);
  5511. _JumpIfError(hr, error, "EnableMatchedCertIdInfoEditFields");
  5512. }
  5513. // update validity period string
  5514. hr = SelectValidityString(
  5515. pComp,
  5516. GetDlgItem(hDlg, IDC_IDINFO_COMBO_VALIDITYSTRING),
  5517. enumValidityPeriod);
  5518. _JumpIfError(hr, error, "SelectValidityString");
  5519. // update validity
  5520. SetWindowText(GetDlgItem(hDlg, IDC_IDINFO_EDIT_VALIDITYCOUNT), wszValidity);
  5521. hr = UpdateExpirationDate(hDlg, pServer);
  5522. _JumpIfError(hr, error, "UpdateExpirationDate");
  5523. // update validity digits max for validation
  5524. hr = UpdateValidityMaxDigits(fMatchAll, pIdPageString);
  5525. _JumpIfError(hr, error, "UpdateValidityMaxDigits");
  5526. EnableValidityControls(hDlg, !IsSubordinateCA(pServer->CAType) && !fMatchAll);
  5527. done:
  5528. hr = S_OK;
  5529. error:
  5530. return hr;
  5531. }
  5532. // check server RDN info, warning any invalid or
  5533. // or confirm from users once if any unicode string encoding
  5534. BOOL
  5535. IsAnyInvalidRDN(
  5536. OPTIONAL HWND hDlg,
  5537. PER_COMPONENT_DATA *pComp)
  5538. {
  5539. HRESULT hr = S_OK;
  5540. BOOL fInvalidRDN = TRUE;
  5541. BYTE *pbEncodedName = NULL;
  5542. DWORD cbEncodedName;
  5543. CERT_NAME_INFO *pbDecodedNameInfo = NULL;
  5544. DWORD cbDecodedNameInfo;
  5545. CERT_NAME_INFO *pNameInfo = NULL;
  5546. DWORD *pIndexRDN = NULL;
  5547. DWORD *pIndexAttr = NULL;
  5548. DWORD dwUnicodeCount;
  5549. WCHAR *pwszAllStrings = NULL;
  5550. CASERVERSETUPINFO *pServer = pComp->CA.pServer;
  5551. DWORD indexRDN;
  5552. DWORD indexAttr;
  5553. DWORD indexValue;
  5554. int idControl;
  5555. LPCWSTR pszErrorPtr = NULL;
  5556. // don't bother calling with CERT_NAME_STR_REVERSE_FLAG, we're just throwing this encoding away
  5557. hr = myCertStrToName(
  5558. X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
  5559. pServer->pwszDNSuffix,
  5560. CERT_X500_NAME_STR | CERT_NAME_STR_COMMA_FLAG,
  5561. NULL,
  5562. &pbEncodedName,
  5563. &cbEncodedName,
  5564. &pszErrorPtr);
  5565. if(S_OK != hr)
  5566. {
  5567. CertWarningMessageBox(
  5568. pComp->hInstance,
  5569. pComp->fUnattended,
  5570. hDlg,
  5571. IDS_WRN_IDINFO_INVALIDDN,
  5572. 0,
  5573. NULL);
  5574. int nStartIndex = 0;
  5575. int nEndIndex = wcslen(pServer->pwszDNSuffix);
  5576. if(pszErrorPtr)
  5577. {
  5578. nStartIndex = SAFE_SUBTRACT_POINTERS(pszErrorPtr,pServer->pwszDNSuffix);
  5579. const WCHAR *pwszNextComma = wcsstr(pszErrorPtr, L",");
  5580. if(pwszNextComma)
  5581. {
  5582. nEndIndex = SAFE_SUBTRACT_POINTERS(pwszNextComma,pServer->pwszDNSuffix+1);
  5583. }
  5584. }
  5585. SetEditFocusAndSelect(
  5586. GetDlgItem(hDlg, IDC_IDINFO_DNSUFFIXEDIT),
  5587. nStartIndex,
  5588. nEndIndex);
  5589. }
  5590. _JumpIfError(hr, error, "myCertStrToName");
  5591. // call CryptDecodeObject to get pbDecodedNameInfo
  5592. // if hit here, check if any unicode string encoding
  5593. if (!g_fAllowUnicodeStrEncoding && !pComp->fUnattended)
  5594. {
  5595. // decode to nameinfo
  5596. if (!myDecodeName(
  5597. X509_ASN_ENCODING,
  5598. X509_UNICODE_NAME,
  5599. pbEncodedName,
  5600. cbEncodedName,
  5601. CERTLIB_USE_LOCALALLOC,
  5602. &pbDecodedNameInfo,
  5603. &cbDecodedNameInfo))
  5604. {
  5605. hr = myHLastError();
  5606. _JumpError(hr, error, "myDecodeName");
  5607. }
  5608. // calculate attributes total in RDN
  5609. dwUnicodeCount = 0;
  5610. for (indexRDN = 0; indexRDN < pbDecodedNameInfo->cRDN; ++indexRDN)
  5611. {
  5612. dwUnicodeCount += pbDecodedNameInfo->rgRDN[indexRDN].cRDNAttr;
  5613. }
  5614. // allocate & init index
  5615. // sure allocate max for possible all unicode strings
  5616. pIndexRDN = (DWORD*)LocalAlloc(LMEM_FIXED | LMEM_ZEROINIT,
  5617. dwUnicodeCount * sizeof(DWORD));
  5618. _JumpIfOutOfMemory(hr, error, pIndexRDN);
  5619. pIndexAttr = (DWORD*)LocalAlloc(LMEM_FIXED | LMEM_ZEROINIT,
  5620. dwUnicodeCount * sizeof(DWORD));
  5621. _JumpIfOutOfMemory(hr, error, pIndexAttr);
  5622. dwUnicodeCount = 0; // reset count
  5623. for (indexRDN = 0; indexRDN < pbDecodedNameInfo->cRDN; ++indexRDN)
  5624. {
  5625. DWORD cRDNAttr = pbDecodedNameInfo->rgRDN[indexRDN].cRDNAttr;
  5626. CERT_RDN_ATTR *rgRDNAttr = pbDecodedNameInfo->rgRDN[indexRDN].rgRDNAttr;
  5627. // for each RDN
  5628. for (indexAttr = 0; indexAttr < cRDNAttr; indexAttr++)
  5629. {
  5630. // for each attr, check unicode string
  5631. switch (rgRDNAttr[indexAttr].dwValueType)
  5632. {
  5633. case CERT_RDN_UTF8_STRING:
  5634. case CERT_RDN_UNICODE_STRING:
  5635. // there is a unicode or UTF8 string, save index
  5636. pIndexRDN[dwUnicodeCount] = indexRDN;
  5637. pIndexAttr[dwUnicodeCount] = indexAttr;
  5638. // set count
  5639. ++dwUnicodeCount;
  5640. break;
  5641. }
  5642. }
  5643. }
  5644. if (0 == dwUnicodeCount)
  5645. {
  5646. // no unicode string encoding
  5647. goto done;
  5648. }
  5649. // calculate size of all unicode strings for display
  5650. DWORD dwLen = 0;
  5651. for (indexAttr = 0; indexAttr < dwUnicodeCount; ++indexAttr)
  5652. {
  5653. dwLen += (wcslen((WCHAR*)pbDecodedNameInfo->rgRDN[pIndexRDN[indexAttr]].rgRDNAttr[pIndexAttr[indexAttr]].Value.pbData) + 3 ) * sizeof(WCHAR);
  5654. }
  5655. pwszAllStrings = (WCHAR*)LocalAlloc(LMEM_FIXED, dwLen);
  5656. _JumpIfOutOfMemory(hr, error, pwszAllStrings);
  5657. // form all strings for display
  5658. for (indexAttr = 0; indexAttr < dwUnicodeCount; ++indexAttr)
  5659. {
  5660. if (0 == indexAttr)
  5661. {
  5662. wcscpy(pwszAllStrings, (WCHAR*)
  5663. pbDecodedNameInfo->rgRDN[pIndexRDN[indexAttr]].rgRDNAttr[pIndexAttr[indexAttr]].Value.pbData);
  5664. }
  5665. else
  5666. {
  5667. wcscat(pwszAllStrings, (WCHAR*)
  5668. pbDecodedNameInfo->rgRDN[pIndexRDN[indexAttr]].rgRDNAttr[pIndexAttr[indexAttr]].Value.pbData);
  5669. }
  5670. if (dwUnicodeCount - 1 > indexAttr)
  5671. {
  5672. // add comma + new line
  5673. wcscat(pwszAllStrings, L",\n");
  5674. }
  5675. }
  5676. // ok, ready to put out a warning
  5677. if (IDYES == CertMessageBox(
  5678. pComp->hInstance,
  5679. pComp->fUnattended,
  5680. hDlg,
  5681. IDS_WRN_UNICODESTRINGENCODING,
  5682. 0,
  5683. MB_YESNO |
  5684. MB_ICONWARNING |
  5685. CMB_NOERRFROMSYS,
  5686. NULL)) //pwszAllStrings))
  5687. {
  5688. // warning only once
  5689. g_fAllowUnicodeStrEncoding = TRUE;
  5690. goto done;
  5691. }
  5692. goto error;
  5693. }
  5694. done:
  5695. fInvalidRDN = FALSE;
  5696. error:
  5697. if (NULL != pIndexRDN)
  5698. {
  5699. LocalFree(pIndexRDN);
  5700. }
  5701. if (NULL != pIndexAttr)
  5702. {
  5703. LocalFree(pIndexAttr);
  5704. }
  5705. if (NULL != pwszAllStrings)
  5706. {
  5707. LocalFree(pwszAllStrings);
  5708. }
  5709. if (NULL != pbEncodedName)
  5710. {
  5711. LocalFree(pbEncodedName);
  5712. }
  5713. if (NULL != pbDecodedNameInfo)
  5714. {
  5715. LocalFree(pbDecodedNameInfo);
  5716. }
  5717. if (NULL != pNameInfo)
  5718. {
  5719. csiFreeCertNameInfo(pNameInfo);
  5720. }
  5721. return fInvalidRDN;
  5722. }
  5723. /*HRESULT ExtractCommonName(LPCWSTR pcwszDN, LPWSTR* ppwszCN)
  5724. {
  5725. HRESULT hr = S_OK;
  5726. WCHAR* pszComma;
  5727. LPWSTR pwszDNUpperCase = NULL;
  5728. const WCHAR* pszCN = pcwszDN;
  5729. if(0!=_wcsnicmp(pcwszDN, L"CN=", wcslen(L"CN=")))
  5730. {
  5731. hr = E_INVALIDARG;
  5732. _JumpError(hr, error,
  5733. "distinguished name doesn't start with the common name");
  5734. }
  5735. pszCN += wcslen(L"CN=");
  5736. while(iswspace(*pszCN))
  5737. pszCN++;
  5738. pszComma = wcsstr(pszCN, L",");
  5739. DWORD iChars;
  5740. if (pszComma == NULL)
  5741. {
  5742. // ONLY CN= string, no additional names
  5743. iChars = wcslen(pszCN);
  5744. }
  5745. else
  5746. {
  5747. iChars = SAFE_SUBTRACT_POINTERS(pszComma, pszCN);
  5748. }
  5749. if(0==iChars)
  5750. {
  5751. hr = E_INVALIDARG;
  5752. _JumpError(hr, error,
  5753. "invalid syntax, common name should follow CN=");
  5754. }
  5755. *ppwszCN = (LPWSTR)LocalAlloc(LMEM_FIXED, (iChars+1)*sizeof(WCHAR));
  5756. _JumpIfAllocFailed(*ppwszCN, error);
  5757. CopyMemory(*ppwszCN, pszCN, iChars*sizeof(WCHAR));
  5758. (*ppwszCN)[iChars] = L'\0';
  5759. error:
  5760. LOCAL_FREE(pwszDNUpperCase);
  5761. return hr;
  5762. }*/
  5763. HRESULT
  5764. HandleIdInfoWizNextOrBack(
  5765. HWND hDlg,
  5766. PER_COMPONENT_DATA *pComp,
  5767. PAGESTRINGS *pIdPageString,
  5768. int iWizBN)
  5769. {
  5770. HRESULT hr;
  5771. WCHAR *pwszSanitizedName = NULL;
  5772. CASERVERSETUPINFO *pServer = pComp->CA.pServer;
  5773. BOOL fDontNext = FALSE;
  5774. WCHAR wszCountryCode[cchCOUNTRYNAMEMAX+1];
  5775. HWND hwnd;
  5776. DWORD size;
  5777. DWORD i;
  5778. BOOL fValidDigitString;
  5779. WCHAR * pwszFullPath = NULL;
  5780. WCHAR * pwszDir = NULL;
  5781. DWORD cDirLen;
  5782. hr = FinishWizardPageEditControls(hDlg, pIdPageString);
  5783. _JumpIfError(hr, error, "FinishWizardPageEditControls");
  5784. if (PSN_WIZBACK == iWizBN)
  5785. {
  5786. goto done;
  5787. }
  5788. hr = WizardPageValidation(pComp->hInstance, pComp->fUnattended,
  5789. hDlg, pIdPageString);
  5790. if (S_OK != hr)
  5791. {
  5792. _PrintError(hr, "WizardPageValidation");
  5793. fDontNext = TRUE;
  5794. goto done;
  5795. }
  5796. // snag the full DN specified
  5797. if (NULL != pServer->pwszCACommonName)
  5798. {
  5799. LocalFree(pServer->pwszCACommonName);
  5800. pServer->pwszCACommonName = NULL;
  5801. }
  5802. if (NULL != pServer->pwszFullCADN)
  5803. {
  5804. LocalFree(pServer->pwszFullCADN);
  5805. pServer->pwszFullCADN = NULL;
  5806. }
  5807. if (NULL != pServer->pwszDNSuffix)
  5808. {
  5809. LocalFree(pServer->pwszDNSuffix);
  5810. pServer->pwszDNSuffix = NULL;
  5811. }
  5812. myUIGetWindowText(GetDlgItem(hDlg, IDC_IDINFO_NAMEEDIT), &pServer->pwszCACommonName);
  5813. myUIGetWindowText(GetDlgItem(hDlg, IDC_IDINFO_NAMEPREVIEW), &pServer->pwszFullCADN);
  5814. myUIGetWindowText(GetDlgItem(hDlg, IDC_IDINFO_DNSUFFIXEDIT), &pServer->pwszDNSuffix);
  5815. // if generate a new cert
  5816. if (NULL == pServer->pccExistingCert &&
  5817. IsAnyInvalidRDN(hDlg, pComp))
  5818. {
  5819. fDontNext = TRUE;
  5820. goto done;
  5821. }
  5822. // if we are not using an existing cert, verify the chosen validity
  5823. // period of the new cert.
  5824. if (NULL==pServer->pccExistingCert)
  5825. {
  5826. // convert validity count string to a number
  5827. pServer->dwValidityPeriodCount = myWtoI(
  5828. pServer->pwszValidityPeriodCount,
  5829. &fValidDigitString);
  5830. if (!fValidDigitString ||
  5831. !IsValidPeriod(pServer))
  5832. {
  5833. // validity out of range, put out a warning dlg
  5834. CertWarningMessageBox(
  5835. pComp->hInstance,
  5836. pComp->fUnattended,
  5837. hDlg,
  5838. IDS_IDINFO_INVALID_VALIDITY,
  5839. 0,
  5840. NULL);
  5841. SetEditFocusAndSelect(GetDlgItem(hDlg, IDC_IDINFO_EDIT_VALIDITYCOUNT), 0, -1);
  5842. _PrintError(E_INVALIDARG, "invalid validity");
  5843. fDontNext = TRUE;
  5844. goto done;
  5845. }
  5846. }
  5847. // get sanitized name
  5848. hr = mySanitizeName(pServer->pwszCACommonName, &pwszSanitizedName);
  5849. _JumpIfError(hr, error, "mySanitizeName");
  5850. CSILOG(
  5851. hr,
  5852. IDS_ILOG_SANITIZEDNAME,
  5853. pwszSanitizedName,
  5854. NULL,
  5855. NULL);
  5856. if (MAX_PATH <= wcslen(pwszSanitizedName) + cwcSUFFIXMAX)
  5857. {
  5858. CertMessageBox(
  5859. pComp->hInstance,
  5860. pComp->fUnattended,
  5861. hDlg,
  5862. IDS_WRN_KEYNAMETOOLONG,
  5863. S_OK,
  5864. MB_ICONWARNING | CMB_NOERRFROMSYS,
  5865. pwszSanitizedName);
  5866. SetEditFocusAndSelect(GetDlgItem(hDlg, IDC_IDINFO_NAMEEDIT), 0, -1);
  5867. fDontNext = TRUE;
  5868. goto done;
  5869. }
  5870. // if we are making a new key, see if a key by that name already exists.
  5871. // if it does, see if the user wants to overwrite it.
  5872. if (NULL == pServer->pwszKeyContainerName)
  5873. {
  5874. if (S_OK == DetermineKeyExistence(pServer->pCSPInfo, pwszSanitizedName))
  5875. {
  5876. // warn user if key exist
  5877. if (IDYES != CertMessageBox(
  5878. pComp->hInstance,
  5879. pComp->fUnattended,
  5880. hDlg,
  5881. IDS_WRN_OVERWRITEEXISTINGKEY,
  5882. S_OK,
  5883. MB_YESNO |
  5884. MB_ICONWARNING |
  5885. MB_DEFBUTTON2 |
  5886. CMB_NOERRFROMSYS,
  5887. pServer->pwszCACommonName))
  5888. {
  5889. SetEditFocusAndSelect(GetDlgItem(hDlg, IDC_IDINFO_NAMEEDIT), 0, -1);
  5890. fDontNext = TRUE;
  5891. goto done;
  5892. }
  5893. }
  5894. }
  5895. if (NULL != pServer->pwszSanitizedName)
  5896. {
  5897. // free old
  5898. LocalFree(pServer->pwszSanitizedName);
  5899. }
  5900. pServer->pwszSanitizedName = pwszSanitizedName;
  5901. pwszSanitizedName = NULL;
  5902. if (pServer->fUseDS)
  5903. {
  5904. if (IsCAExistInDS(pServer->pwszSanitizedName))
  5905. {
  5906. int ret = CertMessageBox(
  5907. pComp->hInstance,
  5908. pComp->fUnattended,
  5909. hDlg,
  5910. IDS_IDINFO_CAEXISTINDS,
  5911. 0,
  5912. MB_YESNO |
  5913. MB_ICONWARNING |
  5914. CMB_NOERRFROMSYS,
  5915. NULL);
  5916. if (IDYES != ret)
  5917. {
  5918. // not overwrite
  5919. SetEditFocusAndSelect(GetDlgItem(hDlg, IDC_IDINFO_NAMEEDIT), 0, -1);
  5920. fDontNext = TRUE;
  5921. goto done;
  5922. }
  5923. else
  5924. {
  5925. hr = RemoveCAInDS(pServer->pwszSanitizedName);
  5926. if(hr != S_OK)
  5927. {
  5928. _PrintError(hr, "RemoveCAInDS");
  5929. SetEditFocusAndSelect(GetDlgItem(hDlg, IDC_IDINFO_NAMEEDIT), 0, -1);
  5930. fDontNext = TRUE;
  5931. goto done;
  5932. }
  5933. }
  5934. }
  5935. }
  5936. hr = UpdateDomainAndUserName(hDlg, pComp);
  5937. _JumpIfError(hr, error, "UpdateDomainAndUserName");
  5938. if(pServer->fUseDS)
  5939. {
  5940. pServer->dwRevocationFlags = REVEXT_DEFAULT_DS;
  5941. }
  5942. else
  5943. {
  5944. pServer->dwRevocationFlags = REVEXT_DEFAULT_NODS;
  5945. }
  5946. // validate cert file path lenght
  5947. cDirLen = wcslen(pComp->pwszSystem32)+
  5948. wcslen(wszCERTENROLLSHAREPATH) + 1;
  5949. pwszDir = (WCHAR *) LocalAlloc(LMEM_FIXED, cDirLen * sizeof(WCHAR));
  5950. if (NULL == pwszDir)
  5951. {
  5952. hr = E_OUTOFMEMORY;
  5953. _JumpError(hr, error, "LocalAlloc");
  5954. }
  5955. wcscpy(pwszDir, pComp->pwszSystem32); // has trailing "\\"
  5956. wcscat(pwszDir, wszCERTENROLLSHAREPATH);
  5957. hr = csiBuildFileName(
  5958. pwszDir,
  5959. pServer->pwszSanitizedName,
  5960. L".crt",
  5961. 0,
  5962. &pwszFullPath,
  5963. pComp->hInstance,
  5964. pComp->fUnattended,
  5965. hDlg);
  5966. _JumpIfError(hr, error, "csiBuildFileName");
  5967. if (MAX_PATH <= wcslen(pwszFullPath) + cwcSUFFIXMAX)
  5968. {
  5969. // pop up warning
  5970. CertWarningMessageBox(
  5971. pComp->hInstance,
  5972. pComp->fUnattended,
  5973. hDlg,
  5974. IDS_PATH_TOO_LONG_CANAME,
  5975. S_OK,
  5976. pwszFullPath);
  5977. fDontNext = TRUE;
  5978. goto done;
  5979. }
  5980. done:
  5981. if (fDontNext)
  5982. {
  5983. SetWindowLongPtr(hDlg, DWLP_MSGRESULT, TRUE); // forbid
  5984. }
  5985. else
  5986. {
  5987. pServer->LastWiz = ENUM_WIZ_IDINFO;
  5988. }
  5989. hr = S_OK;
  5990. error:
  5991. if (NULL != pwszSanitizedName)
  5992. {
  5993. LocalFree(pwszSanitizedName);
  5994. }
  5995. if(NULL != pwszFullPath)
  5996. {
  5997. LocalFree(pwszFullPath);
  5998. }
  5999. if(NULL != pwszDir)
  6000. {
  6001. LocalFree(pwszDir);
  6002. }
  6003. return hr;
  6004. }
  6005. PAGESTRINGS g_aIdPageString[] =
  6006. {
  6007. {
  6008. IDC_IDINFO_NAMEEDIT,
  6009. IDS_LOG_CANAME,
  6010. IDS_IDINFO_NAMENULLSTRERR,
  6011. IDS_IDINFO_NAMELENSTRERR,
  6012. cchCOMMONNAMEMAX,
  6013. NULL,
  6014. },
  6015. {
  6016. IDC_IDINFO_EDIT_VALIDITYCOUNT,
  6017. IDS_LOG_VALIDITY,
  6018. IDS_IDINFO_VALIDITYNULLSTRERR,
  6019. IDS_IDINFO_VALIDITYLENSTRERR,
  6020. UB_VALIDITY,
  6021. NULL,
  6022. },
  6023. // you need to add code in HookIdInfoPageStrings if adding more...
  6024. {
  6025. 0,
  6026. 0,
  6027. 0,
  6028. 0,
  6029. 0,
  6030. NULL,
  6031. }
  6032. };
  6033. LRESULT CALLBACK
  6034. IdInfoNameEditFilterHook(
  6035. HWND hwnd,
  6036. UINT iMsg,
  6037. WPARAM wParam,
  6038. LPARAM lParam)
  6039. {
  6040. WCHAR rgchUpper[] = {'\0', '\0'};
  6041. switch(iMsg)
  6042. {
  6043. case WM_CHAR:
  6044. if ((WCHAR)wParam == L',')
  6045. {
  6046. MessageBeep(0xFFFFFFFF);
  6047. return 0;
  6048. break;
  6049. }
  6050. break;
  6051. default:
  6052. break;
  6053. }
  6054. return CallWindowProc(g_pfnIdInfoWndProcs,
  6055. hwnd,
  6056. iMsg,
  6057. wParam,
  6058. lParam);
  6059. return 0;
  6060. }
  6061. //-------------------------------------------------------------------------
  6062. // WizIdInfoPageDlgProc
  6063. //-------------------------------------------------------------------------
  6064. INT_PTR
  6065. WizIdInfoPageDlgProc(HWND hDlg, UINT iMsg, WPARAM wParam, LPARAM lParam)
  6066. {
  6067. PER_COMPONENT_DATA *pComp = NULL;
  6068. switch(iMsg)
  6069. {
  6070. case WM_INITDIALOG:
  6071. // point to component data
  6072. SetWindowLongPtr(hDlg, DWLP_USER,
  6073. (ULONG_PTR)((PROPSHEETPAGE*)lParam)->lParam);
  6074. pComp = (PER_COMPONENT_DATA*)(ULONG_PTR)((PROPSHEETPAGE*)lParam)->lParam;
  6075. _ReturnIfWizError(pComp->hrContinue);
  6076. pComp->hrContinue = InitIdInfoWizControls(hDlg,
  6077. g_aIdPageString,
  6078. pComp);
  6079. _ReturnIfWizError(pComp->hrContinue);
  6080. break;
  6081. case WM_COMMAND:
  6082. switch (LOWORD(wParam))
  6083. {
  6084. case IDC_IDINFO_NAMEEDIT:
  6085. case IDC_IDINFO_DNSUFFIXEDIT:
  6086. if (HIWORD(wParam) == EN_CHANGE)
  6087. {
  6088. CAutoLPWSTR pwszCAName, pwszDNSuffix, pwszFullDN;
  6089. CASERVERSETUPINFO* pServer;
  6090. pComp = _GetCompDataOrReturnIfError(pComp, hDlg);
  6091. pServer = pComp->CA.pServer;
  6092. // if using existing certs ignore the notification
  6093. // to avoid building the full DN
  6094. if(pServer->pccExistingCert)
  6095. {
  6096. break;
  6097. }
  6098. pComp->hrContinue = myUIGetWindowText(
  6099. GetDlgItem(hDlg, IDC_IDINFO_NAMEEDIT),
  6100. &pwszCAName);
  6101. _ReturnIfWizError(pComp->hrContinue);
  6102. pComp->hrContinue = myUIGetWindowText(
  6103. GetDlgItem(hDlg, IDC_IDINFO_DNSUFFIXEDIT),
  6104. &pwszDNSuffix);
  6105. _ReturnIfWizError(pComp->hrContinue);
  6106. pComp->hrContinue = BuildFullDN(
  6107. pwszCAName,
  6108. pwszDNSuffix,
  6109. &pwszFullDN);
  6110. _ReturnIfWizError(pComp->hrContinue);
  6111. SetDlgItemText(
  6112. hDlg,
  6113. IDC_IDINFO_NAMEPREVIEW,
  6114. pwszFullDN);
  6115. }
  6116. break;
  6117. case IDC_IDINFO_EDIT_VALIDITYCOUNT:
  6118. break;
  6119. case IDC_IDINFO_COMBO_VALIDITYSTRING:
  6120. switch (HIWORD(wParam))
  6121. {
  6122. case CBN_SELCHANGE:
  6123. pComp = _GetCompDataOrReturnIfError(pComp, hDlg);
  6124. pComp->hrContinue = HandleValidityStringChange(
  6125. hDlg,
  6126. pComp->CA.pServer);
  6127. _ReturnIfWizError(pComp->hrContinue);
  6128. break;
  6129. }
  6130. break;
  6131. }
  6132. break;
  6133. case WM_NOTIFY:
  6134. switch (((NMHDR FAR *) lParam)->code)
  6135. {
  6136. case PSN_KILLACTIVE:
  6137. break;
  6138. case PSN_RESET:
  6139. break;
  6140. case PSN_QUERYCANCEL:
  6141. pComp = _GetCompDataOrReturnIfError(pComp, hDlg);
  6142. return CertConfirmCancel(hDlg, pComp);
  6143. break;
  6144. case PSN_SETACTIVE:
  6145. CSILOGDWORD(IDS_IDINFO_TITLE, dwWIZACTIVE);
  6146. PropSheet_SetWizButtons(GetParent(hDlg), PSWIZB_BACK|PSWIZB_NEXT);
  6147. pComp = _GetCompDataOrReturn(pComp, hDlg);
  6148. _DisableWizDisplayIfError(pComp, hDlg);
  6149. _ReturnIfWizError(pComp->hrContinue);
  6150. pComp->hrContinue = HandleIdInfoWizActive(hDlg,
  6151. pComp,
  6152. g_aIdPageString);
  6153. _ReturnIfWizError(pComp->hrContinue);
  6154. break;
  6155. case PSN_WIZBACK:
  6156. CSILOGDWORD(IDS_IDINFO_TITLE, dwWIZBACK);
  6157. pComp = _GetCompDataOrReturnIfError(pComp, hDlg);
  6158. pComp->hrContinue = HandleIdInfoWizNextOrBack(
  6159. hDlg, pComp, g_aIdPageString, PSN_WIZBACK);
  6160. _ReturnIfWizError(pComp->hrContinue);
  6161. break;
  6162. case PSN_WIZNEXT:
  6163. CSILOGDWORD(IDS_IDINFO_TITLE, dwWIZNEXT);
  6164. pComp = _GetCompDataOrReturnIfError(pComp, hDlg);
  6165. pComp->hrContinue = HandleIdInfoWizNextOrBack(
  6166. hDlg, pComp, g_aIdPageString, PSN_WIZNEXT);
  6167. _ReturnIfWizError(pComp->hrContinue);
  6168. break;
  6169. default:
  6170. return FALSE;
  6171. }
  6172. break;
  6173. default:
  6174. return FALSE;
  6175. }
  6176. return TRUE;
  6177. }