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.

1492 lines
40 KiB

  1. /**********************************************************************/
  2. /** Microsoft Windows/NT **/
  3. /** Copyright(c) Microsoft Corporation, 1997 - 2002 **/
  4. /**********************************************************************/
  5. /*
  6. provider.cpp
  7. Main Mode Policy node handler
  8. FILE HISTORY:
  9. */
  10. #include "stdafx.h"
  11. #include "server.h"
  12. #include "ActPol.h"
  13. // magic strings
  14. #define IPSEC_SERVICE_NAME TEXT("policyagent")
  15. #define GPEXT_KEY TEXT("Software\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon\\GPExtensions")
  16. TCHAR pcszGPTIPSecKey[] = TEXT("SOFTWARE\\Policies\\Microsoft\\Windows\\IPSEC\\GPTIPSECPolicy");
  17. TCHAR pcszGPTIPSecName[] = TEXT("DSIPSECPolicyName");
  18. TCHAR pcszGPTIPSecFlags[] = TEXT("DSIPSECPolicyFlags");
  19. TCHAR pcszGPTIPSecPath[] = TEXT("DSIPSECPolicyPath");
  20. TCHAR pcszLocIPSecKey[] = TEXT("SOFTWARE\\Policies\\Microsoft\\Windows\\IPSEC\\Policy\\Local");
  21. TCHAR pcszLocIPSecPol[] = TEXT("ActivePolicy");
  22. TCHAR pcszCacheIPSecKey[] = TEXT("SOFTWARE\\Policies\\Microsoft\\Windows\\IPSEC\\Policy\\Cache");
  23. TCHAR pcszIPSecPolicy[] = TEXT("ipsecPolicy");
  24. TCHAR pcszIPSecName[] = TEXT("ipsecName");
  25. TCHAR pcszIPSecDesc[] = TEXT("description");
  26. TCHAR pcszIPSecTimestamp[] = TEXT("whenChanged");
  27. TCHAR pcszIpsecClsid[] = TEXT("{e437bc1c-aa7d-11d2-a382-00c04f991e27}");
  28. UINT ActPolItems[] = {
  29. IDS_ACTPOL_POLNAME,
  30. IDS_ACTPOL_POLDESCR,
  31. IDS_ACTPOL_LASTMODF,
  32. IDS_ACTPOL_POLSTORE,
  33. IDS_ACTPOL_POLPATH,
  34. IDS_ACTPOL_OU,
  35. IDS_ACTPOL_GPONAME
  36. };
  37. /*---------------------------------------------------------------------------
  38. Class CActPolHandler implementation
  39. ---------------------------------------------------------------------------*/
  40. /*---------------------------------------------------------------------------
  41. Constructor and destructor
  42. Description
  43. Author: NSun
  44. ---------------------------------------------------------------------------*/
  45. CActPolHandler::CActPolHandler
  46. (
  47. ITFSComponentData * pComponentData
  48. ) : CIpsmHandler(pComponentData)
  49. {
  50. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  51. }
  52. CActPolHandler::~CActPolHandler()
  53. {
  54. }
  55. /*!--------------------------------------------------------------------------
  56. CActPolHandler::InitializeNode
  57. Initializes node specific data
  58. Author: NSun
  59. ---------------------------------------------------------------------------*/
  60. HRESULT
  61. CActPolHandler::InitializeNode
  62. (
  63. ITFSNode * pNode
  64. )
  65. {
  66. AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
  67. CString strTemp;
  68. strTemp.LoadString(IDS_ACTIVE_POLICY);
  69. SetDisplayName(strTemp);
  70. // Make the node immediately visible
  71. pNode->SetVisibilityState(TFS_VIS_SHOW);
  72. pNode->SetData(TFS_DATA_COOKIE, (LPARAM) pNode);
  73. pNode->SetData(TFS_DATA_IMAGEINDEX, ICON_IDX_FOLDER_CLOSED);
  74. pNode->SetData(TFS_DATA_OPENIMAGEINDEX, ICON_IDX_FOLDER_OPEN);
  75. pNode->SetData(TFS_DATA_USER, (LPARAM) this);
  76. pNode->SetData(TFS_DATA_TYPE, IPSECMON_ACTIVEPOL);
  77. pNode->SetData(TFS_DATA_SCOPE_LEAF_NODE, TRUE);
  78. SetColumnStringIDs(&aColumns[IPSECMON_ACTIVEPOL][0]);
  79. SetColumnWidths(&aColumnWidths[IPSECMON_ACTIVEPOL][0]);
  80. return hrOK;
  81. }
  82. /*---------------------------------------------------------------------------
  83. CActPolHandler::GetImageIndex
  84. -
  85. Author: NSun
  86. ---------------------------------------------------------------------------*/
  87. int
  88. CActPolHandler::GetImageIndex(BOOL bOpenImage)
  89. {
  90. int nIndex = -1;
  91. return nIndex;
  92. }
  93. /*---------------------------------------------------------------------------
  94. Overridden base handler functions
  95. ---------------------------------------------------------------------------*/
  96. /*---------------------------------------------------------------------------
  97. CActPolHandler::OnAddMenuItems
  98. Adds context menu items for the SA scope pane node
  99. Author: NSun
  100. ---------------------------------------------------------------------------*/
  101. STDMETHODIMP
  102. CActPolHandler::OnAddMenuItems
  103. (
  104. ITFSNode * pNode,
  105. LPCONTEXTMENUCALLBACK pContextMenuCallback,
  106. LPDATAOBJECT lpDataObject,
  107. DATA_OBJECT_TYPES type,
  108. DWORD dwType,
  109. long * pInsertionAllowed
  110. )
  111. {
  112. AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
  113. LONG fFlags = 0, fLoadingFlags = 0;
  114. HRESULT hr = S_OK;
  115. if (type == CCT_SCOPE)
  116. {
  117. //load scope node context menu items here
  118. // these menu items go in the new menu,
  119. // only visible from scope pane
  120. if (*pInsertionAllowed & CCM_INSERTIONALLOWED_TOP)
  121. {
  122. }
  123. }
  124. return hr;
  125. }
  126. /*!--------------------------------------------------------------------------
  127. CActPolHandler::AddMenuItems
  128. Adds context menu items for virtual list box (result pane) items
  129. Author: NSun
  130. ---------------------------------------------------------------------------*/
  131. STDMETHODIMP
  132. CActPolHandler::AddMenuItems
  133. (
  134. ITFSComponent * pComponent,
  135. MMC_COOKIE cookie,
  136. LPDATAOBJECT pDataObject,
  137. LPCONTEXTMENUCALLBACK pContextMenuCallback,
  138. long * pInsertionAllowed
  139. )
  140. {
  141. AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
  142. HRESULT hr = hrOK;
  143. CString strMenuItem;
  144. SPINTERNAL spInternal;
  145. LONG fFlags = 0;
  146. spInternal = ExtractInternalFormat(pDataObject);
  147. // virtual listbox notifications come to the handler of the node that is selected.
  148. // check to see if this notification is for a virtual listbox item or this SA
  149. // node itself.
  150. if (*pInsertionAllowed & CCM_INSERTIONALLOWED_VIEW)
  151. {
  152. //load and view menu items here
  153. }
  154. return hr;
  155. }
  156. /*!--------------------------------------------------------------------------
  157. CActPolHandler::OnRefresh
  158. Default implementation for the refresh functionality
  159. Author: NSun
  160. ---------------------------------------------------------------------------*/
  161. HRESULT
  162. CActPolHandler::OnRefresh
  163. (
  164. ITFSNode * pNode,
  165. LPDATAOBJECT pDataObject,
  166. DWORD dwType,
  167. LPARAM arg,
  168. LPARAM param
  169. )
  170. {
  171. HRESULT hr = S_OK;
  172. int i = 0;
  173. SPIConsole spConsole;
  174. CORg(CHandler::OnRefresh(pNode, pDataObject, dwType, arg, param));
  175. i = sizeof(ActPolItems)/sizeof(UINT);
  176. UpdateActivePolicyInfo();
  177. // now notify the virtual listbox
  178. CORg ( m_spNodeMgr->GetConsole(&spConsole) );
  179. CORg ( spConsole->UpdateAllViews(pDataObject, i, RESULT_PANE_SET_VIRTUAL_LB_SIZE));
  180. Error:
  181. return hr;
  182. }
  183. /*---------------------------------------------------------------------------
  184. CActPolHandler::OnCommand
  185. Handles context menu commands for SA scope pane node
  186. Author: NSun
  187. ---------------------------------------------------------------------------*/
  188. STDMETHODIMP
  189. CActPolHandler::OnCommand
  190. (
  191. ITFSNode * pNode,
  192. long nCommandId,
  193. DATA_OBJECT_TYPES type,
  194. LPDATAOBJECT pDataObject,
  195. DWORD dwType
  196. )
  197. {
  198. AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
  199. return S_OK;
  200. }
  201. /*!--------------------------------------------------------------------------
  202. CActPolHandler::Command
  203. Handles context menu commands for virtual listbox items
  204. Author: NSun
  205. ---------------------------------------------------------------------------*/
  206. STDMETHODIMP
  207. CActPolHandler::Command
  208. (
  209. ITFSComponent * pComponent,
  210. MMC_COOKIE cookie,
  211. int nCommandID,
  212. LPDATAOBJECT pDataObject
  213. )
  214. {
  215. AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
  216. HRESULT hr = S_OK;
  217. SPITFSNode spNode;
  218. m_spResultNodeMgr->FindNode(cookie, &spNode);
  219. // handle result context menu and view menus here
  220. return hr;
  221. }
  222. /*!--------------------------------------------------------------------------
  223. CActPolHandler::HasPropertyPages
  224. Implementation of ITFSNodeHandler::HasPropertyPages
  225. NOTE: the root node handler has to over-ride this function to
  226. handle the snapin manager property page (wizard) case!!!
  227. Author: KennT
  228. ---------------------------------------------------------------------------*/
  229. STDMETHODIMP
  230. CActPolHandler::HasPropertyPages
  231. (
  232. ITFSNode * pNode,
  233. LPDATAOBJECT pDataObject,
  234. DATA_OBJECT_TYPES type,
  235. DWORD dwType
  236. )
  237. {
  238. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  239. return hrFalse;
  240. }
  241. /*---------------------------------------------------------------------------
  242. CActPolHandler::CreatePropertyPages
  243. Description
  244. Author: NSun
  245. ---------------------------------------------------------------------------*/
  246. STDMETHODIMP
  247. CActPolHandler::CreatePropertyPages
  248. (
  249. ITFSNode * pNode,
  250. LPPROPERTYSHEETCALLBACK lpSA,
  251. LPDATAOBJECT pDataObject,
  252. LONG_PTR handle,
  253. DWORD dwType
  254. )
  255. {
  256. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  257. return hrFalse;
  258. }
  259. /*---------------------------------------------------------------------------
  260. CActPolHandler::OnPropertyChange
  261. Description
  262. Author: NSun
  263. ---------------------------------------------------------------------------*/
  264. HRESULT
  265. CActPolHandler::OnPropertyChange
  266. (
  267. ITFSNode * pNode,
  268. LPDATAOBJECT pDataobject,
  269. DWORD dwType,
  270. LPARAM arg,
  271. LPARAM lParam
  272. )
  273. {
  274. AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
  275. //CServerProperties * pServerProp = reinterpret_cast<CServerProperties *>(lParam);
  276. LONG_PTR changeMask = 0;
  277. // tell the property page to do whatever now that we are back on the
  278. // main thread
  279. //pServerProp->OnPropertyChange(TRUE, &changeMask);
  280. //pServerProp->AcknowledgeNotify();
  281. if (changeMask)
  282. pNode->ChangeNode(changeMask);
  283. return hrOK;
  284. }
  285. /*---------------------------------------------------------------------------
  286. CActPolHandler::OnExpand
  287. Handles enumeration of a scope item
  288. Author: NSun
  289. ---------------------------------------------------------------------------*/
  290. HRESULT
  291. CActPolHandler::OnExpand
  292. (
  293. ITFSNode * pNode,
  294. LPDATAOBJECT pDataObject,
  295. DWORD dwType,
  296. LPARAM arg,
  297. LPARAM param
  298. )
  299. {
  300. HRESULT hr = hrOK;
  301. if (m_bExpanded)
  302. return hr;
  303. // do the default handling
  304. CORg (CIpsmHandler::OnExpand(pNode, pDataObject, dwType, arg, param));
  305. Error:
  306. return hr;
  307. }
  308. /*!--------------------------------------------------------------------------
  309. CActPolHandler::OnResultSelect
  310. Handles the MMCN_SELECT notifcation
  311. Author: NSun
  312. ---------------------------------------------------------------------------*/
  313. HRESULT
  314. CActPolHandler::OnResultSelect
  315. (
  316. ITFSComponent * pComponent,
  317. LPDATAOBJECT pDataObject,
  318. MMC_COOKIE cookie,
  319. LPARAM arg,
  320. LPARAM lParam
  321. )
  322. {
  323. AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
  324. HRESULT hr = hrOK;
  325. SPINTERNAL spInternal;
  326. SPIConsole spConsole;
  327. SPIConsoleVerb spConsoleVerb;
  328. SPITFSNode spNode;
  329. BOOL bStates[ARRAYLEN(g_ConsoleVerbs)];
  330. int i;
  331. LONG_PTR dwNodeType;
  332. BOOL fSelect = HIWORD(arg);
  333. // virtual listbox notifications come to the handler of the node that is selected.
  334. // check to see if this notification is for a virtual listbox item or the active
  335. // registrations node itself.
  336. CORg (pComponent->GetConsoleVerb(&spConsoleVerb));
  337. m_verbDefault = MMC_VERB_OPEN;
  338. if (!fSelect)
  339. {
  340. return hr;
  341. }
  342. // Get the current count
  343. i = sizeof(ActPolItems)/sizeof(UINT);
  344. // now notify the virtual listbox
  345. CORg ( m_spNodeMgr->GetConsole(&spConsole) );
  346. CORg ( spConsole->UpdateAllViews(pDataObject, i, RESULT_PANE_SET_VIRTUAL_LB_SIZE) );
  347. // now update the verbs...
  348. spInternal = ExtractInternalFormat(pDataObject);
  349. Assert(spInternal);
  350. if (spInternal->HasVirtualIndex())
  351. {
  352. //TODO add to here if we want to have some result console verbs
  353. // we gotta do special stuff for the virtual index items
  354. dwNodeType = IPSECMON_MM_IKESTATS_ITEM;
  355. for (i = 0; i < ARRAYLEN(g_ConsoleVerbs); bStates[i++] = FALSE);
  356. m_verbDefault = MMC_VERB_PROPERTIES;
  357. }
  358. else
  359. {
  360. // enable/disable delete depending if the node supports it
  361. CORg (m_spNodeMgr->FindNode(cookie, &spNode));
  362. dwNodeType = spNode->GetData(TFS_DATA_TYPE);
  363. for (i = 0; i < ARRAYLEN(g_ConsoleVerbs); bStates[i++] = TRUE);
  364. //hide "delete" context menu
  365. bStates[MMC_VERB_DELETE & 0x000F] = FALSE;
  366. }
  367. EnableVerbs(spConsoleVerb, g_ConsoleVerbStates[dwNodeType], bStates);
  368. COM_PROTECT_ERROR_LABEL;
  369. return hr;
  370. }
  371. /*!--------------------------------------------------------------------------
  372. CActPolHandler::OnDelete
  373. The base handler calls this when MMC sends a MMCN_DELETE for a
  374. scope pane item. We just call our delete command handler.
  375. Author: NSun
  376. ---------------------------------------------------------------------------*/
  377. HRESULT
  378. CActPolHandler::OnDelete
  379. (
  380. ITFSNode * pNode,
  381. LPARAM arg,
  382. LPARAM lParam
  383. )
  384. {
  385. return S_FALSE;
  386. }
  387. /*!--------------------------------------------------------------------------
  388. CActPolHandler::HasPropertyPages
  389. Handle the result notification
  390. Author: NSun
  391. ---------------------------------------------------------------------------*/
  392. STDMETHODIMP
  393. CActPolHandler::HasPropertyPages(
  394. ITFSComponent *pComponent,
  395. MMC_COOKIE cookie,
  396. LPDATAOBJECT pDataObject)
  397. {
  398. return hrFalse;
  399. }
  400. /*!--------------------------------------------------------------------------
  401. CActPolHandler::HasPropertyPages
  402. Handle the result notification. Create the filter property sheet
  403. Author: NSun
  404. ---------------------------------------------------------------------------*/
  405. STDMETHODIMP CActPolHandler::CreatePropertyPages
  406. (
  407. ITFSComponent * pComponent,
  408. MMC_COOKIE cookie,
  409. LPPROPERTYSHEETCALLBACK lpProvider,
  410. LPDATAOBJECT pDataObject,
  411. LONG_PTR handle
  412. )
  413. {
  414. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  415. return hrFalse;
  416. }
  417. /*---------------------------------------------------------------------------
  418. CActPolHandler::OnGetResultViewType
  419. Return the result view that this node is going to support
  420. Author: NSun
  421. ---------------------------------------------------------------------------*/
  422. HRESULT
  423. CActPolHandler::OnGetResultViewType
  424. (
  425. ITFSComponent * pComponent,
  426. MMC_COOKIE cookie,
  427. LPOLESTR * ppViewType,
  428. long * pViewOptions
  429. )
  430. {
  431. if (cookie != NULL)
  432. {
  433. *pViewOptions = MMC_VIEW_OPTIONS_OWNERDATALIST;
  434. }
  435. return S_FALSE;
  436. }
  437. /*---------------------------------------------------------------------------
  438. CActPolHandler::GetVirtualImage
  439. Returns the image index for virtual listbox items
  440. Author: NSun
  441. ---------------------------------------------------------------------------*/
  442. int
  443. CActPolHandler::GetVirtualImage
  444. (
  445. int nIndex
  446. )
  447. {
  448. return ICON_IDX_POLICY;
  449. }
  450. /*---------------------------------------------------------------------------
  451. CActPolHandler::GetVirtualString
  452. returns a pointer to the string for virtual listbox items
  453. Author: NSun
  454. ---------------------------------------------------------------------------*/
  455. LPCWSTR
  456. CActPolHandler::GetVirtualString
  457. (
  458. int nIndex,
  459. int nCol
  460. )
  461. {
  462. HRESULT hr = S_OK;
  463. static CString strTemp;
  464. strTemp.Empty();
  465. if (nCol >= DimensionOf(aColumns[IPSECMON_MM_IKESTATS]))
  466. return NULL;
  467. switch (aColumns[IPSECMON_ACTIVEPOL][nCol])
  468. {
  469. case IDS_ACTPOL_ITEM:
  470. strTemp.LoadString(ActPolItems[nIndex]);
  471. return strTemp;
  472. break;
  473. case IDS_ACTPOL_DESCR:
  474. switch(ActPolItems[nIndex])
  475. {
  476. case IDS_ACTPOL_POLNAME:
  477. if(m_PolicyInfo.iPolicySource == PS_NO_POLICY)
  478. strTemp.LoadString(IDS_ACTPOL_NOACTPOL);
  479. else
  480. strTemp = m_PolicyInfo.pszPolicyName;
  481. break;
  482. case IDS_ACTPOL_POLDESCR:
  483. if(m_PolicyInfo.iPolicySource == PS_NO_POLICY)
  484. strTemp.LoadString(IDS_ACTPOL_NA);
  485. else
  486. strTemp = m_PolicyInfo.pszPolicyDesc;
  487. break;
  488. case IDS_ACTPOL_LASTMODF:
  489. if(m_PolicyInfo.iPolicySource == PS_NO_POLICY)
  490. strTemp.LoadString(IDS_ACTPOL_NA);
  491. else if(m_PolicyInfo.timestamp)
  492. FormatTime(m_PolicyInfo.timestamp, strTemp);
  493. break;
  494. case IDS_ACTPOL_POLSTORE:
  495. if(m_PolicyInfo.iPolicySource == PS_DS_POLICY)
  496. strTemp.LoadString(IDS_ACTPOL_DOMAIN);
  497. else if(m_PolicyInfo.iPolicySource == PS_DS_POLICY_CACHED)
  498. strTemp.LoadString(IDS_ACTPOL_DOMAIN_CACHED);
  499. else if(m_PolicyInfo.iPolicySource == PS_LOC_POLICY)
  500. strTemp.LoadString(IDS_ACTPOL_LOCAL);
  501. else
  502. strTemp.LoadString(IDS_ACTPOL_NA);
  503. break;
  504. case IDS_ACTPOL_POLPATH:
  505. if((m_PolicyInfo.iPolicySource == PS_DS_POLICY) || (m_PolicyInfo.iPolicySource == PS_DS_POLICY_CACHED))
  506. strTemp = m_PolicyInfo.pszPolicyPath;
  507. else
  508. strTemp.LoadString(IDS_ACTPOL_NA);
  509. break;
  510. case IDS_ACTPOL_OU:
  511. if((m_PolicyInfo.iPolicySource == PS_DS_POLICY) || (m_PolicyInfo.iPolicySource == PS_DS_POLICY_CACHED))
  512. strTemp = m_PolicyInfo.pszOU;
  513. else
  514. strTemp.LoadString(IDS_ACTPOL_NA);
  515. break;
  516. case IDS_ACTPOL_GPONAME:
  517. if((m_PolicyInfo.iPolicySource == PS_DS_POLICY) || (m_PolicyInfo.iPolicySource == PS_DS_POLICY_CACHED))
  518. strTemp = m_PolicyInfo.pszGPOName;
  519. else
  520. strTemp.LoadString(IDS_ACTPOL_NA);
  521. break;
  522. }
  523. return strTemp;
  524. break;
  525. default:
  526. Panic0("CActPolHandler::GetVirtualString - Unknown column!\n");
  527. break;
  528. }
  529. return NULL;
  530. }
  531. /*---------------------------------------------------------------------------
  532. CActPolHandler::CacheHint
  533. MMC tells us which items it will need before it requests things
  534. Author: NSun
  535. ---------------------------------------------------------------------------*/
  536. STDMETHODIMP
  537. CActPolHandler::CacheHint
  538. (
  539. int nStartIndex,
  540. int nEndIndex
  541. )
  542. {
  543. HRESULT hr = hrOK;;
  544. Trace2("CacheHint - Start %d, End %d\n", nStartIndex, nEndIndex);
  545. return hr;
  546. }
  547. /*---------------------------------------------------------------------------
  548. CActPolHandler::SortItems
  549. We are responsible for sorting of virtual listbox items
  550. Author: NSun
  551. ---------------------------------------------------------------------------*/
  552. /*STDMETHODIMP
  553. CActPolHandler::SortItems
  554. (
  555. int nColumn,
  556. DWORD dwSortOptions,
  557. LPARAM lUserParam
  558. )
  559. {
  560. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  561. HRESULT hr = S_OK;
  562. if (nColumn >= DimensionOf(aColumns[IPSECMON_MM_POLICY]))
  563. return E_INVALIDARG;
  564. BEGIN_WAIT_CURSOR
  565. DWORD dwIndexType = aColumns[IPSECMON_MM_POLICY][nColumn];
  566. hr = m_spSpdInfo->SortMmPolicies(dwIndexType, dwSortOptions);
  567. END_WAIT_CURSOR
  568. return hr;
  569. }*/
  570. /*!--------------------------------------------------------------------------
  571. CActPolHandler::OnResultUpdateView
  572. Implementation of ITFSResultHandler::OnResultUpdateView
  573. Author: NSun
  574. ---------------------------------------------------------------------------*/
  575. HRESULT CActPolHandler::OnResultUpdateView
  576. (
  577. ITFSComponent *pComponent,
  578. LPDATAOBJECT pDataObject,
  579. LPARAM data,
  580. LONG_PTR hint
  581. )
  582. {
  583. HRESULT hr = hrOK;
  584. SPITFSNode spSelectedNode;
  585. pComponent->GetSelectedNode(&spSelectedNode);
  586. if (spSelectedNode == NULL)
  587. return S_OK; // no selection for our IComponentData
  588. if ( hint == IPSECMON_UPDATE_STATUS )
  589. {
  590. SPINTERNAL spInternal = ExtractInternalFormat(pDataObject);
  591. ITFSNode * pNode = reinterpret_cast<ITFSNode *>(spInternal->m_cookie);
  592. SPITFSNode spSelectedNode;
  593. pComponent->GetSelectedNode(&spSelectedNode);
  594. if (pNode == spSelectedNode)
  595. {
  596. // if we are the selected node, then we need to update
  597. SPIResultData spResultData;
  598. CORg (pComponent->GetResultData(&spResultData));
  599. CORg (spResultData->SetItemCount((int) data, MMCLV_UPDATE_NOSCROLL));
  600. }
  601. }
  602. else
  603. {
  604. // we don't handle this message, let the base class do it.
  605. return CIpsmHandler::OnResultUpdateView(pComponent, pDataObject, data, hint);
  606. }
  607. COM_PROTECT_ERROR_LABEL;
  608. return hr;
  609. }
  610. /*!--------------------------------------------------------------------------
  611. CActPolHandler::LoadColumns
  612. Set the correct column header and then call the base class
  613. Author: NSun
  614. ---------------------------------------------------------------------------*/
  615. HRESULT
  616. CActPolHandler::LoadColumns
  617. (
  618. ITFSComponent * pComponent,
  619. MMC_COOKIE cookie,
  620. LPARAM arg,
  621. LPARAM lParam
  622. )
  623. {
  624. //set column info
  625. return CIpsmHandler::LoadColumns(pComponent, cookie, arg, lParam);
  626. }
  627. /*---------------------------------------------------------------------------
  628. Command handlers
  629. ---------------------------------------------------------------------------*/
  630. /*---------------------------------------------------------------------------
  631. CActPolHandler::OnDelete
  632. Removes a service SA
  633. Author: NSun
  634. ---------------------------------------------------------------------------*/
  635. HRESULT
  636. CActPolHandler::OnDelete
  637. (
  638. ITFSNode * pNode
  639. )
  640. {
  641. HRESULT hr = S_FALSE;
  642. return hr;
  643. }
  644. /*---------------------------------------------------------------------------
  645. CActPolHandler::UpdateStatus
  646. -
  647. Author: NSun
  648. ---------------------------------------------------------------------------*/
  649. HRESULT
  650. CActPolHandler::UpdateStatus
  651. (
  652. ITFSNode * pNode
  653. )
  654. {
  655. HRESULT hr = hrOK;
  656. SPIComponentData spComponentData;
  657. SPIConsole spConsole;
  658. IDataObject * pDataObject;
  659. SPIDataObject spDataObject;
  660. int i = 0;
  661. Trace0("CActPolHandler::UpdateStatus - Updating status for Filter");
  662. // force the listbox to update. We do this by setting the count and
  663. // telling it to invalidate the data
  664. CORg(m_spNodeMgr->GetComponentData(&spComponentData));
  665. CORg(m_spNodeMgr->GetConsole(&spConsole));
  666. // grab a data object to use
  667. CORg(spComponentData->QueryDataObject((MMC_COOKIE) pNode, CCT_RESULT, &pDataObject) );
  668. spDataObject = pDataObject;
  669. i = sizeof(ActPolItems)/sizeof(UINT);
  670. UpdateActivePolicyInfo();
  671. CORg(spConsole->UpdateAllViews(pDataObject, i, IPSECMON_UPDATE_STATUS));
  672. COM_PROTECT_ERROR_LABEL;
  673. return hr;
  674. }
  675. /*---------------------------------------------------------------------------
  676. Misc functions
  677. ---------------------------------------------------------------------------*/
  678. /*---------------------------------------------------------------------------
  679. CActPolHandler::InitData
  680. Initializes data for this node
  681. Author: NSun
  682. ---------------------------------------------------------------------------*/
  683. HRESULT
  684. CActPolHandler::InitData
  685. (
  686. ISpdInfo * pSpdInfo
  687. )
  688. {
  689. HRESULT hr = hrOK;
  690. m_spSpdInfo.Set(pSpdInfo);
  691. m_spSpdInfo->GetComputerName(&m_strCompName);
  692. UpdateActivePolicyInfo();
  693. return hr;
  694. }
  695. /********************************************************************
  696. FUNCTION: getPolicyInfo
  697. PURPOSE: gets information about currently assigned policy
  698. into m_PolicyInfo structure
  699. INPUT: none
  700. RETURNS: HRESULT. Will return ERROR_SUCCESS if everything is fine.
  701. *********************************************************************/
  702. HRESULT CActPolHandler::getPolicyInfo ( )
  703. {
  704. HKEY hRegKey=NULL, hRegHKey=NULL;
  705. DWORD dwType; // for RegQueryValueEx
  706. DWORD dwBufLen; // for RegQueryValueEx
  707. TCHAR pszBuf[STRING_TEXT_SIZE];
  708. DWORD dwError;
  709. DWORD dwValue;
  710. DWORD dwLength = sizeof(DWORD);
  711. //Initialize the m_PolicyInfo as PS_NO_POLICY assigned
  712. m_PolicyInfo.iPolicySource = PS_NO_POLICY;
  713. m_PolicyInfo.pszPolicyPath[0] = 0;
  714. m_PolicyInfo.pszPolicyName[0] = 0;
  715. m_PolicyInfo.pszPolicyDesc[0] = 0;
  716. dwError = RegConnectRegistry( m_strCompName,
  717. HKEY_LOCAL_MACHINE,
  718. &hRegHKey);
  719. BAIL_ON_WIN32_ERROR(dwError);
  720. dwError = RegOpenKeyEx( hRegHKey,
  721. pcszGPTIPSecKey,
  722. 0,
  723. KEY_READ,
  724. &hRegKey);
  725. if(ERROR_SUCCESS == dwError)
  726. {
  727. // query for flags, if flags aint' there or equal to 0, we don't have domain policy
  728. dwError = RegQueryValueEx(hRegKey,
  729. pcszGPTIPSecFlags,
  730. NULL,
  731. &dwType,
  732. (LPBYTE)&dwValue,
  733. &dwLength);
  734. if (dwValue == 0)
  735. dwError = ERROR_FILE_NOT_FOUND;
  736. // now get name
  737. if (dwError == ERROR_SUCCESS)
  738. {
  739. dwBufLen = MAXSTRLEN*sizeof(TCHAR);
  740. dwError = RegQueryValueEx( hRegKey,
  741. pcszGPTIPSecName,
  742. NULL,
  743. &dwType, // will be REG_SZ
  744. (LPBYTE) pszBuf,
  745. &dwBufLen);
  746. }
  747. }
  748. if (dwError == ERROR_SUCCESS)
  749. {
  750. PSPD_POLICY_STATE pPolicyState;
  751. QuerySpdPolicyState((LPTSTR)(LPCTSTR)m_strCompName, 0, &pPolicyState, 0);
  752. if (pPolicyState->PolicyLoadState == SPD_STATE_CACHE_APPLY_SUCCESS) {
  753. m_PolicyInfo.iPolicySource = PS_DS_POLICY_CACHED;
  754. } else {
  755. m_PolicyInfo.iPolicySource = PS_DS_POLICY;
  756. }
  757. m_PolicyInfo.pszPolicyPath[0] = 0;
  758. _tcscpy(m_PolicyInfo.pszPolicyName, pszBuf);
  759. dwBufLen = MAXSTRLEN*sizeof(TCHAR);
  760. dwError = RegQueryValueEx( hRegKey,
  761. pcszGPTIPSecPath,
  762. NULL,
  763. &dwType, // will be REG_SZ
  764. (LPBYTE) pszBuf,
  765. &dwBufLen);
  766. if (dwError == ERROR_SUCCESS)
  767. {
  768. _tcscpy(m_PolicyInfo.pszPolicyPath, pszBuf);
  769. }
  770. dwError = ERROR_SUCCESS;
  771. goto error;
  772. }
  773. else
  774. {
  775. RegCloseKey(hRegKey);
  776. hRegKey = NULL;
  777. if (dwError == ERROR_FILE_NOT_FOUND)
  778. {
  779. // DS reg key not found, check local
  780. dwError = RegOpenKeyEx( hRegHKey,
  781. pcszLocIPSecKey,
  782. 0,
  783. KEY_READ,
  784. &hRegKey);
  785. BAIL_ON_WIN32_ERROR(dwError);
  786. dwBufLen = MAXSTRLEN*sizeof(TCHAR);
  787. dwError = RegQueryValueEx( hRegKey,
  788. pcszLocIPSecPol,
  789. NULL,
  790. &dwType, // will be REG_SZ
  791. (LPBYTE) pszBuf,
  792. &dwBufLen);
  793. if (dwError == ERROR_SUCCESS)
  794. {
  795. // read it
  796. RegCloseKey(hRegKey);
  797. hRegKey = NULL;
  798. dwError = RegOpenKeyEx( hRegHKey,
  799. pszBuf,
  800. 0,
  801. KEY_READ,
  802. &hRegKey);
  803. _tcscpy(m_PolicyInfo.pszPolicyPath, pszBuf);
  804. if (dwError == ERROR_SUCCESS)
  805. {
  806. dwBufLen = MAXSTRLEN*sizeof(TCHAR);
  807. dwError = RegQueryValueEx( hRegKey,
  808. pcszIPSecName,
  809. NULL,
  810. &dwType, // will be REG_SZ
  811. (LPBYTE) pszBuf,
  812. &dwBufLen);
  813. }
  814. if (dwError == ERROR_SUCCESS)
  815. { // found it
  816. m_PolicyInfo.iPolicySource = PS_LOC_POLICY;
  817. _tcscpy(m_PolicyInfo.pszPolicyName, pszBuf);
  818. }
  819. dwError = ERROR_SUCCESS;
  820. }
  821. }
  822. }
  823. error:
  824. if (hRegKey)
  825. {
  826. RegCloseKey(hRegKey);
  827. }
  828. if (hRegHKey)
  829. {
  830. RegCloseKey(hRegHKey);
  831. }
  832. return (HRESULT) dwError;
  833. }
  834. /********************************************************************
  835. FUNCTION: getMorePolicyInfo
  836. PURPOSE: gets additional information about currently assigned policy
  837. into m_PolicyInfo structure
  838. INPUT: none, uses m_PolicyInfo structure
  839. particularly
  840. iPolicySource
  841. pszPolicyName
  842. pszPolicyPath
  843. fields
  844. RETURNS: HRESULT. Will return ERROR_SUCCESS if everything is fine.
  845. Currently fills pszPolicyDesc and timestamp fields of the global structure
  846. NOTES: This is separate from getPolicyInfo routine for two reasons
  847. a) the information obtained here is optional and error during this particular routine
  848. is not considered fatal
  849. b) the code structure is simpler as this routine is "built on top" of what getPolicyInfo provides
  850. *********************************************************************/
  851. HRESULT CActPolHandler::getMorePolicyInfo ( )
  852. {
  853. DWORD dwError = ERROR_SUCCESS;
  854. HKEY hRegKey = NULL, hRegHKey = NULL;
  855. DWORD dwType; // for RegQueryValueEx
  856. DWORD dwBufLen; // for RegQueryValueEx
  857. DWORD dwValue;
  858. DWORD dwLength = sizeof(DWORD);
  859. TCHAR pszBuf[STRING_TEXT_SIZE];
  860. PTCHAR* ppszExplodeDN = NULL;
  861. // set some default values
  862. m_PolicyInfo.pszPolicyDesc[0] = 0;
  863. m_PolicyInfo.timestamp = 0;
  864. dwError = RegConnectRegistry( m_strCompName,
  865. HKEY_LOCAL_MACHINE,
  866. &hRegHKey);
  867. BAIL_ON_WIN32_ERROR(dwError);
  868. switch (m_PolicyInfo.iPolicySource)
  869. {
  870. case PS_LOC_POLICY:
  871. // open the key
  872. dwError = RegOpenKeyEx( hRegHKey,
  873. m_PolicyInfo.pszPolicyPath,
  874. 0,
  875. KEY_READ,
  876. &hRegKey);
  877. BAIL_ON_WIN32_ERROR(dwError);
  878. // timestamp
  879. dwError = RegQueryValueEx(hRegKey,
  880. pcszIPSecTimestamp,
  881. NULL,
  882. &dwType,
  883. (LPBYTE)&dwValue,
  884. &dwLength);
  885. BAIL_ON_WIN32_ERROR(dwError);
  886. m_PolicyInfo.timestamp = dwValue;
  887. // description
  888. dwBufLen = MAXSTRLEN*sizeof(TCHAR);
  889. dwError = RegQueryValueEx( hRegKey,
  890. pcszIPSecDesc,
  891. NULL,
  892. &dwType, // will be REG_SZ
  893. (LPBYTE) pszBuf,
  894. &dwBufLen);
  895. BAIL_ON_WIN32_ERROR(dwError);
  896. _tcscpy(m_PolicyInfo.pszPolicyDesc, pszBuf);
  897. break;
  898. case PS_DS_POLICY:
  899. case PS_DS_POLICY_CACHED:
  900. // get the policy name from DN
  901. _tcscpy(pszBuf, pcszCacheIPSecKey);
  902. ppszExplodeDN = ldap_explode_dn(m_PolicyInfo.pszPolicyPath, 1);
  903. if (!ppszExplodeDN)
  904. {
  905. goto error;
  906. }
  907. _tcscat(pszBuf, TEXT("\\"));
  908. _tcscat(pszBuf, ppszExplodeDN[0]);
  909. // open the regkey
  910. dwError = RegOpenKeyEx( hRegHKey,
  911. pszBuf,
  912. 0,
  913. KEY_READ,
  914. &hRegKey);
  915. BAIL_ON_WIN32_ERROR(dwError);
  916. // get the more correct name info
  917. dwBufLen = sizeof(pszBuf);
  918. dwError = RegQueryValueEx( hRegKey,
  919. pcszIPSecName,
  920. NULL,
  921. &dwType, // will be REG_SZ
  922. (LPBYTE) pszBuf,
  923. &dwBufLen);
  924. if (dwError == ERROR_SUCCESS)
  925. {
  926. _tcscpy(m_PolicyInfo.pszPolicyName, pszBuf);
  927. }
  928. // timestamp
  929. dwError = RegQueryValueEx(hRegKey,
  930. pcszIPSecTimestamp,
  931. NULL,
  932. &dwType,
  933. (LPBYTE)&dwValue,
  934. &dwLength);
  935. BAIL_ON_WIN32_ERROR(dwError);
  936. m_PolicyInfo.timestamp = dwValue;
  937. // description
  938. dwBufLen = MAXSTRLEN*sizeof(TCHAR);
  939. dwError = RegQueryValueEx( hRegKey,
  940. pcszIPSecDesc,
  941. NULL,
  942. &dwType, // will be REG_SZ
  943. (LPBYTE) pszBuf,
  944. &dwBufLen);
  945. BAIL_ON_WIN32_ERROR(dwError);
  946. _tcscpy(m_PolicyInfo.pszPolicyDesc, pszBuf);
  947. break;
  948. }
  949. error:
  950. if (hRegKey)
  951. {
  952. RegCloseKey(hRegKey);
  953. }
  954. if (hRegHKey)
  955. {
  956. RegCloseKey(hRegHKey);
  957. }
  958. if (ppszExplodeDN)
  959. {
  960. ldap_value_free(ppszExplodeDN);
  961. }
  962. return (HRESULT) dwError;
  963. }
  964. HRESULT CActPolHandler::UpdateActivePolicyInfo()
  965. {
  966. HRESULT hr;
  967. hr = getPolicyInfo();
  968. if( hr == ERROR_SUCCESS )
  969. {
  970. switch (m_PolicyInfo.iPolicySource)
  971. {
  972. case PS_NO_POLICY:
  973. break;
  974. case PS_DS_POLICY:
  975. case PS_DS_POLICY_CACHED:
  976. {
  977. PGROUP_POLICY_OBJECT pGPO;
  978. pGPO = NULL;
  979. getMorePolicyInfo();
  980. pGPO = getIPSecGPO();
  981. if (pGPO)
  982. {
  983. PGROUP_POLICY_OBJECT pLastGPO = pGPO;
  984. while ( 1 )
  985. {
  986. if ( pLastGPO->pNext )
  987. pLastGPO = pLastGPO->pNext;
  988. else
  989. break;
  990. }
  991. lstrcpy(m_PolicyInfo.pszOU,pLastGPO->lpLink);
  992. lstrcpy(m_PolicyInfo.pszGPOName, pLastGPO->lpDisplayName);
  993. FreeGPOList (pGPO);
  994. }
  995. }
  996. break;
  997. case PS_LOC_POLICY:
  998. getMorePolicyInfo();
  999. break;
  1000. }
  1001. }
  1002. return hr;
  1003. }
  1004. /********************************************************************
  1005. FUNCTION: getIPSecGPO
  1006. PURPOSE: returns GPO that is assigning IPSec Policy
  1007. INPUT: none
  1008. RETURNS: pointer to GROUP_POLICY_OBJECT structure
  1009. NULL if policy is not assigned or if GPO information is not retrievable
  1010. NOTES: Tested only with domain GPOs
  1011. Behaves unpredictably when run for the computer
  1012. that does not have active Directory IPSec policy assigned
  1013. CALLER is responsible for freeing the memory!
  1014. *********************************************************************/
  1015. /*PGROUP_POLICY_OBJECT CActPolHandler::getIPSecGPO ( )
  1016. {
  1017. HKEY hKey, hSubKey, hRegHKey;
  1018. DWORD dwType, dwSize, dwIndex, dwNameSize;
  1019. LONG lResult;
  1020. TCHAR szName[50];
  1021. GUID guid;
  1022. PGROUP_POLICY_OBJECT pGPO, pGPOTemp;
  1023. PGROUP_POLICY_OBJECT pGPOReturn = NULL;
  1024. DWORD dwResult;
  1025. //
  1026. // Enumerate the extensions
  1027. //
  1028. lResult = RegConnectRegistry( m_strCompName,
  1029. HKEY_LOCAL_MACHINE,
  1030. &hRegHKey);
  1031. if(lResult != ERROR_SUCCESS)
  1032. {
  1033. return NULL;
  1034. }
  1035. lResult = RegOpenKeyEx (hRegHKey, GPEXT_KEY, 0, KEY_READ, &hKey);
  1036. if (lResult == ERROR_SUCCESS)
  1037. {
  1038. dwIndex = 0;
  1039. dwNameSize = 50;
  1040. while ((dwResult = RegEnumKeyEx (hKey, dwIndex++, szName, &dwNameSize, NULL, NULL,
  1041. NULL, NULL)) == ERROR_SUCCESS)
  1042. {
  1043. dwNameSize = 50;
  1044. //
  1045. // Skip the registry extension since we did it above
  1046. //
  1047. if (lstrcmpi(TEXT("{35378EAC-683F-11D2-A89A-00C04FBBCFA2}"), szName))
  1048. {
  1049. //
  1050. // Get the list of GPOs this extension applied
  1051. //
  1052. StringToGuid(szName, &guid);
  1053. lResult = GetAppliedGPOList (GPO_LIST_FLAG_MACHINE, m_strCompName, NULL,
  1054. &guid, &pGPO);
  1055. if (lResult == ERROR_SUCCESS)
  1056. {
  1057. if (pGPO)
  1058. {
  1059. //
  1060. // Get the extension's friendly display name
  1061. //
  1062. lResult = RegOpenKeyEx (hKey, szName, 0, KEY_READ, &hSubKey);
  1063. if (lResult == ERROR_SUCCESS)
  1064. {
  1065. if (!lstrcmpi(TEXT("{e437bc1c-aa7d-11d2-a382-00c04f991e27}"), szName))
  1066. {
  1067. // found IPSec
  1068. return pGPO;
  1069. }
  1070. else
  1071. {
  1072. FreeGPOList(pGPO);
  1073. }
  1074. }
  1075. }
  1076. }
  1077. }
  1078. }
  1079. }
  1080. return pGPOReturn;
  1081. }*/
  1082. PGROUP_POLICY_OBJECT CActPolHandler::getIPSecGPO ( )
  1083. {
  1084. HKEY hKey = NULL;
  1085. HKEY hRegHKey = NULL;
  1086. DWORD dwType, dwSize, dwIndex, dwNameSize;
  1087. LONG lResult;
  1088. TCHAR szName[50];
  1089. GUID guid;
  1090. PGROUP_POLICY_OBJECT pGPO = NULL;
  1091. DWORD dwResult;
  1092. //
  1093. // Enumerate the extensions
  1094. //
  1095. lResult = RegConnectRegistry( m_strCompName,
  1096. HKEY_LOCAL_MACHINE,
  1097. &hRegHKey);
  1098. if(lResult != ERROR_SUCCESS)
  1099. {
  1100. return NULL;
  1101. }
  1102. CString strGPExt;
  1103. strGPExt = GPEXT_KEY;
  1104. strGPExt += TEXT("\\");
  1105. strGPExt += pcszIpsecClsid;
  1106. lResult = RegOpenKeyEx (hRegHKey, strGPExt, 0, KEY_READ, &hKey);
  1107. if (lResult == ERROR_SUCCESS)
  1108. {
  1109. dwIndex = 0;
  1110. dwNameSize = 50;
  1111. lstrcpy(szName,pcszIpsecClsid);
  1112. StringToGuid(szName, &guid);
  1113. lResult = GetAppliedGPOList (GPO_LIST_FLAG_MACHINE, m_strCompName, NULL,
  1114. &guid, &pGPO);
  1115. }
  1116. if( hKey )
  1117. RegCloseKey(hKey);
  1118. if( hRegHKey )
  1119. RegCloseKey(hRegHKey);
  1120. return pGPO;
  1121. }
  1122. //+---------------------------------------------------------------------------
  1123. //
  1124. // Member: CAdvIpcfgDlg::FormatTime
  1125. //
  1126. // Purpose: convert time_t to a string.
  1127. //
  1128. // Returns: error code
  1129. //
  1130. // Note: _wasctime has some localization problems. So we do the formatting ourselves
  1131. HRESULT CActPolHandler::FormatTime(time_t t, CString & str)
  1132. {
  1133. time_t timeCurrent = time(NULL);
  1134. LONGLONG llTimeDiff = 0;
  1135. FILETIME ftCurrent = {0};
  1136. FILETIME ftLocal = {0};
  1137. SYSTEMTIME SysTime;
  1138. WCHAR szBuff[256] = {0};
  1139. str = L"";
  1140. GetSystemTimeAsFileTime(&ftCurrent);
  1141. llTimeDiff = (LONGLONG)t - (LONGLONG)timeCurrent;
  1142. llTimeDiff *= 10000000;
  1143. *((LONGLONG UNALIGNED64 *)&ftCurrent) += llTimeDiff;
  1144. if (!FileTimeToLocalFileTime(&ftCurrent, &ftLocal ))
  1145. {
  1146. return HRESULT_FROM_WIN32(GetLastError());
  1147. }
  1148. if (!FileTimeToSystemTime( &ftLocal, &SysTime ))
  1149. {
  1150. return HRESULT_FROM_WIN32(GetLastError());
  1151. }
  1152. if (0 == GetDateFormat(LOCALE_USER_DEFAULT,
  1153. 0,
  1154. &SysTime,
  1155. NULL,
  1156. szBuff,
  1157. celems(szBuff)))
  1158. {
  1159. return HRESULT_FROM_WIN32(GetLastError());
  1160. }
  1161. str = szBuff;
  1162. str += L" ";
  1163. ZeroMemory(szBuff, sizeof(szBuff));
  1164. if (0 == GetTimeFormat(LOCALE_USER_DEFAULT,
  1165. 0,
  1166. &SysTime,
  1167. NULL,
  1168. szBuff,
  1169. celems(szBuff)))
  1170. {
  1171. return HRESULT_FROM_WIN32(GetLastError());
  1172. }
  1173. str += szBuff;
  1174. return S_OK;
  1175. }
  1176. //*************************************************************
  1177. //
  1178. // StringToGuid()
  1179. //
  1180. // Purpose: Converts a GUID in string format to a GUID structure
  1181. //
  1182. // Parameters: szValue - guid in string format
  1183. // pGuid - guid structure receiving the guid
  1184. //
  1185. //
  1186. // Return: void
  1187. //
  1188. //*************************************************************
  1189. void CActPolHandler::StringToGuid( TCHAR * szValue, GUID * pGuid )
  1190. {
  1191. TCHAR wc;
  1192. INT i;
  1193. //
  1194. // If the first character is a '{', skip it
  1195. //
  1196. if ( szValue[0] == TEXT('{') )
  1197. szValue++;
  1198. //
  1199. // Since szValue may be used again, no permanent modification to
  1200. // it is be made.
  1201. //
  1202. wc = szValue[8];
  1203. szValue[8] = 0;
  1204. pGuid->Data1 = _tcstoul( &szValue[0], 0, 16 );
  1205. szValue[8] = wc;
  1206. wc = szValue[13];
  1207. szValue[13] = 0;
  1208. pGuid->Data2 = (USHORT)_tcstoul( &szValue[9], 0, 16 );
  1209. szValue[13] = wc;
  1210. wc = szValue[18];
  1211. szValue[18] = 0;
  1212. pGuid->Data3 = (USHORT)_tcstoul( &szValue[14], 0, 16 );
  1213. szValue[18] = wc;
  1214. wc = szValue[21];
  1215. szValue[21] = 0;
  1216. pGuid->Data4[0] = (unsigned char)_tcstoul( &szValue[19], 0, 16 );
  1217. szValue[21] = wc;
  1218. wc = szValue[23];
  1219. szValue[23] = 0;
  1220. pGuid->Data4[1] = (unsigned char)_tcstoul( &szValue[21], 0, 16 );
  1221. szValue[23] = wc;
  1222. for ( i = 0; i < 6; i++ )
  1223. {
  1224. wc = szValue[26+i*2];
  1225. szValue[26+i*2] = 0;
  1226. pGuid->Data4[2+i] = (unsigned char)_tcstoul( &szValue[24+i*2], 0, 16 );
  1227. szValue[26+i*2] = wc;
  1228. }
  1229. }