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

1367 lines
43 KiB

  1. //----------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 2001.
  5. //
  6. // File: Mngrfldr.cpp
  7. //
  8. // Contents: Wireless Policy Snapin - Policy Main Page Manager.
  9. //
  10. //
  11. // History: TaroonM
  12. // 10/30/01
  13. //
  14. //----------------------------------------------------------------------------
  15. #include "stdafx.h"
  16. // #include "lm.h"
  17. #include "dsgetdc.h"
  18. #ifdef _DEBUG
  19. #define new DEBUG_NEW
  20. #undef THIS_FILE
  21. static char THIS_FILE[] = __FILE__;
  22. #endif
  23. #define RESULTVIEW_COLUMN_COUNT 3
  24. ///////////////////////////////////////////////////////////////////////////////
  25. // class CWirelessManagerFolder - represents the MMC scope view item
  26. CWirelessManagerFolder::CWirelessManagerFolder () :
  27. m_bEnumerated( FALSE ),
  28. m_pExtScopeObject( NULL ),
  29. m_ptszResultDisplayName( NULL ),
  30. m_dwSortOrder( 0 ), // default is 0, else RSI_DESCENDING
  31. m_nSortColumn( 0 ),
  32. m_dwNumPolItems( 1 )
  33. {
  34. // INTERNALCookie( (LONG_PTR)this );
  35. ZeroMemory( &m_ScopeItem, sizeof( SCOPEDATAITEM ) );
  36. m_bLocationPageOk = TRUE;
  37. m_bScopeItemInserted = FALSE;
  38. }
  39. CWirelessManagerFolder::~CWirelessManagerFolder ()
  40. {
  41. DELETE_OBJECT(m_ptszResultDisplayName);
  42. // No need to release since we never did an AddRef
  43. m_pExtScopeObject = NULL;
  44. }
  45. void CWirelessManagerFolder::SetNodeNameByLocation()
  46. {
  47. // Construct display name. Assume this doesn't change during a single
  48. // invocation of this snap-in????
  49. CString nodeName;
  50. CString nodeNameOn;
  51. // If this folder is being asked for scope info, it better know
  52. // where ComponentData is.
  53. ASSERT( NULL != m_pComponentDataImpl );
  54. // Concatenate a string containing the location of this node
  55. switch (m_pComponentDataImpl->EnumLocation())
  56. {
  57. case LOCATION_REMOTE:
  58. {
  59. nodeNameOn = L"\\\\";
  60. nodeNameOn += m_pComponentDataImpl->RemoteMachineName ();
  61. break;
  62. }
  63. case LOCATION_GLOBAL:
  64. {
  65. nodeNameOn.LoadString (IDS_NODENAME_GLOBAL);
  66. if (m_pComponentDataImpl->RemoteMachineName().GetLength() > 0)
  67. {
  68. nodeNameOn += L" (";
  69. nodeNameOn += m_pComponentDataImpl->RemoteMachineName();
  70. nodeNameOn += L")";
  71. }
  72. // TODO: concider using this code to display the dns domain name
  73. // even when not specified. Unfortunately MMC stashes this in the
  74. // .MSC file IN IT'S OWN SECTION and uses it when the node is
  75. // first displayed. So it would be incorrect until the snapin
  76. // was loaded and had a chance to change it (assuming the .MSC file
  77. // was created in a different domain). So for now we don't do this
  78. /*
  79. // let them know which (DNS domain name) is
  80. // being used
  81. PDOMAIN_CONTROLLER_INFO pDomainControllerInfo = NULL;
  82. DWORD Flags = DS_DIRECTORY_SERVICE_REQUIRED | DS_RETURN_DNS_NAME | DS_FORCE_REDISCOVERY;
  83. DWORD dwStatus = DsGetDcName(NULL,
  84. NULL,
  85. NULL,
  86. NULL,
  87. Flags,
  88. &pDomainControllerInfo
  89. ) ;
  90. if (dwStatus == NO_ERROR)
  91. {
  92. nodeNameOn += L" (";
  93. nodeNameOn += pDomainControllerInfo->DomainName;
  94. nodeNameOn += L")";
  95. }
  96. */
  97. break;
  98. }
  99. default:
  100. {
  101. nodeNameOn.LoadString (IDS_NODENAME_GLOBAL);
  102. if (m_pComponentDataImpl->RemoteMachineName().GetLength() > 0)
  103. {
  104. nodeNameOn += L" (";
  105. nodeNameOn += m_pComponentDataImpl->RemoteMachineName();
  106. nodeNameOn += L")";
  107. }
  108. break;
  109. }
  110. }
  111. // nodeName has a %s in it, which is where nodeNameOn goes
  112. nodeName.LoadString (IDS_NODENAME_BASE);
  113. //nodeName.FormatMessage (IDS_NODENAME_BASE ,nodeNameOn);
  114. // nodeName += nodeNameOn;
  115. OPT_TRACE(_T("CWirelessManagerFolder::Initialize(%p) created node name-%s\n"), this, (LPCTSTR)nodeName);
  116. // store name in our dataobject
  117. NodeName( nodeName );
  118. }
  119. void CWirelessManagerFolder::Initialize
  120. (
  121. CComponentDataImpl* pComponentDataImpl,
  122. CComponentImpl* pComponentImpl,
  123. int nImage,
  124. int nOpenImage,
  125. BOOL bHasChildrenBox
  126. )
  127. {
  128. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  129. // call base class initializer
  130. CSnapObject::Initialize( pComponentDataImpl, pComponentImpl, FALSE );
  131. ZeroMemory( &m_ScopeItem, sizeof( SCOPEDATAITEM ) );
  132. GetScopeItem()->mask = SDI_STR;
  133. GetScopeItem()->displayname = (unsigned short*)(-1);
  134. // Add close image
  135. GetScopeItem()->mask |= SDI_IMAGE;
  136. GetScopeItem()->nImage = nImage;
  137. // Add open image
  138. GetScopeItem()->mask |= SDI_OPENIMAGE;
  139. GetScopeItem()->nOpenImage = nOpenImage;
  140. // TODO: folder children flag needs to be dynamic based on actual children (PS: it doesn't work anyway!?)
  141. // Add button to node if the folder has children
  142. if (bHasChildrenBox)
  143. {
  144. GetScopeItem()->mask |= SDI_CHILDREN;
  145. GetScopeItem()->cChildren = 1;
  146. }
  147. ASSERT( NodeName().IsEmpty() ); // there should be no name since we are initializing
  148. // get our default node name set
  149. SetNodeNameByLocation ();
  150. }
  151. //////////////////////////////////////////////////////////////////////////
  152. // handle IExtendContextMenu
  153. STDMETHODIMP CWirelessManagerFolder::AddMenuItems
  154. (
  155. LPCONTEXTMENUCALLBACK pContextMenuCallback,
  156. long *pInsertionAllowed
  157. )
  158. {
  159. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  160. CONTEXTMENUITEM mItem;
  161. HRESULT hr = S_OK;
  162. if ( m_pComponentDataImpl->IsRsop() )
  163. {
  164. //do not need any context menu for rsop mode
  165. return hr;
  166. }
  167. //if we haven't open the storage yet, don't show the context menus
  168. if (NULL == m_pComponentDataImpl->GetPolicyStoreHandle())
  169. {
  170. return hr;
  171. }
  172. LONG lFlags = 0;
  173. if (*pInsertionAllowed & CCM_INSERTIONALLOWED_TOP && (m_dwNumPolItems == 0))
  174. {
  175. CString strMenuText;
  176. CString strMenuDescription;
  177. // create policy
  178. strMenuText.LoadString (IDS_MENUTEXT_CREATENEWSECPOL);
  179. strMenuDescription.LoadString (IDS_MENUDESCRIPTION_CREATENEWSECPOL);
  180. CONFIGUREITEM (mItem, strMenuText, strMenuDescription, IDM_CREATENEWSECPOL, CCM_INSERTIONPOINTID_PRIMARY_TOP, lFlags, 0);
  181. hr &= pContextMenuCallback->AddItem(&mItem);
  182. ASSERT(hr == S_OK);
  183. }
  184. if (*pInsertionAllowed & CCM_INSERTIONALLOWED_NEW && (m_dwNumPolItems == 0))
  185. {
  186. CString strMenuText;
  187. CString strMenuDescription;
  188. // Vbug 25 indicates that all _TOP menu options must ALSO be added under TASK or NEW:
  189. // create policy
  190. strMenuText.LoadString (IDS_MENUTEXT_CREATENEWSECPOL);
  191. strMenuDescription.LoadString (IDS_MENUDESCRIPTION_CREATENEWSECPOL);
  192. CONFIGUREITEM (mItem, strMenuText, strMenuDescription, IDM_CREATENEWSECPOL, CCM_INSERTIONPOINTID_PRIMARY_TASK, lFlags, 0);
  193. hr = pContextMenuCallback->AddItem(&mItem);
  194. ASSERT(hr == S_OK);
  195. }
  196. if (*pInsertionAllowed & CCM_INSERTIONALLOWED_TASK)
  197. {
  198. CString strMenuText;
  199. CString strMenuDescription;
  200. // Vbug 25 indicates that all _TOP menu options must ALSO be added under TASK or NEW:
  201. }
  202. return hr;
  203. }
  204. STDMETHODIMP_(BOOL) CWirelessManagerFolder::UpdateToolbarButton(
  205. UINT id, // button ID
  206. BOOL bSnapObjSelected, // ==TRUE when result/scope item is selected
  207. BYTE fsState ) // enable/disable this button state by returning TRUE/FALSE
  208. {
  209. if ( m_pComponentDataImpl->IsRsop() && ( IDM_CREATENEWSECPOL == id ) )
  210. return FALSE;
  211. // GPO Change stuff
  212. if ((m_dwNumPolItems > 0) && (IDM_CREATENEWSECPOL == id))
  213. return FALSE;
  214. if ((fsState == ENABLED) && m_pComponentDataImpl->GetPolicyStoreHandle())
  215. return TRUE;
  216. if ((fsState == INDETERMINATE) && NULL == m_pComponentDataImpl->GetPolicyStoreHandle())
  217. return TRUE;
  218. return FALSE;
  219. }
  220. STDMETHODIMP CWirelessManagerFolder::Command
  221. (
  222. long lCommandID,
  223. IConsoleNameSpace *pNameSpace
  224. )
  225. {
  226. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  227. HRESULT hrReturn = S_OK;
  228. DWORD dwError = ERROR_SUCCESS;
  229. //
  230. // You can always talk to storage
  231. //
  232. switch (lCommandID)
  233. {
  234. case IDM_CREATENEWSECPOL:
  235. {
  236. // get a name for our new security policy
  237. CString strUName;
  238. DWORD dwError = 0;
  239. GenerateUniqueSecPolicyName (strUName, IDS_NEWWIRELESSPOLICYNAME);
  240. PWIRELESS_POLICY_DATA pPolicy = NULL;
  241. hrReturn = CreateWirelessPolicyDataBuffer(&pPolicy);
  242. if (FAILED(hrReturn))
  243. {
  244. break;
  245. }
  246. pPolicy->pszWirelessName = AllocPolStr(strUName);
  247. pPolicy->pszOldWirelessName = NULL;
  248. // create the new wireless policy item
  249. CComObject <CSecPolItem> * pNewPolItem;
  250. CComObject <CSecPolItem>::CreateInstance(&pNewPolItem);
  251. if (NULL == pNewPolItem)
  252. {
  253. FreeWirelessPolicyData(pPolicy);
  254. return E_OUTOFMEMORY;
  255. }
  256. //Add ref to control the life time of the object
  257. pNewPolItem->AddRef();
  258. // initialize our new item
  259. pNewPolItem->Initialize (
  260. pPolicy,
  261. m_pComponentDataImpl,
  262. m_pComponentImpl,
  263. TRUE);
  264. // Force the properties of the new item to display.
  265. //
  266. // Note: This must be a wizard because other code assumes it is so:
  267. // 1. If this is ever changed to add a policy without using the wizard,
  268. // CSecPolRulesPage::OnCancel() must be modified to distinguish between
  269. // the sheet which adds the policy, and the sheet which is displayed
  270. // after the wizard Finishes.
  271. //
  272. // 2. ForcePropertiesDisplay returns 1 for cancel ONLY on wizard.
  273. HRESULT hr = pNewPolItem->DisplaySecPolProperties (strUName);
  274. if (S_OK == hr)
  275. {
  276. hrReturn = CreateWirelessPolicy(pPolicy);
  277. if (FAILED(hrReturn))
  278. {
  279. ReportError(IDS_SAVE_ERROR, hrReturn);
  280. dwError = 1;
  281. }
  282. else
  283. {
  284. m_pComponentDataImpl->GetConsole()->UpdateAllViews( this, 0,0 );
  285. if (pNewPolItem->IsPropertyChangeHookEnabled())
  286. {
  287. pNewPolItem->EnablePropertyChangeHook(FALSE);
  288. pNewPolItem->DoPropertyChangeHook();
  289. }
  290. }
  291. } else
  292. {
  293. dwError = 1;
  294. }
  295. pNewPolItem->Release();
  296. // GPO Change :
  297. //
  298. // inform GPE that the policy has been added or deleted
  299. //
  300. //
  301. if (dwError) {
  302. break;
  303. }
  304. GUID guidClientExt = CLSID_WIRELESSClientEx;
  305. GUID guidSnapin = CLSID_Snapin;
  306. m_pComponentDataImpl->UseGPEInformationInterface()->PolicyChanged (
  307. TRUE,
  308. TRUE,
  309. &guidClientExt,
  310. &guidSnapin
  311. );
  312. break;
  313. }
  314. default:
  315. hrReturn = S_FALSE;
  316. break;
  317. }
  318. // S_FALSE if we didn't handle command
  319. return hrReturn;
  320. }
  321. STDMETHODIMP CWirelessManagerFolder::QueryPagesFor( void )
  322. {
  323. // we only want to display the location page once
  324. HRESULT hr = E_UNEXPECTED;
  325. if (m_bLocationPageOk)
  326. {
  327. // display our locations dialog via this
  328. hr = S_OK;
  329. }
  330. return hr;
  331. }
  332. // Notify helper
  333. STDMETHODIMP CWirelessManagerFolder::OnPropertyChange(LPARAM lParam, LPCONSOLE pConsole )
  334. {
  335. if (NULL != lParam)
  336. {
  337. // If lParam knows about our internal interface, let it handle this event
  338. CComQIPtr<IWirelessSnapInDataObject, &IID_IWirelessSnapInDataObject>
  339. spData( (LPUNKNOWN)lParam );
  340. if (spData != NULL)
  341. {
  342. return spData->Notify( MMCN_PROPERTY_CHANGE, 0, 0, FALSE, pConsole, NULL /* IHeaderCtrl* */ );
  343. }
  344. }
  345. // call base class
  346. return CWirelessSnapInDataObjectImpl<CWirelessManagerFolder>::OnPropertyChange( lParam, pConsole );
  347. }
  348. // let us know when we are 'bout to go away
  349. STDMETHODIMP CWirelessManagerFolder::Destroy ( void )
  350. {
  351. // nothing to say about the destroy
  352. return S_OK;
  353. }
  354. // handle IComponent and IComponentData
  355. STDMETHODIMP CWirelessManagerFolder::Notify
  356. (
  357. MMC_NOTIFY_TYPE event,
  358. LPARAM arg,
  359. LPARAM param,
  360. BOOL bComponentData, // TRUE when caller is IComponentData
  361. IConsole *pConsole,
  362. IHeaderCtrl *pHeader
  363. )
  364. {
  365. #ifdef DO_TRACE
  366. OPT_TRACE(_T("CWirelessManagerFolder::Notify this-%p "), this);
  367. switch (event)
  368. {
  369. case MMCN_ACTIVATE:
  370. OPT_TRACE(_T("MMCN_ACTIVATE\n"));
  371. break;
  372. case MMCN_ADD_IMAGES:
  373. OPT_TRACE(_T("MMCN_ADD_IMAGES\n"));
  374. break;
  375. case MMCN_BTN_CLICK:
  376. OPT_TRACE(_T("MMCN_BTN_CLICK\n"));
  377. break;
  378. case MMCN_CLICK:
  379. OPT_TRACE(_T("MMCN_CLICK\n"));
  380. break;
  381. case MMCN_COLUMN_CLICK:
  382. OPT_TRACE(_T("MMCN_COLUMN_CLICK\n"));
  383. break;
  384. case MMCN_CONTEXTMENU:
  385. OPT_TRACE(_T("MMCN_CONTEXTMENU\n"));
  386. break;
  387. case MMCN_CUTORMOVE:
  388. OPT_TRACE(_T("MMCN_CUTORMOVE\n"));
  389. break;
  390. case MMCN_DELETE:
  391. OPT_TRACE(_T("MMCN_DELETE\n"));
  392. break;
  393. case MMCN_DESELECT_ALL:
  394. OPT_TRACE(_T("MMCN_DESELECT_ALL\n"));
  395. break;
  396. case MMCN_EXPAND:
  397. OPT_TRACE(_T("MMCN_EXPAND\n"));
  398. break;
  399. case MMCN_HELP:
  400. OPT_TRACE(_T("MMCN_HELP\n"));
  401. break;
  402. case MMCN_MENU_BTNCLICK:
  403. OPT_TRACE(_T("MMCN_MENU_BTNCLICK\n"));
  404. break;
  405. case MMCN_MINIMIZED:
  406. OPT_TRACE(_T("MMCN_MINIMIZED\n"));
  407. break;
  408. case MMCN_PASTE:
  409. OPT_TRACE(_T("MMCN_PASTE\n"));
  410. break;
  411. case MMCN_PROPERTY_CHANGE:
  412. OPT_TRACE(_T("MMCN_PROPERTY_CHANGE\n"));
  413. break;
  414. case MMCN_QUERY_PASTE:
  415. OPT_TRACE(_T("MMCN_QUERY_PASTE\n"));
  416. break;
  417. case MMCN_REFRESH:
  418. OPT_TRACE(_T("MMCN_REFRESH\n"));
  419. break;
  420. case MMCN_REMOVE_CHILDREN:
  421. OPT_TRACE(_T("MMCN_REMOVE_CHILDREN\n"));
  422. break;
  423. case MMCN_RENAME:
  424. OPT_TRACE(_T("MMCN_RENAME\n"));
  425. break;
  426. case MMCN_SELECT:
  427. OPT_TRACE(_T("MMCN_SELECT\n"));
  428. break;
  429. case MMCN_SHOW:
  430. OPT_TRACE(_T("MMCN_SHOW\n"));
  431. break;
  432. case MMCN_VIEW_CHANGE:
  433. OPT_TRACE(_T("MMCN_VIEW_CHANGE\n"));
  434. break;
  435. case MMCN_SNAPINHELP:
  436. OPT_TRACE(_T("MMCN_SNAPINHELP\n"));
  437. break;
  438. case MMCN_CONTEXTHELP:
  439. OPT_TRACE(_T("MMCN_CONTEXTHELP\n"));
  440. break;
  441. case MMCN_INITOCX:
  442. OPT_TRACE(_T("MMCN_INITOCX\n"));
  443. break;
  444. case MMCN_FILTER_CHANGE:
  445. OPT_TRACE(_T("MMCN_FILTER_CHANGE\n"));
  446. break;
  447. default:
  448. OPT_TRACE(_T("Unknown event\n"));
  449. break;
  450. }
  451. #endif //#ifdef DO_TRACE
  452. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  453. HRESULT hr = S_FALSE;
  454. // handle the event
  455. switch(event)
  456. {
  457. case MMCN_CONTEXTHELP:
  458. {
  459. CComQIPtr <IDisplayHelp, &IID_IDisplayHelp> pDisplayHelp ( pConsole );
  460. ASSERT( pDisplayHelp != NULL );
  461. if (pDisplayHelp)
  462. {
  463. // need to form a complete path to the .chm file
  464. CString s, s2;
  465. s.LoadString(IDS_HELPCONCEPTSFILE);
  466. DWORD dw = ExpandEnvironmentStrings (s, s2.GetBuffer (512), 512);
  467. s2.ReleaseBuffer (-1);
  468. if ((dw == 0) || (dw > 512))
  469. {
  470. return E_UNEXPECTED;
  471. }
  472. pDisplayHelp->ShowTopic(s2.GetBuffer(512));
  473. s2.ReleaseBuffer (-1);
  474. hr = S_OK;
  475. }
  476. break;
  477. }
  478. case MMCN_SELECT:
  479. {
  480. BOOL bSelect = (BOOL) HIWORD(arg);
  481. if (bSelect)
  482. {
  483. // Obtain IConsoleVerb from console
  484. CComPtr<IConsoleVerb> spVerb;
  485. pConsole->QueryConsoleVerb( &spVerb );
  486. // call object to set verb state
  487. AdjustVerbState( (IConsoleVerb*)spVerb );
  488. }
  489. hr = S_OK;
  490. break;
  491. }
  492. case MMCN_SHOW:
  493. {
  494. // Note - arg is TRUE when it is time to enumerate
  495. if (arg == TRUE)
  496. {
  497. CWaitCursor waitCursor; // turn on the hourglass
  498. CComQIPtr <IResultData, &IID_IResultData> pResultData( pConsole );
  499. ASSERT( pResultData != NULL );
  500. ASSERT( pHeader != NULL );
  501. SetHeaders( pHeader, pResultData );
  502. //$review sometimes the MMCN_SELECT was not sent to the snapin when the node
  503. //is selected, use MMCN_SHOW to adjustverbstate instead
  504. CComPtr<IConsoleVerb> spVerb;
  505. pConsole->QueryConsoleVerb( &spVerb );
  506. AdjustVerbState((IConsoleVerb*)spVerb);
  507. // enumerate result items in that Folder
  508. EnumerateResults( pResultData, m_nSortColumn, m_dwSortOrder );
  509. }
  510. else
  511. {
  512. // TODO: free data associated with the result pane items, because
  513. // TODO: your node is no longer being displayed (??)
  514. CComQIPtr <IResultData, &IID_IResultData> pResultData( pConsole );
  515. ASSERT( pResultData != NULL );
  516. // if we have a handle to the pResultData
  517. if (pResultData)
  518. {
  519. // zip through and free off any result items we have laying around
  520. RESULTDATAITEM resultItem;
  521. ZeroMemory(&resultItem, sizeof(resultItem));
  522. resultItem.mask = RDI_PARAM | RDI_STATE;
  523. resultItem.nIndex = -1;
  524. resultItem.nState = LVNI_ALL;
  525. HRESULT hr;
  526. do
  527. {
  528. hr = pResultData->GetNextItem (&resultItem);
  529. if (hr == S_OK)
  530. {
  531. // free it off
  532. // if it ain't the right type of object we'll leak it
  533. IUnknown* pUnk = (IUnknown*)resultItem.lParam;
  534. ASSERT (pUnk);
  535. if (pUnk)
  536. {
  537. CComQIPtr<IWirelessSnapInDataObject, &IID_IWirelessSnapInDataObject> spData( pUnk );
  538. if (spData)
  539. {
  540. // release it in prep for tossing all the objects
  541. spData.Release();
  542. }
  543. }
  544. }
  545. } while (hr == S_OK);
  546. // now release this handle to their interface
  547. // m_pResultData->Release();
  548. }
  549. // NOTE: but the following, found in the sample snapin at this point,
  550. // NOTE: conflicted with my above comment...
  551. // Note: The console will remove the items from the result pane
  552. }
  553. return S_OK;
  554. }
  555. case MMCN_PROPERTY_CHANGE:
  556. {
  557. hr = OnPropertyChange( param, pConsole );
  558. break;
  559. }
  560. case MMCN_DELETE:
  561. {
  562. CThemeContextActivator activator;
  563. // delete the item
  564. if (AfxMessageBox (IDS_SUREYESNO, MB_YESNO | MB_DEFBUTTON2) == IDYES)
  565. {
  566. hr = OnDelete( arg, param );
  567. if (S_OK == hr)
  568. {
  569. // CAN'T DO THIS ON A STRICTLY SCOPE DELETE
  570. /*
  571. // find reference to the parent (get pDataObject of parent)
  572. SCOPEDATAITEM parentScopeDataItem;
  573. parentScopeDataItem.ID = m_pScopeItem->relativeID;
  574. parentScopeDataItem.mask = RDI_STR | RDI_PARAM | RDI_INDEX;
  575. hr = m_pComponentDataImpl->GetConsoleNameSpace()->GetItem (&parentScopeDataItem);
  576. ASSERT (SUCCEEDED(hr));
  577. CSnapFolder* pParentFolder = reinterpret_cast<CSnapFolder*>(parentScopeDataItem.lParam);
  578. // now tell the parent to refresh
  579. pParentFolder->ForceRefresh (NULL);
  580. */
  581. }
  582. }
  583. break;
  584. }
  585. case MMCN_REMOVE_CHILDREN:
  586. {
  587. SetEnumerated(FALSE);
  588. m_bScopeItemInserted = FALSE;
  589. break;
  590. }
  591. case MMCN_RENAME:
  592. {
  593. hr = OnRename (arg, param);
  594. break;
  595. }
  596. case MMCN_EXPAND:
  597. {
  598. if (arg == TRUE)
  599. {
  600. // TODO: if this is the root node this is our chance to save off the HSCOPEITEM of roots parent
  601. //if (pInternal->m_cookie == NULL)
  602. // m_pRootFolderScopeItem = pParent;
  603. CComQIPtr <IConsoleNameSpace, &IID_IConsoleNameSpace> spConsoleNameSpace( pConsole );
  604. // tell this folder to enumerate itself to the scope pane
  605. OnScopeExpand( (IConsoleNameSpace*)spConsoleNameSpace, param );
  606. hr = S_OK;
  607. } else
  608. {
  609. // TODO: handle MMCN_EXPAND arg == FALSE
  610. ASSERT (0);
  611. hr = S_FALSE;
  612. }
  613. break;
  614. }
  615. case MMCN_VIEW_CHANGE:
  616. {
  617. // Obtain IResultData
  618. CComQIPtr <IResultData, &IID_IResultData> pResultData( pConsole );
  619. ASSERT( pResultData != NULL );
  620. // Hint contains sort info, save it for calls to EnumerateResults
  621. m_nSortColumn = LOWORD( param );
  622. m_dwSortOrder = HIWORD( param );
  623. ASSERT( RESULTVIEW_COLUMN_COUNT > m_nSortColumn );
  624. ASSERT( 0 == m_dwSortOrder || RSI_DESCENDING == m_dwSortOrder );
  625. ForceRefresh( pResultData );
  626. break;
  627. }
  628. case MMCN_REFRESH:
  629. {
  630. // reset the reconnect flag
  631. m_pComponentDataImpl->m_bAttemptReconnect = TRUE;
  632. // Cause result pane to refresh its policy list
  633. hr = pConsole->UpdateAllViews( this, 0, 0 );
  634. ASSERT(hr == S_OK);
  635. break;
  636. }
  637. case MMCN_ADD_IMAGES:
  638. {
  639. // Obtain IImageList from console
  640. CComPtr<IImageList> spImage;
  641. HRESULT hr = pConsole->QueryResultImageList( &spImage );
  642. ASSERT(hr == S_OK);
  643. OnAddImages( arg, param, (IImageList*)spImage );
  644. hr = S_OK;
  645. break;
  646. }
  647. default:
  648. break;
  649. }
  650. return hr;
  651. }
  652. // handle IComponent
  653. STDMETHODIMP CWirelessManagerFolder::GetResultDisplayInfo( RESULTDATAITEM *pResultDataItem )
  654. {
  655. TCHAR *temp = NULL;
  656. DWORD dwError = S_OK;
  657. OPT_TRACE(_T("CWirelessManagerFolder::GetResultDisplayInfo this-%p\n"), this);
  658. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  659. // We should be here only if we are loaded as an extension snap-in.
  660. ASSERT( NULL != GetExtScopeObject() );
  661. // are they looking for the image?
  662. if (pResultDataItem->mask & RDI_IMAGE)
  663. {
  664. pResultDataItem->nImage = GetScopeItem()->nImage;
  665. OPT_TRACE(_T(" returning image[%i]\n"), GetScopeItem()->nImage);
  666. }
  667. // are they looking for a string?
  668. if (pResultDataItem->mask & RDI_STR)
  669. {
  670. // which column?
  671. switch (pResultDataItem->nCol)
  672. {
  673. case 0:
  674. // node name
  675. temp = (TCHAR*)realloc( m_ptszResultDisplayName, (NodeName().GetLength()+1)*sizeof(TCHAR) );
  676. if (temp != NULL)
  677. {
  678. m_ptszResultDisplayName = temp;
  679. lstrcpy (m_ptszResultDisplayName, NodeName().GetBuffer(20));
  680. } else
  681. {
  682. dwError = GetLastError();
  683. }
  684. NodeName().ReleaseBuffer(-1);
  685. pResultDataItem->str = m_ptszResultDisplayName;
  686. OPT_TRACE(_T(" returning node name-%s\n"), m_ptszResultDisplayName);
  687. break;
  688. case 1:
  689. {
  690. // node description
  691. CString strDescription;
  692. strDescription.LoadString (IDS_DESCRIPTION);
  693. temp = (TCHAR*) realloc (m_ptszResultDisplayName, (strDescription.GetLength()+1)*sizeof(TCHAR));
  694. if (temp != NULL)
  695. {
  696. m_ptszResultDisplayName = temp;
  697. lstrcpy (m_ptszResultDisplayName, strDescription.GetBuffer(20));
  698. } else
  699. {
  700. dwError = GetLastError();
  701. }
  702. strDescription.ReleaseBuffer(-1);
  703. pResultDataItem->str = m_ptszResultDisplayName;
  704. OPT_TRACE(_T(" returning node description-%s\n"), m_ptszResultDisplayName);
  705. break;
  706. }
  707. default:
  708. pResultDataItem->str = (LPOLESTR)_T("");
  709. OPT_TRACE(_T(" returning NULL string\n"));
  710. break;
  711. }
  712. }
  713. return HRESULT_FROM_WIN32(dwError);
  714. }
  715. // handle IComponentData
  716. STDMETHODIMP CWirelessManagerFolder::GetScopeDisplayInfo( SCOPEDATAITEM *pScopeDataItem )
  717. {
  718. OPT_TRACE(_T("CWirelessManagerFolder::GetScopeDisplayInfo SCOPEDATAITEM.lParam-%p\n"), pScopeDataItem->lParam);
  719. if (pScopeDataItem->mask & SDI_STR)
  720. {
  721. ASSERT( NodeName().GetLength() );
  722. OPT_TRACE(_T(" display string-%s\n"), (LPCTSTR)NodeName());
  723. // return display string
  724. pScopeDataItem->displayname = (LPTSTR)(LPCTSTR)NodeName();
  725. }
  726. if (pScopeDataItem->mask & SDI_IMAGE)
  727. pScopeDataItem->nImage = GetScopeItem()->nImage;
  728. if (pScopeDataItem->mask & SDI_OPENIMAGE)
  729. pScopeDataItem->nOpenImage = GetScopeItem()->nOpenImage;
  730. if (pScopeDataItem->mask & SDI_CHILDREN)
  731. pScopeDataItem->cChildren = 0; // WIFI mgr is always a scope leaf node
  732. return S_OK;
  733. }
  734. // IWirelessSnapInData
  735. STDMETHODIMP CWirelessManagerFolder::GetScopeData( SCOPEDATAITEM **ppScopeDataItem )
  736. {
  737. ASSERT( NULL == ppScopeDataItem );
  738. if (NULL == ppScopeDataItem)
  739. return E_INVALIDARG;
  740. *ppScopeDataItem = GetScopeItem();
  741. return S_OK;
  742. }
  743. STDMETHODIMP CWirelessManagerFolder::GetGuidForCompare( GUID *pGuid )
  744. {
  745. return E_UNEXPECTED;
  746. }
  747. STDMETHODIMP CWirelessManagerFolder::AdjustVerbState (LPCONSOLEVERB pConsoleVerb)
  748. {
  749. HRESULT hr = S_OK;
  750. // Don't need to call base class, it disables REFRESH
  751. if ( m_pComponentDataImpl->IsRsop() ) {
  752. hr = pConsoleVerb->SetVerbState(MMC_VERB_REFRESH, HIDDEN, TRUE);
  753. } else {
  754. // Enable refresh
  755. hr = pConsoleVerb->SetVerbState( MMC_VERB_REFRESH, HIDDEN, FALSE);
  756. ASSERT (hr == S_OK);
  757. hr = pConsoleVerb->SetVerbState( MMC_VERB_REFRESH, ENABLED, TRUE);
  758. ASSERT (hr == S_OK);
  759. }
  760. // double make sure that properties is disabled
  761. // (we don't ever enabled it but we have been seeing it work on some builds
  762. // and not on others, i suspect this is an uninitialized variable in MMCland)
  763. hr = pConsoleVerb->SetVerbState(MMC_VERB_PROPERTIES, ENABLED, FALSE);
  764. ASSERT (hr == S_OK);
  765. hr = pConsoleVerb->SetVerbState(MMC_VERB_PROPERTIES, HIDDEN, TRUE);
  766. ASSERT (hr == S_OK);
  767. return hr;
  768. }
  769. void CWirelessManagerFolder::RemoveResultItem(LPUNKNOWN pUnkWalkingDead)
  770. {
  771. // free it off
  772. // if it ain't the right type of object we'll leak it
  773. ASSERT (pUnkWalkingDead);
  774. if (pUnkWalkingDead)
  775. {
  776. CComQIPtr<IWirelessSnapInDataObject, &IID_IWirelessSnapInDataObject> spData( pUnkWalkingDead );
  777. if (spData)
  778. {
  779. // release it in prep for tossing all the objects
  780. spData.Release();
  781. }
  782. }
  783. }
  784. ///////////////////////////////////////////////////////////////////////////
  785. STDMETHODIMP
  786. CWirelessManagerFolder::EnumerateResults (
  787. LPRESULTDATA pResult, int nSortColumn, DWORD dwSortOrder
  788. )
  789. {
  790. HRESULT hr = S_OK;
  791. DWORD i = 0;
  792. HANDLE hPolicyStore = NULL;
  793. PWIRELESS_POLICY_DATA pWirelessPolicyData = NULL;
  794. PWIRELESS_POLICY_DATA pPolicy = NULL;
  795. DWORD dwNumPolicyObjects = 0;
  796. DWORD dwError = 0;
  797. PWIRELESS_POLICY_DATA * ppWirelessPolicyData = NULL;
  798. // Obtain storage containing policies
  799. hPolicyStore = m_pComponentDataImpl->GetPolicyStoreHandle();
  800. if (NULL == hPolicyStore)
  801. return hr;
  802. m_dwNumPolItems = 0;
  803. dwError = WirelessEnumPolicyData(
  804. hPolicyStore,
  805. &ppWirelessPolicyData,
  806. &dwNumPolicyObjects
  807. );
  808. /* Taroon BUG: Memory Leak.. Not freeing ppWirelessPolicyData*/
  809. if ( dwError != ERROR_SUCCESS )
  810. {
  811. hr = HRESULT_FROM_WIN32(dwError);
  812. return hr;
  813. }
  814. for (i = 0; i < dwNumPolicyObjects; i++) {
  815. // create a new CSecPolItem
  816. pPolicy = *(ppWirelessPolicyData + i);
  817. LPCSECPOLITEM pItem;
  818. CComObject <CSecPolItem>::CreateInstance(&pItem);
  819. // initialize the item
  820. pItem->Initialize (pPolicy, m_pComponentDataImpl, m_pComponentImpl, FALSE);
  821. pItem->GetResultItem()->mask |= RDI_PARAM;
  822. pItem->GetResultItem()->lParam = (LPARAM) pItem;
  823. OPT_TRACE(_T(" setting RESULTDATAITEM.lParam-%p\n"), pItem);
  824. // QI to increment ref count
  825. LPUNKNOWN pUnk;
  826. hr = pItem->QueryInterface(IID_IUnknown, (void**)&pUnk);
  827. ASSERT (hr == S_OK);
  828. OPT_TRACE(_T(" QI on ComObject->IUnknown - %p->%p\n"), pItem, pUnk);
  829. // add item to result pane
  830. LPRESULTDATAITEM prdi = NULL;
  831. dynamic_cast<IWirelessSnapInDataObject*>(pItem)->GetResultData(&prdi);
  832. ASSERT( NULL != prdi );
  833. hr = pResult->InsertItem( prdi );
  834. // when the item is removed from the UI the QI'd interface will be released
  835. }
  836. m_dwNumPolItems = dwNumPolicyObjects;
  837. // set the sort parameters
  838. if (m_dwNumPolItems > 1) {
  839. pResult->Sort( nSortColumn, dwSortOrder, 0 );
  840. }
  841. return hr;
  842. }
  843. STDMETHODIMP_(void) CWirelessManagerFolder::SetHeaders(LPHEADERCTRL pHeader, LPRESULTDATA pResult)
  844. {
  845. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  846. ASSERT(pResult != NULL);
  847. // set the description bar text
  848. CString strDesc;
  849. strDesc.LoadString (IDS_SNAPIN_DESC);
  850. pResult->SetDescBarText(strDesc.GetBuffer(5));
  851. CString strName;
  852. //first two columns are common for both rsop and non-rsop case
  853. strName.LoadString (IDS_COLUMN_NAME);
  854. pHeader->InsertColumn(COL_NAME, strName, LVCFMT_LEFT, 140);
  855. strName.LoadString (IDS_COLUMN_DESCRIPTION);
  856. pHeader->InsertColumn(COL_DESCRIPTION, strName, LVCFMT_LEFT, 160);
  857. // GPO New
  858. if ( !m_pComponentDataImpl->IsRsop() )
  859. {
  860. /*
  861. // if it is local or remote then third column is the ASSIGNED column
  862. if ((m_pComponentDataImpl->EnumLocation()==LOCATION_REMOTE)
  863. || (m_pComponentDataImpl->EnumLocation()==LOCATION_LOCAL)
  864. // extension snapin?
  865. || ((m_pComponentDataImpl->EnumLocation()==LOCATION_GLOBAL) && (NULL != m_pComponentDataImpl->GetStaticScopeObject()->GetExtScopeObject()))
  866. )
  867. {
  868. strName.LoadString (IDS_COLUMN_POLICYASSIGNED);
  869. pHeader->InsertColumn(COL_ACTIVE, strName, LVCFMT_LEFT, 160);
  870. }
  871. //for ds case, date stored in polstore is not valid, do not show for ds
  872. if (m_pComponentDataImpl->EnumLocation() != LOCATION_GLOBAL )
  873. {
  874. strName.LoadString (IDS_POLICY_MODIFIEDTIME);
  875. pHeader->InsertColumn(COL_LAST_MODIFIED, strName, LVCFMT_LEFT, 160);
  876. }
  877. */
  878. }
  879. else
  880. {
  881. //rsop case, columns will be different
  882. strName.LoadString(IDS_COLUMN_GPONAME);
  883. pHeader->InsertColumn(COL_GPONAME, strName, LVCFMT_LEFT, 160);
  884. strName.LoadString(IDS_COLUMN_PRECEDENCE);
  885. pHeader->InsertColumn(COL_PRECEDENCE, strName, LVCFMT_LEFT, 160);
  886. strName.LoadString(IDS_COLUMN_OU);
  887. pHeader->InsertColumn(COL_OU, strName, LVCFMT_LEFT, 160);
  888. m_nSortColumn = COL_PRECEDENCE;
  889. }
  890. }
  891. /////////////////////////////////////////////////////////////////////////////
  892. void CWirelessManagerFolder::GenerateUniqueSecPolicyName (CString& strName, UINT nID)
  893. {
  894. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  895. BOOL bUnique = TRUE;
  896. int iUTag = 0;
  897. CString strUName;
  898. DWORD dwError = 0;
  899. DWORD i = 0;
  900. PWIRELESS_POLICY_DATA pWirelessPolicyData = NULL;
  901. PWIRELESS_POLICY_DATA * ppWirelessPolicyData = NULL;
  902. DWORD dwNumPolicyObjects = 0;
  903. // if an nID was passed in then start with that
  904. if (nID != 0)
  905. {
  906. strName.LoadString (nID);
  907. }
  908. // zip through the policies and verify name is unique
  909. do
  910. {
  911. HANDLE hPolicyStore = NULL;
  912. // only start tacking numbers on after the first pass
  913. if (iUTag > 0)
  914. {
  915. TCHAR buff[32];
  916. wsprintf (buff, _T(" (%d)"), iUTag);
  917. strUName = strName + buff;
  918. bUnique = TRUE;
  919. } else
  920. {
  921. strUName = strName;
  922. bUnique = TRUE;
  923. }
  924. hPolicyStore = m_pComponentDataImpl->GetPolicyStoreHandle();
  925. dwError = WirelessEnumPolicyData(
  926. hPolicyStore,
  927. &ppWirelessPolicyData,
  928. &dwNumPolicyObjects
  929. );
  930. for (i = 0; i < dwNumPolicyObjects; i++) {
  931. pWirelessPolicyData = *(ppWirelessPolicyData + i);
  932. if (0 == strUName.CompareNoCase(pWirelessPolicyData->pszWirelessName)) {
  933. // set bUnique to FALSE
  934. bUnique = FALSE;
  935. iUTag++;
  936. }
  937. FreeWirelessPolicyData(pWirelessPolicyData);
  938. }
  939. }
  940. while (bUnique == FALSE);
  941. // done
  942. strName = strUName;
  943. }
  944. HRESULT CWirelessManagerFolder::ForceRefresh( LPRESULTDATA pResultData )
  945. {
  946. HRESULT hr = S_OK;
  947. DWORD dwError = 0;
  948. BOOL bNeedChangeToolbar = FALSE;
  949. //if haven't successfully opened the storage yet, try again now.
  950. if (NULL == m_pComponentDataImpl->GetPolicyStoreHandle())
  951. {
  952. DWORD dwError = 0;
  953. dwError = m_pComponentDataImpl->OpenPolicyStore();
  954. if (ERROR_SUCCESS != dwError)
  955. {
  956. hr = HRESULT_FROM_WIN32(dwError);
  957. ReportError(IDS_POLMSG_EFAIL, hr);
  958. return hr;
  959. }
  960. ASSERT(NULL != m_pComponentDataImpl->GetPolicyStoreHandle());
  961. }
  962. // turn on the hourglass
  963. CWaitCursor waitCursor;
  964. // to determine if we should delete the result items
  965. CPtrList deletedList;
  966. CPtrList releaseList;
  967. BOOL bEnumerateItems = FALSE;
  968. // release the interface for each of these result items as
  969. // we are 'bout to nuke them
  970. RESULTDATAITEM resultItem;
  971. ZeroMemory(&resultItem, sizeof(resultItem));
  972. resultItem.mask = RDI_PARAM | RDI_STATE | RDI_INDEX;
  973. resultItem.nIndex = -1;
  974. resultItem.nState = LVNI_ALL;
  975. // get the next item
  976. hr = pResultData->GetNextItem (&resultItem);
  977. if (hr == S_OK)
  978. {
  979. while (hr == S_OK)
  980. {
  981. // if we recieved a scope node from the enumerations bail, they
  982. // are refreshing a view that is displaying our scope node, not
  983. // our result items (the only things that need to be refreshed)
  984. // NOTE: an alternate (and more correct?) way to do this could
  985. // be to keep track of our IComponent instances; in this situation
  986. // we actually have two of them and if we knew which one we
  987. // were we'd know if there were any result items to be refreshed
  988. // We can't currently do this because the CWirelessManagerFolder is
  989. // stored in the IComponentData implementation.
  990. if (resultItem.bScopeItem == TRUE)
  991. return S_OK;
  992. // free it off
  993. // if it ain't the right type of object we'll leak it
  994. IUnknown* pUnk = (IUnknown*)resultItem.lParam;
  995. ASSERT (pUnk);
  996. if (pUnk)
  997. {
  998. CComQIPtr<IWirelessSnapInDataObject, &IID_IWirelessSnapInDataObject> spData( pUnk );
  999. if (spData)
  1000. {
  1001. // delete it
  1002. HRESULTITEM actualItemID;
  1003. if (pResultData->FindItemByLParam (resultItem.lParam, &actualItemID) == S_OK)
  1004. {
  1005. // save for delete, release and note that we need to do deletion
  1006. deletedList.AddHead ((void*)actualItemID);
  1007. releaseList.AddHead ((void*)spData);
  1008. bEnumerateItems = TRUE;
  1009. }
  1010. } else
  1011. {
  1012. OPT_TRACE(_T("\tCWirelessManagerFolder::ForceRefresh(%p) couldn't QI on pUnk\n"), this);
  1013. }
  1014. }
  1015. // get the next item
  1016. hr = pResultData->GetNextItem (&resultItem);
  1017. }
  1018. } else
  1019. {
  1020. // there was _nothing_ in the list; so we enumerate anyway to see
  1021. // if there is something to add
  1022. bEnumerateItems = TRUE;
  1023. }
  1024. if (bEnumerateItems)
  1025. {
  1026. // delete them
  1027. while (!deletedList.IsEmpty())
  1028. {
  1029. LONG_PTR pLong = (LONG_PTR)deletedList.RemoveHead();
  1030. pResultData->DeleteItem (pLong, 0);
  1031. OPT_TRACE(_T("\tCWirelessManagerFolder::ForceRefresh(%p) deleting item, itemID(%p)\n"), this, pLong);
  1032. }
  1033. // we have no longer been enumerated
  1034. SetEnumerated(FALSE);
  1035. // re-add all items to our local list, which re-connects to storage
  1036. // for us; so we want to make sure that any warnings are displayed
  1037. m_pComponentDataImpl->IssueStorageWarning (TRUE);
  1038. //EnumerateResults( pResultData, m_nSortColumn, m_dwSortOrder );
  1039. HRESULT hrTemp = EnumerateResults( pResultData, m_nSortColumn, m_dwSortOrder );
  1040. //If the rpc connection is broken after we open the storage last time, the handle will
  1041. //become invalid. We need to re-open the storage to get a new handle.
  1042. if (FAILED(hrTemp))
  1043. {
  1044. dwError = m_pComponentDataImpl->OpenPolicyStore();
  1045. if (ERROR_SUCCESS != dwError)
  1046. {
  1047. hrTemp = HRESULT_FROM_WIN32(dwError);
  1048. }
  1049. else
  1050. {
  1051. hrTemp = EnumerateResults( pResultData, m_nSortColumn, m_dwSortOrder );
  1052. }
  1053. }
  1054. if (FAILED(hrTemp))
  1055. {
  1056. bNeedChangeToolbar = TRUE;
  1057. //ReportError(IDS_POLMSG_EFAIL, hrTemp);
  1058. }
  1059. //release them
  1060. while (!releaseList.IsEmpty())
  1061. {
  1062. IWirelessSnapInDataObject* spData = (IWirelessSnapInDataObject*)releaseList.RemoveHead();
  1063. OPT_TRACE(_T("\tCWirelessManagerFolder::ForceRefresh(%p) releasing spData (%p)\n"), this, spData);
  1064. spData->Release();
  1065. }
  1066. }
  1067. return hr;
  1068. }
  1069. HRESULT CWirelessManagerFolder::OnScopeExpand( LPCONSOLENAMESPACE pConsoleNameSpace, HSCOPEITEM hScopeItem )
  1070. {
  1071. // paramater validation
  1072. ASSERT(pConsoleNameSpace != NULL);
  1073. // turn on the hourglass
  1074. CWaitCursor waitCursor;
  1075. HRESULT hr = S_OK;
  1076. // for later addition of sub-items we need to store our ID...
  1077. // (note that if we were inserted by ourself we would already have a valid id here
  1078. // ASSERT(hScopeItem != NULL);
  1079. GetScopeItem()->ID = hScopeItem;
  1080. if (!IsEnumerated())
  1081. {
  1082. // Insert the scope item if we are an extension snap-in
  1083. if (NULL != GetExtScopeObject() && !m_bScopeItemInserted)
  1084. {
  1085. // Set the parent
  1086. GetScopeItem()->relativeID = hScopeItem;
  1087. // insert it into the scope
  1088. hr = pConsoleNameSpace->InsertItem( GetScopeItem() );
  1089. ASSERT(hr == S_OK);
  1090. m_bScopeItemInserted = TRUE;
  1091. // Note - On return, the ID member of 'm_pScopeItem'
  1092. // contains the handle to the newly inserted item!
  1093. ASSERT( GetScopeItem()->ID != NULL );
  1094. }
  1095. DWORD dwError = 0;
  1096. dwError = m_pComponentDataImpl->OpenPolicyStore();
  1097. if (ERROR_SUCCESS != dwError)
  1098. {
  1099. hr = HRESULT_FROM_WIN32(dwError);
  1100. ReportError(IDS_POLMSG_EFAIL, hr);
  1101. }
  1102. // We have been enumerated
  1103. SetEnumerated(TRUE);
  1104. }
  1105. return hr;
  1106. }
  1107. HRESULT CWirelessManagerFolder::OnAddImages(LPARAM arg, LPARAM param, IImageList* pImageList )
  1108. {
  1109. ASSERT( NULL != pImageList );
  1110. // TODO: what is arg, this only succeeds if it is not 0 but it isn't used...
  1111. if (arg == 0)
  1112. return E_INVALIDARG;
  1113. CBitmap bmp16x16;
  1114. CBitmap bmp32x32;
  1115. // Load the bitmaps from the dll
  1116. bmp16x16.LoadBitmap(IDB_16x16);
  1117. bmp32x32.LoadBitmap(IDB_32x32);
  1118. // Set the images
  1119. HRESULT hr = pImageList->ImageListSetStrip(reinterpret_cast<LONG_PTR*>(static_cast<HBITMAP>(bmp16x16)), reinterpret_cast<LONG_PTR*>(static_cast<HBITMAP>(bmp32x32)), 0, RGB(255, 0, 255));
  1120. ASSERT (hr == S_OK);
  1121. return S_OK;
  1122. }
  1123. HRESULT CWirelessManagerFolder::CreateWirelessPolicy(PWIRELESS_POLICY_DATA pPolicy)
  1124. {
  1125. ASSERT(pPolicy);
  1126. HRESULT hr = S_OK;
  1127. HANDLE hPolicyStore = NULL;
  1128. // NEW GPO
  1129. // Add Microsoft/Windows in Policies Container if its not there.
  1130. CString szMachinePath;
  1131. szMachinePath = m_pComponentDataImpl->DomainGPOName();
  1132. hr = AddWirelessPolicyContainerToGPO(szMachinePath);
  1133. if (FAILED(hr)) {
  1134. goto Error;
  1135. }
  1136. hPolicyStore = m_pComponentDataImpl->GetPolicyStoreHandle();
  1137. ASSERT(hPolicyStore);
  1138. CWRg(WirelessCreatePolicyData(hPolicyStore,
  1139. pPolicy));
  1140. Error:
  1141. return hr;
  1142. }