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

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