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.

1085 lines
30 KiB

  1. #include "stdafx.h"
  2. #include "HotfixManager.h"
  3. #include "Hotfix_Manager.h"
  4. #ifndef DNS_MAX_NAME_LENGTH
  5. #define DNS_MAX_NAME_LENGTH 255
  6. #endif
  7. #define REMOTE_STATE 0
  8. #define HOTFIX_STATE 1
  9. static CRITICAL_SECTION CritSec;
  10. BSTR CHotfix_ManagerData::m_bstrColumnType;
  11. BSTR CHotfix_ManagerData::m_bstrColumnDesc;
  12. static CComPtr<IDispatch> gpDisp = NULL;
  13. /////////////////////////////////////////////////////////////////////////////
  14. // CHotfix_ManagerComponentData
  15. static const GUID CHotfix_ManagerGUID_NODETYPE =
  16. { 0x2315305b, 0x3abe, 0x4c07, { 0xaf, 0x6e, 0x95, 0xdc, 0xa4, 0x82, 0x5b, 0xdd } };
  17. const GUID* CHotfix_ManagerData::m_NODETYPE = &CHotfix_ManagerGUID_NODETYPE;
  18. const OLECHAR* CHotfix_ManagerData::m_SZNODETYPE = OLESTR("2315305B-3ABE-4C07-AF6E-95DCA4825BDD");
  19. const OLECHAR* CHotfix_ManagerData::m_SZDISPLAY_NAME = OLESTR("Hotfix_Manager");
  20. const CLSID* CHotfix_ManagerData::m_SNAPIN_CLASSID = &CLSID_Hotfix_Manager;
  21. static const GUID CHotfix_ManagerExtGUID_NODETYPE =
  22. { 0x476e6448, 0xaaff, 0x11d0, { 0xb9, 0x44, 0x0, 0xc0, 0x4f, 0xd8, 0xd5, 0xb0 } };
  23. const GUID* CHotfix_ManagerExtData::m_NODETYPE = &CHotfix_ManagerExtGUID_NODETYPE;
  24. const OLECHAR* CHotfix_ManagerExtData::m_SZNODETYPE = OLESTR("476e6448-aaff-11d0-b944-00c04fd8d5b0");
  25. const OLECHAR* CHotfix_ManagerExtData::m_SZDISPLAY_NAME = OLESTR("Hotfix_Manager");
  26. const CLSID* CHotfix_ManagerExtData::m_SNAPIN_CLASSID = &CLSID_Hotfix_Manager;
  27. CHotfix_Manager::CHotfix_Manager()
  28. {
  29. DWORD dwSize = 255;
  30. GetComputerName(m_szComputerName,&dwSize);
  31. InitializeCriticalSection(&CritSec);
  32. // m_pNode = new CHotfix_ManagerData(NULL ,m_szComputerName, FALSE);
  33. // _ASSERTE(m_pNode != NULL);
  34. m_pComponentData = this;
  35. RegisterRemotedClass();
  36. }
  37. HRESULT CHotfix_ManagerData::GetScopePaneInfo(SCOPEDATAITEM *pScopeDataItem)
  38. {
  39. if (pScopeDataItem->mask & SDI_STR)
  40. pScopeDataItem->displayname = m_bstrDisplayName;
  41. if (pScopeDataItem->mask & SDI_IMAGE)
  42. pScopeDataItem->nImage = m_scopeDataItem.nImage;
  43. if (pScopeDataItem->mask & SDI_OPENIMAGE)
  44. pScopeDataItem->nOpenImage = m_scopeDataItem.nOpenImage;
  45. if (pScopeDataItem->mask & SDI_PARAM)
  46. pScopeDataItem->lParam = m_scopeDataItem.lParam;
  47. if (pScopeDataItem->mask & SDI_STATE )
  48. pScopeDataItem->nState = m_scopeDataItem.nState;
  49. // TODO : Add code for SDI_CHILDREN
  50. if (pScopeDataItem->mask & SDI_CHILDREN )
  51. pScopeDataItem->cChildren = 0;
  52. return S_OK;
  53. }
  54. HRESULT CHotfix_ManagerData::GetResultPaneInfo(RESULTDATAITEM *pResultDataItem)
  55. {
  56. if (pResultDataItem->bScopeItem)
  57. {
  58. if (pResultDataItem->mask & RDI_STR)
  59. {
  60. pResultDataItem->str = GetResultPaneColInfo(pResultDataItem->nCol);
  61. }
  62. if (pResultDataItem->mask & RDI_IMAGE)
  63. {
  64. pResultDataItem->nImage = m_scopeDataItem.nImage;
  65. }
  66. if (pResultDataItem->mask & RDI_PARAM)
  67. {
  68. pResultDataItem->lParam = m_scopeDataItem.lParam;
  69. }
  70. return S_OK;
  71. }
  72. if (pResultDataItem->mask & RDI_STR)
  73. {
  74. pResultDataItem->str = GetResultPaneColInfo(pResultDataItem->nCol);
  75. }
  76. if (pResultDataItem->mask & RDI_IMAGE)
  77. {
  78. pResultDataItem->nImage = m_resultDataItem.nImage;
  79. }
  80. if (pResultDataItem->mask & RDI_PARAM)
  81. {
  82. pResultDataItem->lParam = m_resultDataItem.lParam;
  83. }
  84. if (pResultDataItem->mask & RDI_INDEX)
  85. {
  86. pResultDataItem->nIndex = m_resultDataItem.nIndex;
  87. }
  88. return S_OK;
  89. }
  90. HRESULT CHotfix_Manager::Notify(LPDATAOBJECT lpDataObject, MMC_NOTIFY_TYPE event, LPARAM arg, LPARAM param)
  91. {
  92. HRESULT hr = E_UNEXPECTED;
  93. if (lpDataObject != NULL)
  94. {
  95. switch ( event )
  96. {
  97. case MMCN_EXPAND:
  98. {
  99. //
  100. // Process out the local or machine name if we're expanding.
  101. //
  102. if (arg == TRUE)
  103. {
  104. if ( ExtractString( lpDataObject, m_ccfRemotedFormat, m_szComputerName, DNS_MAX_NAME_LENGTH + 1 ) )
  105. {
  106. if (!_tcscmp (m_szComputerName,_T("\0")))
  107. {
  108. DWORD dwSize = 255;
  109. GetComputerName(m_szComputerName,&dwSize);
  110. }
  111. }
  112. else
  113. {
  114. DWORD dwSize = 255;
  115. GetComputerName(m_szComputerName,&dwSize);
  116. }
  117. if ( _tcscmp (gszComputerName, m_szComputerName) )
  118. {
  119. // MessageBox (NULL,_T("Setting Computername sent to false"), _T("Main Data Notify"),MB_OK);
  120. ComputerNameSent = FALSE;
  121. _tcscpy (gszComputerName,m_szComputerName);
  122. }
  123. //
  124. // Intentionally left to fall through to default handler.
  125. //
  126. }
  127. }
  128. default:
  129. {
  130. //
  131. // Call our default handling.
  132. //
  133. hr = IComponentDataImpl<CHotfix_Manager, CHotfix_ManagerComponent>::Notify( lpDataObject, event, arg, param );
  134. }
  135. }
  136. }
  137. return( hr );
  138. }
  139. HRESULT CHotfix_ManagerData::Notify( MMC_NOTIFY_TYPE event,
  140. long arg,
  141. long param,
  142. IComponentData* pComponentData,
  143. IComponent* pComponent,
  144. DATA_OBJECT_TYPES type)
  145. {
  146. // Add code to handle the different notifications.
  147. // Handle MMCN_SHOW and MMCN_EXPAND to enumerate children items.
  148. // In response to MMCN_SHOW you have to enumerate both the scope
  149. // and result pane items.
  150. // For MMCN_EXPAND you only need to enumerate the scope items
  151. // Use IConsoleNameSpace::InsertItem to insert scope pane items
  152. // Use IResultData::InsertItem to insert result pane item.
  153. HRESULT hr = E_NOTIMPL;
  154. _ASSERTE(pComponentData != NULL || pComponent != NULL);
  155. CComPtr<IConsole> spConsole;
  156. CComQIPtr<IHeaderCtrl, &IID_IHeaderCtrl> spHeader;
  157. if (pComponentData != NULL)
  158. spConsole = ((CHotfix_Manager*)pComponentData)->m_spConsole;
  159. else
  160. {
  161. spConsole = ((CHotfix_ManagerComponent*)pComponent)->m_spConsole;
  162. spHeader = spConsole;
  163. }
  164. switch (event)
  165. {
  166. case MMCN_INITOCX:
  167. {
  168. // MessageBox(NULL,_T("Recieved init OCX"),NULL,MB_OK);
  169. CComQIPtr<IDispatch,&IID_IDispatch> pDisp = (IUnknown *) param;
  170. gpDisp = pDisp;
  171. // MessageBox(NULL,m_szComputerName,_T("Init Ocx Sending"),MB_OK);
  172. SendComputerName(m_szComputerName, gpDisp);
  173. // MessageBox(NULL,_T("Setting ComputerNameSent to TRUE"),_T("ManagerData::Notify"),MB_OK);
  174. ComputerNameSent = TRUE;
  175. break;
  176. }
  177. /* case MMCN_CONTEXTHELP:
  178. {
  179. CComQIPtr<IDisplayHelp,&IID_IDisplayHelp> spHelp = spConsole;
  180. spHelp->ShowTopic(CoTaskDupString(OLESTR("snapsamp.chm::/default.htm")));
  181. hr = S_OK;
  182. }
  183. break;
  184. */
  185. case MMCN_SHOW:
  186. {
  187. if (arg == TRUE)
  188. {
  189. IUnknown *pUnk;
  190. if (gpDisp == NULL)
  191. {
  192. CComQIPtr<IResultData, &IID_IResultData> spResultData(spConsole);
  193. spConsole->QueryResultView(&pUnk);
  194. CComQIPtr<IDispatch,&IID_IDispatch> pDisp = pUnk;
  195. gpDisp = pDisp;
  196. }
  197. EnterCriticalSection(&CritSec);
  198. if (!ComputerNameSent)
  199. {
  200. SendComputerName(m_szComputerName,gpDisp);
  201. // MessageBox(NULL,_T("Setting SentComputerName to TRUE:"), _T("ManagerData::Notify, Show"), MB_OK);
  202. ComputerNameSent = TRUE;
  203. // MessageBox(NULL,m_szComputerName,_T("Show Sending"),MB_OK);
  204. }
  205. LeaveCriticalSection(&CritSec);
  206. EnterCriticalSection(&CritSec);
  207. SendProductName(m_ProductName,gpDisp);
  208. LeaveCriticalSection(&CritSec);
  209. }
  210. hr = S_OK;
  211. break;
  212. }
  213. case MMCN_EXPAND:
  214. {
  215. HKEY hKLM = NULL;
  216. HKEY hKey = NULL;
  217. DWORD dwProductIndex = 0;
  218. _TCHAR szProductName[255];
  219. DWORD dwBufferSize = 255;
  220. if (arg == TRUE)
  221. {
  222. gszManagerCtlDispatch = (IDispatch *) NULL;
  223. //SendProductName(m_ProductName);
  224. if ( !m_bChild)
  225. {
  226. if (!ComputerNameSent)
  227. {
  228. // MessageBox(NULL,_T("Expand Determining New ComputerName"),NULL,MB_OK);
  229. // MessageBox(NULL,m_szComputerName,gszComputerName,MB_OK);
  230. //_tcscpy(m_szComputerName,gszComputerName);
  231. b_Expanded = FALSE;
  232. }
  233. }
  234. if ( ( !m_bChild) && (!b_Expanded))
  235. {
  236. b_Expanded =TRUE;
  237. // open the updates registry key and enumerate the children
  238. // MessageBox(NULL,m_szComputerName,_T("Expand Connecting to "),MB_OK);
  239. RegConnectRegistry(m_szComputerName,HKEY_LOCAL_MACHINE,&hKLM);
  240. if (hKLM != NULL)
  241. {
  242. RegOpenKeyEx(hKLM,_T("SOFTWARE\\MICROSOFT\\UPDATES"),0,KEY_READ,&hKey);
  243. if (hKey != NULL)
  244. {
  245. dwProductIndex = 0;
  246. while (RegEnumKeyEx(hKey, dwProductIndex,szProductName, &dwBufferSize,0,NULL,NULL,NULL) != ERROR_NO_MORE_ITEMS)
  247. {
  248. CSnapInItem* m_pNode;
  249. CComQIPtr<IConsoleNameSpace, &IID_IConsoleNameSpace> spConsoleNameSpace(spConsole);
  250. // TODO : Enumerate scope pane items
  251. SCOPEDATAITEM *pScopeData;
  252. // MessageBox(NULL,szProductName,_T("Creating node"),MB_OK);
  253. // MessageBox(NULL, m_szComputerName,_T("With computer Name"),MB_OK);
  254. m_pNode = new CHotfix_ManagerData( szProductName,m_szComputerName, TRUE);
  255. m_pNode->GetScopeData( &pScopeData );
  256. pScopeData->cChildren = 0;
  257. pScopeData->relativeID = param;
  258. spConsoleNameSpace->InsertItem( pScopeData );
  259. _tcscpy(szProductName,_T("\0"));
  260. ++dwProductIndex;
  261. dwBufferSize = 255;
  262. }
  263. RegCloseKey(hKey);
  264. RegCloseKey(hKLM);
  265. }
  266. }
  267. // SendProductName(m_ProductName);
  268. }
  269. //gf_NewComputer = FALSE;
  270. hr = S_OK;
  271. }
  272. break;
  273. }
  274. case MMCN_ADD_IMAGES:
  275. {
  276. // Add Images
  277. IImageList* pImageList = (IImageList*) arg;
  278. hr = E_FAIL;
  279. // Load bitmaps associated with the scope pane
  280. // and add them to the image list
  281. // Loads the default bitmaps generated by the wizard
  282. // Change as required
  283. HBITMAP hBitmap16 = LoadBitmap(_Module.GetResourceInstance(), MAKEINTRESOURCE(IDB_HOTFIXMANAGER_16));
  284. if (hBitmap16 != NULL)
  285. {
  286. HBITMAP hBitmap32 = LoadBitmap(_Module.GetResourceInstance(), MAKEINTRESOURCE(IDB_HOTFIXMANAGER_32));
  287. if (hBitmap32 != NULL)
  288. {
  289. hr = pImageList->ImageListSetStrip((long*)hBitmap16,
  290. (long*)hBitmap32, 0, RGB(0, 128, 128));
  291. if (FAILED(hr))
  292. ATLTRACE(_T("IImageList::ImageListSetStrip failed\n"));
  293. }
  294. }
  295. break;
  296. }
  297. }
  298. return hr;
  299. }
  300. LPOLESTR CHotfix_ManagerData::GetResultPaneColInfo(int nCol)
  301. {
  302. //if (nCol == 0)
  303. // return m_bstrDisplayName;
  304. LPOLESTR pStr = NULL;
  305. switch ( nCol )
  306. {
  307. case 0:
  308. pStr = m_bstrDisplayName;
  309. break;
  310. case 1:
  311. pStr = m_bstrColumnType;
  312. break;
  313. case 2:
  314. pStr = m_bstrColumnDesc;
  315. break;
  316. }
  317. _ASSERTE( pStr != NULL );
  318. return( pStr );
  319. // TODO : Return the text for other columns
  320. // return OLESTR("Override GetResultPaneColInfo");
  321. }
  322. HRESULT CHotfix_Manager::Initialize(LPUNKNOWN pUnknown)
  323. {
  324. HRESULT hr = IComponentDataImpl<CHotfix_Manager, CHotfix_ManagerComponent >::Initialize(pUnknown);
  325. if (FAILED(hr))
  326. return hr;
  327. CComPtr<IImageList> spImageList;
  328. if (m_spConsole->QueryScopeImageList(&spImageList) != S_OK)
  329. {
  330. ATLTRACE(_T("IConsole::QueryScopeImageList failed\n"));
  331. return E_UNEXPECTED;
  332. }
  333. // Load bitmaps associated with the scope pane
  334. // and add them to the image list
  335. // Loads the default bitmaps generated by the wizard
  336. // Change as required
  337. HBITMAP hBitmap16 = LoadBitmap(_Module.GetResourceInstance(), MAKEINTRESOURCE(IDB_HOTFIXMANAGER_16));
  338. if (hBitmap16 == NULL)
  339. return S_OK;
  340. HBITMAP hBitmap32 = LoadBitmap(_Module.GetResourceInstance(), MAKEINTRESOURCE(IDB_HOTFIXMANAGER_32));
  341. if (hBitmap32 == NULL)
  342. return S_OK;
  343. if (spImageList->ImageListSetStrip((long*)hBitmap16,
  344. (long*)hBitmap32, 0, RGB(0, 128, 128)) != S_OK)
  345. {
  346. ATLTRACE(_T("IImageList::ImageListSetStrip failed\n"));
  347. return E_UNEXPECTED;
  348. }
  349. return S_OK;
  350. }
  351. //
  352. // Retrieves the value of a given clipboard format from a given data object.
  353. //
  354. bool CHotfix_Manager::ExtractString( IDataObject* pDataObject, unsigned int cfClipFormat, LPTSTR pBuf, DWORD dwMaxLength)
  355. {
  356. USES_CONVERSION;
  357. bool fFound = false;
  358. FORMATETC formatetc = { (CLIPFORMAT) cfClipFormat, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
  359. STGMEDIUM stgmedium = { TYMED_HGLOBAL, NULL };
  360. stgmedium.hGlobal = ::GlobalAlloc( GMEM_SHARE, dwMaxLength * sizeof(TCHAR));
  361. HRESULT hr;
  362. do
  363. {
  364. //
  365. // This is a memory error condition!
  366. //
  367. if ( NULL == stgmedium.hGlobal )
  368. break;
  369. hr = pDataObject->GetDataHere( &formatetc, &stgmedium );
  370. if ( FAILED(hr) )
  371. break;
  372. LPWSTR pszNewData = reinterpret_cast<LPWSTR>( ::GlobalLock( stgmedium.hGlobal ) );
  373. if ( NULL == pszNewData )
  374. break;
  375. pszNewData[ dwMaxLength - 1 ] = L'\0';
  376. _tcscpy( pBuf, OLE2T( pszNewData ) );
  377. fFound = true;
  378. }
  379. while( false );
  380. if ( NULL != stgmedium.hGlobal )
  381. {
  382. GlobalUnlock( stgmedium.hGlobal );
  383. GlobalFree( stgmedium.hGlobal );
  384. }
  385. _tcscpy (gszComputerName, pBuf);
  386. return( fFound );
  387. }
  388. //
  389. // Determines if the enumeration is for a remoted machine or not.
  390. //
  391. bool CHotfix_Manager::IsDataObjectRemoted( IDataObject* pDataObject )
  392. {
  393. bool fRemoted = false;
  394. TCHAR szComputerName[ DNS_MAX_NAME_LENGTH + 1 ];
  395. DWORD dwNameLength = (DNS_MAX_NAME_LENGTH + 1) * sizeof(TCHAR);
  396. TCHAR szDataMachineName[ DNS_MAX_NAME_LENGTH + 1 ];
  397. //
  398. // Get local computer name.
  399. //
  400. GetComputerName(szComputerName, &dwNameLength);
  401. //
  402. // Get the machine name from the given data object.
  403. //
  404. if ( ExtractString( pDataObject, m_ccfRemotedFormat, szDataMachineName, DNS_MAX_NAME_LENGTH + 1 ) )
  405. {
  406. _toupper( szDataMachineName );
  407. //
  408. // Find the start of the server name.
  409. //
  410. LPTSTR pStr = szDataMachineName;
  411. while ( pStr && *pStr == L'\\' )
  412. pStr++;
  413. //
  414. // Compare the server name.
  415. //
  416. if ( pStr && *pStr && wcscmp( pStr, szComputerName ) != 0 )
  417. fRemoted = true;
  418. }
  419. if (fRemoted)
  420. _tcscpy (m_szComputerName, szDataMachineName);
  421. else
  422. _tcscpy (m_szComputerName, szComputerName);
  423. return( fRemoted );
  424. }
  425. STDMETHODIMP CHotfix_ManagerData::GetResultViewType ( LPOLESTR* ppViewType, long* pViewOptions )
  426. {
  427. *pViewOptions = MMC_VIEW_OPTIONS_NOLISTVIEWS;
  428. *ppViewType = _T("{883B970F-690C-45F2-8A3A-F4283E078118}");
  429. return S_OK;
  430. }
  431. /////////////////////////////////////////////////////
  432. //
  433. // Dispatch interface of the OCX to send commands
  434. //
  435. /////////////////////////////////////////////////////
  436. BOOL CHotfix_ManagerData::SendComputerName(_TCHAR *szDataMachineName, IDispatch * pDisp)
  437. {
  438. HRESULT hr;
  439. // Ensure that we have a pointer to the OCX
  440. if (pDisp == NULL ){
  441. // MessageBox(NULL,_T("Failed to send Message"),NULL,MB_OK);
  442. return( FALSE );
  443. }
  444. // get the OCX dispatch interface
  445. CComPtr<IDispatch> pManagerCtlDispatch = pDisp;
  446. // get the ID of the "ComputerName" interface
  447. OLECHAR FAR* szMember = TEXT("ComputerName"); // maps this to "put_Command()"
  448. DISPID dispid;
  449. hr = pManagerCtlDispatch->GetIDsOfNames(
  450. IID_NULL, // Reserved for future use. Must be IID_NULL.
  451. &szMember, // Passed-in array of names to be mapped.
  452. 1, // Count of the names to be mapped.
  453. LOCALE_USER_DEFAULT,// The locale context in which to interpret the names.
  454. &dispid); // Caller-allocated array
  455. if (!SUCCEEDED(hr)) {
  456. // MessageBox(NULL,_T("Failed to send Message"),NULL,MB_OK);
  457. return FALSE;
  458. }
  459. DISPID mydispid = DISPID_PROPERTYPUT;
  460. VARIANTARG* pvars = new VARIANTARG;
  461. VariantInit(&pvars[0]);
  462. BSTR NewVal( szDataMachineName);
  463. pvars[0].vt = VT_BSTR;
  464. // pvars[0].iVal = (short)lparamCommand;
  465. pvars[0].bstrVal = NewVal;
  466. DISPPARAMS disp = { pvars, &mydispid, 1, 1 };
  467. hr = pManagerCtlDispatch->Invoke(
  468. dispid, // unique number identifying the method to invoke
  469. IID_NULL, // Reserved. Must be IID_NULL
  470. LOCALE_USER_DEFAULT, // A locale ID
  471. DISPATCH_PROPERTYPUT, // flag indicating the context of the method to invoke
  472. &disp, // A structure with the parameters to pass to the method
  473. NULL, // The result from the calling method
  474. NULL, // returned exception information
  475. NULL); // index indicating the first argument that is in error
  476. delete [] pvars;
  477. if (!SUCCEEDED(hr)) {
  478. // MessageBox(NULL,_T("Failed to send Message"),NULL,MB_OK);
  479. return FALSE;
  480. }
  481. // MessageBox(NULL,_T("Message sent"),NULL,MB_OK);
  482. return TRUE;
  483. }
  484. DWORD GetCtrlStatus()
  485. {
  486. DISPID dispid;
  487. HRESULT hr;
  488. DWORD Status = 0;
  489. if ( gpDisp == NULL)
  490. return FALSE;
  491. // array of the interface names
  492. OLECHAR FAR* szMember[1] = {
  493. OLESTR("CurrentState")
  494. };
  495. hr = gpDisp->GetIDsOfNames(
  496. IID_NULL, // Reserved for future use. Must be IID_NULL.
  497. &szMember[0], // Passed-in array of names to be mapped.
  498. 1/*INTERFACE_COUNT*/, // Count of the names to be mapped.
  499. LOCALE_USER_DEFAULT,// The locale context in which to interpret the names.
  500. &dispid); // Caller-allocated array (see help for details)
  501. if (!SUCCEEDED(hr)) {
  502. // MessageBox(NULL,_T("Failed to get Dispatch pointer"),NULL,MB_OK);
  503. return FALSE;
  504. }
  505. VARIANT varResult;
  506. VariantInit(&varResult);
  507. V_VT(&varResult) = VT_I2;
  508. DISPPARAMS dispparamsNoArgs = {NULL, NULL, 0, 0};
  509. hr = gpDisp->Invoke(
  510. dispid, // unique number identifying the method to invoke
  511. IID_NULL, // Reserved. Must be IID_NULL
  512. LOCALE_USER_DEFAULT, // A locale ID
  513. DISPATCH_PROPERTYGET, // flag indicating the context of the method to invoke
  514. &dispparamsNoArgs, // A structure with the parameters to pass to the method
  515. &varResult, // The result from the calling method
  516. NULL, // returned exception information
  517. NULL); // index indicating the first argument that is in error
  518. if (!SUCCEEDED(hr)) {
  519. // MessageBox(NULL,_T("Failed To Get Value"),NULL,MB_OK);
  520. return FALSE;
  521. }
  522. // return varResult.bVal;
  523. Status = varResult.lVal;
  524. //delete [] pvars;
  525. _TCHAR Message[100];
  526. _stprintf(Message,_T("%d"),Status);
  527. // MessageBox(NULL, Message, _T("Returned Status"),MB_OK);
  528. return Status;
  529. }
  530. BOOL CHotfix_ManagerData::SendProductName(_TCHAR *szProductName, IDispatch * pDisp)
  531. {
  532. HRESULT hr;
  533. if ( pDisp == NULL ){
  534. return( FALSE );
  535. }
  536. // get the OCX dispatch interface
  537. CComPtr<IDispatch> pManagerCtlDispatch = pDisp;
  538. // get the ID of the "ComputerName" interface
  539. OLECHAR FAR* szMember = TEXT("ProductName"); // maps this to "put_Command()"
  540. DISPID dispid;
  541. hr = pManagerCtlDispatch->GetIDsOfNames(
  542. IID_NULL, // Reserved for future use. Must be IID_NULL.
  543. &szMember, // Passed-in array of names to be mapped.
  544. 1, // Count of the names to be mapped.
  545. LOCALE_USER_DEFAULT,// The locale context in which to interpret the names.
  546. &dispid); // Caller-allocated array
  547. if (!SUCCEEDED(hr)) {
  548. // MessageBox(NULL,_T("Failed to send Message"),NULL,MB_OK);
  549. return FALSE;
  550. }
  551. DISPID mydispid = DISPID_PROPERTYPUT;
  552. VARIANTARG* pvars = new VARIANTARG;
  553. VariantInit(&pvars[0]);
  554. BSTR NewVal( szProductName);
  555. pvars[0].vt = VT_BSTR;
  556. // pvars[0].iVal = (short)lparamCommand;
  557. pvars[0].bstrVal = NewVal;
  558. DISPPARAMS disp = { pvars, &mydispid, 1, 1 };
  559. hr = pManagerCtlDispatch->Invoke(
  560. dispid, // unique number identifying the method to invoke
  561. IID_NULL, // Reserved. Must be IID_NULL
  562. LOCALE_USER_DEFAULT, // A locale ID
  563. DISPATCH_PROPERTYPUT, // flag indicating the context of the method to invoke
  564. &disp, // A structure with the parameters to pass to the method
  565. NULL, // The result from the calling method
  566. NULL, // returned exception information
  567. NULL); // index indicating the first argument that is in error
  568. delete [] pvars;
  569. if (!SUCCEEDED(hr)) {
  570. return FALSE;
  571. }
  572. return TRUE;
  573. }
  574. BOOL CHotfix_ManagerData::SendCommand(LPARAM lparamCommand)
  575. {
  576. HRESULT hr;
  577. // Ensure that we have a pointer to the OCX
  578. if ( gpDisp == NULL ){
  579. return( FALSE );
  580. }
  581. // get the OCX dispatch interface
  582. CComPtr<IDispatch> pManagerCtlDispatch = gpDisp;
  583. // get the ID of the "Command" interface
  584. OLECHAR FAR* szMember = TEXT("Command"); // maps this to "put_Command()"
  585. DISPID dispid;
  586. hr = pManagerCtlDispatch->GetIDsOfNames(
  587. IID_NULL, // Reserved for future use. Must be IID_NULL.
  588. &szMember, // Passed-in array of names to be mapped.
  589. 1, // Count of the names to be mapped.
  590. LOCALE_USER_DEFAULT,// The locale context in which to interpret the names.
  591. &dispid); // Caller-allocated array
  592. if (!SUCCEEDED(hr)) {
  593. return FALSE;
  594. }
  595. DISPID mydispid = DISPID_PROPERTYPUT;
  596. VARIANTARG* pvars = new VARIANTARG;
  597. VariantInit(&pvars[0]);
  598. pvars[0].vt = VT_I2;
  599. pvars[0].iVal = (short)lparamCommand;
  600. DISPPARAMS disp = { pvars, &mydispid, 1, 1 };
  601. hr = pManagerCtlDispatch->Invoke(
  602. dispid, // unique number identifying the method to invoke
  603. IID_NULL, // Reserved. Must be IID_NULL
  604. LOCALE_USER_DEFAULT, // A locale ID
  605. DISPATCH_PROPERTYPUT, // flag indicating the context of the method to invoke
  606. &disp, // A structure with the parameters to pass to the method
  607. NULL, // The result from the calling method
  608. NULL, // returned exception information
  609. NULL); // index indicating the first argument that is in error
  610. delete [] pvars;
  611. if (!SUCCEEDED(hr)) {
  612. return FALSE;
  613. }
  614. return TRUE;
  615. }
  616. ///////////////////////////////////
  617. // IExtendContextMenu::Command()
  618. STDMETHODIMP CHotfix_ManagerData::Command(long lCommandID,
  619. CSnapInObjectRootBase* pObj,
  620. DATA_OBJECT_TYPES type)
  621. {
  622. // Handle each of the commands.
  623. switch (lCommandID) {
  624. case ID_VIEW_BY_FILE:
  625. // MessageBox(NULL,_T("Sending View By File"),NULL,MB_OK);
  626. SendCommand(IDC_VIEW_BY_FILE);
  627. m_dwCurrentView = IDC_VIEW_BY_FILE;
  628. break;
  629. case ID_VIEW_BY_KB:
  630. SendCommand(IDC_VIEW_BY_HOTFIX);
  631. m_dwCurrentView = IDC_VIEW_BY_HOTFIX;
  632. break;
  633. case ID_UNINSTALL:
  634. SendCommand(IDC_UNINSTALL);
  635. break;
  636. case ID_VIEW_WEB:
  637. SendCommand(IDC_VIEW_WEB);
  638. break;
  639. case ID_PRINT_REPORT:
  640. SendCommand(IDC_PRINT_REPORT);
  641. break;
  642. case ID_EXPORT:
  643. SendCommand(IDC_EXPORT);
  644. break;
  645. default:
  646. break;
  647. }
  648. return S_OK;
  649. }
  650. HRESULT CHotfix_ManagerExtData::Notify( MMC_NOTIFY_TYPE event,
  651. long arg,
  652. long param,
  653. IComponentData* pComponentData,
  654. IComponent* pComponent,
  655. DATA_OBJECT_TYPES type)
  656. {
  657. // Add code to handle the different notifications.
  658. // Handle MMCN_SHOW and MMCN_EXPAND to enumerate children items.
  659. // In response to MMCN_SHOW you have to enumerate both the scope
  660. // and result pane items.
  661. // For MMCN_EXPAND you only need to enumerate the scope items
  662. // Use IConsoleNameSpace::InsertItem to insert scope pane items
  663. // Use IResultData::InsertItem to insert result pane item.
  664. HRESULT hr = E_NOTIMPL;
  665. bool fRemoted = false;
  666. _ASSERTE( pComponentData != NULL || pComponent != NULL );
  667. CComPtr<IConsole> spConsole;
  668. if ( pComponentData != NULL )
  669. {
  670. CHotfix_Manager* pExt = (CHotfix_Manager*) pComponentData;
  671. spConsole = pExt->m_spConsole;
  672. //
  673. // Determine if we're remoted.
  674. //
  675. fRemoted = pExt->IsRemoted();
  676. }
  677. else
  678. {
  679. spConsole = ( (CHotfix_ManagerComponent*) pComponent )->m_spConsole;
  680. }
  681. switch ( event )
  682. {
  683. case MMCN_SHOW:
  684. arg = arg;
  685. hr = S_OK;
  686. break;
  687. case MMCN_EXPAND:
  688. {
  689. if ( arg == TRUE )
  690. {
  691. CComQIPtr<IConsoleNameSpace, &IID_IConsoleNameSpace> spConsoleNameSpace(spConsole);
  692. SCOPEDATAITEM* pScopeData;
  693. DWORD dwSize = 255;
  694. if (!_tcscmp(gszComputerName,_T("\0")))
  695. GetComputerName(gszComputerName,&dwSize);
  696. m_pNode = new CHotfix_ManagerData( NULL,gszComputerName, FALSE);
  697. m_pNode->GetScopeData( &pScopeData );
  698. pScopeData->relativeID = param;
  699. spConsoleNameSpace->InsertItem( pScopeData );
  700. if ( pComponentData )
  701. ( (CHotfix_Manager*) pComponentData )->m_pNode = m_pNode;
  702. }
  703. hr = S_OK;
  704. break;
  705. }
  706. case MMCN_REMOVE_CHILDREN:
  707. {
  708. //
  709. // We are not deleting this node since this same pointer is
  710. // stashed in the pComponentData in response to the MMCN_EXPAND
  711. // notification. The destructor of pComponentData deletes the pointer
  712. // to this node.
  713. //
  714. //delete m_pNode;
  715. m_pNode = NULL;
  716. hr = S_OK;
  717. break;
  718. }
  719. case MMCN_ADD_IMAGES:
  720. {
  721. }
  722. }
  723. return S_OK;
  724. }
  725. STDMETHODIMP CHotfix_ManagerComponent::Command(long lCommandID, LPDATAOBJECT pDataObject)
  726. {
  727. HRESULT hr;
  728. if ( IS_SPECIAL_DATAOBJECT( pDataObject ) )
  729. {
  730. hr = m_pComponentData->m_pNode->Command( lCommandID, this, CCT_RESULT );
  731. }
  732. else
  733. {
  734. hr = IExtendContextMenuImpl<CHotfix_Manager>::Command( lCommandID, pDataObject );
  735. }
  736. return( hr );
  737. }
  738. STDMETHODIMP CHotfix_ManagerData::AddMenuItems(
  739. LPCONTEXTMENUCALLBACK pContextMenuCallback,
  740. long *pInsertionAllowed,
  741. DATA_OBJECT_TYPES type)
  742. {
  743. DWORD Status = GetCtrlStatus();
  744. HRESULT hr = S_OK;
  745. // Note - snap-ins need to look at the data object and determine
  746. // in what context, menu items need to be added. They must also
  747. // observe the insertion allowed flags to see what items can be
  748. // added.
  749. /* handy comment:
  750. typedef struct _CONTEXTMENUITEM
  751. {
  752. LPWSTR strName;
  753. LPWSTR strStatusBarText;
  754. LONG lCommandID;
  755. LONG lInsertionPointID;
  756. LONG fFlags;
  757. LONG fSpecialFlags;
  758. } CONTEXTMENUITEM;
  759. */
  760. CONTEXTMENUITEM singleMenuItem;
  761. TCHAR menuText[200];
  762. TCHAR statusBarText[300];
  763. singleMenuItem.strName = menuText;
  764. singleMenuItem.strStatusBarText = statusBarText;
  765. singleMenuItem.fFlags = 0;
  766. singleMenuItem.fSpecialFlags = 0;
  767. // Add each of the items to the Action menu
  768. if (*pInsertionAllowed & CCM_INSERTIONALLOWED_TOP) {
  769. // setting for the Action menu
  770. singleMenuItem.lInsertionPointID = CCM_INSERTIONPOINTID_PRIMARY_TOP;
  771. singleMenuItem.lCommandID = ID_VIEW_WEB;
  772. if (Status & HOTFIX_SELECTED)
  773. singleMenuItem.fFlags = MF_ENABLED;
  774. else
  775. singleMenuItem.fFlags = MF_GRAYED;
  776. LoadString(_Module.GetResourceInstance(), IDS_VIEW_WEB, menuText, sizeof(menuText) / sizeof(TCHAR));
  777. LoadString(_Module.GetResourceInstance(), IDS_VIEW_WEB_STATUS_BAR, statusBarText, sizeof(statusBarText) / sizeof(TCHAR));
  778. hr = pContextMenuCallback->AddItem(&singleMenuItem);
  779. singleMenuItem.lCommandID = ID_UNINSTALL;
  780. if (Status & UNINSTALL_OK)
  781. singleMenuItem.fFlags = MF_ENABLED;
  782. else
  783. singleMenuItem.fFlags = MF_GRAYED;
  784. LoadString(_Module.GetResourceInstance(), IDS_UNINSTALL, menuText, sizeof(menuText) / sizeof(TCHAR));
  785. LoadString(_Module.GetResourceInstance(), IDS_UNINSTALL_STATUS_BAR, statusBarText, sizeof(statusBarText) / sizeof(TCHAR));
  786. hr = pContextMenuCallback->AddItem(&singleMenuItem);
  787. if (Status & DATA_TO_SAVE)
  788. {
  789. singleMenuItem.lCommandID = ID_EXPORT;
  790. singleMenuItem.fFlags = MF_ENABLED;
  791. LoadString(_Module.GetResourceInstance(), IDS_EXPORT, menuText, sizeof(menuText) / sizeof(TCHAR));
  792. LoadString(_Module.GetResourceInstance(), IDS_EXPORT_STATUS_BAR, statusBarText, sizeof(statusBarText) / sizeof(TCHAR));
  793. hr = pContextMenuCallback->AddItem(&singleMenuItem);
  794. singleMenuItem.lCommandID = ID_PRINT_REPORT;
  795. singleMenuItem.fFlags = MF_ENABLED;
  796. LoadString(_Module.GetResourceInstance(), IDS_PRINT_REPORT, menuText, sizeof(menuText) / sizeof(TCHAR));
  797. LoadString(_Module.GetResourceInstance(), IDS_PRINT_REPORT_STATUS_BAR, statusBarText, sizeof(statusBarText) / sizeof(TCHAR));
  798. hr = pContextMenuCallback->AddItem(&singleMenuItem);
  799. }
  800. else
  801. {
  802. singleMenuItem.lCommandID = ID_EXPORT;
  803. singleMenuItem.fFlags = MF_GRAYED;
  804. LoadString(_Module.GetResourceInstance(), IDS_EXPORT, menuText, sizeof(menuText) / sizeof(TCHAR));
  805. LoadString(_Module.GetResourceInstance(), IDS_EXPORT_STATUS_BAR, statusBarText, sizeof(statusBarText) / sizeof(TCHAR));
  806. hr = pContextMenuCallback->AddItem(&singleMenuItem);
  807. singleMenuItem.lCommandID = ID_PRINT_REPORT;
  808. singleMenuItem.fFlags = MF_GRAYED;
  809. LoadString(_Module.GetResourceInstance(), IDS_PRINT_REPORT, menuText, sizeof(menuText) / sizeof(TCHAR));
  810. LoadString(_Module.GetResourceInstance(), IDS_PRINT_REPORT_STATUS_BAR, statusBarText, sizeof(statusBarText) / sizeof(TCHAR));
  811. hr = pContextMenuCallback->AddItem(&singleMenuItem);
  812. }
  813. }
  814. return S_OK;
  815. }
  816. STDMETHODIMP CHotfix_ManagerComponent::AddMenuItems(LPDATAOBJECT pDataObject, LPCONTEXTMENUCALLBACK piCallback,long *pInsertionAllowed)
  817. {
  818. HRESULT hr;
  819. if ( IS_SPECIAL_DATAOBJECT( pDataObject ) )
  820. {
  821. }
  822. else
  823. {
  824. CONTEXTMENUITEM singleMenuItem;
  825. TCHAR menuText[200];
  826. TCHAR statusBarText[300];
  827. DWORD State = GetCtrlStatus();
  828. //
  829. // Retrieve the control from the current component.
  830. //
  831. // assert( m_pComponent != NULL );
  832. // CComPtr<IDispatch> spDispCtl = m_pComponent->GetControl();
  833. singleMenuItem.strName = menuText;
  834. singleMenuItem.strStatusBarText = statusBarText;
  835. singleMenuItem.fFlags = 0;
  836. singleMenuItem.fSpecialFlags = 0;
  837. // Add each of the items to the Action menu
  838. if (*pInsertionAllowed & CCM_INSERTIONALLOWED_VIEW)
  839. {
  840. singleMenuItem.lInsertionPointID = CCM_INSERTIONPOINTID_PRIMARY_VIEW;
  841. singleMenuItem.lCommandID = ID_VIEW_BY_KB ;
  842. if ( State & STATE_VIEW_HOTFIX)
  843. singleMenuItem.fFlags = MF_CHECKED;
  844. else
  845. singleMenuItem.fFlags = MF_UNCHECKED;
  846. LoadString(_Module.GetResourceInstance(), IDS_BY_KB_ARTICLE, menuText, sizeof(menuText) / sizeof(TCHAR));
  847. LoadString(_Module.GetResourceInstance(), IDS_BY_KB_ARTICLE_STATUS_BAR, statusBarText, sizeof(statusBarText) / sizeof(TCHAR));
  848. hr = piCallback->AddItem(&singleMenuItem);
  849. // setting for the Action menu
  850. singleMenuItem.lInsertionPointID = CCM_INSERTIONPOINTID_PRIMARY_VIEW;
  851. singleMenuItem.lCommandID = ID_VIEW_BY_FILE;
  852. if ( State & STATE_VIEW_FILE )
  853. singleMenuItem.fFlags = MF_CHECKED ;
  854. else
  855. singleMenuItem.fFlags = MF_UNCHECKED ;
  856. LoadString(_Module.GetResourceInstance(), IDS_VIEW_BY_FILE, menuText, sizeof(menuText) / sizeof(TCHAR));
  857. LoadString(_Module.GetResourceInstance(), IDS_BY_FILE_STATUS_BAR, statusBarText, sizeof(statusBarText) / sizeof(TCHAR));
  858. hr = piCallback->AddItem(&singleMenuItem);
  859. hr = IExtendContextMenuImpl<CHotfix_Manager>::AddMenuItems( pDataObject, piCallback, pInsertionAllowed );
  860. // setting for the Action menu
  861. /* singleMenuItem.lInsertionPointID = CCM_INSERTIONPOINTID_PRIMARY_TOP;
  862. singleMenuItem.lCommandID = IDM_VIEW_WEB;
  863. if (HaveHotfix)
  864. singleMenuItem.fFlags = MF_ENABLED;
  865. else
  866. singleMenuItem.fFlags = MF_GRAYED;
  867. LoadString(_Module.GetResourceInstance(), IDS_VIEW_WEB, menuText, sizeof(menuText) / sizeof(TCHAR));
  868. LoadString(_Module.GetResourceInstance(), IDS_VIEW_WEB_STATUS_BAR, statusBarText, sizeof(statusBarText) / sizeof(TCHAR));
  869. hr = piCallback->AddItem(&singleMenuItem);
  870. // singleMenuItem.lInsertionPointID = CCM_INSERTIONPOINTID_PRIMARY_VIEW;
  871. singleMenuItem.lCommandID = IDM_UNINSTALL;
  872. // singleMenuItem.fFlags = analyzeFlags;
  873. if ((!Remote) && (HaveHotfix))
  874. singleMenuItem.fFlags = MF_ENABLED;
  875. else
  876. singleMenuItem.fFlags = MF_GRAYED;
  877. LoadString(_Module.GetResourceInstance(), IDS_UNINSTALL, menuText, sizeof(menuText) / sizeof(TCHAR));
  878. LoadString(_Module.GetResourceInstance(), IDS_UNINSTALL_STATUS_BAR, statusBarText, sizeof(statusBarText) / sizeof(TCHAR));
  879. hr = piCallback->AddItem(&singleMenuItem);
  880. // singleMenuItem.lInsertionPointID = CCM_INSERTIONPOINTID_PRIMARY_VIEW;
  881. singleMenuItem.lCommandID = IDM_GENERATE_REPORT;
  882. singleMenuItem.fFlags = MF_ENABLED;
  883. LoadString(_Module.GetResourceInstance(), IDS_GENERATE_REPORT, menuText, sizeof(menuText) / sizeof(TCHAR));
  884. LoadString(_Module.GetResourceInstance(), IDS_GENERATE_REPORT_STATUS_BAR, statusBarText, sizeof(statusBarText) / sizeof(TCHAR));
  885. hr = piCallback->AddItem(&singleMenuItem); */
  886. }
  887. // hr = m_pComponentData->m_pNode->AddMenuItems( piCallback, pInsertionAllowed, CCT_RESULT );
  888. }
  889. return( hr );
  890. }