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.

781 lines
21 KiB

  1. // Copyright (c) 1997-2002 Microsoft Corporation
  2. #include "precomp.h"
  3. #ifdef EXT_DEBUG
  4. #undef THIS_FILE
  5. static char THIS_FILE[] = __FILE__;
  6. #endif
  7. #include "DepPage.h"
  8. // avoid some warnings.
  9. #undef HDS_HORZ
  10. #undef HDS_BUTTONS
  11. #undef HDS_HIDDEN
  12. #include "resource.h"
  13. #include <stdlib.h>
  14. #include <TCHAR.h>
  15. #include "..\Common\util.h"
  16. #include <regstr.h>
  17. #include "..\common\ConnectThread.h"
  18. #include "..\MMFUtil\MsgDlg.h"
  19. #include "winuser.h"
  20. BOOL AfxIsValidAddress(const void* lp,
  21. UINT nBytes,
  22. BOOL bReadWrite)
  23. {
  24. // simple version using Win-32 APIs for pointer validation.
  25. return (lp != NULL && !IsBadReadPtr(lp, nBytes) &&
  26. (!bReadWrite || !IsBadWritePtr((LPVOID)lp, nBytes)));
  27. }
  28. const wchar_t *CFServiceName = L"FILEMGMT_SNAPIN_SERVICE_NAME";
  29. const wchar_t *CFServiceDisplayName = L"FILEMGMT_SNAPIN_SERVICE_DISPLAYNAME";
  30. //--------------------------------------------------------------
  31. DependencyPage::DependencyPage(WbemConnectThread *pConnectThread,
  32. IDataObject *pDataObject,
  33. long lNotifyHandle, bool bDeleteHandle, TCHAR* pTitle)
  34. : PageHelper(pConnectThread),
  35. CSnapInPropertyPageImpl<DependencyPage> (pTitle),
  36. m_lNotifyHandle(lNotifyHandle),
  37. m_bDeleteHandle(bDeleteHandle),
  38. m_qLang("WQL"),
  39. m_NameProp("Name"),
  40. m_DispNameProp("DisplayName")
  41. {
  42. m_servIcon = 0;
  43. m_sysDriverIcon = 0;
  44. m_emptyIcon = 0;
  45. m_groupIcon = 0;
  46. ATLTRACE(L"dependency Page CTOR\n");
  47. m_queryFormat = new TCHAR[QUERY_SIZE];
  48. m_queryTemp = new TCHAR[QUERY_SIZE];
  49. Extract(pDataObject, L"FILEMGMT_SNAPIN_SERVICE_NAME", m_ServiceName);
  50. Extract(pDataObject, L"FILEMGMT_SNAPIN_SERVICE_DISPLAYNAME", m_ServiceDispName);
  51. }
  52. //--------------------------------------------------------------
  53. DependencyPage::~DependencyPage()
  54. {
  55. ATLTRACE(L"dependency Page DTOR\n");
  56. delete[] m_queryFormat;
  57. delete[] m_queryTemp;
  58. }
  59. //--------------------------------------------------------------
  60. void DependencyPage::BuildQuery(TV_ITEM *fmNode,
  61. QUERY_TYPE queryType,
  62. bool depends,
  63. bstr_t &query)
  64. {
  65. // clean the working space.
  66. memset(m_queryFormat, 0, QUERY_SIZE * sizeof(TCHAR));
  67. memset(m_queryTemp, 0, QUERY_SIZE * sizeof(TCHAR));
  68. // here's the WQL syntax format.
  69. switch(queryType)
  70. {
  71. case DepService:
  72. _tcscpy(m_queryFormat,
  73. _T("Associators of {Win32_BaseService.Name=\"%s\"} where Role=%s AssocClass=Win32_DependentService"));
  74. // build the query for this level.
  75. _sntprintf(m_queryTemp, QUERY_SIZE- 1, m_queryFormat,
  76. (LPCTSTR)((ITEMEXTRA *)fmNode->lParam)->realName,
  77. (depends ? _T("Dependent") : _T("Antecedent")));
  78. break;
  79. case DepGroup:
  80. _tcscpy(m_queryFormat,
  81. _T("Associators of {Win32_BaseService.Name=\"%s\"} where ResultClass=Win32_LoadOrderGroup Role=%s AssocClass=Win32_LoadOrderGroupServiceDependencies"));
  82. // build the query for this level.
  83. _sntprintf(m_queryTemp, QUERY_SIZE- 1, m_queryFormat,
  84. (LPCTSTR)((ITEMEXTRA *)fmNode->lParam)->realName,
  85. (depends ? _T("Dependent") : _T("Antecedent")));
  86. break;
  87. case GroupMember:
  88. _tcscpy(m_queryFormat,
  89. _T("Associators of {Win32_LoadOrderGroup.Name=\"%s\"} where Role=GroupComponent AssocClass=Win32_LoadOrderGroupServiceMembers"));
  90. // L"Associators of {Win32_LoadOrderGroup.Name=\"%s\"} where ResultClass=Win32_Service Role=GroupComponent AssocClass=Win32_LoadOrderGroupServiceMembers");
  91. // build the query for this level.
  92. _sntprintf(m_queryTemp, QUERY_SIZE- 1, m_queryFormat,
  93. (LPCTSTR)((ITEMEXTRA *)fmNode->lParam)->realName);
  94. break;
  95. } // endswitch
  96. m_queryTemp[QUERY_SIZE - 1] = 0;
  97. // cast to bstr_t and return.
  98. query = m_queryTemp;
  99. }
  100. //--------------------------------------------------------------
  101. void DependencyPage::LoadLeaves(HWND hTree, TV_ITEM *fmNode, bool depends )
  102. {
  103. bstr_t query;
  104. NODE_TYPE nodeType = ((ITEMEXTRA *)fmNode->lParam)->nodeType;
  105. bool foundIt = false;
  106. // HourGlass(true);
  107. switch(nodeType)
  108. {
  109. case ServiceNode:
  110. // NOTE: services can depend on groups but not the
  111. // other way around.
  112. if(depends)
  113. {
  114. //load groups.
  115. BuildQuery(fmNode, DepGroup, depends, query);
  116. foundIt = Load(hTree, fmNode, query, GroupNode);
  117. }
  118. // load services.
  119. BuildQuery(fmNode, DepService, depends, query);
  120. foundIt |= Load(hTree, fmNode, query, ServiceNode);
  121. break;
  122. case GroupNode:
  123. // NOTE: 'depends' doesn't matter in this case.
  124. // load group members.
  125. BuildQuery(fmNode, GroupMember, depends, query);
  126. foundIt = Load(hTree, fmNode, query, ServiceNode);
  127. break;
  128. }//endswitch
  129. //TODO: Decide opn what to do for this
  130. // HourGlass(false);
  131. if(!foundIt)
  132. {
  133. NothingMore(hTree, fmNode);
  134. if(depends)
  135. {
  136. if(fmNode->hItem == TVI_ROOT)
  137. {
  138. ::EnableWindow(GetDlgItem(IDC_DEPENDS_LBL), FALSE);
  139. }
  140. }
  141. else
  142. {
  143. if(fmNode->hItem == TVI_ROOT)
  144. {
  145. ::EnableWindow(GetDlgItem(IDC_NEEDED_LBL), FALSE);
  146. }
  147. }
  148. }
  149. }
  150. //--------------------------------------------------------------
  151. // READ: In 'hTree', run 'query' and make the children
  152. // 'childType' nodes under 'fmNode'.
  153. bool DependencyPage::Load(HWND hTree, TV_ITEM *fmNode, bstr_t query,
  154. NODE_TYPE childType)
  155. {
  156. HRESULT hRes;
  157. variant_t pRealName, pDispName;
  158. ULONG uReturned;
  159. IWbemClassObject *pOther = NULL;
  160. IEnumWbemClassObject *pEnumOther = NULL;
  161. TV_INSERTSTRUCT leaf;
  162. leaf.hInsertAfter = TVI_SORT;
  163. leaf.hParent = fmNode->hItem;
  164. bool foundOne = false;
  165. ATLTRACE(L"query started\n");
  166. hRes = m_WbemServices.ExecQuery(m_qLang, query,
  167. WBEM_FLAG_RETURN_IMMEDIATELY |
  168. WBEM_FLAG_FORWARD_ONLY,
  169. &pEnumOther);
  170. //-------------------
  171. // query for all related services or groups.
  172. if(hRes == S_OK)
  173. {
  174. ATLTRACE(L"query worked %x\n", hRes);
  175. //-------------------
  176. // enumerate through services.
  177. while(SUCCEEDED(hRes = pEnumOther->Next(500, 1, &pOther, &uReturned)))
  178. {
  179. if(hRes == WBEM_S_TIMEDOUT)
  180. continue;
  181. if(uReturned != 1)
  182. {
  183. ATLTRACE(L"uReturned failed %x: %s \n", hRes, query);
  184. break;
  185. }
  186. foundOne = true;
  187. //-------------------
  188. // get the node's name(s).
  189. switch(childType)
  190. {
  191. case ServiceNode:
  192. hRes = pOther->Get(m_DispNameProp, 0, &pDispName, NULL, NULL);
  193. hRes = pOther->Get(m_NameProp, 0, &pRealName, NULL, NULL);
  194. if(SUCCEEDED(hRes))
  195. {
  196. hRes = pOther->Get(m_DispNameProp, 0, &pDispName, NULL, NULL);
  197. }
  198. break;
  199. case GroupNode:
  200. hRes = pOther->Get(m_NameProp, 0, &pRealName, NULL, NULL);
  201. if(SUCCEEDED(hRes))
  202. {
  203. pDispName = pRealName;
  204. }
  205. break;
  206. }// endswitch
  207. // got the properties ok?
  208. if(SUCCEEDED(hRes))
  209. {
  210. // add the leaf.
  211. leaf.item.mask = TVIF_TEXT | TVIF_PARAM |
  212. TVIF_CHILDREN |TVIF_IMAGE |TVIF_SELECTEDIMAGE;
  213. leaf.item.hItem = 0;
  214. leaf.item.state = 0;
  215. leaf.item.stateMask = 0;
  216. if(pDispName.vt == VT_BSTR)
  217. {
  218. leaf.item.pszText = CloneString((bstr_t)pDispName);
  219. }
  220. else
  221. {
  222. leaf.item.pszText = CloneString((bstr_t)pRealName);
  223. }
  224. leaf.item.cchTextMax = ARRAYSIZE(leaf.item.pszText);
  225. TCHAR pszCreationClassName[20];
  226. _tcscpy(pszCreationClassName,_T("CreationClassName"));
  227. variant_t pCreationName;
  228. _bstr_t strCreationClassName;
  229. // set the icon based on 'childType'
  230. switch(childType)
  231. {
  232. case ServiceNode:
  233. //Here we will have to change the icon depending on whether it is a win32_service or
  234. //Win32_SystemDriver
  235. pOther->Get(pszCreationClassName, 0, &pCreationName, NULL, NULL);
  236. strCreationClassName = pCreationName.bstrVal;
  237. if(_tcsicmp(strCreationClassName,_T("Win32_Service")) == 0)
  238. {
  239. leaf.item.iImage = m_servIcon;
  240. leaf.item.iSelectedImage = m_servIcon;
  241. }
  242. else
  243. {
  244. leaf.item.iImage = m_sysDriverIcon;
  245. leaf.item.iSelectedImage = m_sysDriverIcon;
  246. }
  247. break;
  248. case GroupNode:
  249. leaf.item.iImage = m_groupIcon;
  250. leaf.item.iSelectedImage = m_groupIcon;
  251. break;
  252. } // endswitch
  253. // turn on the '+' sign.
  254. leaf.item.cChildren = 1;
  255. // set internal data.
  256. ITEMEXTRA *extra = new ITEMEXTRA;
  257. if (extra != NULL)
  258. {
  259. extra->loaded = false;
  260. extra->nodeType = childType;
  261. // true name.
  262. extra->realName = CloneString((bstr_t)pRealName);
  263. leaf.item.lParam = (LPARAM) extra;
  264. TreeView_InsertItem(hTree, &leaf);
  265. // if there is a parent...
  266. if(fmNode->hItem != TVI_ROOT)
  267. {
  268. // indicate that the parent's children have been
  269. // loaded. This helps optimize for collapsing/re-
  270. // expanding.
  271. fmNode->mask = TVIF_PARAM | TVIF_HANDLE;
  272. ((ITEMEXTRA *)fmNode->lParam)->loaded = true;
  273. TreeView_SetItem(hTree, fmNode);
  274. }
  275. }
  276. } // endif Get() user name
  277. // done with the ClassObject
  278. if (pOther)
  279. {
  280. pOther->Release();
  281. pOther = NULL;
  282. }
  283. } //endwhile Next()
  284. ATLTRACE(L"while %x: %s \n", hRes, (wchar_t *)query);
  285. // release the enumerator.
  286. if(pEnumOther)
  287. {
  288. pEnumOther->Release();
  289. pEnumOther = NULL;
  290. }
  291. }
  292. else
  293. {
  294. ATLTRACE(L"query failed %x: %s \n", hRes, query);
  295. } //endif ExecQuery()
  296. // if nothing found...
  297. return foundOne;
  298. }
  299. //---------------------------------------------------
  300. void DependencyPage::NothingMore(HWND hTree, TV_ITEM *fmNode)
  301. {
  302. TV_INSERTSTRUCT leaf;
  303. leaf.hInsertAfter = TVI_SORT;
  304. leaf.hParent = fmNode->hItem;
  305. // and its the root...
  306. if(fmNode->hItem == TVI_ROOT)
  307. {
  308. // indicate an 'empty' tree.
  309. leaf.item.pszText = new TCHAR[100];
  310. if( NULL == leaf.item.pszText ) return;
  311. leaf.item.cchTextMax = 100;
  312. ::LoadString(HINST_THISDLL, IDS_NO_DEPS,
  313. leaf.item.pszText,
  314. leaf.item.cchTextMax);
  315. leaf.item.mask = TVIF_TEXT | TVIF_PARAM |
  316. TVIF_CHILDREN | TVIF_IMAGE |
  317. TVIF_SELECTEDIMAGE;
  318. leaf.item.hItem = 0;
  319. leaf.item.state = 0;
  320. leaf.item.stateMask = 0;
  321. leaf.item.iImage = m_emptyIcon;
  322. leaf.item.iSelectedImage = m_emptyIcon;
  323. leaf.item.cChildren = 0;
  324. ITEMEXTRA *extra = new ITEMEXTRA;
  325. if(extra == NULL)
  326. {
  327. delete[] leaf.item.pszText;
  328. return;
  329. }
  330. extra->loaded = false;
  331. extra->nodeType = ServiceNode;
  332. extra->realName = NULL; // to be safe during cleanup.
  333. leaf.item.lParam = (LPARAM) extra;
  334. TreeView_InsertItem(hTree, &leaf);
  335. ::EnableWindow(hTree, FALSE);
  336. delete[] leaf.item.pszText;
  337. }
  338. else // not the root.
  339. {
  340. // Cant drill down anymore.
  341. // Turn off the [+] symbol.
  342. fmNode->mask = TVIF_CHILDREN | TVIF_HANDLE;
  343. fmNode->cChildren = 0;
  344. TreeView_SetItem(hTree, fmNode);
  345. }
  346. }
  347. //--------------------------------------------------------------
  348. void DependencyPage::TwoLines(UINT uID, LPCTSTR staticString, LPCTSTR inStr, LPTSTR outStr,bool bStaticFirst)
  349. {
  350. HWND ctl = ::GetDlgItem(m_hWnd, uID);
  351. HDC hDC = ::GetDC(ctl);
  352. //THIS IS A HACK. I COULD NOT CALCULATE THE ACTUAL WIDTH OF THE CONTROL
  353. //IN LOGICAL UNITS. SO AS OF NOW, CALCULATED MANUALLY AND HARDCODING IT.
  354. int ctlWidth = 509;
  355. TCHAR strTemp[1024];
  356. TCHAR *strCurr;
  357. int lenstrTemp;
  358. SIZE sizeTemp;
  359. int nFit = 0;
  360. //First we will try whether the whole string fits in the space
  361. if(bStaticFirst == true)
  362. {
  363. _sntprintf(strTemp, 1023, _T("%s \"%s\""),staticString,inStr);
  364. }
  365. else
  366. {
  367. _sntprintf(strTemp, 1023, _T("\"%s\" %s"),inStr,staticString);
  368. }
  369. strTemp[1023] = 0;
  370. strCurr = strTemp;
  371. lenstrTemp = lstrlen(strTemp);
  372. GetTextExtentExPoint(hDC,strTemp,lenstrTemp,ctlWidth,&nFit,NULL,&sizeTemp);
  373. if(lenstrTemp <= nFit)
  374. {
  375. //The whole string will fit in a line. So we will all a \r\n in the beginning
  376. _sntprintf(outStr, 1023, _T("\r\n%s"),strTemp);
  377. outStr[1023] = 0;
  378. return;
  379. }
  380. //Now we will try if the whole string atleast fits in 2 lines.
  381. strCurr += nFit;
  382. int nFit1;
  383. lenstrTemp = lstrlen(strCurr);
  384. GetTextExtentExPoint(hDC,strCurr,lenstrTemp,ctlWidth,&nFit1,NULL,&sizeTemp);
  385. if(lenstrTemp <= nFit1)
  386. {
  387. //The whole string will fit in 2 lines. So we will all a \r\n in the end of the first line
  388. TCHAR strTemp1[1024];
  389. _tcsncpy(strTemp1,strTemp,nFit);
  390. strTemp1[nFit] = _T('\0');
  391. _sntprintf(outStr,1023,_T("%s\r\n%s"),strTemp1,strCurr);
  392. outStr[1023] = 0;
  393. return;
  394. }
  395. //NOW since it won't fit in 2 lines, we will have to do some calculations and
  396. //add a "..." to the end of the instr so that it will fit in 2 lines.
  397. //If the static string is in the from, then we can easily do it.
  398. TCHAR strLast[5];
  399. _tcscpy(strLast,_T("...\""));
  400. int sizeLast = lstrlen(strLast);
  401. SIZE sz1;
  402. GetTextExtentPoint32(hDC,strLast,sizeLast,&sz1);
  403. TCHAR strTemp1[1024];
  404. _tcsncpy(strTemp1,strTemp,nFit);
  405. strTemp1[nFit] = _T('\0');
  406. if(bStaticFirst == true)
  407. {
  408. TCHAR strTemp2[10];
  409. //Now take characters from the end of the array and match it until the
  410. //width needed to print is greater than the "..."" string
  411. bool bFit = false;
  412. int nStart = nFit1 - 4;
  413. int nStart1;
  414. SIZE sz2;
  415. while(bFit == false)
  416. {
  417. nStart1 = nStart;
  418. for(int i=0; i < nFit1 - nStart; i++)
  419. {
  420. strTemp2[i] = strCurr[nStart1];
  421. nStart1 ++;
  422. }
  423. strTemp2[i] = _T('\0');
  424. GetTextExtentPoint32(hDC,strTemp2,nFit1 - nStart,&sz2);
  425. if(sz2.cx < sz1.cx)
  426. {
  427. nStart --;
  428. }
  429. else
  430. {
  431. break;
  432. }
  433. }
  434. strCurr[nStart] = _T('\0');
  435. _sntprintf(outStr,1023,_T("%s\r\n%s%s"),strTemp1,strCurr,strLast);
  436. outStr[1023] = 0;
  437. return;
  438. }
  439. else
  440. {
  441. //Now we will have to add strLast to the end of trimmed string.
  442. //Since it will be the same in the first line, we will first calculate fit1 again.
  443. SIZE szFinal;
  444. TCHAR strFinal[1024];
  445. _sntprintf(strFinal,1023,_T("%s %s"),strLast,staticString);
  446. strFinal[1023] = 0;
  447. GetTextExtentPoint32(hDC,strFinal,lstrlen(strFinal),&szFinal);
  448. //Now subtract szFinal from the ctlWidth and calculate the number of characters
  449. //that will fit in to that space
  450. GetTextExtentExPoint(hDC,strCurr,lstrlen(strCurr),ctlWidth - szFinal.cx ,&nFit1,NULL,&sizeTemp);
  451. strCurr[nFit1-1] = _T('\0');
  452. _sntprintf(outStr,1023,_T("%s\r\n%s%s"),strTemp1,strCurr,strFinal);
  453. outStr[1023] = 0;
  454. return;
  455. }
  456. }
  457. //--------------------------------------------------------------
  458. LRESULT DependencyPage::OnInit(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  459. {
  460. m_hDlg = m_hWnd;
  461. //TODO: Check this out
  462. if(m_pgConnectThread)
  463. {
  464. m_pgConnectThread->SendPtr(m_hWnd);
  465. }
  466. TCHAR szBuffer1[100] = {0}, szBuffer2[256] = {0};
  467. SetDlgItemText(IDC_DEPENDS_SRVC, (wchar_t *)m_ServiceDispName);
  468. // set the nice bitmap.
  469. SetClearBitmap(GetDlgItem(IDC_PICT ), MAKEINTRESOURCE( IDB_SERVICE ), 0);
  470. // create an empty imagelist.
  471. HIMAGELIST hImageList = ImageList_Create(16, 16, ILC_COLOR8|ILC_MASK, 3, 0);
  472. // add an icon
  473. m_servIcon = ImageList_AddIcon(hImageList,
  474. LoadIcon(HINST_THISDLL,
  475. MAKEINTRESOURCE(IDI_SERVICE)));
  476. m_sysDriverIcon = ImageList_AddIcon(hImageList,
  477. LoadIcon(HINST_THISDLL,
  478. MAKEINTRESOURCE(IDI_SYSTEMDRIVER)));
  479. m_emptyIcon = ImageList_AddIcon(hImageList,
  480. LoadIcon(NULL,
  481. MAKEINTRESOURCE(IDI_INFORMATION)));
  482. m_groupIcon = ImageList_AddIcon(hImageList,
  483. LoadIcon(HINST_THISDLL,
  484. MAKEINTRESOURCE(IDI_SERVGROUP)));
  485. // sent it to the trees.
  486. TreeView_SetImageList(GetDlgItem(IDC_DEPENDS_TREE),
  487. hImageList,
  488. TVSIL_NORMAL);
  489. TreeView_SetImageList(GetDlgItem(IDC_NEEDED_TREE),
  490. hImageList,
  491. TVSIL_NORMAL);
  492. InvalidateRect(NULL);
  493. UpdateWindow();
  494. ATLTRACE(L"UpdateWindow() fm Init\n");
  495. // can we get data yet?
  496. ::PostMessage(m_hDlg, WM_ENUM_NOW, 0, 0);
  497. HourGlass(true);
  498. return S_OK;
  499. }
  500. //--------------------------------------------------------------
  501. void DependencyPage::LoadTrees(void)
  502. {
  503. ATLTRACE(L"checking service\n");
  504. // did that background connection thread work yet?
  505. if(ServiceIsReady(IDS_DISPLAY_NAME, IDS_CONNECTING, IDS_BAD_CONNECT))
  506. {
  507. //Now we will check if there is already some nodes.
  508. //If it is, then it means that we don't have to enumerate it again.
  509. //This normally happens in the first time when we connect to a remote machine
  510. /* //We will clear the nodes if it already exists
  511. TreeView_DeleteAllItems(GetDlgItem(IDC_DEPENDS_TREE));
  512. TreeView_DeleteAllItems(GetDlgItem(IDC_NEEDED_TREE));
  513. */
  514. if(TreeView_GetCount(GetDlgItem(IDC_DEPENDS_TREE)) == 0)
  515. {
  516. HourGlass(true);
  517. TV_ITEM root;
  518. ITEMEXTRA *extra = new ITEMEXTRA;
  519. if(extra == NULL)
  520. return;
  521. root.hItem = TVI_ROOT; // I'm making a root.
  522. root.pszText = m_ServiceDispName;
  523. extra->realName = CloneString(m_ServiceName);
  524. extra->loaded = false;
  525. extra->nodeType = ServiceNode;
  526. root.lParam = (LPARAM)extra;
  527. InvalidateRect(NULL);
  528. UpdateWindow();
  529. // load the first levels.
  530. LoadLeaves(GetDlgItem(IDC_DEPENDS_TREE),
  531. &root, true);
  532. LoadLeaves(GetDlgItem(IDC_NEEDED_TREE),
  533. &root, false);
  534. SetFocus();
  535. HourGlass(false);
  536. }
  537. }
  538. }
  539. //--------------------------------------------------------------
  540. BOOL DependencyPage::OnApply()
  541. {
  542. ::SetWindowLongPtr(m_hDlg, DWLP_USER, 0);
  543. return TRUE;
  544. }
  545. //--------------------------------------------------------------
  546. BOOL DependencyPage::OnKillActive()
  547. {
  548. //SetWindowLong(DWL_MSGRESULT, 0);
  549. return TRUE;
  550. }
  551. //--------------------------------------------------------------
  552. LRESULT DependencyPage::OnEnumNow(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  553. {
  554. if(lParam)
  555. {
  556. IStream *pStream = (IStream *)lParam;
  557. IWbemServices *pServices = 0;
  558. HRESULT hr = CoGetInterfaceAndReleaseStream(pStream,
  559. IID_IWbemServices,
  560. (void**)&pServices);
  561. if(SUCCEEDED(hr))
  562. {
  563. SetWbemService(pServices);
  564. pServices->Release();
  565. }
  566. LoadTrees(); //calls ServiceIsReady() itself.
  567. }
  568. else if(FAILED(m_pgConnectThread->m_hr))
  569. {
  570. DisplayUserMessage(m_hDlg, HINST_THISDLL,
  571. IDS_DISPLAY_NAME, BASED_ON_SRC,
  572. ConnectServer,
  573. m_pgConnectThread->m_hr,
  574. MB_ICONSTOP);
  575. }
  576. else
  577. {
  578. m_pgConnectThread->NotifyWhenDone(&m_hDlg);
  579. }
  580. return S_OK;
  581. }
  582. //--------------------------------------------------------------
  583. LRESULT DependencyPage::OnItemExpanding(int idCtrl, LPNMHDR pnmh, BOOL& bHandled)
  584. {
  585. // which node?
  586. NM_TREEVIEW *notice = (NM_TREEVIEW *)pnmh;
  587. // we're expanding, not collapsing...
  588. if(notice->action == TVE_EXPAND)
  589. {
  590. // which tree?
  591. HWND treeHWND = GetDlgItem(idCtrl);
  592. TV_ITEM item;
  593. item.mask = TVIF_TEXT | TVIF_PARAM | TVIF_CHILDREN |TVIF_IMAGE;
  594. item.pszText = new TCHAR[200];
  595. item.cchTextMax = 200;
  596. item.hItem = notice->itemNew.hItem;
  597. TreeView_GetItem(treeHWND, &item);
  598. // if we've never tried...
  599. if(((ITEMEXTRA *)item.lParam)->loaded == false)
  600. {
  601. // NOTE: really cant get here if its not ready
  602. // but better safe than sorry.
  603. if(ServiceIsReady(IDS_DISPLAY_NAME, IDS_CONNECTING, IDS_BAD_CONNECT))
  604. {
  605. // load it.
  606. LoadLeaves(treeHWND, &item, (idCtrl == IDC_DEPENDS_TREE));
  607. }
  608. }
  609. delete[] item.pszText;
  610. } //end action
  611. return S_OK;
  612. }
  613. //-------------------------------------------------------------------------------
  614. LRESULT DependencyPage::OnDeleteItem(int idCtrl, LPNMHDR pnmh, BOOL& bHandled)
  615. {
  616. NM_TREEVIEW *notice = (NM_TREEVIEW *)pnmh;
  617. delete[] (TCHAR *)((ITEMEXTRA *)notice->itemOld.lParam)->realName;
  618. delete (ITEMEXTRA *)notice->itemOld.lParam;
  619. return S_OK;
  620. }
  621. //-------------------------------------------------------------------------------
  622. DWORD aDepHelpIds[] = {
  623. IDC_PICT, -1,
  624. IDC_DESC, -1,
  625. IDC_DEPENDS_LBL, (985), // dependsOn
  626. IDC_DEPENDS_TREE, (985), // dependsOn
  627. IDC_NEEDED_LBL, (988), // neededBy
  628. IDC_NEEDED_TREE, (988), // neededBy
  629. 0, 0
  630. };
  631. LRESULT DependencyPage::OnF1Help(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  632. {
  633. ::WinHelp((HWND)((LPHELPINFO)lParam)->hItemHandle,
  634. L"filemgmt.hlp",
  635. HELP_WM_HELP,
  636. (ULONG_PTR)(LPSTR)aDepHelpIds);
  637. return S_OK;
  638. }
  639. //-------------------------------------------------------------------------------
  640. LRESULT DependencyPage::OnContextHelp(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  641. {
  642. ::WinHelp((HWND)wParam,
  643. L"filemgmt.hlp",
  644. HELP_CONTEXTMENU,
  645. (ULONG_PTR)(LPSTR)aDepHelpIds);
  646. return S_OK;
  647. }