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.

2965 lines
90 KiB

  1. // This is a part of the Microsoft Management Console.
  2. // Copyright (C) Microsoft Corporation, 1995 - 1999
  3. // All rights reserved.
  4. //
  5. // This source code is only intended as a supplement to the
  6. // Microsoft Management Console and related
  7. // electronic documentation provided with the interfaces.
  8. #include "stdafx.h"
  9. #include "setupids.h"
  10. #include "resource.h"
  11. #include "genpage.h"
  12. #include "chooser.h"
  13. #include "misc.h"
  14. #include "csdisp.h" // picker
  15. #include <esent.h> // database error
  16. #include <aclui.h>
  17. #include <winldap.h>
  18. #include "csldap.h"
  19. #include <atlimpl.cpp>
  20. #define __dwFILE__ __dwFILE_CERTMMC_COMPDATA_CPP__
  21. #ifdef _DEBUG
  22. #undef THIS_FILE
  23. static char THIS_FILE[] = __FILE__;
  24. #endif
  25. struct FOLDER_DATA
  26. {
  27. FOLDER_TYPES type;
  28. UINT iNameRscID;
  29. };
  30. static FOLDER_DATA SvrFuncFolderData[] =
  31. {
  32. {SERVERFUNC_CRL_PUBLICATION, IDS_CERTS_REVOKED},
  33. {SERVERFUNC_ISSUED_CERTIFICATES, IDS_CERTS_ISSUED},
  34. {SERVERFUNC_PENDING_CERTIFICATES, IDS_CERTS_PENDING},
  35. {SERVERFUNC_FAILED_CERTIFICATES, IDS_CERTS_FAILED},
  36. {SERVERFUNC_ALIEN_CERTIFICATES, IDS_CERTS_IMPORTED},
  37. {SERVERFUNC_ISSUED_CRLS, IDS_CRL_TITLE},
  38. };
  39. // keep this enum in synch with SvrFuncFolderData[]
  40. enum ENUM_FOLDERS
  41. {
  42. ENUM_FOLDER_CRL=0,
  43. ENUM_FOLDER_ISSUED,
  44. ENUM_FOLDER_PENDING,
  45. ENUM_FOLDER_FAILED,
  46. ENUM_FOLDER_ALIEN,
  47. ENUM_FOLDER_CRLS,
  48. };
  49. // Array of view items to be inserted into the context menu.
  50. // keep this enum in synch with viewItems[]
  51. enum ENUM_TASK_STARTSTOP_ITEMS
  52. {
  53. ENUM_TASK_START=0,
  54. ENUM_TASK_STOP,
  55. ENUM_TASK_SEPERATOR,
  56. };
  57. MY_CONTEXTMENUITEM taskStartStop[] =
  58. {
  59. {
  60. {
  61. L"", L"",
  62. IDC_STARTSERVER, CCM_INSERTIONPOINTID_PRIMARY_TASK, 0, 0
  63. },
  64. IDS_TASKMENU_STARTSERVICE,
  65. IDS_TASKMENU_STATUSBAR_STARTSERVICE,
  66. CA_ACCESS_ADMIN,
  67. },
  68. {
  69. {
  70. L"", L"",
  71. IDC_STOPSERVER, CCM_INSERTIONPOINTID_PRIMARY_TASK, 0, 0
  72. },
  73. IDS_TASKMENU_STOPSERVICE,
  74. IDS_TASKMENU_STATUSBAR_STOPSERVICE,
  75. CA_ACCESS_ADMIN,
  76. },
  77. {
  78. { NULL, NULL, 0, 0, 0 },
  79. IDS_EMPTY,
  80. IDS_EMPTY,
  81. },
  82. };
  83. // Array of view items to be inserted into the context menu.
  84. // WARNING: keep this enum in synch with taskItems[]
  85. enum ENUM_TASK_ITEMS
  86. {
  87. ENUM_TASK_CRLPUB=0,
  88. ENUM_TASK_ATTREXTS_CRL,
  89. ENUM_TASK_ATTREXTS_ISS,
  90. ENUM_TASK_ATTREXTS_PEND,
  91. ENUM_TASK_ATTREXTS_FAIL,
  92. ENUM_TASK_DUMP_ASN_CRLPUB,
  93. ENUM_TASK_DUMP_ASN_ISS,
  94. ENUM_TASK_DUMP_ASN_PEND,
  95. ENUM_TASK_DUMP_ASN_FAIL,
  96. ENUM_TASK_DUMP_ASN_ALIEN,
  97. ENUM_TASK_DUMP_ASN_CRL,
  98. ENUM_TASK_SEPERATOR1,
  99. ENUM_TASK_SEPERATOR4,
  100. ENUM_TASK_SUBMIT_REQUEST,
  101. ENUM_TASK_REVOKECERT,
  102. ENUM_TASK_RESUBMITREQ,
  103. ENUM_TASK_DENYREQ,
  104. ENUM_TASK_RESUBMITREQ2,
  105. ENUM_TASK_SEPERATOR2,
  106. ENUM_TASK_BACKUP,
  107. ENUM_TASK_RESTORE,
  108. ENUM_TASK_SEPERATOR3,
  109. ENUM_TASK_INSTALL,
  110. ENUM_TASK_REQUEST,
  111. ENUM_TASK_ROLLOVER,
  112. };
  113. TASKITEM taskItems[] =
  114. {
  115. { SERVERFUNC_CRL_PUBLICATION,
  116. 0,
  117. {
  118. {
  119. L"", L"",
  120. IDC_PUBLISHCRL, CCM_INSERTIONPOINTID_PRIMARY_TASK, MF_ENABLED, 0
  121. },
  122. IDS_TASKMENU_PUBLISHCRL,
  123. IDS_TASKMENU_STATUSBAR_PUBLISHCRL,
  124. CA_ACCESS_ADMIN,
  125. }
  126. },
  127. /////////////////////
  128. // BEGIN ATTR/EXT
  129. { SERVERFUNC_CRL_PUBLICATION, // where
  130. TASKITEM_FLAG_RESULTITEM, // dwFlags
  131. {
  132. {
  133. L"", L"",
  134. IDC_VIEW_ATTR_EXT, CCM_INSERTIONPOINTID_PRIMARY_TASK, MF_ENABLED, 0
  135. },
  136. IDS_TASKMENU_VIEWATTREXT,
  137. IDS_TASKMENU_STATUSBAR_VIEWATTREXT,
  138. CA_ACCESS_MASKROLES|CA_ACCESS_READ, // any role with read acccess
  139. }
  140. },
  141. { SERVERFUNC_ISSUED_CERTIFICATES, // where
  142. TASKITEM_FLAG_RESULTITEM, // dwFlags
  143. {
  144. {
  145. L"", L"",
  146. IDC_VIEW_ATTR_EXT, CCM_INSERTIONPOINTID_PRIMARY_TASK, MF_ENABLED, 0
  147. },
  148. IDS_TASKMENU_VIEWATTREXT,
  149. IDS_TASKMENU_STATUSBAR_VIEWATTREXT,
  150. CA_ACCESS_MASKROLES|CA_ACCESS_READ, // any role with read acccess
  151. }
  152. },
  153. { SERVERFUNC_PENDING_CERTIFICATES, // where
  154. TASKITEM_FLAG_RESULTITEM, // dwFlags
  155. {
  156. {
  157. L"", L"",
  158. IDC_VIEW_ATTR_EXT, CCM_INSERTIONPOINTID_PRIMARY_TASK, MF_ENABLED, 0
  159. },
  160. IDS_TASKMENU_VIEWATTREXT,
  161. IDS_TASKMENU_STATUSBAR_VIEWATTREXT,
  162. CA_ACCESS_MASKROLES|CA_ACCESS_READ, // any role with read acccess
  163. }
  164. },
  165. { SERVERFUNC_FAILED_CERTIFICATES, // where
  166. TASKITEM_FLAG_RESULTITEM, // dwFlags
  167. {
  168. {
  169. L"", L"",
  170. IDC_VIEW_ATTR_EXT, CCM_INSERTIONPOINTID_PRIMARY_TASK, MF_ENABLED, 0
  171. },
  172. IDS_TASKMENU_VIEWATTREXT,
  173. IDS_TASKMENU_STATUSBAR_VIEWATTREXT,
  174. CA_ACCESS_MASKROLES|CA_ACCESS_READ, // any role with read acccess
  175. }
  176. },
  177. // END ATTR/EXT
  178. /////////////////////
  179. /////////////////////
  180. // BEGIN ENUM_TASK_DUMP_ASN*
  181. { SERVERFUNC_CRL_PUBLICATION, // where
  182. TASKITEM_FLAG_RESULTITEM, // dwFlags
  183. {
  184. {
  185. L"", L"",
  186. IDC_DUMP_ASN, CCM_INSERTIONPOINTID_PRIMARY_TASK, MF_ENABLED, 0
  187. },
  188. IDS_TASKMENU_DUMPASN,
  189. IDS_TASKMENU_STATUSBAR_DUMPASN,
  190. CA_ACCESS_MASKROLES|CA_ACCESS_READ, // any role with read acccess
  191. }
  192. },
  193. { SERVERFUNC_ISSUED_CERTIFICATES, // where
  194. TASKITEM_FLAG_RESULTITEM, // dwFlags
  195. {
  196. {
  197. L"", L"",
  198. IDC_DUMP_ASN, CCM_INSERTIONPOINTID_PRIMARY_TASK, MF_ENABLED, 0
  199. },
  200. IDS_TASKMENU_DUMPASN,
  201. IDS_TASKMENU_STATUSBAR_DUMPASN,
  202. CA_ACCESS_MASKROLES|CA_ACCESS_READ, // any role with read acccess
  203. }
  204. },
  205. { SERVERFUNC_PENDING_CERTIFICATES, // where
  206. TASKITEM_FLAG_RESULTITEM, // dwFlags
  207. {
  208. {
  209. L"", L"",
  210. IDC_DUMP_ASN, CCM_INSERTIONPOINTID_PRIMARY_TASK, MF_ENABLED, 0
  211. },
  212. IDS_TASKMENU_DUMPASN,
  213. IDS_TASKMENU_STATUSBAR_DUMPASN,
  214. CA_ACCESS_MASKROLES|CA_ACCESS_READ, // any role with read acccess
  215. }
  216. },
  217. { SERVERFUNC_FAILED_CERTIFICATES, // where
  218. TASKITEM_FLAG_RESULTITEM, // dwFlags
  219. {
  220. {
  221. L"", L"",
  222. IDC_DUMP_ASN, CCM_INSERTIONPOINTID_PRIMARY_TASK, MF_ENABLED, 0
  223. },
  224. IDS_TASKMENU_DUMPASN,
  225. IDS_TASKMENU_STATUSBAR_DUMPASN,
  226. CA_ACCESS_MASKROLES|CA_ACCESS_READ, // any role with read acccess
  227. }
  228. },
  229. { SERVERFUNC_ALIEN_CERTIFICATES, // where
  230. TASKITEM_FLAG_RESULTITEM, // dwFlags
  231. {
  232. {
  233. L"", L"",
  234. IDC_DUMP_ASN, CCM_INSERTIONPOINTID_PRIMARY_TASK, MF_ENABLED, 0
  235. },
  236. IDS_TASKMENU_DUMPASN,
  237. IDS_TASKMENU_STATUSBAR_DUMPASN,
  238. CA_ACCESS_MASKROLES|CA_ACCESS_READ, // any role with read acccess
  239. }
  240. },
  241. { SERVERFUNC_ISSUED_CRLS, // where
  242. TASKITEM_FLAG_RESULTITEM, // dwFlags
  243. {
  244. {
  245. L"", L"",
  246. IDC_DUMP_ASN, CCM_INSERTIONPOINTID_PRIMARY_TASK, MF_ENABLED, 0
  247. },
  248. IDS_TASKMENU_DUMPASN,
  249. IDS_TASKMENU_STATUSBAR_DUMPASN,
  250. CA_ACCESS_MASKROLES|CA_ACCESS_READ, // any role with read acccess
  251. }
  252. },
  253. // END ENUM_TASK_DUMP_ASN*
  254. /////////////////////
  255. // seperator
  256. { SERVERFUNC_ALL_FOLDERS,
  257. TASKITEM_FLAG_RESULTITEM, // dwFlags
  258. {
  259. {
  260. L"", L"",
  261. 0, CCM_INSERTIONPOINTID_PRIMARY_TASK, MF_ENABLED, CCM_SPECIAL_SEPARATOR
  262. },
  263. IDS_EMPTY,
  264. IDS_EMPTY,
  265. }
  266. },
  267. // seperator
  268. { SERVER_INSTANCE,
  269. 0, // dwFlags
  270. {
  271. {
  272. L"", L"",
  273. 0, CCM_INSERTIONPOINTID_PRIMARY_TASK, MF_ENABLED, CCM_SPECIAL_SEPARATOR
  274. },
  275. IDS_EMPTY,
  276. IDS_EMPTY,
  277. }
  278. },
  279. { SERVER_INSTANCE,
  280. 0,
  281. {
  282. {
  283. L"", L"",
  284. IDC_SUBMITREQUEST, CCM_INSERTIONPOINTID_PRIMARY_TASK, MF_ENABLED, 0
  285. },
  286. IDS_TASKMENU_SUBMITREQUEST,
  287. IDS_TASKMENU_STATUSBAR_SUBMITREQUEST,
  288. CA_ACCESS_ENROLL,
  289. }
  290. },
  291. { SERVERFUNC_ISSUED_CERTIFICATES,
  292. TASKITEM_FLAG_RESULTITEM, // dwFlags
  293. {
  294. {
  295. L"", L"",
  296. IDC_REVOKECERT, CCM_INSERTIONPOINTID_PRIMARY_TASK, MF_ENABLED, 0
  297. },
  298. IDS_TASKMENU_REVOKECERT,
  299. IDS_TASKMENU_STATUSBAR_REVOKECERT,
  300. CA_ACCESS_OFFICER,
  301. }
  302. },
  303. { SERVERFUNC_PENDING_CERTIFICATES,
  304. TASKITEM_FLAG_RESULTITEM, // dwFlags
  305. {
  306. {
  307. L"", L"",
  308. IDC_RESUBMITREQUEST, CCM_INSERTIONPOINTID_PRIMARY_TASK, MF_ENABLED, 0
  309. },
  310. IDS_TASKMENU_RESUBMIT,
  311. IDS_TASKMENU_STATUSBAR_RESUBMIT,
  312. CA_ACCESS_OFFICER,
  313. }
  314. },
  315. { SERVERFUNC_PENDING_CERTIFICATES,
  316. TASKITEM_FLAG_RESULTITEM, // dwFlags
  317. {
  318. {
  319. L"", L"",
  320. IDC_DENYREQUEST, CCM_INSERTIONPOINTID_PRIMARY_TASK, MF_ENABLED, 0
  321. },
  322. IDS_TASKMENU_DENYREQUEST,
  323. IDS_TASKMENU_STATUSBAR_DENYREQUEST,
  324. CA_ACCESS_OFFICER,
  325. }
  326. },
  327. { SERVERFUNC_FAILED_CERTIFICATES,
  328. TASKITEM_FLAG_RESULTITEM, // dwFlags
  329. {
  330. {
  331. L"", L"",
  332. IDC_RESUBMITREQUEST, CCM_INSERTIONPOINTID_PRIMARY_TASK, MF_ENABLED, 0
  333. },
  334. IDS_TASKMENU_RESUBMIT,
  335. IDS_TASKMENU_STATUSBAR_RESUBMIT,
  336. CA_ACCESS_OFFICER,
  337. }
  338. },
  339. // seperator
  340. { SERVERFUNC_ALL_FOLDERS,
  341. 0, // dwFlags
  342. {
  343. {
  344. L"", L"",
  345. 0, CCM_INSERTIONPOINTID_PRIMARY_TASK, MF_ENABLED, CCM_SPECIAL_SEPARATOR
  346. },
  347. IDS_EMPTY,
  348. IDS_EMPTY,
  349. }
  350. },
  351. { SERVER_INSTANCE,
  352. TASKITEM_FLAG_LOCALONLY,
  353. {
  354. {
  355. L"", L"",
  356. IDC_BACKUP_CA, CCM_INSERTIONPOINTID_PRIMARY_TASK, MF_ENABLED, 0
  357. },
  358. IDS_TASKMENU_BACKUP,
  359. IDS_TASKMENU_STATUSBAR_BACKUP,
  360. CA_ACCESS_OPERATOR,
  361. }
  362. },
  363. { SERVER_INSTANCE,
  364. TASKITEM_FLAG_LOCALONLY,
  365. {
  366. {
  367. L"", L"",
  368. IDC_RESTORE_CA, CCM_INSERTIONPOINTID_PRIMARY_TASK, MF_ENABLED, 0
  369. },
  370. IDS_TASKMENU_RESTORE,
  371. IDS_TASKMENU_STATUSBAR_RESTORE,
  372. CA_ACCESS_OPERATOR,
  373. }
  374. },
  375. // seperator
  376. { SERVER_INSTANCE,
  377. 0,
  378. {
  379. {
  380. L"", L"",
  381. 0, CCM_INSERTIONPOINTID_PRIMARY_TASK, MF_ENABLED, CCM_SPECIAL_SEPARATOR
  382. },
  383. IDS_EMPTY,
  384. IDS_EMPTY,
  385. }
  386. },
  387. { SERVER_INSTANCE,
  388. 0,
  389. {
  390. {
  391. L"", L"",
  392. IDC_INSTALL_CA, CCM_INSERTIONPOINTID_PRIMARY_TASK, MF_ENABLED, 0
  393. },
  394. IDS_TASKMENU_INSTALL_CA,
  395. IDS_TASKMENU_STATUSBAR_INSTALL_CA,
  396. CA_ACCESS_MASKROLES|CA_ACCESS_READ, // not based on roles, enable for all roles
  397. }
  398. },
  399. { SERVER_INSTANCE,
  400. 0,
  401. {
  402. {
  403. L"", L"",
  404. IDC_REQUEST_CA, CCM_INSERTIONPOINTID_PRIMARY_TASK, MF_ENABLED, 0
  405. },
  406. IDS_TASKMENU_REQUEST_CA,
  407. IDS_TASKMENU_STATUSBAR_REQUEST_CA,
  408. CA_ACCESS_MASKROLES|CA_ACCESS_READ, // not based on roles, enable for all roles
  409. }
  410. },
  411. { SERVER_INSTANCE,
  412. TASKITEM_FLAG_LOCALONLY,
  413. {
  414. {
  415. L"", L"",
  416. IDC_ROLLOVER_CA, CCM_INSERTIONPOINTID_PRIMARY_TASK, MF_GRAYED, 0
  417. },
  418. IDS_TASKMENU_ROLLOVER,
  419. IDS_TASKMENU_STATUSBAR_ROLLOVER,
  420. CA_ACCESS_MASKROLES|CA_ACCESS_READ, // not based on roles, enable for all roles
  421. }
  422. },
  423. { NONE,
  424. FALSE,
  425. {
  426. { NULL, NULL, 0, 0, 0 },
  427. IDS_EMPTY,
  428. IDS_EMPTY,
  429. }
  430. }
  431. };
  432. // Array of view items to be inserted into the context menu.
  433. // keep this enum in synch with topItems[]
  434. enum ENUM_TOP_ITEMS
  435. {
  436. ENUM_TOP_REVOKEDOPEN=0,
  437. ENUM_TOP_ISSUEDOPEN,
  438. ENUM_TOP_ALIENOPEN,
  439. ENUM_RETARGET_SNAPIN,
  440. };
  441. TASKITEM topItems[] =
  442. {
  443. { SERVERFUNC_CRL_PUBLICATION,
  444. TASKITEM_FLAG_RESULTITEM, // dwFlags
  445. {
  446. {
  447. L"", L"",
  448. IDC_VIEW_CERT_PROPERTIES, CCM_INSERTIONPOINTID_PRIMARY_TOP, MF_ENABLED, CCM_SPECIAL_DEFAULT_ITEM
  449. },
  450. IDS_TOPMENU_OPEN,
  451. IDS_TOPMENU_STATUSBAR_OPEN,
  452. CA_ACCESS_MASKROLES|CA_ACCESS_READ, // any role with read acccess
  453. }
  454. },
  455. { SERVERFUNC_ISSUED_CERTIFICATES,
  456. TASKITEM_FLAG_RESULTITEM, // dwFlags
  457. {
  458. {
  459. L"", L"",
  460. IDC_VIEW_CERT_PROPERTIES, CCM_INSERTIONPOINTID_PRIMARY_TOP, MF_ENABLED, CCM_SPECIAL_DEFAULT_ITEM
  461. },
  462. IDS_TOPMENU_OPEN,
  463. IDS_TOPMENU_STATUSBAR_OPEN,
  464. CA_ACCESS_MASKROLES|CA_ACCESS_READ, // any role with read acccess
  465. }
  466. },
  467. { SERVERFUNC_ALIEN_CERTIFICATES,
  468. TASKITEM_FLAG_RESULTITEM, // dwFlags
  469. {
  470. {
  471. L"", L"",
  472. IDC_VIEW_CERT_PROPERTIES, CCM_INSERTIONPOINTID_PRIMARY_TOP, MF_ENABLED, CCM_SPECIAL_DEFAULT_ITEM
  473. },
  474. IDS_TOPMENU_OPEN,
  475. IDS_TOPMENU_STATUSBAR_OPEN,
  476. CA_ACCESS_MASKROLES|CA_ACCESS_READ, // any role with read acccess
  477. }
  478. },
  479. { SERVERFUNC_ISSUED_CRLS,
  480. TASKITEM_FLAG_RESULTITEM, // dwFlags
  481. {
  482. {
  483. L"", L"",
  484. IDC_VIEW_CERT_PROPERTIES, CCM_INSERTIONPOINTID_PRIMARY_TOP, MF_ENABLED, CCM_SPECIAL_DEFAULT_ITEM
  485. },
  486. IDS_TOPMENU_OPEN,
  487. IDS_TOPMENU_STATUSBAR_OPEN,
  488. CA_ACCESS_MASKROLES|CA_ACCESS_READ, // any role with read acccess
  489. }
  490. },
  491. {
  492. MACHINE_INSTANCE,
  493. 0,
  494. {
  495. {
  496. L"", L"",
  497. IDC_RETARGET_SNAPIN, CCM_INSERTIONPOINTID_PRIMARY_TOP, MF_ENABLED, 0
  498. },
  499. IDS_RETARGET_SNAPIN,
  500. IDS_STATUSBAR_RETARGET_SNAPIN,
  501. CA_ACCESS_MASKROLES|CA_ACCESS_READ, // any role with read acccess
  502. }
  503. },
  504. { NONE,
  505. 0,
  506. {
  507. { NULL, NULL, 0, 0, 0 },
  508. IDS_EMPTY,
  509. IDS_EMPTY,
  510. }
  511. }
  512. };
  513. BOOL g_fCertViewOnly = TRUE;
  514. ///////////////////////////////////////////////////////////////////////////////
  515. // IComponentData implementation
  516. DEBUG_DECLARE_INSTANCE_COUNTER(CComponentDataImpl);
  517. CComponentDataImpl::CComponentDataImpl()
  518. : m_bIsDirty(TRUE), m_pScope(NULL), m_pConsole(NULL)
  519. #if DBG
  520. , m_bInitializedCD(false), m_bDestroyedCD(false)
  521. #endif
  522. {
  523. DEBUG_INCREMENT_INSTANCE_COUNTER(CComponentDataImpl);
  524. m_dwFlagsPersist = 0;
  525. m_pStaticRoot = NULL;
  526. m_pCurSelFolder = NULL;
  527. m_fScopeAlreadyEnumerated = FALSE;
  528. m_fSchemaWasResolved = FALSE; // resolve schema once per load
  529. m_fCertView = TRUE;
  530. // checked in ::Initialize, ::CreatePropertyPages
  531. m_pCertMachine = new CertSvrMachine;
  532. m_cLastKnownSchema = 0;
  533. m_rgcstrLastKnownSchema = NULL;
  534. m_rgltypeLastKnownSchema = NULL;
  535. m_rgfindexedLastKnownSchema = NULL;
  536. m_dwNextViewIndex = 0;
  537. }
  538. CComponentDataImpl::~CComponentDataImpl()
  539. {
  540. DEBUG_DECREMENT_INSTANCE_COUNTER(CComponentDataImpl);
  541. ASSERT(m_pScope == NULL);
  542. ASSERT(!m_bInitializedCD || m_bDestroyedCD);
  543. // Delete enumerated scope items
  544. // note: we don't own pCA memory, m_pCertMachine does
  545. POSITION pos = m_scopeItemList.GetHeadPosition();
  546. while (pos)
  547. delete m_scopeItemList.GetNext(pos);
  548. m_scopeItemList.RemoveAll();
  549. m_pCurSelFolder = NULL;
  550. m_fScopeAlreadyEnumerated = FALSE;
  551. if (m_pCertMachine)
  552. m_pCertMachine->Release();
  553. m_cLastKnownSchema = 0;
  554. if (m_rgcstrLastKnownSchema)
  555. delete [] m_rgcstrLastKnownSchema;
  556. if (m_rgltypeLastKnownSchema)
  557. delete [] m_rgltypeLastKnownSchema;
  558. if (m_rgfindexedLastKnownSchema)
  559. delete [] m_rgfindexedLastKnownSchema;
  560. }
  561. STDMETHODIMP_(ULONG)
  562. CComponentDataImpl::AddRef()
  563. {
  564. return InterlockedIncrement((LONG *) &_cRefs);
  565. }
  566. STDMETHODIMP_(ULONG)
  567. CComponentDataImpl::Release()
  568. {
  569. ULONG cRefsTemp;
  570. cRefsTemp = InterlockedDecrement((LONG *)&_cRefs);
  571. if (0 == cRefsTemp)
  572. {
  573. delete this;
  574. }
  575. return cRefsTemp;
  576. }
  577. int CComponentDataImpl::FindColIdx(IN LPCWSTR szHeading)
  578. {
  579. for (DWORD dw=0; dw<m_cLastKnownSchema; dw++)
  580. {
  581. if (m_rgcstrLastKnownSchema[dw].IsEqual(szHeading))
  582. return dw;
  583. }
  584. return -1;
  585. }
  586. HRESULT CComponentDataImpl::GetDBSchemaEntry(
  587. IN int iIndex,
  588. OUT OPTIONAL LPCWSTR* pszHeading,
  589. OUT OPTIONAL LONG* plType,
  590. OUT OPTIONAL BOOL* pfIndexed)
  591. {
  592. if (m_cLastKnownSchema<= (DWORD)iIndex)
  593. return HRESULT_FROM_WIN32(ERROR_INVALID_INDEX);
  594. if (pszHeading)
  595. *pszHeading = m_rgcstrLastKnownSchema[iIndex];
  596. if (plType)
  597. *plType = m_rgltypeLastKnownSchema[iIndex];
  598. if (pfIndexed)
  599. *pfIndexed = m_rgfindexedLastKnownSchema[iIndex];
  600. return S_OK;
  601. }
  602. HRESULT CComponentDataImpl::SetDBSchema(
  603. IN CString* rgcstr,
  604. LONG* rgtype,
  605. BOOL* rgfIndexed,
  606. DWORD cEntries)
  607. {
  608. if (m_rgcstrLastKnownSchema)
  609. delete [] m_rgcstrLastKnownSchema;
  610. m_rgcstrLastKnownSchema = rgcstr;
  611. if (m_rgltypeLastKnownSchema)
  612. delete [] m_rgltypeLastKnownSchema;
  613. m_rgltypeLastKnownSchema = rgtype;
  614. if (m_rgfindexedLastKnownSchema)
  615. delete [] m_rgfindexedLastKnownSchema;
  616. m_rgfindexedLastKnownSchema = rgfIndexed;
  617. m_cLastKnownSchema = cEntries;
  618. return S_OK;
  619. }
  620. STDMETHODIMP CComponentDataImpl::Initialize(LPUNKNOWN pUnknown)
  621. {
  622. // NOTA BENE: Init is called when a snap-in is being
  623. // created and has items to enumerate in the scope pane ... NOT BEFORE
  624. // Example: Add/Remove snapin, Add...
  625. // -> CComponentDataImpl will get called for CreatePropertyPages() before ::Initialize is called
  626. #if DBG
  627. m_bInitializedCD = true;
  628. #endif
  629. ASSERT(pUnknown != NULL);
  630. HRESULT hr;
  631. LPIMAGELIST lpScopeImage = NULL;
  632. CBitmap bmpResultStrip16x16, bmpResultStrip32x32;
  633. g_pResources = new CLocalizedResources;
  634. if (NULL == g_pResources)
  635. {
  636. hr = E_OUTOFMEMORY;
  637. _JumpError(hr, Ret, "Alloc Resources");
  638. }
  639. // Load resources
  640. if (!g_pResources->Load())
  641. {
  642. hr = GetLastError();
  643. _JumpError(hr, Ret, "Load Resources");
  644. }
  645. // create a per-instance id (failure not fatal)
  646. ResetPersistedColumnInformation();
  647. // MMC should only call ::Initialize once!
  648. // m_pCertMachine created in constructor, but verified here
  649. ASSERT(m_pCertMachine != NULL);
  650. _JumpIfOutOfMemory(hr, Ret, m_pCertMachine);
  651. // MMC should only call ::Initialize once!
  652. ASSERT(m_pScope == NULL);
  653. hr = pUnknown->QueryInterface(IID_IConsoleNameSpace2, reinterpret_cast<void**>(&m_pScope));
  654. _JumpIfError(hr, Ret, "QueryInterface IID_IConsoleNameSpace2");
  655. // add the images for the scope tree
  656. hr = pUnknown->QueryInterface(IID_IConsole2, reinterpret_cast<void**>(&m_pConsole));
  657. ASSERT(hr == S_OK);
  658. _JumpIfError(hr, Ret, "QueryInterface IID_IConsole2");
  659. hr = m_pConsole->QueryScopeImageList(&lpScopeImage);
  660. ASSERT(hr == S_OK);
  661. _JumpIfError(hr, Ret, "QueryScopeImageList");
  662. if ( (NULL == bmpResultStrip16x16.LoadBitmap(IDB_16x16)) ||
  663. (NULL == bmpResultStrip32x32.LoadBitmap(IDB_32x32)) )
  664. {
  665. hr = S_FALSE;
  666. _JumpError(hr, Ret, "LoadBitmap");
  667. }
  668. // Load the bitmaps from the dll
  669. lpScopeImage->ImageListSetStrip(reinterpret_cast<LONG_PTR *>(static_cast<HBITMAP>(bmpResultStrip16x16)),
  670. reinterpret_cast<LONG_PTR *>(static_cast<HBITMAP>(bmpResultStrip32x32)),
  671. 0, RGB(255, 0, 255));
  672. _JumpIfError(hr, Ret, "ImageListSetStrip");
  673. Ret:
  674. if (lpScopeImage)
  675. lpScopeImage->Release();
  676. return hr;
  677. }
  678. STDMETHODIMP CComponentDataImpl::Destroy()
  679. {
  680. // release all references to the console here
  681. ASSERT(m_bInitializedCD);
  682. #if DBG
  683. m_bDestroyedCD = true;
  684. #endif
  685. SAFE_RELEASE(m_pScope);
  686. SAFE_RELEASE(m_pConsole);
  687. return S_OK;
  688. }
  689. STDMETHODIMP CComponentDataImpl::CreateComponent(LPCOMPONENT* ppComponent)
  690. {
  691. HRESULT hr = S_OK;
  692. ASSERT(ppComponent != NULL);
  693. CComObject<CSnapin>* pObject;
  694. CComObject<CSnapin>::CreateInstance(&pObject);
  695. ASSERT(pObject != NULL);
  696. _JumpIfOutOfMemory(hr, Ret, pObject);
  697. // Store IComponentData
  698. pObject->SetIComponentData(this);
  699. pObject->SetViewID(m_dwNextViewIndex++);
  700. hr = pObject->QueryInterface(IID_IComponent,
  701. reinterpret_cast<void**>(ppComponent));
  702. Ret:
  703. return hr;
  704. }
  705. STDMETHODIMP CComponentDataImpl::Notify(LPDATAOBJECT lpDataObject, MMC_NOTIFY_TYPE event, LPARAM arg, LPARAM param)
  706. {
  707. ASSERT(m_pScope != NULL);
  708. HRESULT hr = S_OK;
  709. INTERNAL* pInternal = NULL;
  710. MMC_COOKIE cookie = NULL;
  711. // handle events with (NULL == lpDataObject)
  712. switch(event)
  713. {
  714. case MMCN_PROPERTY_CHANGE:
  715. {
  716. // Notification from property page "notify change"
  717. //
  718. // arg == fIsScopeItem
  719. // lParam == page param value
  720. // return value unused
  721. if (param == CERTMMC_PROPERTY_CHANGE_REFRESHVIEWS)
  722. {
  723. m_pConsole->UpdateAllViews(
  724. lpDataObject,
  725. 0,
  726. 0);
  727. }
  728. goto Ret;
  729. }
  730. default: // all others
  731. break;
  732. }
  733. pInternal = ExtractInternalFormat(lpDataObject);
  734. if (pInternal == NULL)
  735. {
  736. return S_OK;
  737. }
  738. cookie = pInternal->m_cookie;
  739. FREE_DATA(pInternal);
  740. switch(event)
  741. {
  742. case MMCN_PASTE:
  743. DBGPRINT((DBG_SS_CERTMMC, "CComponentDataImpl::MMCN_PASTE"));
  744. break;
  745. case MMCN_DELETE:
  746. hr = OnDelete(cookie);
  747. break;
  748. case MMCN_REMOVE_CHILDREN:
  749. hr = OnRemoveChildren(arg);
  750. break;
  751. case MMCN_RENAME:
  752. hr = OnRename(cookie, arg, param);
  753. break;
  754. case MMCN_EXPAND:
  755. hr = OnExpand(lpDataObject, arg, param);
  756. break;
  757. case MMCN_PRELOAD:
  758. {
  759. if (NULL == cookie)
  760. {
  761. // base node
  762. // this call gave us time to load our dynamic base nodename (Certification Authority on %ws)
  763. DisplayProperRootNodeName((HSCOPEITEM)arg);
  764. }
  765. }
  766. default:
  767. break;
  768. }
  769. Ret:
  770. return hr;
  771. }
  772. HRESULT CComponentDataImpl::DisplayProperRootNodeName(HSCOPEITEM hRoot)
  773. {
  774. // hRoot not optional
  775. if (hRoot == NULL)
  776. return E_POINTER;
  777. // if static root not yet set, save it (CASE: load from file)
  778. if (m_pStaticRoot == NULL)
  779. m_pStaticRoot = hRoot;
  780. // let us have time to load our dynamic base nodename (Certification Authority on %ws)
  781. SCOPEDATAITEM item;
  782. item.mask = SDI_STR;
  783. item.ID = hRoot;
  784. CString cstrMachineName;
  785. CString cstrDisplayStr, cstrFormatStr, cstrMachine;
  786. cstrFormatStr.LoadString(IDS_NODENAME_FORMAT);
  787. if (m_pCertMachine->m_strMachineName.IsEmpty())
  788. cstrMachine.LoadString(IDS_LOCALMACHINE);
  789. else
  790. cstrMachine = m_pCertMachine->m_strMachineName;
  791. if (!cstrFormatStr.IsEmpty())
  792. {
  793. cstrMachineName.Format(cstrFormatStr, cstrMachine);
  794. item.displayname = (LPWSTR)(LPCWSTR)cstrMachineName;
  795. }
  796. else
  797. {
  798. // protect against null formatstring
  799. item.displayname = (LPWSTR)(LPCWSTR)cstrMachine;
  800. }
  801. m_pScope->SetItem (&item);
  802. return S_OK;
  803. }
  804. STDMETHODIMP CComponentDataImpl::QueryDataObject(MMC_COOKIE cookie, DATA_OBJECT_TYPES type, LPDATAOBJECT* ppDataObject)
  805. {
  806. #ifdef _DEBUG
  807. if (cookie == 0)
  808. {
  809. ASSERT(type != CCT_RESULT);
  810. }
  811. else
  812. {
  813. ASSERT(type == CCT_SCOPE);
  814. DWORD dwItemType = *reinterpret_cast<DWORD*>(cookie);
  815. ASSERT((dwItemType == SCOPE_LEVEL_ITEM) || (dwItemType == CA_LEVEL_ITEM));
  816. }
  817. #endif
  818. return _QueryDataObject(cookie, type, MAXDWORD, this, ppDataObject);
  819. }
  820. ///////////////////////////////////////////////////////////////////////////////
  821. //// ISnapinHelp interface
  822. STDMETHODIMP CComponentDataImpl::GetHelpTopic(LPOLESTR* lpCompiledHelpFile)
  823. {
  824. if (lpCompiledHelpFile == NULL)
  825. return E_POINTER;
  826. UINT cbWindows = 0;
  827. WCHAR szWindows[MAX_PATH];
  828. szWindows[0] = L'\0';
  829. cbWindows = GetSystemWindowsDirectory(szWindows, MAX_PATH);
  830. if (cbWindows == 0)
  831. return S_FALSE;
  832. cbWindows++; // include null term
  833. cbWindows *= sizeof(WCHAR); // make this bytes, not chars
  834. *lpCompiledHelpFile = (LPOLESTR) CoTaskMemAlloc(sizeof(HTMLHELP_COLLECTION_FILENAME) + cbWindows);
  835. if (*lpCompiledHelpFile == NULL)
  836. return E_OUTOFMEMORY;
  837. myRegisterMemFree(*lpCompiledHelpFile, CSM_COTASKALLOC); // this is freed by mmc, not our tracking
  838. USES_CONVERSION;
  839. wcscpy(*lpCompiledHelpFile, T2OLE(szWindows));
  840. wcscat(*lpCompiledHelpFile, T2OLE(HTMLHELP_COLLECTION_FILENAME));
  841. return S_OK;
  842. }
  843. // tells of other topics my chm links to
  844. STDMETHODIMP CComponentDataImpl::GetLinkedTopics(LPOLESTR* lpCompiledHelpFiles)
  845. {
  846. if (lpCompiledHelpFiles == NULL)
  847. return E_POINTER;
  848. UINT cbWindows = 0;
  849. WCHAR szWindows[MAX_PATH];
  850. szWindows[0] = L'\0';
  851. cbWindows = GetSystemWindowsDirectory(szWindows, MAX_PATH);
  852. if (cbWindows == 0)
  853. return S_FALSE;
  854. cbWindows++; // include null term
  855. cbWindows *= sizeof(WCHAR); // make this bytes, not chars
  856. *lpCompiledHelpFiles = (LPOLESTR) CoTaskMemAlloc(sizeof(HTMLHELP_COLLECTIONLINK_FILENAME) + cbWindows);
  857. if (*lpCompiledHelpFiles == NULL)
  858. return E_OUTOFMEMORY;
  859. myRegisterMemFree(*lpCompiledHelpFiles, CSM_COTASKALLOC); // this is freed by mmc, not our tracking
  860. USES_CONVERSION;
  861. wcscpy(*lpCompiledHelpFiles, T2OLE(szWindows));
  862. wcscat(*lpCompiledHelpFiles, T2OLE(HTMLHELP_COLLECTIONLINK_FILENAME));
  863. return S_OK;
  864. }
  865. ///////////////////////////////////////////////////////////////////////////////
  866. //// IPersistStream interface members
  867. STDMETHODIMP CComponentDataImpl::GetClassID(CLSID *pClassID)
  868. {
  869. ASSERT(pClassID != NULL);
  870. // Copy the CLSID for this snapin
  871. *pClassID = CLSID_Snapin;
  872. return S_OK;
  873. }
  874. STDMETHODIMP CComponentDataImpl::IsDirty()
  875. {
  876. // Always save / Always dirty.
  877. return ThisIsDirty() ? S_OK : S_FALSE;
  878. }
  879. STDMETHODIMP CComponentDataImpl::Load(IStream *pStm)
  880. {
  881. ASSERT(pStm);
  882. ASSERT(m_bInitializedCD);
  883. // Read the string
  884. BOOL fMachineOverrideFound = FALSE;
  885. DWORD dwVer;
  886. CertSvrCA* pDummyCA = NULL;
  887. HRESULT hr;
  888. // read version
  889. hr = ReadOfSize(pStm, &dwVer, sizeof(DWORD));
  890. _JumpIfError(hr, Ret, "Read dwVer");
  891. // flags is version-dependent
  892. if (VER_CCOMPDATA_SAVE_STREAM_3 == dwVer)
  893. {
  894. // version 3 includes file flags
  895. hr = ReadOfSize(pStm, &m_dwFlagsPersist, sizeof(DWORD));
  896. _JumpIfError(hr, Ret, "Read m_dwFlagsPersist");
  897. }
  898. else if (VER_CCOMPDATA_SAVE_STREAM_2 != dwVer)
  899. {
  900. // not version 2 or 3
  901. return STG_E_OLDFORMAT;
  902. }
  903. // load machine data
  904. hr = m_pCertMachine->Load(pStm);
  905. _JumpIfError(hr, Ret, "Load m_pCertMachine")
  906. if (m_dwFlagsPersist & CCOMPDATAIMPL_FLAGS_ALLOW_MACHINE_OVERRIDE)
  907. {
  908. // override m_pCertMachine->m_strMachineName (not to be persisted)
  909. LPWSTR lpCommandLine = GetCommandLine(); // no need to free
  910. DBGPRINT((DBG_SS_CERTMMC, "CComponentData::Load: Command line switch override enabled. Searching command line(%ws)\n", lpCommandLine));
  911. LPWSTR pszMachineStart, pszMachineEnd;
  912. // search for "/machine" in cmd line
  913. _wcsupr(lpCommandLine); // convert to uppercase
  914. pszMachineStart = wcsstr(lpCommandLine, WSZ_MACHINE_OVERRIDE_SWITCH);
  915. do // not a loop
  916. {
  917. if (NULL == pszMachineStart) // user did not override
  918. break;
  919. pszMachineStart += WSZARRAYSIZE(WSZ_MACHINE_OVERRIDE_SWITCH); // skip past "/machine:"
  920. //
  921. // Found the hint switch
  922. //
  923. pszMachineEnd = wcschr(pszMachineStart, L' '); // look for first space char, call this end
  924. if (NULL == pszMachineEnd)
  925. pszMachineEnd = &pszMachineStart[wcslen(pszMachineStart)]; // space not found in this string;
  926. m_pCertMachine->m_strMachineName = pszMachineStart;
  927. m_pCertMachine->m_strMachineName.SetAt(SAFE_SUBTRACT_POINTERS(pszMachineEnd, pszMachineStart), L'\0');
  928. DBGPRINT((DBG_SS_CERTMMC, "CComponentData::Load: Found machinename (%ws)\n", m_pCertMachine->m_strMachineName));
  929. fMachineOverrideFound = TRUE;
  930. } while (0);
  931. }
  932. if (!fMachineOverrideFound)
  933. {
  934. // Get CA count
  935. DWORD dwNumCAs;
  936. hr = ReadOfSize(pStm, &dwNumCAs, sizeof(DWORD));
  937. _JumpIfError(hr, Ret, "Load dwNumCAs");
  938. // for each CA, get folder data
  939. for (DWORD dwCA=0; dwCA< dwNumCAs; dwCA++)
  940. {
  941. CString cstrThisCA;
  942. hr = CStringLoad(cstrThisCA, pStm);
  943. _JumpIfError(hr, Ret, "CStringLoad");
  944. // create a dummy CA with the correct common name; we'll fix this later (see Synch CA)
  945. pDummyCA = new CertSvrCA(m_pCertMachine);
  946. _JumpIfOutOfMemory(hr, Ret, pDummyCA);
  947. pDummyCA->m_strCommonName = cstrThisCA;
  948. if (VER_CCOMPDATA_SAVE_STREAM_2 < dwVer)
  949. {
  950. m_fSchemaWasResolved = FALSE; // resolve schema once per CComponentData load
  951. // LOAD last known schema
  952. hr = ReadOfSize(pStm, &m_cLastKnownSchema, sizeof(DWORD));
  953. _JumpIfError(hr, Ret, "Load m_cLastKnownSchema");
  954. // alloc
  955. if (m_cLastKnownSchema != 0)
  956. {
  957. m_rgcstrLastKnownSchema = new CString[m_cLastKnownSchema];
  958. _JumpIfOutOfMemory(hr, Ret, m_rgcstrLastKnownSchema);
  959. for (unsigned int i=0; i<m_cLastKnownSchema; i++)
  960. {
  961. hr = CStringLoad(m_rgcstrLastKnownSchema[i], pStm);
  962. _JumpIfError(hr, Ret, "Load m_rgcstrLastKnownSchema");
  963. }
  964. }
  965. }
  966. // find out how many folders are in the stream under this CA
  967. DWORD dwNumFolders=0;
  968. hr = ReadOfSize(pStm, &dwNumFolders, sizeof(DWORD));
  969. _JumpIfError(hr, Ret, "Load dwNumFolders");
  970. // load each of these
  971. for(DWORD dwCount=0; dwCount<dwNumFolders; dwCount++)
  972. {
  973. CFolder* pFolder = new CFolder();
  974. _JumpIfOutOfMemory(hr, Ret, pFolder);
  975. // point at previously constructed dummy ca; we'll fix this later
  976. pFolder->m_pCertCA = pDummyCA;
  977. hr = pFolder->Load(pStm);
  978. _JumpIfError(hr, Ret, "Load CFolder");
  979. m_scopeItemList.AddTail(pFolder);
  980. }
  981. pDummyCA = NULL; // owned by at least one folder
  982. }
  983. }
  984. // version-dependent info
  985. if (VER_CCOMPDATA_SAVE_STREAM_2 < dwVer)
  986. {
  987. // per-instance guid for identifying columns uniquely
  988. hr = ReadOfSize(pStm, &m_guidInstance, sizeof(GUID));
  989. _JumpIfError(hr, Ret, "ReadOfSize instance guid");
  990. hr = ReadOfSize(pStm, &m_dwNextViewIndex, sizeof(DWORD));
  991. _JumpIfError(hr, Ret, "ReadOfSize view index");
  992. }
  993. Ret:
  994. if (pDummyCA)
  995. delete pDummyCA;
  996. ClearDirty();
  997. return hr;
  998. }
  999. STDMETHODIMP CComponentDataImpl::Save(IStream *pStm, BOOL fClearDirty)
  1000. {
  1001. ASSERT(pStm);
  1002. ASSERT(m_bInitializedCD);
  1003. HRESULT hr;
  1004. DWORD dwVer;
  1005. DWORD dwCA;
  1006. DWORD dwNumCAs;
  1007. #if DBG_CERTSRV
  1008. bool fSaveConsole = false;
  1009. LPWSTR lpCommandLine = GetCommandLine(); // no need to free
  1010. _wcsupr(lpCommandLine); // convert to uppercase
  1011. fSaveConsole = (NULL!=wcsstr(lpCommandLine, L"/certsrv_saveconsole"));
  1012. #endif
  1013. // Write the version
  1014. dwVer = VER_CCOMPDATA_SAVE_STREAM_3;
  1015. hr = WriteOfSize(pStm, &dwVer, sizeof(DWORD));
  1016. _JumpIfError(hr, Ret, "Save dwVer");
  1017. // write dwFlags (a VERSION 3 addition)
  1018. hr = WriteOfSize(pStm, &m_dwFlagsPersist, sizeof(DWORD));
  1019. _JumpIfError(hr, Ret, "pStm->Write m_dwFlagsPersist");
  1020. #if DBG_CERTSRV
  1021. if(fSaveConsole)
  1022. m_pCertMachine->m_strMachineNamePersist.Empty();
  1023. #endif
  1024. hr = m_pCertMachine->Save(pStm, fClearDirty);
  1025. _JumpIfError(hr, Ret, "Save m_pCertMachine");
  1026. // save CA count
  1027. dwNumCAs = m_pCertMachine->GetCaCount();
  1028. hr = WriteOfSize(pStm, &dwNumCAs, sizeof(DWORD));
  1029. _JumpIfError(hr, Ret, "pStm->Write dwNumCAs");
  1030. // for each CA, save folder info
  1031. for (dwCA=0; dwCA < dwNumCAs; dwCA++)
  1032. {
  1033. DWORD dwNumFolders=0;
  1034. CString cstrThisCA, cstrThisCASave;
  1035. cstrThisCASave = cstrThisCA = m_pCertMachine->GetCaCommonNameAtPos(dwCA);
  1036. #if DBG_CERTSRV
  1037. if(fSaveConsole)
  1038. cstrThisCASave.Empty();
  1039. #endif
  1040. hr = CStringSave(cstrThisCASave, pStm, fClearDirty);
  1041. _JumpIfError(hr, Ret, "CStringSave");
  1042. // SAVE last known schema
  1043. hr = WriteOfSize(pStm, &m_cLastKnownSchema, sizeof(DWORD));
  1044. _JumpIfError(hr, Ret, "pStm->Write m_cLastKnownSchema");
  1045. for (unsigned int i=0; i<m_cLastKnownSchema; i++)
  1046. {
  1047. hr = CStringSave(m_rgcstrLastKnownSchema[i], pStm, fClearDirty);
  1048. _JumpIfError(hr, Ret, "CStringSave");
  1049. }
  1050. // walk through every folder, find how many folders to save
  1051. POSITION pos = m_scopeItemList.GetHeadPosition();
  1052. while(pos)
  1053. {
  1054. CFolder* pFolder = m_scopeItemList.GetNext(pos);
  1055. if (pFolder->GetCA()->m_strCommonName.IsEqual(cstrThisCA))
  1056. dwNumFolders++;
  1057. }
  1058. // write how many folders under this CA
  1059. hr = WriteOfSize(pStm, &dwNumFolders, sizeof(DWORD));
  1060. _JumpIfError(hr, Ret, "pStm->Write dwNumFolders");
  1061. pos = m_scopeItemList.GetHeadPosition();
  1062. while(pos)
  1063. {
  1064. CFolder* pFolder = m_scopeItemList.GetNext(pos);
  1065. if (pFolder->GetCA()->m_strCommonName.IsEqual(cstrThisCA))
  1066. {
  1067. hr = pFolder->Save(pStm, fClearDirty);
  1068. _JumpIfError(hr, Ret, "Save CFolder");
  1069. }
  1070. }
  1071. }
  1072. // per-instance guid for identifying columns uniquely
  1073. hr = WriteOfSize(pStm, &m_guidInstance, sizeof(GUID));
  1074. _JumpIfError(hr, Ret, "WriteOfSize instance guid");
  1075. hr = WriteOfSize(pStm, &m_dwNextViewIndex, sizeof(DWORD));
  1076. _JumpIfError(hr, Ret, "WriteOfSize view index");
  1077. Ret:
  1078. if (fClearDirty)
  1079. ClearDirty();
  1080. return hr;
  1081. }
  1082. STDMETHODIMP CComponentDataImpl::GetSizeMax(ULARGE_INTEGER *pcbSize)
  1083. {
  1084. ASSERT(pcbSize);
  1085. int iTotalSize=0;
  1086. // version
  1087. iTotalSize = sizeof(DWORD) + sizeof(m_dwFlagsPersist);
  1088. // machine info
  1089. int iSize;
  1090. m_pCertMachine->GetSizeMax(&iSize);
  1091. iTotalSize += iSize;
  1092. // CA count
  1093. iTotalSize += sizeof(DWORD);
  1094. DWORD dwNumCAs = m_pCertMachine->GetCaCount();
  1095. for (DWORD dwCA=0; dwCA < dwNumCAs; dwCA++)
  1096. {
  1097. CString cstrThisCA;
  1098. cstrThisCA = m_pCertMachine->GetCaCommonNameAtPos(dwCA);
  1099. CStringGetSizeMax(cstrThisCA, &iSize);
  1100. iTotalSize += iSize;
  1101. // Number of folders under this CA
  1102. iTotalSize += sizeof(DWORD);
  1103. // walk through every folder, find how many folders to save
  1104. POSITION pos = m_scopeItemList.GetHeadPosition();
  1105. while(pos)
  1106. {
  1107. CFolder* pFolder = m_scopeItemList.GetNext(pos);
  1108. if (pFolder->GetCA()->m_strCommonName.IsEqual(cstrThisCA))
  1109. {
  1110. // folder size
  1111. pFolder->GetSizeMax(&iSize);
  1112. iTotalSize += iSize;
  1113. }
  1114. }
  1115. }
  1116. // per-instance guid for identifying columns uniquely
  1117. iTotalSize += sizeof(GUID);
  1118. // next View Index to assign
  1119. iTotalSize += sizeof(DWORD);
  1120. // size of string to be saved
  1121. pcbSize->QuadPart = iTotalSize;
  1122. return S_OK;
  1123. }
  1124. ///////////////////////////////////////////////////////////////////////////////
  1125. //// Notify handlers for IComponentData
  1126. HRESULT
  1127. CComponentDataImpl::OnDelete(
  1128. MMC_COOKIE /* cookie */ )
  1129. {
  1130. return S_OK;
  1131. }
  1132. HRESULT
  1133. CComponentDataImpl::OnRemoveChildren(
  1134. LPARAM /* arg */ )
  1135. {
  1136. return S_OK;
  1137. }
  1138. VOID SetCertView()
  1139. {
  1140. LPWSTR lpCommandLine = GetCommandLine(); // no need to free
  1141. LPWSTR pwsz;
  1142. DWORD dw;
  1143. static BOOL s_fFirst = TRUE;
  1144. #define wszCOMMANDLINEE L"/E"
  1145. if (s_fFirst)
  1146. {
  1147. // search for "/e" in cmd line
  1148. _wcsupr(lpCommandLine); // convert to uppercase
  1149. pwsz = wcsstr(lpCommandLine, wszCOMMANDLINEE);
  1150. do // not a loop
  1151. {
  1152. if (NULL == pwsz) // user did not override
  1153. break;
  1154. pwsz += WSZARRAYSIZE(wszCOMMANDLINEE); // skip past "/e"
  1155. if (L'\0' != *pwsz && L' ' != *pwsz)
  1156. break;
  1157. g_fCertViewOnly = FALSE;
  1158. } while (0);
  1159. if (g_fCertViewOnly && NULL != getenv("certsrv_crl"))
  1160. g_fCertViewOnly = FALSE;
  1161. if (g_fCertViewOnly &&
  1162. S_OK == myGetCertRegDWValue(NULL, NULL, NULL, L"CRL", &dw) &&
  1163. 0 != dw)
  1164. g_fCertViewOnly = FALSE;
  1165. s_fFirst = FALSE;
  1166. }
  1167. }
  1168. HRESULT CComponentDataImpl::OnRename(MMC_COOKIE cookie, LPARAM arg, LPARAM param)
  1169. {
  1170. // cookie is cookie
  1171. // arg is fRenamed (ask for permission/notify of rename)
  1172. // param (szNewName)
  1173. CFolder* pFolder = reinterpret_cast<CFolder*>(cookie);
  1174. BOOL fRenamed = (BOOL)arg;
  1175. if (!fRenamed)
  1176. {
  1177. if (pFolder)
  1178. return S_FALSE; // don't allow children to be renamed
  1179. else
  1180. return S_OK; // allow root to be renamed
  1181. }
  1182. LPOLESTR pszNewName = reinterpret_cast<LPOLESTR>(param);
  1183. if (pszNewName == NULL)
  1184. return E_INVALIDARG;
  1185. if (pFolder)
  1186. {
  1187. ASSERT(pFolder != NULL);
  1188. if (pFolder == NULL)
  1189. return E_INVALIDARG;
  1190. pFolder->SetName(pszNewName);
  1191. }
  1192. return S_OK;
  1193. }
  1194. HRESULT CComponentDataImpl::OnExpand(LPDATAOBJECT lpDataObject, LPARAM arg, LPARAM param)
  1195. {
  1196. if (arg == TRUE)
  1197. {
  1198. // Did Initialize get called?
  1199. ASSERT(m_pScope != NULL);
  1200. EnumerateScopePane(lpDataObject, param);
  1201. }
  1202. return S_OK;
  1203. }
  1204. HRESULT CComponentDataImpl::SynchDisplayedCAList(LPDATAOBJECT lpDataObject)
  1205. {
  1206. HRESULT hr;
  1207. BOOL fFound;
  1208. POSITION pos, nextpos;
  1209. DWORD dwKnownCAs;
  1210. m_fScopeAlreadyEnumerated = TRUE; // don't need to refresh view automagically from enum if we get here
  1211. // should never get here otherwise
  1212. ASSERT(m_pStaticRoot);
  1213. if (NULL == m_pStaticRoot)
  1214. return E_POINTER;
  1215. // select root node, delete all items in UI underneath (we'll readd if necessary)
  1216. hr = m_pConsole->SelectScopeItem(m_pStaticRoot);
  1217. _PrintIfError2(hr, "SelectScopeItem", hr);
  1218. hr = m_pScope->DeleteItem(m_pStaticRoot, FALSE); // remove everything from UI
  1219. _PrintIfError2(hr, "DeleteItem", hr);
  1220. // build knowledge of current CAs
  1221. // note: this may orphan some pCAs, but we'll catch it during cleanup
  1222. HWND hwndMain = NULL;
  1223. hr = m_pConsole->GetMainWindow(&hwndMain);
  1224. if (hr != S_OK)
  1225. hwndMain = NULL; // this should work
  1226. // this hr gets returned after we're done
  1227. hr = m_pCertMachine->PrepareData(hwndMain);
  1228. // don't fail out if PrepareData fails -- we still need to
  1229. // make the snapin state reflect no known nodes!
  1230. ASSERT((hr == S_OK) || (0 == m_pCertMachine->GetCaCount()) ); // make sure m_pCertMachine zeros itself
  1231. // Tasks
  1232. // #1: Remove folders in m_scopeItemList for CAs that no longer exist in m_pCertMachine.m_rgpCAList[]
  1233. // #2: Add folders to m_scopeItemList for CAs that now exist in m_pCertMachine.m_rgpCAList[]
  1234. // Task #1
  1235. // scour m_scopeItemList for entries we already know about, delete stale folders
  1236. for (pos = m_scopeItemList.GetHeadPosition(); (NULL != pos); )
  1237. {
  1238. // ASSERTION: every folder has an associated m_pCertCA
  1239. ASSERT(NULL != m_scopeItemList.GetAt(pos)->m_pCertCA);
  1240. nextpos = pos; // save next position off
  1241. fFound = FALSE;
  1242. // for each scope item, walk through m_rgpCAList looking for current
  1243. for (dwKnownCAs=0; dwKnownCAs<(DWORD)m_pCertMachine->m_CAList.GetSize(); dwKnownCAs++)
  1244. {
  1245. if (m_scopeItemList.GetAt(pos)->m_pCertCA->m_strCommonName.IsEqual(m_pCertMachine->GetCaCommonNameAtPos(dwKnownCAs)))
  1246. {
  1247. fFound = TRUE;
  1248. break;
  1249. }
  1250. }
  1251. CFolder* pFolder = m_scopeItemList.GetAt(pos);
  1252. ASSERT(pFolder); // this should never happen
  1253. if (pFolder == NULL)
  1254. {
  1255. hr = E_POINTER;
  1256. _JumpError(hr, Ret, "GetAt");
  1257. }
  1258. if (fFound)
  1259. {
  1260. // always point to latest pCA:
  1261. // NOTE: this allows for load to populate us with dummy CAs!
  1262. pFolder->m_pCertCA = m_pCertMachine->GetCaAtPos(dwKnownCAs);
  1263. // if base node, do insert (other nodes get inserted during Expand() notification)
  1264. if (SERVER_INSTANCE == pFolder->GetType())
  1265. BaseFolderInsertIntoScope(pFolder, pFolder->m_pCertCA);
  1266. // fwd to next elt
  1267. m_scopeItemList.GetNext(pos);
  1268. }
  1269. else // !fFound
  1270. {
  1271. // delete immediately from m_scopeItemList
  1272. m_scopeItemList.GetNext(nextpos);
  1273. delete pFolder; // destroy the elt
  1274. m_scopeItemList.RemoveAt(pos);
  1275. pos = nextpos; // restore next position
  1276. }
  1277. }
  1278. // Task #2
  1279. // scour m_pCertMachine[] for new entries, create default folders
  1280. for (dwKnownCAs=0; dwKnownCAs<(DWORD)m_pCertMachine->m_CAList.GetSize(); dwKnownCAs++)
  1281. {
  1282. fFound = FALSE;
  1283. for (pos = m_scopeItemList.GetHeadPosition(); (NULL != pos); m_scopeItemList.GetNext(pos))
  1284. {
  1285. if (m_scopeItemList.GetAt(pos)->m_pCertCA->m_strCommonName.IsEqual(m_pCertMachine->GetCaCommonNameAtPos(dwKnownCAs)))
  1286. {
  1287. fFound = TRUE;
  1288. break; // if matches something in the refreshed list, we're fine
  1289. }
  1290. }
  1291. // found?
  1292. if (!fFound)
  1293. {
  1294. CertSvrCA* pCA;
  1295. CFolder* pFolder;
  1296. pCA = m_pCertMachine->GetCaAtPos(dwKnownCAs);
  1297. if (NULL == pCA)
  1298. {
  1299. hr = E_POINTER;
  1300. _JumpError(hr, Ret, "m_pCertMachine->GetCaAtPos(iCAPos)");
  1301. }
  1302. // create base node, add to list, insert into scope pane
  1303. pFolder = new CFolder();
  1304. _JumpIfOutOfMemory(hr, Ret, pFolder);
  1305. m_scopeItemList.AddTail(pFolder);
  1306. hr = BaseFolderInsertIntoScope(pFolder, pCA);
  1307. _JumpIfError(hr, Ret, "BaseFolderInsertIntoScope");
  1308. // and create all template folders underneath
  1309. hr = CreateTemplateFolders(pCA);
  1310. _JumpIfError(hr, Ret, "CreateTemplateFolders");
  1311. }
  1312. else
  1313. {
  1314. // no need to do anything, ca is already known & inserted into scope
  1315. }
  1316. }
  1317. // BOGDANT
  1318. // Task #3
  1319. // for each CA, offer to do any one-time per-CA upgrades
  1320. for (dwKnownCAs=0; dwKnownCAs<(DWORD)m_pCertMachine->m_CAList.GetSize(); dwKnownCAs++)
  1321. {
  1322. CertSvrCA* pCA;
  1323. pCA = m_pCertMachine->GetCaAtPos(dwKnownCAs);
  1324. if (NULL == pCA)
  1325. {
  1326. hr = E_POINTER;
  1327. _JumpError(hr, Ret, "m_pCertMachine->GetCaAtPos(iCAPos)");
  1328. }
  1329. if (pCA->FDoesSecurityNeedUpgrade())
  1330. {
  1331. bool fUserHasWriteAccess = false;
  1332. CString cstrMsg, cstrTitle;
  1333. cstrMsg.LoadString(IDS_W2K_SECURITY_UPGRADE_DESCR);
  1334. cstrTitle.LoadString(IDS_W2K_UPGRADE_DETECTED_TITLE);
  1335. hr = CurrentUserCanInstallCA(fUserHasWriteAccess);
  1336. _JumpIfError(hr, Ret, "IsUserDomainAdministrator");
  1337. if (fUserHasWriteAccess)
  1338. {
  1339. // ask to upgrade security
  1340. // confirm this action
  1341. CString cstrTmp;
  1342. cstrTmp.LoadString(IDS_CONFIRM_W2K_SECURITY_UPGRADE);
  1343. cstrMsg += cstrTmp;
  1344. int iRet;
  1345. if ((S_OK == m_pConsole->MessageBox(cstrMsg, cstrTitle, MB_YESNO, &iRet)) &&
  1346. (iRet == IDYES))
  1347. {
  1348. // do stuff
  1349. hr = pCA->FixEnrollmentObject();
  1350. _JumpIfError(hr, error, "FixEnrollmentObject");
  1351. hr = AddCAMachineToCertPublishers();
  1352. _JumpIfError(hr, error, "AddCAMachineToCertPublishers");
  1353. if(pCA->FIsAdvancedServer())
  1354. {
  1355. hr = AddCAMachineToPreWin2kGroup();
  1356. _JumpIfError(hr, error, "AddCAMachineToPreWin2kGroup");
  1357. }
  1358. if(RestartService(hwndMain, pCA->m_pParentMachine))
  1359. m_pConsole->UpdateAllViews(
  1360. lpDataObject,
  1361. 0,
  1362. 0);
  1363. error:
  1364. if (hr != S_OK)
  1365. DisplayGenericCertSrvError(m_pConsole, hr);
  1366. else
  1367. {
  1368. hr = pCA->CleanSetupStatusBits(
  1369. SETUP_W2K_SECURITY_NOT_UPGRADED_FLAG);
  1370. _PrintIfError(hr,
  1371. "Failed to clear SETUP_W2K_SECURITY_NOT_UPGRADED_FLAG setup flag");
  1372. hr = S_OK;
  1373. }
  1374. }
  1375. }
  1376. else
  1377. {
  1378. // just warn
  1379. CString cstrTmp;
  1380. cstrTmp.LoadString(IDS_BLOCK_W2K_SECURITY_UPGRADE);
  1381. cstrMsg += cstrTmp;
  1382. m_pConsole->MessageBoxW(cstrMsg, cstrTitle, MB_OK, NULL);
  1383. }
  1384. }
  1385. }
  1386. Ret:
  1387. return hr;
  1388. }
  1389. HRESULT CComponentDataImpl::BaseFolderInsertIntoScope(CFolder* pFolder, CertSvrCA* pCA)
  1390. {
  1391. HRESULT hr = S_OK;
  1392. int nImage;
  1393. HSCOPEITEM pParent = m_pStaticRoot; // we'll always be initialized by this time if parent exists
  1394. ASSERT(m_pStaticRoot);
  1395. if (NULL == m_pStaticRoot)
  1396. {
  1397. hr = E_POINTER;
  1398. _JumpError(hr, Ret, "m_pStaticRoot");
  1399. }
  1400. if ((NULL == pFolder) || (NULL == pCA))
  1401. {
  1402. hr = E_POINTER;
  1403. _JumpError(hr, Ret, "NULL ptr");
  1404. }
  1405. if (pCA->m_strCommonName.IsEmpty())
  1406. {
  1407. hr = E_POINTER;
  1408. _JumpError(hr, Ret, "m_strCommonName");
  1409. }
  1410. if (m_pCertMachine->IsCertSvrServiceRunning())
  1411. nImage = IMGINDEX_CERTSVR_RUNNING;
  1412. else
  1413. nImage = IMGINDEX_CERTSVR_STOPPED;
  1414. pFolder->SetScopeItemInformation(nImage, nImage);
  1415. pFolder->SetProperties(
  1416. pCA->m_strCommonName,
  1417. SCOPE_LEVEL_ITEM,
  1418. SERVER_INSTANCE,
  1419. TRUE);
  1420. pFolder->m_pCertCA = pCA; // fill this in as root
  1421. // Set the parent
  1422. pFolder->m_ScopeItem.mask |= SDI_PARENT;
  1423. pFolder->m_ScopeItem.relativeID = pParent;
  1424. // Set the folder as the cookie
  1425. pFolder->m_ScopeItem.mask |= SDI_PARAM;
  1426. pFolder->m_ScopeItem.lParam = reinterpret_cast<LPARAM>(pFolder);
  1427. pFolder->SetCookie(reinterpret_cast<MMC_COOKIE>(pFolder));
  1428. // insert SCOPE_LEVEL_ITEM into scope pane
  1429. m_pScope->InsertItem(&pFolder->m_ScopeItem);
  1430. // Note - On return, the ID member of 'm_ScopeItem'
  1431. // contains the handle to the newly inserted item!
  1432. ASSERT(pFolder->m_ScopeItem.ID != NULL);
  1433. Ret:
  1434. return hr;
  1435. }
  1436. HRESULT CComponentDataImpl::CreateTemplateFolders(CertSvrCA* pCA)
  1437. {
  1438. HRESULT hr = S_OK;
  1439. SetCertView();
  1440. // add all template folders under it
  1441. for (int iUnder=0; iUnder < ARRAYLEN(SvrFuncFolderData); iUnder++)
  1442. {
  1443. // skip alien if svr doesn't support
  1444. if ((iUnder==ENUM_FOLDER_ALIEN) && !pCA->FDoesServerAllowForeignCerts())
  1445. continue;
  1446. if ((iUnder==ENUM_FOLDER_CRLS) && g_fCertViewOnly)
  1447. continue;
  1448. CString cstrRsc;
  1449. cstrRsc.LoadString(SvrFuncFolderData[iUnder].iNameRscID);
  1450. CFolder* pFolder;
  1451. pFolder = new CFolder();
  1452. _JumpIfOutOfMemory(hr, Ret, pFolder);
  1453. pFolder->m_pCertCA = pCA;
  1454. pFolder->SetScopeItemInformation(IMGINDEX_FOLDER, IMGINDEX_FOLDER_OPEN);
  1455. pFolder->SetProperties(
  1456. cstrRsc,
  1457. CA_LEVEL_ITEM,
  1458. SvrFuncFolderData[iUnder].type,
  1459. FALSE);
  1460. m_scopeItemList.AddTail(pFolder);
  1461. }
  1462. Ret:
  1463. return hr;
  1464. }
  1465. void CComponentDataImpl::EnumerateScopePane(LPDATAOBJECT lpDataObject, HSCOPEITEM pParent)
  1466. {
  1467. ASSERT(m_pScope != NULL); // make sure we QI'ed for the interface
  1468. ASSERT(lpDataObject != NULL);
  1469. INTERNAL* pInternal = ExtractInternalFormat(lpDataObject);
  1470. if (pInternal == NULL)
  1471. return;
  1472. MMC_COOKIE cookie = pInternal->m_cookie;
  1473. FREE_DATA(pInternal);
  1474. // Enumerate the scope pane
  1475. // return the folder object that represents the cookie
  1476. // Note - for large list, use dictionary
  1477. CFolder* pStatic = FindObject(cookie);
  1478. if (pStatic)
  1479. ASSERT(!pStatic->IsEnumerated());
  1480. if (NULL == cookie)
  1481. {
  1482. if (!m_fScopeAlreadyEnumerated) // if base node and we've never inserted nodes
  1483. {
  1484. // TASK: expand machine node
  1485. // Note - Each cookie in the scope pane represents a folder.
  1486. // Cache the HSCOPEITEM of the static root.
  1487. ASSERT(pParent != NULL);
  1488. m_pStaticRoot = pParent; // add/remove: EXPAND case
  1489. // synch folder list if asking to expand machine node
  1490. // SyncDisplayedCAList adds all necessary folders
  1491. HRESULT hr = SynchDisplayedCAList(lpDataObject);
  1492. if (hr != S_OK)
  1493. {
  1494. HWND hwnd;
  1495. DWORD dwErr2 = m_pConsole->GetMainWindow(&hwnd);
  1496. ASSERT(dwErr2 == ERROR_SUCCESS);
  1497. if (dwErr2 != ERROR_SUCCESS)
  1498. hwnd = NULL; // should work
  1499. if (((HRESULT)RPC_S_SERVER_UNAVAILABLE) == hr)
  1500. {
  1501. DisplayCertSrvErrorWithContext(hwnd, hr, IDS_SERVER_UNAVAILABLE);
  1502. }
  1503. else if(HRESULT_FROM_WIN32(ERROR_OLD_WIN_VERSION)==hr ||
  1504. ((HRESULT)ERROR_OLD_WIN_VERSION)==hr)
  1505. {
  1506. DisplayCertSrvErrorWithContext(hwnd, hr, IDS_OLD_CA);
  1507. }
  1508. else
  1509. {
  1510. DisplayCertSrvErrorWithContext(hwnd, hr, IDS_CANNOT_OPEN_CERT_SERVICES);
  1511. }
  1512. }
  1513. }
  1514. }
  1515. else
  1516. {
  1517. // TASK: expand non-machine node
  1518. if (NULL == pStatic)
  1519. return;
  1520. switch(pStatic->GetType())
  1521. {
  1522. case SERVER_INSTANCE:
  1523. {
  1524. // TASK: expand CA instance node
  1525. POSITION pos = m_scopeItemList.GetHeadPosition();
  1526. while(pos)
  1527. {
  1528. CFolder* pFolder;
  1529. pFolder = m_scopeItemList.GetNext(pos);
  1530. if (pFolder==NULL)
  1531. break;
  1532. // only expand folders that belong under the SERVER_INSTANCE
  1533. if (pFolder->m_itemType != CA_LEVEL_ITEM)
  1534. continue;
  1535. // and only those under the correct CA
  1536. if (pFolder->m_pCertCA != pStatic->m_pCertCA)
  1537. continue;
  1538. // Set the parent
  1539. pFolder->m_ScopeItem.relativeID = pParent;
  1540. // Set the folder as the cookie
  1541. pFolder->m_ScopeItem.mask |= SDI_PARAM;
  1542. pFolder->m_ScopeItem.lParam = reinterpret_cast<LPARAM>(pFolder);
  1543. pFolder->SetCookie(reinterpret_cast<MMC_COOKIE>(pFolder));
  1544. m_pScope->InsertItem(&pFolder->m_ScopeItem);
  1545. // Note - On return, the ID member of 'm_ScopeItem'
  1546. // contains the handle to the newly inserted item!
  1547. ASSERT(pFolder->m_ScopeItem.ID != NULL);
  1548. }
  1549. }
  1550. break;
  1551. default:
  1552. // TASK: expand nodes with no folders under them
  1553. break;
  1554. }
  1555. }
  1556. }
  1557. CFolder* CComponentDataImpl::FindObject(MMC_COOKIE cookie)
  1558. {
  1559. CFolder* pFolder = NULL;
  1560. POSITION pos = m_scopeItemList.GetHeadPosition();
  1561. while(pos)
  1562. {
  1563. pFolder = m_scopeItemList.GetNext(pos);
  1564. if (*pFolder == cookie)
  1565. return pFolder;
  1566. }
  1567. return NULL;
  1568. }
  1569. STDMETHODIMP CComponentDataImpl::GetDisplayInfo(SCOPEDATAITEM* pScopeDataItem)
  1570. {
  1571. ASSERT(pScopeDataItem != NULL);
  1572. if (pScopeDataItem == NULL)
  1573. return E_POINTER;
  1574. CFolder* pFolder = reinterpret_cast<CFolder*>(pScopeDataItem->lParam);
  1575. if ((pScopeDataItem->mask & SDI_STR) && (pFolder != NULL))
  1576. {
  1577. pScopeDataItem->displayname = pFolder->m_pszName;
  1578. }
  1579. // I was told by Ravi Rudrappa that these notifications
  1580. // would never be given. If it is given, move UpdateScopeIcons()
  1581. // functionality here!!!
  1582. ASSERT(0 == (pScopeDataItem->mask & SDI_IMAGE));
  1583. ASSERT(0 == (pScopeDataItem->mask & SDI_OPENIMAGE));
  1584. return S_OK;
  1585. }
  1586. STDMETHODIMP CComponentDataImpl::CompareObjects(LPDATAOBJECT lpDataObjectA, LPDATAOBJECT lpDataObjectB)
  1587. {
  1588. if (lpDataObjectA == NULL || lpDataObjectB == NULL)
  1589. return E_POINTER;
  1590. HRESULT hr = S_FALSE;
  1591. // Make sure both data object are mine
  1592. INTERNAL* pA = ExtractInternalFormat(lpDataObjectA);
  1593. INTERNAL* pB = ExtractInternalFormat(lpDataObjectA);
  1594. if (pA != NULL && pB != NULL)
  1595. hr = (*pA == *pB) ? S_OK : S_FALSE;
  1596. FREE_DATA(pA);
  1597. FREE_DATA(pB);
  1598. return hr;
  1599. }
  1600. /////////////////////////////////////////////////////////////////////////////
  1601. // IExtendPropertySheet Implementation
  1602. STDMETHODIMP CComponentDataImpl::CreatePropertyPages(LPPROPERTYSHEETCALLBACK lpProvider,
  1603. LONG_PTR handle,
  1604. LPDATAOBJECT lpIDataObject)
  1605. {
  1606. HRESULT hr = S_OK;
  1607. // Look at the data object and determine if this an extension or a primary
  1608. ASSERT(lpIDataObject != NULL);
  1609. PropertyPage* pBasePage;
  1610. INTERNAL* pInternal = ExtractInternalFormat(lpIDataObject);
  1611. if (pInternal == NULL)
  1612. return S_OK;
  1613. switch (pInternal->m_type)
  1614. {
  1615. case CCT_SNAPIN_MANAGER:
  1616. {
  1617. CChooseMachinePropPage* pPage = new CChooseMachinePropPage();
  1618. _JumpIfOutOfMemory(hr, Ret, pPage);
  1619. // this alloc might have failed (should be in ctor)
  1620. _JumpIfOutOfMemory(hr, Ret, m_pCertMachine);
  1621. pPage->SetCaption(IDS_SCOPE_MYCOMPUTER);
  1622. // Initialize state of object
  1623. pPage->InitMachineName(NULL);
  1624. // point to our member vars
  1625. pPage->SetOutputBuffers(
  1626. &m_pCertMachine->m_strMachineNamePersist,
  1627. &m_pCertMachine->m_strMachineName,
  1628. &m_dwFlagsPersist);
  1629. pBasePage = pPage;
  1630. // Object gets deleted when the page is destroyed
  1631. ASSERT(lpProvider != NULL);
  1632. ASSERT(pBasePage != NULL);
  1633. HPROPSHEETPAGE hPage = CreatePropertySheetPage(&pBasePage->m_psp);
  1634. if (hPage == NULL)
  1635. {
  1636. hr = myHLastError();
  1637. _JumpError(hr, Ret, "CreatePropertySheetPage");
  1638. }
  1639. lpProvider->AddPage(hPage);
  1640. break;
  1641. }
  1642. case CCT_SCOPE:
  1643. {
  1644. // if not base scope
  1645. if (0 != pInternal->m_cookie)
  1646. {
  1647. // switch on folder type
  1648. CFolder* pFolder = GetParentFolder(pInternal);
  1649. ASSERT(pFolder != NULL);
  1650. if (pFolder == NULL)
  1651. {
  1652. hr = E_POINTER;
  1653. _JumpError(hr, Ret, "GetParentFolder");
  1654. }
  1655. switch(pFolder->m_type)
  1656. {
  1657. case SERVER_INSTANCE:
  1658. {
  1659. //1
  1660. CSvrSettingsGeneralPage* pControlPage = new CSvrSettingsGeneralPage(pFolder->m_pCertCA);
  1661. if (pControlPage != NULL)
  1662. {
  1663. pControlPage->m_hConsoleHandle = handle; // only do this on primary
  1664. pBasePage = pControlPage;
  1665. HPROPSHEETPAGE hPage = CreatePropertySheetPage(&pBasePage->m_psp);
  1666. if (hPage == NULL)
  1667. {
  1668. hr = myHLastError();
  1669. _JumpError(hr, Ret, "CreatePropertySheetPage");
  1670. }
  1671. lpProvider->AddPage(hPage);
  1672. }
  1673. //2
  1674. {
  1675. CSvrSettingsPolicyPage* pPage = new CSvrSettingsPolicyPage(pControlPage);
  1676. if (pPage != NULL)
  1677. {
  1678. pBasePage = pPage;
  1679. HPROPSHEETPAGE hPage = CreatePropertySheetPage(&pBasePage->m_psp);
  1680. if (hPage == NULL)
  1681. {
  1682. hr = myHLastError();
  1683. _JumpError(hr, Ret, "CreatePropertySheetPage");
  1684. }
  1685. lpProvider->AddPage(hPage);
  1686. }
  1687. }
  1688. //3
  1689. {
  1690. CSvrSettingsExitPage* pPage = new CSvrSettingsExitPage(pControlPage);
  1691. if (pPage != NULL)
  1692. {
  1693. pBasePage = pPage;
  1694. HPROPSHEETPAGE hPage = CreatePropertySheetPage(&pBasePage->m_psp);
  1695. if (hPage == NULL)
  1696. {
  1697. hr = myHLastError();
  1698. _JumpError(hr, Ret, "CreatePropertySheetPage");
  1699. }
  1700. lpProvider->AddPage(hPage);
  1701. }
  1702. }
  1703. //4
  1704. {
  1705. // Centralized extensions page available only in whistler
  1706. if (pFolder->m_pCertCA->m_pParentMachine->FIsWhistlerMachine())
  1707. {
  1708. CSvrSettingsExtensionPage* pPage = new CSvrSettingsExtensionPage(pFolder->m_pCertCA, pControlPage);
  1709. if (pPage != NULL)
  1710. {
  1711. pBasePage = pPage;
  1712. HPROPSHEETPAGE hPage = CreatePropertySheetPage(&pBasePage->m_psp);
  1713. if (hPage == NULL)
  1714. {
  1715. hr = myHLastError();
  1716. _JumpError(hr, Ret, "CreatePropertySheetPage");
  1717. }
  1718. lpProvider->AddPage(hPage);
  1719. }
  1720. }
  1721. }
  1722. //5
  1723. {
  1724. CSvrSettingsStoragePage* pPage = new CSvrSettingsStoragePage(pControlPage);
  1725. if (pPage != NULL)
  1726. {
  1727. pBasePage = pPage;
  1728. HPROPSHEETPAGE hPage = CreatePropertySheetPage(&pBasePage->m_psp);
  1729. if (hPage == NULL)
  1730. {
  1731. hr = myHLastError();
  1732. _JumpError(hr, Ret, "CreatePropertySheetPage");
  1733. }
  1734. lpProvider->AddPage(hPage);
  1735. }
  1736. }
  1737. //6
  1738. {
  1739. // restricted officers available only in whistler advanced server
  1740. if(pFolder->m_pCertCA->m_pParentMachine->FIsWhistlerMachine() && pFolder->m_pCertCA->FIsAdvancedServer())
  1741. {
  1742. CSvrSettingsCertManagersPage* pPage =
  1743. new CSvrSettingsCertManagersPage(pControlPage);
  1744. if (pPage != NULL)
  1745. {
  1746. pBasePage = pPage;
  1747. HPROPSHEETPAGE hPage = CreatePropertySheetPage(&pBasePage->m_psp);
  1748. if (hPage == NULL)
  1749. {
  1750. hr = myHLastError();
  1751. _JumpError(hr, Ret, "CreatePropertySheetPage");
  1752. }
  1753. lpProvider->AddPage(hPage);
  1754. }
  1755. }
  1756. }
  1757. //7
  1758. {
  1759. // audit available only in whistler
  1760. if(pFolder->m_pCertCA->m_pParentMachine->FIsWhistlerMachine())
  1761. {
  1762. CSvrSettingsAuditFilterPage* pPage =
  1763. new CSvrSettingsAuditFilterPage(pControlPage);
  1764. if (pPage != NULL)
  1765. {
  1766. pBasePage = pPage;
  1767. HPROPSHEETPAGE hPage = CreatePropertySheetPage(&pBasePage->m_psp);
  1768. if (hPage == NULL)
  1769. {
  1770. hr = myHLastError();
  1771. _JumpError(hr, Ret, "CreatePropertySheetPage");
  1772. }
  1773. lpProvider->AddPage(hPage);
  1774. }
  1775. }
  1776. }
  1777. //8
  1778. {
  1779. // audit available only in whistler advanced server, enterprise
  1780. if(pFolder->m_pCertCA->m_pParentMachine->FIsWhistlerMachine() && pFolder->m_pCertCA->FIsAdvancedServer() && IsEnterpriseCA(pFolder->m_pCertCA->GetCAType()) )
  1781. {
  1782. CSvrSettingsKRAPage* pPage = new CSvrSettingsKRAPage(
  1783. pFolder->m_pCertCA,
  1784. pControlPage);
  1785. if (pPage != NULL)
  1786. {
  1787. pBasePage = pPage;
  1788. HPROPSHEETPAGE hPage = CreatePropertySheetPage(&pBasePage->m_psp);
  1789. if (hPage == NULL)
  1790. {
  1791. hr = myHLastError();
  1792. _JumpError(hr, Ret, "CreatePropertySheetPage");
  1793. }
  1794. lpProvider->AddPage(hPage);
  1795. }
  1796. }
  1797. }
  1798. //9
  1799. {
  1800. // if error, don't display this page
  1801. LPSECURITYINFO pCASecurity = NULL;
  1802. hr = CreateCASecurityInfo(pFolder->m_pCertCA, &pCASecurity);
  1803. _PrintIfError(hr, "CreateCASecurityInfo");
  1804. if (hr == S_OK)
  1805. {
  1806. // allow proppages to clean up security info
  1807. pControlPage->SetAllocedSecurityInfo(pCASecurity);
  1808. HPROPSHEETPAGE hPage = CreateSecurityPage(pCASecurity);
  1809. if (hPage == NULL)
  1810. {
  1811. hr = myHLastError();
  1812. _JumpError(hr, Ret, "CreatePropertySheetPage");
  1813. }
  1814. lpProvider->AddPage(hPage);
  1815. }
  1816. }
  1817. hr = S_OK;
  1818. break;
  1819. }// end case SERVER_INSTANCE
  1820. case SERVERFUNC_CRL_PUBLICATION:
  1821. {
  1822. //1
  1823. CCRLPropPage* pControlPage = new CCRLPropPage(pFolder->m_pCertCA);
  1824. if (pControlPage != NULL)
  1825. {
  1826. pControlPage->m_hConsoleHandle = handle;
  1827. pBasePage = pControlPage;
  1828. // Object gets deleted when the page is destroyed
  1829. ASSERT(lpProvider != NULL);
  1830. ASSERT(pBasePage != NULL);
  1831. HPROPSHEETPAGE hPage = CreatePropertySheetPage(&pBasePage->m_psp);
  1832. if (hPage == NULL)
  1833. {
  1834. hr = myHLastError();
  1835. _JumpError(hr, Ret, "CreatePropertySheetPage");
  1836. }
  1837. lpProvider->AddPage(hPage);
  1838. }
  1839. //2
  1840. {
  1841. CCRLViewPage* pPage = new CCRLViewPage(pControlPage);
  1842. if (pPage != NULL)
  1843. {
  1844. pBasePage = pPage;
  1845. HPROPSHEETPAGE hPage = CreatePropertySheetPage(&pBasePage->m_psp);
  1846. if (hPage == NULL)
  1847. {
  1848. hr = myHLastError();
  1849. _JumpError(hr, Ret, "CreatePropertySheetPage");
  1850. }
  1851. lpProvider->AddPage(hPage);
  1852. }
  1853. }
  1854. break;
  1855. }
  1856. default:
  1857. break;
  1858. } // end switch(pFolder->m_type)
  1859. } // end switch(scope)
  1860. }
  1861. break;
  1862. default:
  1863. break;
  1864. }
  1865. Ret:
  1866. FREE_DATA(pInternal);
  1867. return hr;
  1868. }
  1869. STDMETHODIMP CComponentDataImpl::QueryPagesFor(LPDATAOBJECT lpDataObject)
  1870. {
  1871. BOOL bResult = FALSE;
  1872. INTERNAL* pInternal = ExtractInternalFormat(lpDataObject);
  1873. if (NULL == pInternal)
  1874. return S_FALSE;
  1875. if (pInternal->m_cookie != NULL)
  1876. {
  1877. CFolder* pFolder = GetParentFolder(pInternal);
  1878. if (pFolder != NULL)
  1879. {
  1880. switch(pFolder->m_type)
  1881. {
  1882. case SERVER_INSTANCE:
  1883. case SERVERFUNC_CRL_PUBLICATION:
  1884. bResult = TRUE;
  1885. default:
  1886. break;
  1887. }
  1888. }
  1889. }
  1890. else
  1891. {
  1892. // say YES to snapin manager
  1893. if (CCT_SNAPIN_MANAGER == pInternal->m_type)
  1894. bResult = TRUE;
  1895. }
  1896. FREE_DATA(pInternal);
  1897. return (bResult) ? S_OK : S_FALSE;
  1898. // Look at the data object and see if it an item in the scope pane
  1899. // return IsScopePaneNode(lpDataObject) ? S_OK : S_FALSE;
  1900. }
  1901. ///////////////////////////////////////////////////////////////////////////////
  1902. // IExtendContextMenu implementation
  1903. //
  1904. STDMETHODIMP CComponentDataImpl::AddMenuItems(LPDATAOBJECT pDataObject,
  1905. LPCONTEXTMENUCALLBACK pContextMenuCallback,
  1906. LONG *pInsertionAllowed)
  1907. {
  1908. HRESULT hr = S_OK;
  1909. TASKITEM* pm = NULL;
  1910. // Note - snap-ins need to look at the data object and determine
  1911. // in what context, menu items need to be added. They must also
  1912. // observe the insertion allowed flags to see what items can be
  1913. // added.
  1914. INTERNAL* pInternal = ExtractInternalFormat(pDataObject);
  1915. if (NULL == pInternal)
  1916. return S_OK;
  1917. BOOL fResultItem = (pInternal->m_type == CCT_RESULT);
  1918. BOOL fMultiSel = IsMMCMultiSelectDataObject(pDataObject);
  1919. CFolder* pFolder;
  1920. if (!fResultItem)
  1921. pFolder = GetParentFolder(pInternal);
  1922. else
  1923. {
  1924. // GetParent might work, but doesn't for virtual items...
  1925. ASSERT(m_pCurSelFolder);
  1926. pFolder = m_pCurSelFolder;
  1927. }
  1928. FOLDER_TYPES folderType = NONE;
  1929. if (pFolder == NULL)
  1930. folderType = MACHINE_INSTANCE;
  1931. else
  1932. folderType = pFolder->GetType();
  1933. // Loop through and add each of the "topItems"
  1934. if (*pInsertionAllowed & CCM_INSERTIONALLOWED_TOP)
  1935. {
  1936. // don't do for multisel
  1937. if (!fMultiSel)
  1938. {
  1939. pm = (TASKITEM*) LocalAlloc(LMEM_FIXED, sizeof(topItems));
  1940. _JumpIfAllocFailed(pm, Ret);
  1941. memcpy(pm, topItems, sizeof(topItems));
  1942. // Disable retarget if we haven't yet clicked on the static root. Otherwise,
  1943. // DisplayProperRootNodeName handles load-from-file
  1944. // MMCN_EXPAND handles add/remove and expanded
  1945. pm[ENUM_RETARGET_SNAPIN].myitem.item.fFlags = m_pStaticRoot ? MFS_ENABLED : MFS_GRAYED;
  1946. for (TASKITEM* pm1=pm; pm1->myitem.item.strName; pm1++)
  1947. {
  1948. // does it match scope/result type?
  1949. if (fResultItem != ((pm1->dwFlags & TASKITEM_FLAG_RESULTITEM) != 0) )
  1950. continue;
  1951. // does it match area it should be in?
  1952. // for each task, insert if matches the current folder
  1953. if ((pm1->type != SERVERFUNC_ALL_FOLDERS) && (folderType != pm1->type))
  1954. continue;
  1955. hr = pContextMenuCallback->AddItem(&pm1->myitem.item);
  1956. _JumpIfError(hr, Ret, "AddItem");
  1957. }
  1958. LocalFree(pm);
  1959. pm = NULL;
  1960. }
  1961. }
  1962. // this is the end of the line if folder nonexistant
  1963. if (pFolder == NULL)
  1964. goto Ret;
  1965. // Loop through and add each of the view items
  1966. if (*pInsertionAllowed & CCM_INSERTIONALLOWED_VIEW)
  1967. {
  1968. }
  1969. if (*pInsertionAllowed & CCM_INSERTIONALLOWED_TASK)
  1970. {
  1971. // ptr to tasks
  1972. pm = (TASKITEM*) LocalAlloc(LMEM_FIXED, sizeof(taskItems));
  1973. _JumpIfAllocFailed(pm, Ret);
  1974. memcpy(pm, taskItems, sizeof(taskItems));
  1975. BOOL fRunningLocally = m_pCertMachine->IsLocalMachine();
  1976. BOOL fSvcRunning = m_pCertMachine->IsCertSvrServiceRunning();
  1977. if ( IsAllowedStartStop(pFolder, m_pCertMachine) )
  1978. AddStartStopTasks(pFolder, pContextMenuCallback, fSvcRunning);
  1979. // only fixup on server instance
  1980. if (folderType == SERVER_INSTANCE)
  1981. {
  1982. // fixup entries depending on install type/state
  1983. if (IsRootCA(pFolder->GetCA()->GetCAType())) // root ca?
  1984. {
  1985. pm[ENUM_TASK_INSTALL].myitem.item.fFlags = MFS_HIDDEN; // not available
  1986. pm[ENUM_TASK_REQUEST].myitem.item.fFlags = MFS_HIDDEN; // not available
  1987. pm[ENUM_TASK_ROLLOVER].myitem.item.fFlags = MFS_ENABLED;
  1988. }
  1989. else // sub ca
  1990. {
  1991. if (pFolder->GetCA()->FIsRequestOutstanding())
  1992. pm[ENUM_TASK_INSTALL].myitem.item.fFlags = MFS_ENABLED;
  1993. else
  1994. pm[ENUM_TASK_INSTALL].myitem.item.fFlags = MFS_HIDDEN;
  1995. if (pFolder->GetCA()->FIsIncompleteInstallation()) // incomplete
  1996. {
  1997. pm[ENUM_TASK_REQUEST].myitem.item.fFlags = MFS_ENABLED;
  1998. pm[ENUM_TASK_ROLLOVER].myitem.item.fFlags = MFS_HIDDEN; // not available
  1999. }
  2000. else // complete install
  2001. {
  2002. pm[ENUM_TASK_REQUEST].myitem.item.fFlags = MFS_HIDDEN; // not available
  2003. pm[ENUM_TASK_ROLLOVER].myitem.item.fFlags = MFS_ENABLED;
  2004. }
  2005. }
  2006. static bool fIsMember;
  2007. static bool fIsMemberChecked = false;
  2008. if(!fIsMemberChecked)
  2009. {
  2010. hr = myIsCurrentUserBuiltinAdmin(&fIsMember);
  2011. if(S_OK==hr)
  2012. {
  2013. fIsMemberChecked = true;
  2014. }
  2015. }
  2016. // Hide renew/install CA cert item if not local admin or if we
  2017. // failed to figure it out. Ignore the error.
  2018. // !!! Post Whistler when we get renew CA cert to work for non
  2019. // local admin we should change the code here to hide the item
  2020. // based on the role that is allowed to do it.
  2021. if(S_OK != hr || !fIsMember)
  2022. {
  2023. pm[ENUM_TASK_ROLLOVER].myitem.item.fFlags = MFS_HIDDEN;
  2024. hr = S_OK;
  2025. }
  2026. }
  2027. // don't allow properties on multisel
  2028. pm[ENUM_TASK_ATTREXTS_CRL].myitem.item.fFlags = fMultiSel ? MFS_HIDDEN : MFS_ENABLED;
  2029. pm[ENUM_TASK_ATTREXTS_ISS].myitem.item.fFlags = fMultiSel ? MFS_HIDDEN : MFS_ENABLED;
  2030. pm[ENUM_TASK_ATTREXTS_PEND].myitem.item.fFlags = fMultiSel ? MFS_HIDDEN : MFS_ENABLED;
  2031. pm[ENUM_TASK_ATTREXTS_FAIL].myitem.item.fFlags = fMultiSel ? MFS_HIDDEN : MFS_ENABLED;
  2032. // disable based on roles
  2033. for(TASKITEM* pm1=pm; pm1->myitem.item.strName; pm1++)
  2034. {
  2035. if((pm1->myitem.item.fFlags == MFS_ENABLED) &&
  2036. !((pm1->myitem.dwRoles) & (pFolder->m_pCertCA->GetMyRoles())))
  2037. pm1->myitem.item.fFlags = MFS_GRAYED;
  2038. }
  2039. // insert all other tasks per folder
  2040. for (TASKITEM* pm1=pm; pm1->myitem.item.strName; pm1++)
  2041. {
  2042. // does it match scope/result type?
  2043. if (fResultItem != ((pm1->dwFlags & TASKITEM_FLAG_RESULTITEM) != 0))
  2044. continue;
  2045. // are we remote, and is it marked localonly? (not yes/no like other tests here)
  2046. if (((pm1->dwFlags & TASKITEM_FLAG_LOCALONLY)) && (!fRunningLocally))
  2047. continue;
  2048. // does it match area it should be in?
  2049. // for each task, insert if matches the current folder
  2050. if ((pm1->type != SERVERFUNC_ALL_FOLDERS) && (folderType != pm1->type))
  2051. continue;
  2052. // is this task supposed to be hidden?
  2053. if (MFS_HIDDEN == pm1->myitem.item.fFlags)
  2054. continue;
  2055. hr = pContextMenuCallback->AddItem(&pm1->myitem.item);
  2056. _JumpIfError(hr, Ret, "AddItem");
  2057. }
  2058. LocalFree(pm);
  2059. pm = NULL;
  2060. }
  2061. Ret:
  2062. LOCAL_FREE(pm);
  2063. FREE_DATA(pInternal);
  2064. return hr;
  2065. }
  2066. BOOL CComponentDataImpl::AddStartStopTasks(
  2067. CFolder *pFolder,
  2068. LPCONTEXTMENUCALLBACK pContextMenuCallback,
  2069. BOOL fSvcRunning)
  2070. {
  2071. HRESULT hr;
  2072. MY_CONTEXTMENUITEM* pm = taskStartStop;
  2073. bool fUserCanStart = (pm[ENUM_TASK_START].dwRoles) & (pFolder->m_pCertCA->GetMyRoles())?
  2074. true:false;
  2075. bool fUserCanStop = (pm[ENUM_TASK_STOP].dwRoles) & (pFolder->m_pCertCA->GetMyRoles())?
  2076. true:false;
  2077. pm[ENUM_TASK_START].item.fFlags =
  2078. (fSvcRunning || !fUserCanStart)?
  2079. MF_GRAYED : MF_ENABLED;
  2080. hr = pContextMenuCallback->AddItem(&pm[ENUM_TASK_START].item);
  2081. _JumpIfError(hr, Ret, "AddItem");
  2082. pm[ENUM_TASK_STOP].item.fFlags =
  2083. (fSvcRunning && fUserCanStop)?
  2084. MF_ENABLED : MF_GRAYED;
  2085. hr = pContextMenuCallback->AddItem(&pm[ENUM_TASK_STOP].item);
  2086. _JumpIfError(hr, Ret, "AddItem");
  2087. Ret:
  2088. return (hr == ERROR_SUCCESS);
  2089. }
  2090. STDMETHODIMP CComponentDataImpl::Command(LONG nCommandID, LPDATAOBJECT pDataObject)
  2091. {
  2092. // Note - snap-ins need to look at the data object and determine
  2093. // in what context the command is being called.
  2094. HRESULT dwErr = S_OK;
  2095. INTERNAL* pInternal = ExtractInternalFormat(pDataObject);
  2096. ASSERT(pInternal);
  2097. if (NULL == pInternal)
  2098. return S_OK;
  2099. BOOL fMustRefresh = FALSE;
  2100. BOOL fPopup = TRUE;
  2101. CFolder* pFolder = GetParentFolder(pInternal);
  2102. // Handle each of the commands.
  2103. switch (nCommandID)
  2104. {
  2105. case IDC_STOPSERVER:
  2106. {
  2107. HWND hwndMain;
  2108. dwErr = m_pConsole->GetMainWindow(&hwndMain);
  2109. if (dwErr == S_OK)
  2110. dwErr = m_pCertMachine->CertSvrStartStopService(hwndMain, FALSE);
  2111. // notify views: refresh service toolbar buttons
  2112. fMustRefresh = TRUE;
  2113. break;
  2114. }
  2115. case IDC_STARTSERVER:
  2116. {
  2117. HWND hwndMain;
  2118. dwErr = m_pConsole->GetMainWindow(&hwndMain);
  2119. if (S_OK == dwErr)
  2120. dwErr = m_pCertMachine->CertSvrStartStopService(hwndMain, TRUE);
  2121. // check for ERROR_INSTALL_SUSPEND or HR(ERROR_INSTALL_SUSPEND)!!
  2122. if ((((HRESULT)ERROR_INSTALL_SUSPEND) == dwErr) || (HRESULT_FROM_WIN32(ERROR_INSTALL_SUSPEND) == dwErr))
  2123. {
  2124. CString cstrMsg, cstrTitle;
  2125. cstrMsg.LoadString(IDS_COMPLETE_HIERARCHY_INSTALL_MSG);
  2126. cstrTitle.LoadString(IDS_MSG_TITLE);
  2127. CertSvrCA* pCA;
  2128. for (DWORD i=0; i<m_pCertMachine->GetCaCount(); i++)
  2129. {
  2130. pCA = m_pCertMachine->GetCaAtPos(i);
  2131. // search for any/all incomplete hierarchies
  2132. if (pCA->FIsIncompleteInstallation())
  2133. {
  2134. int iRet;
  2135. WCHAR sz[512];
  2136. wsprintf(sz, (LPCWSTR)cstrMsg, (LPCWSTR)pCA->m_strCommonName, (LPCWSTR)pCA->m_strServer);
  2137. m_pConsole->MessageBox(
  2138. sz,
  2139. cstrTitle,
  2140. MB_YESNO,
  2141. &iRet);
  2142. if (IDYES != iRet)
  2143. break;
  2144. dwErr = CARequestInstallHierarchyWizard(pCA, hwndMain, FALSE, FALSE);
  2145. if (dwErr != S_OK)
  2146. {
  2147. // fPopup = FALSE;// sometimes no notification -- better to have 2 dlgs
  2148. break;
  2149. }
  2150. }
  2151. }
  2152. // my responsibility to start the service again
  2153. if (dwErr == S_OK)
  2154. dwErr = m_pCertMachine->CertSvrStartStopService(hwndMain, TRUE);
  2155. }
  2156. else if ((((HRESULT)ERROR_FILE_NOT_FOUND) == dwErr) || (HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == dwErr))
  2157. {
  2158. // file not found error could be related to policy module
  2159. WCHAR const *pwsz = myGetErrorMessageText(dwErr, TRUE);
  2160. CString cstrFullMessage = pwsz;
  2161. if (NULL != pwsz)
  2162. {
  2163. LocalFree(const_cast<WCHAR *>(pwsz));
  2164. }
  2165. cstrFullMessage += L"\n\n";
  2166. CString cstrHelpfulMessage;
  2167. cstrHelpfulMessage.LoadString(IDS_POSSIBLEERROR_NO_POLICY_MODULE);
  2168. cstrFullMessage += cstrHelpfulMessage;
  2169. CString cstrTitle;
  2170. cstrTitle.LoadString(IDS_MSG_TITLE);
  2171. int iRet;
  2172. m_pConsole->MessageBox(
  2173. cstrFullMessage,
  2174. cstrTitle,
  2175. MB_OK,
  2176. &iRet);
  2177. dwErr = ERROR_SUCCESS;
  2178. }
  2179. // notify views: refresh service toolbar buttons
  2180. fMustRefresh = TRUE;
  2181. break;
  2182. }
  2183. case IDC_PUBLISHCRL:
  2184. {
  2185. ASSERT(pInternal->m_type != CCT_RESULT);
  2186. if (NULL == pFolder)
  2187. break;
  2188. HWND hwnd;
  2189. dwErr = m_pConsole->GetMainWindow(&hwnd);
  2190. ASSERT(dwErr == ERROR_SUCCESS);
  2191. if (dwErr != ERROR_SUCCESS)
  2192. hwnd = NULL; // should work
  2193. dwErr = PublishCRLWizard(pFolder->m_pCertCA, hwnd);
  2194. break;
  2195. // no refresh
  2196. }
  2197. case IDC_BACKUP_CA:
  2198. {
  2199. HWND hwnd;
  2200. dwErr = m_pConsole->GetMainWindow(&hwnd);
  2201. // NULL should work
  2202. if (S_OK != dwErr)
  2203. hwnd = NULL;
  2204. if (NULL == pFolder)
  2205. break;
  2206. dwErr = CABackupWizard(pFolder->GetCA(), hwnd);
  2207. // refresh the status of the CA -- may have started it during this operation
  2208. fMustRefresh = TRUE;
  2209. break;
  2210. }
  2211. case IDC_RESTORE_CA:
  2212. {
  2213. HWND hwnd;
  2214. dwErr = m_pConsole->GetMainWindow(&hwnd);
  2215. // NULL should work
  2216. if (S_OK != dwErr)
  2217. hwnd = NULL;
  2218. if (NULL == pFolder)
  2219. break;
  2220. dwErr = CARestoreWizard(pFolder->GetCA(), hwnd);
  2221. if ((myJetHResult(JET_errDatabaseDuplicate) == dwErr) ||
  2222. HRESULT_FROM_WIN32(ERROR_DIR_NOT_EMPTY) == dwErr)
  2223. {
  2224. DisplayCertSrvErrorWithContext(hwnd, dwErr, IDS_ERR_RESTORE_OVER_EXISTING_DATABASE);
  2225. dwErr = S_OK;
  2226. }
  2227. if (HRESULT_FROM_WIN32(ERROR_DIRECTORY) == dwErr)
  2228. {
  2229. DisplayCertSrvErrorWithContext(hwnd, dwErr, IDS_ERR_RESTORE_OUT_OF_ORDER);
  2230. dwErr = S_OK;
  2231. }
  2232. // refresh after restore
  2233. fMustRefresh = TRUE;
  2234. break;
  2235. }
  2236. case IDC_SUBMITREQUEST:
  2237. {
  2238. HWND hwnd;
  2239. WCHAR szCmdLine[MAX_PATH], szSysDir[MAX_PATH];
  2240. STARTUPINFO sStartup;
  2241. ZeroMemory(&sStartup, sizeof(sStartup));
  2242. PROCESS_INFORMATION sProcess;
  2243. ZeroMemory(&sProcess, sizeof(sProcess));
  2244. sStartup.cb = sizeof(sStartup);
  2245. dwErr = m_pConsole->GetMainWindow(&hwnd);
  2246. // NULL should work
  2247. if (S_OK != dwErr)
  2248. hwnd = NULL;
  2249. if (NULL == pFolder)
  2250. break;
  2251. if (0 == GetSystemDirectory(szSysDir, ARRAYSIZE(szSysDir)))
  2252. {
  2253. dwErr = GetLastError();
  2254. break;
  2255. }
  2256. // exec "certutil -dump szReqFile szTempFile"
  2257. wsprintf(szCmdLine, L"%ws\\certreq.exe -config \"%ws\"", szSysDir, (LPCWSTR)pFolder->GetCA()->m_strConfig);
  2258. wcscat(szSysDir, L"\\certreq.exe");
  2259. if (!CreateProcess(
  2260. szSysDir, // exe
  2261. szCmdLine, // full cmd line
  2262. NULL,
  2263. NULL,
  2264. FALSE,
  2265. CREATE_NO_WINDOW,
  2266. NULL,
  2267. NULL,
  2268. &sStartup,
  2269. &sProcess))
  2270. {
  2271. dwErr = GetLastError();
  2272. break;
  2273. }
  2274. dwErr = S_OK;
  2275. break;
  2276. }
  2277. case IDC_INSTALL_CA:
  2278. case IDC_REQUEST_CA:
  2279. case IDC_ROLLOVER_CA:
  2280. {
  2281. HWND hwnd;
  2282. dwErr = m_pConsole->GetMainWindow(&hwnd);
  2283. // NULL should work
  2284. if (S_OK != dwErr)
  2285. hwnd = NULL;
  2286. if (NULL == pFolder)
  2287. {
  2288. dwErr = E_UNEXPECTED;
  2289. break;
  2290. }
  2291. dwErr = CARequestInstallHierarchyWizard(pFolder->GetCA(), hwnd, (nCommandID==IDC_ROLLOVER_CA), TRUE);
  2292. if (S_OK != dwErr)
  2293. {
  2294. // low level lib had popup
  2295. // fPopup = FALSE; // sometimes no notification -- better to have 2 dlgs
  2296. }
  2297. // notify views: refresh service toolbar buttons
  2298. fMustRefresh = TRUE;
  2299. break;
  2300. }
  2301. case IDC_RETARGET_SNAPIN:
  2302. {
  2303. HWND hwnd;
  2304. dwErr = m_pConsole->GetMainWindow(&hwnd);
  2305. // NULL should work
  2306. if (S_OK != dwErr)
  2307. hwnd = NULL;
  2308. // this should be base folder ONLY
  2309. if(pFolder != NULL)
  2310. {
  2311. dwErr = E_POINTER;
  2312. break;
  2313. }
  2314. CString strMachineNamePersist, strMachineName;
  2315. CChooseMachinePropPage* pPage = new CChooseMachinePropPage(); // autodelete proppage -- don't delete
  2316. if (pPage == NULL)
  2317. {
  2318. dwErr = E_OUTOFMEMORY;
  2319. break;
  2320. }
  2321. pPage->SetCaption(IDS_SCOPE_MYCOMPUTER);
  2322. // Initialize state of object
  2323. pPage->InitMachineName(NULL);
  2324. // populate UI
  2325. strMachineNamePersist = m_pCertMachine->m_strMachineNamePersist;
  2326. strMachineName = m_pCertMachine->m_strMachineName;
  2327. // point to our member vars
  2328. pPage->SetOutputBuffers(
  2329. &strMachineNamePersist,
  2330. &strMachineName,
  2331. &m_dwFlagsPersist);
  2332. ASSERT(pPage != NULL);
  2333. HPROPSHEETPAGE hPage = CreatePropertySheetPage(&pPage->m_psp);
  2334. if (hPage == NULL)
  2335. {
  2336. dwErr = E_UNEXPECTED;
  2337. break;
  2338. }
  2339. PROPSHEETHEADER sPsh;
  2340. ZeroMemory(&sPsh, sizeof(sPsh));
  2341. sPsh.dwSize = sizeof(sPsh);
  2342. sPsh.dwFlags = PSH_WIZARD;
  2343. sPsh.hwndParent = hwnd;
  2344. sPsh.hInstance = g_hInstance;
  2345. sPsh.nPages = 1;
  2346. sPsh.phpage = &hPage;
  2347. dwErr = (DWORD) PropertySheet(&sPsh);
  2348. if (dwErr == (HRESULT)-1)
  2349. {
  2350. // error
  2351. dwErr = GetLastError();
  2352. break;
  2353. }
  2354. if (dwErr == (HRESULT)0)
  2355. {
  2356. // cancel
  2357. break;
  2358. }
  2359. // we've grabbed the user's choice by now, finish retargetting
  2360. CertSvrMachine* pOldMachine = m_pCertMachine;
  2361. m_pCertMachine = new CertSvrMachine;
  2362. if (NULL == m_pCertMachine)
  2363. {
  2364. m_pCertMachine = pOldMachine;
  2365. break; // bail!
  2366. }
  2367. // copy to machine object
  2368. m_pCertMachine->m_strMachineNamePersist = strMachineNamePersist;
  2369. m_pCertMachine->m_strMachineName = strMachineName;
  2370. dwErr = DisplayProperRootNodeName(m_pStaticRoot); // fix display
  2371. _PrintIfError(dwErr, "DisplayProperRootNodeName");
  2372. dwErr = SynchDisplayedCAList(pDataObject); // add/remove folders
  2373. _PrintIfError(dwErr, "SynchDisplayedCAList");
  2374. // after Synch, we remove old machine -- there are no references left to it
  2375. if (pOldMachine)
  2376. pOldMachine->Release();
  2377. fMustRefresh = TRUE; // update folder icons, descriptions
  2378. break;
  2379. }
  2380. default:
  2381. ASSERT(FALSE); // Unknown command!
  2382. break;
  2383. }
  2384. FREE_DATA(pInternal);
  2385. if ((dwErr != ERROR_SUCCESS) &&
  2386. (dwErr != ERROR_CANCELLED) &&
  2387. (dwErr != HRESULT_FROM_WIN32(ERROR_CANCELLED)) &&
  2388. (dwErr != HRESULT_FROM_WIN32(ERROR_NOT_READY))
  2389. && fPopup)
  2390. {
  2391. HWND hwnd;
  2392. DWORD dwErr2 = m_pConsole->GetMainWindow(&hwnd);
  2393. ASSERT(dwErr2 == ERROR_SUCCESS);
  2394. if (dwErr2 != ERROR_SUCCESS)
  2395. hwnd = NULL; // should work
  2396. if (((HRESULT)RPC_S_SERVER_UNAVAILABLE) == dwErr)
  2397. {
  2398. DisplayCertSrvErrorWithContext(hwnd, dwErr, IDS_SERVER_UNAVAILABLE);
  2399. }
  2400. else if(HRESULT_FROM_WIN32(ERROR_OLD_WIN_VERSION)==dwErr ||
  2401. ((HRESULT)ERROR_OLD_WIN_VERSION)==dwErr)
  2402. {
  2403. DisplayCertSrvErrorWithContext(hwnd, dwErr, IDS_OLD_CA);
  2404. }
  2405. else
  2406. {
  2407. DisplayGenericCertSrvError(hwnd, dwErr);
  2408. }
  2409. }
  2410. // only do this once
  2411. if (fMustRefresh)
  2412. {
  2413. // notify views: refresh service toolbar buttons
  2414. m_pConsole->UpdateAllViews(
  2415. pDataObject,
  2416. 0,
  2417. 0);
  2418. }
  2419. return S_OK;
  2420. }
  2421. void CComponentDataImpl::UpdateScopeIcons()
  2422. {
  2423. CFolder* pFolder;
  2424. POSITION pos;
  2425. int nImage;
  2426. // walk through our internal list, modify, and resend to scope
  2427. pos = m_scopeItemList.GetHeadPosition();
  2428. while(pos)
  2429. {
  2430. pFolder = m_scopeItemList.GetNext(pos);
  2431. ASSERT(pFolder);
  2432. if (NULL == pFolder)
  2433. break;
  2434. // only modify server instances
  2435. if (pFolder->GetType() != SERVER_INSTANCE)
  2436. continue;
  2437. if (pFolder->m_pCertCA->m_pParentMachine->IsCertSvrServiceRunning())
  2438. nImage = IMGINDEX_CERTSVR_RUNNING;
  2439. else
  2440. nImage = IMGINDEX_CERTSVR_STOPPED;
  2441. // folder currently has these values defined, right?
  2442. ASSERT(pFolder->m_ScopeItem.mask & SDI_IMAGE);
  2443. ASSERT(pFolder->m_ScopeItem.mask & SDI_OPENIMAGE);
  2444. // These are the only values we wish to reset
  2445. pFolder->m_ScopeItem.mask = SDI_IMAGE | SDI_OPENIMAGE;
  2446. pFolder->m_ScopeItem.nImage = nImage;
  2447. pFolder->m_ScopeItem.nOpenImage = nImage;
  2448. // and send these changes back to scope
  2449. m_pScope->SetItem(&pFolder->m_ScopeItem);
  2450. }
  2451. return;
  2452. }