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.

330 lines
9.5 KiB

  1. #include "stdafx.h"
  2. #include "Vssui.h"
  3. #include "snapext.h"
  4. #include "VSSProp.h"
  5. /////////////////////////////////////////////////////////////////////////////
  6. // CVSSUIComponentData
  7. static const GUID CVSSUIExtGUID1_NODETYPE =
  8. { 0x4e410f0e, 0xabc1, 0x11d0, { 0xb9, 0x44, 0x0, 0xc0, 0x4f, 0xd8, 0xd5, 0xb0 } };
  9. const GUID* CVSSUIExtData1::m_NODETYPE = &CVSSUIExtGUID1_NODETYPE;
  10. const OLECHAR* CVSSUIExtData1::m_SZNODETYPE = OLESTR("4e410f0e-abc1-11d0-b944-00c04fd8d5b0");
  11. const OLECHAR* CVSSUIExtData1::m_SZDISPLAY_NAME = OLESTR("");
  12. const CLSID* CVSSUIExtData1::m_SNAPIN_CLASSID = &CLSID_VSSUI;
  13. static const GUID CVSSUIExtGUID2_NODETYPE =
  14. { 0x312B59C1, 0x4002, 0x11d0, { 0x96, 0xF8, 0x0, 0xA0, 0xC9, 0x19, 0x16, 0x01 } };
  15. const GUID* CVSSUIExtData2::m_NODETYPE = &CVSSUIExtGUID2_NODETYPE;
  16. const OLECHAR* CVSSUIExtData2::m_SZNODETYPE = OLESTR("312B59C1-4002-11d0-96F8-00A0C9191601");
  17. const OLECHAR* CVSSUIExtData2::m_SZDISPLAY_NAME = OLESTR("");
  18. const CLSID* CVSSUIExtData2::m_SNAPIN_CLASSID = &CLSID_VSSUI;
  19. CVSSUI::CVSSUI()
  20. {
  21. #ifdef DEBUG
  22. OutputDebugString(_T("CVSSUI::CVSSUI\n"));
  23. #endif
  24. m_pComponentData = this;
  25. m_pPage = NULL;
  26. }
  27. CVSSUI::~CVSSUI()
  28. {
  29. #ifdef DEBUG
  30. OutputDebugString(_T("CVSSUI::~CVSSUI\n"));
  31. #endif
  32. if (m_pPage)
  33. {
  34. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  35. delete m_pPage;
  36. m_pPage = NULL;
  37. }
  38. }
  39. ///////////////////////////////
  40. // Interface IExtendContextMenu
  41. ///////////////////////////////
  42. CLIPFORMAT g_cfMachineName = (CLIPFORMAT)RegisterClipboardFormat(_T("MMC_SNAPIN_MACHINE_NAME"));
  43. HRESULT CVSSUI::AddMenuItems(
  44. LPDATAOBJECT piDataObject,
  45. LPCONTEXTMENUCALLBACK piCallback,
  46. long *pInsertionAllowed)
  47. {
  48. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  49. //
  50. // we add the context menu item only when targeted machine belongs to postW2K server SKUs
  51. //
  52. TCHAR szMachineName[MAX_PATH] = {0};
  53. HRESULT hr = ExtractData(piDataObject, g_cfMachineName, (PBYTE)szMachineName, MAX_PATH);
  54. if (FAILED(hr))
  55. return hr;
  56. CComPtr<IContextMenuCallback2> spiCallback2;
  57. hr = piCallback->QueryInterface(IID_IContextMenuCallback2, (void **)&spiCallback2);
  58. if (FAILED(hr))
  59. return hr;
  60. if (IsPostW2KServer(szMachineName))
  61. {
  62. CString strMenuName;
  63. strMenuName.LoadString(IDS_MENU_NAME);
  64. CString strStatusBarText;
  65. strStatusBarText.LoadString(IDS_MENU_STATUSBARTEXT);
  66. CONTEXTMENUITEM2 ContextMenuItem;
  67. ZeroMemory(&ContextMenuItem, sizeof(CONTEXTMENUITEM));
  68. ContextMenuItem.strName = (LPTSTR)(LPCTSTR)strMenuName;
  69. ContextMenuItem.strStatusBarText = (LPTSTR)(LPCTSTR)strStatusBarText;
  70. ContextMenuItem.lCommandID = ID_CONFIG_SNAPSHOT;
  71. ContextMenuItem.lInsertionPointID = CCM_INSERTIONPOINTID_3RDPARTY_TASK;
  72. ContextMenuItem.strLanguageIndependentName = _T("ConfigVSS");
  73. if (*pInsertionAllowed & CCM_INSERTIONALLOWED_TASK)
  74. hr = spiCallback2->AddItem(&ContextMenuItem);
  75. }
  76. return hr;
  77. }
  78. HRESULT CVSSUI::Command(
  79. IN long lCommandID,
  80. IN LPDATAOBJECT piDataObject)
  81. {
  82. switch (lCommandID)
  83. {
  84. case ID_CONFIG_SNAPSHOT:
  85. {
  86. InvokePropSheet(piDataObject);
  87. }
  88. break;
  89. }
  90. return S_OK;
  91. }
  92. HRESULT ExtractData(
  93. IDataObject* piDataObject,
  94. CLIPFORMAT cfClipFormat,
  95. BYTE* pbData,
  96. DWORD cbData )
  97. {
  98. HRESULT hr = S_OK;
  99. FORMATETC formatetc = {cfClipFormat, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
  100. STGMEDIUM stgmedium = {TYMED_HGLOBAL, NULL, NULL};
  101. stgmedium.hGlobal = ::GlobalAlloc(GPTR, cbData);
  102. do // false loop
  103. {
  104. if (NULL == stgmedium.hGlobal)
  105. {
  106. hr = E_OUTOFMEMORY;
  107. break;
  108. }
  109. hr = piDataObject->GetDataHere( &formatetc, &stgmedium );
  110. if ( FAILED(hr) )
  111. {
  112. break;
  113. }
  114. BYTE* pbNewData = reinterpret_cast<BYTE*>(stgmedium.hGlobal);
  115. if (NULL == pbNewData)
  116. {
  117. hr = E_UNEXPECTED;
  118. break;
  119. }
  120. ::memcpy( pbData, pbNewData, cbData );
  121. } while (FALSE); // false loop
  122. if (stgmedium.hGlobal)
  123. ::GlobalFree(stgmedium.hGlobal);
  124. return hr;
  125. }
  126. //
  127. // disable the "Cancel" button on the property sheet
  128. //
  129. int CALLBACK SnapinPropSheetProc(
  130. HWND hwndDlg,
  131. UINT uMsg,
  132. LPARAM lParam )
  133. {
  134. if (PSCB_INITIALIZED == uMsg)
  135. {
  136. HWND hwnd = GetDlgItem(hwndDlg, IDCANCEL);
  137. if (hwnd)
  138. EnableWindow(hwnd, FALSE);
  139. }
  140. return 0;
  141. }
  142. //
  143. // This function invokes a modal property sheet.
  144. //
  145. void ReplacePropertyPageCallback(void* vpsp); // implemented in shlext.cpp
  146. HRESULT CVSSUI::InvokePropSheet(LPDATAOBJECT piDataObject)
  147. {
  148. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  149. CWaitCursor wait;
  150. TCHAR szMachineName[MAX_PATH] = {0};
  151. HRESULT hr = ExtractData(piDataObject, g_cfMachineName, (PBYTE)szMachineName, MAX_PATH);
  152. if (FAILED(hr))
  153. return hr;
  154. CString strTitle;
  155. strTitle.LoadString(IDS_PROJNAME);
  156. CVSSProp *pPage = new CVSSProp(szMachineName, NULL);
  157. if (!pPage)
  158. return E_OUTOFMEMORY;
  159. if (pPage->m_psp.dwFlags & PSP_USECALLBACK)
  160. {
  161. //
  162. // Replace with our own callback function such that we can delete pPage
  163. // when the property sheet is closed.
  164. //
  165. // Note: don't change m_psp.lParam, which has to point to CVSSProp object;
  166. // otherwise, MFC won't hook up message handler correctly.
  167. //
  168. ReplacePropertyPageCallback(&(pPage->m_psp));
  169. }
  170. PROPSHEETHEADER psh;
  171. ZeroMemory(&psh, sizeof(psh));
  172. psh.dwSize = sizeof(PROPSHEETHEADER);
  173. psh.dwFlags = PSH_PROPSHEETPAGE | PSH_NOAPPLYNOW | PSH_USECALLBACK;
  174. psh.hwndParent = ::GetActiveWindow();
  175. psh.hInstance = _Module.GetResourceInstance();
  176. psh.pszCaption = strTitle;
  177. psh.nPages = 1;
  178. psh.nStartPage = 0;
  179. psh.ppsp = (LPCPROPSHEETPAGE)&(pPage->m_psp);
  180. psh.pfnCallback = SnapinPropSheetProc;
  181. PropertySheet(&psh); // this will do a modal proerty sheet
  182. return S_OK;
  183. }
  184. /*
  185. //
  186. // This function invokes a modaless property sheet.
  187. //
  188. HRESULT CVSSUI::InvokePropSheet(LPDATAOBJECT piDataObject)
  189. {
  190. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  191. CWaitCursor wait;
  192. //
  193. // CoCreate an instance of the MMC Node Manager to obtain
  194. // an IPropertySheetProvider interface pointer
  195. //
  196. CComPtr<IPropertySheetProvider> spiPropertySheetProvider;
  197. HRESULT hr = CoCreateInstance(CLSID_NodeManager, NULL,
  198. CLSCTX_INPROC_SERVER,
  199. IID_IPropertySheetProvider,
  200. (void **)&spiPropertySheetProvider);
  201. if (FAILED(hr))
  202. return hr;
  203. //
  204. // Create the property sheet
  205. //
  206. CString strTitle;
  207. strTitle.LoadString(IDS_PROJNAME);
  208. hr = spiPropertySheetProvider->CreatePropertySheet(
  209. strTitle, // pointer to the property page title
  210. TRUE, // property sheet
  211. NULL, // cookie of current object - can be NULL for extension snap-ins
  212. piDataObject, // data object of selected node
  213. NULL // specifies flags set by the method call
  214. );
  215. if (FAILED(hr))
  216. return hr;
  217. //
  218. // Call AddPrimaryPages. MMC will then call the
  219. // IExtendPropertySheet methods of our property sheet extension object
  220. //
  221. hr = spiPropertySheetProvider->AddPrimaryPages(
  222. reinterpret_cast<IUnknown *>(this), // pointer to our object's IUnknown
  223. FALSE, // specifies whether to create a notification handle
  224. NULL, // must be NULL
  225. TRUE // scope pane; FALSE for result pane
  226. );
  227. if (FAILED(hr))
  228. return hr;
  229. //
  230. // Allow property page extensions to add
  231. // their own pages to the property sheet
  232. //
  233. hr = spiPropertySheetProvider->AddExtensionPages();
  234. if (FAILED(hr))
  235. return hr;
  236. //
  237. //Display property sheet
  238. //
  239. hr = spiPropertySheetProvider->Show((LONG_PTR)::GetActiveWindow(),0);
  240. // hr = spiPropertySheetProvider->Show(NULL,0); //NULL is allowed for modeless prop sheet
  241. return hr;
  242. }
  243. HRESULT CVSSUI::CreatePropertyPages(
  244. LPPROPERTYSHEETCALLBACK lpProvider,
  245. LONG_PTR handle,
  246. LPDATAOBJECT piDataObject
  247. )
  248. {
  249. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  250. TCHAR szMachineName[MAX_PATH] = {0};
  251. HRESULT hr = ExtractData(piDataObject, g_cfMachineName, (PBYTE)szMachineName, MAX_PATH);
  252. if (FAILED(hr))
  253. return hr;
  254. m_pPage = new CVSSProp(szMachineName, NULL);
  255. if (m_pPage)
  256. {
  257. CPropertyPage* pBasePage = m_pPage;
  258. MMCPropPageCallback(&(pBasePage->m_psp));
  259. HPROPSHEETPAGE hPage = CreatePropertySheetPage(&(pBasePage->m_psp));
  260. if (hPage)
  261. {
  262. hr = lpProvider->AddPage(hPage);
  263. if (FAILED(hr))
  264. DestroyPropertySheetPage(hPage);
  265. } else
  266. hr = E_FAIL;
  267. if (FAILED(hr))
  268. {
  269. delete m_pPage;
  270. m_pPage = NULL;
  271. }
  272. } else
  273. {
  274. hr = E_OUTOFMEMORY;
  275. }
  276. return hr;
  277. }
  278. */