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.

496 lines
15 KiB

  1. //==============================================================;
  2. //
  3. // This source code is only intended as a supplement to
  4. // existing Microsoft documentation.
  5. //
  6. // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
  7. // KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
  8. // IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
  9. // PURPOSE.
  10. //
  11. // Copyright (C) 1999 Microsoft Corporation. All Rights Reserved.
  12. //==============================================================;
  13. #include "stdafx.h"
  14. #include <Shlwapi.h>
  15. #include <Shlobj.H>
  16. #include "StatNode.h"
  17. #include "logsrvc.h"
  18. const GUID CStaticNode::thisGuid = { 0x39874fe4, 0x258d, 0x46f2, { 0xb4, 0x42, 0xe, 0xa0, 0xda, 0x2c, 0xbe, 0xf8 } };
  19. //==============================================================
  20. //
  21. // CStaticNode implementation
  22. //
  23. //
  24. CStaticNode::CStaticNode()
  25. {
  26. children[0] = new CLogService(this);
  27. }
  28. CStaticNode::~CStaticNode()
  29. {
  30. //Note that CStaticNode's children are already deleted when the snap-in
  31. //receives the MMCN_REMOVE_CHILDREN notification.
  32. }
  33. const _TCHAR *CStaticNode::GetDisplayName(int nCol)
  34. {
  35. static _TCHAR szDisplayName[256] = {0};
  36. LoadString(g_hinst, IDS_SNAPINNAME, szDisplayName, sizeof(szDisplayName));
  37. _tcscat(szDisplayName, _T(" ("));
  38. _tcscat(szDisplayName, snapInData.m_host);
  39. _tcscat(szDisplayName, _T(")"));
  40. return szDisplayName;
  41. }
  42. HRESULT CStaticNode::OnExpand(IConsoleNameSpace2 *pConsoleNameSpace2, IConsole *pConsole, HSCOPEITEM parent)
  43. {
  44. SCOPEDATAITEM sdi;
  45. //The HSCOPEITEM passed into OnExpand is the handle of our static node, so cache it
  46. //if it doesn't already exist.
  47. if (GetHandle() == NULL) {
  48. SetHandle((HANDLE)parent);
  49. }
  50. if (!bExpanded) {
  51. // create the child nodes, then expand them
  52. for (int n = 0; n < NUMBER_OF_CHILDREN; n++) {
  53. ZeroMemory(&sdi, sizeof(SCOPEDATAITEM) );
  54. sdi.mask = SDI_STR | // Displayname is valid
  55. SDI_PARAM | // lParam is valid
  56. SDI_IMAGE | // nImage is valid
  57. SDI_OPENIMAGE | // nOpenImage is valid
  58. SDI_PARENT |
  59. SDI_CHILDREN;
  60. sdi.relativeID = (HSCOPEITEM)parent;
  61. sdi.nImage = children[n]->GetBitmapIndex();
  62. sdi.nOpenImage = INDEX_OPENFOLDER;
  63. sdi.displayname = MMC_TEXTCALLBACK;
  64. sdi.lParam = (LPARAM)children[n]; // The cookie
  65. sdi.cChildren = 0; // no child scope items, so remove "+" sign
  66. HRESULT hr = pConsoleNameSpace2->InsertItem( &sdi );
  67. children[n]->SetHandle((HANDLE)sdi.ID);
  68. _ASSERT( SUCCEEDED(hr) );
  69. }
  70. }
  71. //Set bExpanded flag to TRUE
  72. bExpanded = TRUE;
  73. return S_OK;
  74. }
  75. HRESULT CStaticNode::OnRemoveChildren()
  76. {
  77. HRESULT hr = S_OK;
  78. for (int n = 0; n < NUMBER_OF_CHILDREN; n++)
  79. if (children[n]) {
  80. delete children[n];
  81. }
  82. return hr;
  83. }
  84. HRESULT CStaticNode::CreatePropertyPages(IPropertySheetCallback *lpProvider, LONG_PTR handle)
  85. {
  86. PROPSHEETPAGE psp;
  87. HPROPSHEETPAGE hPage = NULL;
  88. psp.dwSize = sizeof(PROPSHEETPAGE);
  89. psp.dwFlags = PSP_DEFAULT;
  90. psp.hInstance = g_hinst;
  91. psp.pszTemplate = MAKEINTRESOURCE(IDD_CHOOSER_CHOOSE_MACHINE);
  92. psp.pfnDlgProc = DialogProc;
  93. psp.lParam = reinterpret_cast<LPARAM>(&snapInData);
  94. psp.pszTitle = MAKEINTRESOURCE(IDS_SELECT_COMPUTER);
  95. hPage = CreatePropertySheetPage(&psp);
  96. _ASSERT(hPage);
  97. return lpProvider->AddPage(hPage);
  98. }
  99. HRESULT CStaticNode::HasPropertySheets()
  100. {
  101. return S_OK;
  102. }
  103. HRESULT CStaticNode::GetWatermarks(HBITMAP *lphWatermark,
  104. HBITMAP *lphHeader,
  105. HPALETTE *lphPalette,
  106. BOOL *bStretch)
  107. {
  108. *lphHeader = (HBITMAP)LoadImage(g_hinst, MAKEINTRESOURCE(IDB_HEADER), IMAGE_BITMAP, 0, 0, 0);
  109. *lphWatermark = (HBITMAP)LoadImage(g_hinst, MAKEINTRESOURCE(IDB_WATERMARK), IMAGE_BITMAP, 0, 0, 0);
  110. *bStretch = FALSE;
  111. return S_OK;
  112. }
  113. BOOL CALLBACK CStaticNode::DialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
  114. {
  115. static privateData *pData = NULL;
  116. static HWND m_hwndCheckboxOverride;
  117. switch (uMsg)
  118. {
  119. case WM_INITDIALOG:
  120. pData = reinterpret_cast<privateData *>(reinterpret_cast<PROPSHEETPAGE *>(lParam)->lParam);
  121. SendDlgItemMessage(hwndDlg, IDC_CHOOSER_RADIO_LOCAL_MACHINE, BM_SETCHECK, pData->m_fIsRadioLocalMachine, 0L);
  122. SendDlgItemMessage(hwndDlg, IDC_CHOOSER_RADIO_SPECIFIC_MACHINE, BM_SETCHECK, !pData->m_fIsRadioLocalMachine, 0L);
  123. EnableWindow(GetDlgItem(hwndDlg, IDC_CHOOSER_EDIT_MACHINE_NAME), !pData->m_fIsRadioLocalMachine);
  124. EnableWindow(GetDlgItem(hwndDlg, IDC_CHOOSER_BUTTON_BROWSE_MACHINENAMES), !pData->m_fIsRadioLocalMachine);
  125. m_hwndCheckboxOverride = ::GetDlgItem(hwndDlg, IDC_CHOOSER_CHECK_OVERRIDE_MACHINE_NAME);
  126. // fill in the supplied machine name (could be us, need to check here first)
  127. if (*pData->m_host != '\0')
  128. {
  129. ::SetWindowText(GetDlgItem(hwndDlg, IDC_CHOOSER_EDIT_MACHINE_NAME), pData->m_host);
  130. ::SendMessage(GetDlgItem(hwndDlg, IDC_CHOOSER_RADIO_SPECIFIC_MACHINE), BM_CLICK, 0, 0);
  131. }
  132. return TRUE;
  133. case WM_COMMAND:
  134. switch (wParam)
  135. {
  136. case IDC_CHOOSER_RADIO_LOCAL_MACHINE:
  137. pData->m_fIsRadioLocalMachine = TRUE;
  138. EnableWindow(GetDlgItem(hwndDlg, IDC_CHOOSER_EDIT_MACHINE_NAME), FALSE);
  139. EnableWindow(GetDlgItem(hwndDlg, IDC_CHOOSER_BUTTON_BROWSE_MACHINENAMES), FALSE);
  140. break;
  141. case IDC_CHOOSER_RADIO_SPECIFIC_MACHINE:
  142. pData->m_fIsRadioLocalMachine = FALSE;
  143. EnableWindow(GetDlgItem(hwndDlg, IDC_CHOOSER_EDIT_MACHINE_NAME), TRUE);
  144. EnableWindow(GetDlgItem(hwndDlg, IDC_CHOOSER_BUTTON_BROWSE_MACHINENAMES), TRUE);
  145. break;
  146. case IDC_CHOOSER_BUTTON_BROWSE_MACHINENAMES:
  147. {
  148. // Fall back to IE-style browser
  149. BROWSEINFO bi;
  150. LPITEMIDLIST lpItemIdList;
  151. LPMALLOC lpMalloc;
  152. if (SUCCEEDED(SHGetSpecialFolderLocation(hwndDlg, CSIDL_NETWORK, &lpItemIdList)))
  153. {
  154. _TCHAR szBrowserCaption[MAX_PATH];
  155. LoadString(g_hinst, IDS_COMPUTER_BROWSER_CAPTION, szBrowserCaption, sizeof(szBrowserCaption));
  156. bi.hwndOwner = hwndDlg;
  157. bi.pidlRoot = lpItemIdList;
  158. bi.pszDisplayName = pData->m_host;
  159. bi.lpszTitle = szBrowserCaption;
  160. bi.ulFlags = BIF_BROWSEFORCOMPUTER | BIF_EDITBOX | BIF_VALIDATE;
  161. bi.lpfn = BrowseCallbackProc;
  162. bi.lParam = NULL;
  163. bi.iImage = NULL;
  164. if (SHBrowseForFolder(&bi) != NULL)
  165. {
  166. if (*pData->m_host != '\0')
  167. {
  168. ::SetWindowText(GetDlgItem(hwndDlg,
  169. IDC_CHOOSER_EDIT_MACHINE_NAME), pData->m_host);
  170. }
  171. }
  172. if (SUCCEEDED(SHGetMalloc(&lpMalloc)))
  173. {
  174. lpMalloc->Free(lpItemIdList);
  175. lpMalloc->Release();
  176. }
  177. }
  178. }
  179. break;
  180. case IDC_CHOOSER_CHECK_OVERRIDE_MACHINE_NAME:
  181. break;
  182. }
  183. break;
  184. case WM_NOTIFY:
  185. switch (((LPNMHDR)lParam)->code) {
  186. case PSN_SETACTIVE:
  187. PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_FINISH);
  188. break;
  189. case PSN_WIZFINISH:
  190. if (pData->m_fIsRadioLocalMachine) {
  191. // Return string with local computer name to the caller
  192. GetLocalComputerName(pData->m_host);
  193. } else {
  194. // Get the machine name from the edit window
  195. GetWindowText(GetDlgItem(hwndDlg, IDC_CHOOSER_EDIT_MACHINE_NAME),
  196. pData->m_host, sizeof(pData->m_host));
  197. //if the user didn't enter anything, we need to
  198. //get the local computer name first. Since
  199. //GetLocalComputerName takes care of putting everything
  200. //into uppercase, we can break from this case
  201. if (*pData->m_host == '\0')
  202. {
  203. GetLocalComputerName(pData->m_host);
  204. break;
  205. }
  206. //Put machine name in uppercase
  207. static _TCHAR sztemp[MAX_PATH];
  208. int n =0;
  209. while (pData->m_host[n] != '\0')
  210. {
  211. sztemp[n] = toupper(pData->m_host[n]);
  212. n++;
  213. }
  214. sztemp[n] = '\0';
  215. _tcscpy(pData->m_host, sztemp);
  216. }
  217. // Save the override flag if the caller asked for it
  218. pData->m_fAllowOverrideMachineNameOut =
  219. SendMessage(m_hwndCheckboxOverride, BM_GETCHECK, 0, 0) == BST_CHECKED ? TRUE : FALSE;
  220. break;
  221. }
  222. break;
  223. }
  224. return FALSE;
  225. }
  226. HRESULT CStaticNode::OnAddMenuItems(IContextMenuCallback *pContextMenuCallback, long *pInsertionsAllowed)
  227. {
  228. HRESULT hr = S_OK;
  229. CONTEXTMENUITEM menuItemsNew[] =
  230. {
  231. {
  232. L"Select Computer", L"Select new computer to manage",
  233. IDM_SELECT_COMPUTER, CCM_INSERTIONPOINTID_PRIMARY_TOP, 0, CCM_SPECIAL_DEFAULT_ITEM
  234. },
  235. { NULL, NULL, 0, 0, 0 }
  236. };
  237. // Loop through and add each of the menu items, we
  238. // want to add to new menu, so see if it is allowed.
  239. if (*pInsertionsAllowed)
  240. {
  241. for (LPCONTEXTMENUITEM m = menuItemsNew; m->strName; m++)
  242. {
  243. hr = pContextMenuCallback->AddItem(m);
  244. if (FAILED(hr))
  245. break;
  246. }
  247. }
  248. return hr;
  249. }
  250. HRESULT CStaticNode::OnMenuCommand(IConsole *pConsole, IConsoleNameSpace2 *pConsoleNameSpace2, long lCommandID, IDataObject *pDataObject)
  251. {
  252. HRESULT hr = S_FALSE;
  253. USES_CONVERSION;
  254. switch (lCommandID)
  255. {
  256. case IDM_SELECT_COMPUTER:
  257. // Fall back to IE-style browser
  258. BROWSEINFO bi;
  259. LPITEMIDLIST lpItemIdList;
  260. LPMALLOC lpMalloc;
  261. HWND hWnd;
  262. hr = pConsole->GetMainWindow(&hWnd);
  263. if (SUCCEEDED(hr))
  264. {
  265. if (SUCCEEDED(SHGetSpecialFolderLocation(hWnd, CSIDL_NETWORK, &lpItemIdList)))
  266. {
  267. _TCHAR szBrowserCaption[MAX_PATH];
  268. _TCHAR szUserSelection[MAX_PATH];
  269. LoadString(g_hinst, IDS_COMPUTER_NEW_BROWSER_CAPTION, szBrowserCaption, sizeof(szBrowserCaption));
  270. //Add machine name to browser caption
  271. _tcscat(szBrowserCaption, _T("\nCurrent computer is "));
  272. _tcscat(szBrowserCaption, snapInData.m_host);
  273. bi.hwndOwner = hWnd;
  274. bi.pidlRoot = lpItemIdList;
  275. bi.pszDisplayName = szUserSelection;
  276. bi.lpszTitle = szBrowserCaption;
  277. bi.ulFlags = BIF_BROWSEFORCOMPUTER | BIF_EDITBOX | BIF_VALIDATE;
  278. bi.lpfn = BrowseCallbackProc;
  279. bi.lParam = NULL;
  280. bi.iImage = NULL;
  281. if (SHBrowseForFolder(&bi) != NULL)
  282. {
  283. //Check to see if user chose a new machine. If yes,
  284. //we'll need to remove the Log Service Node and then
  285. //reinsert it. As a result, Event Viewer will reinsert
  286. //its node under the Log Service Node and request the
  287. //MMC_SPAPIN_MACHINE_NAME clipboard format from us.
  288. if ( (_tcscmp(szUserSelection, getHost())) )
  289. {
  290. //Store the new machine name
  291. static privateData *pData = NULL;
  292. pData = &snapInData;
  293. if (*szUserSelection == 0) //Retrieve local computer name first
  294. GetLocalComputerName(szUserSelection);
  295. _tcscpy(pData->m_host, szUserSelection);
  296. //Put machine name in uppercase
  297. static _TCHAR sztemp[MAX_PATH];
  298. int n =0;
  299. while (pData->m_host[n] != '\0')
  300. {
  301. sztemp[n] = toupper(pData->m_host[n]);
  302. n++;
  303. }
  304. sztemp[n] = '\0';
  305. _tcscpy(pData->m_host, sztemp);
  306. //Now reinsert the Log Service Node
  307. hr = ReinsertChildNodes(pConsole, pConsoleNameSpace2);
  308. }
  309. }
  310. if (SUCCEEDED(SHGetMalloc(&lpMalloc)))
  311. {
  312. lpMalloc->Free(lpItemIdList);
  313. lpMalloc->Release();
  314. }
  315. }
  316. }
  317. }
  318. return hr;
  319. }
  320. int CALLBACK CStaticNode::BrowseCallbackProc(HWND hwnd, UINT uMsg, LPARAM lParam, LPARAM lpData)
  321. {
  322. switch (uMsg)
  323. {
  324. case BFFM_VALIDATEFAILED:
  325. ::MessageBox(hwnd, _T("The selected computer isn't on the network. Try again."), _T("Invalid drive specification"),
  326. MB_OK | MB_ICONEXCLAMATION | MB_APPLMODAL);
  327. return 1; //Don't dismiss the Browse dialog
  328. }
  329. return 0;
  330. }
  331. HRESULT CStaticNode::ReinsertChildNodes(IConsole *pConsole, IConsoleNameSpace2 *pConsoleNameSpace2)
  332. {
  333. HRESULT hr = S_FALSE;
  334. USES_CONVERSION;
  335. //First we change the display name of the static node
  336. SCOPEDATAITEM sdi;
  337. LPOLESTR wszName = NULL;
  338. const _TCHAR *pszName = GetDisplayName();
  339. wszName = (LPOLESTR)T2COLE(pszName);
  340. HSCOPEITEM hStaticNode = (HSCOPEITEM)GetHandle();
  341. ZeroMemory (&sdi, sizeof(SCOPEDATAITEM));
  342. sdi.mask = SDI_STR;
  343. sdi.displayname = wszName;
  344. sdi.ID = hStaticNode;
  345. hr = pConsoleNameSpace2->SetItem(&sdi);
  346. if (S_OK != hr)
  347. return E_FAIL;
  348. //check to see if the static node has already been expanded. If it hasn't,
  349. //there's nothing else we need to do.
  350. if (bExpanded)
  351. {
  352. //Delete children of static node
  353. for (int n = 0; n < NUMBER_OF_CHILDREN; n++)
  354. {
  355. if (children[n])
  356. {
  357. hr = pConsoleNameSpace2->DeleteItem((HSCOPEITEM)(children[n]->GetHandle()), TRUE);
  358. _ASSERT(SUCCEEDED(hr));
  359. }
  360. }
  361. //Reinsert the children of the static node. This will
  362. //result in the Event Viewer snap-in reinserting its own node under ours.
  363. //First set bExpanded flag to FALSE so that the code that inserts
  364. //the children is executed.
  365. bExpanded = FALSE;
  366. OnExpand(pConsoleNameSpace2, pConsole, hStaticNode);
  367. if (S_OK != hr)
  368. return E_FAIL;
  369. }
  370. return hr;
  371. }
  372. CStaticNode::GetLocalComputerName( _TCHAR *szComputerName)
  373. {
  374. static _TCHAR szbuf[MAX_PATH];
  375. static _TCHAR szbuflower[MAX_PATH];
  376. DWORD dw = sizeof(szbuf);
  377. ::GetComputerName(&szbuf[0], &dw);
  378. int n =0;
  379. //Put each character of machine name in uppercase
  380. while (szbuf[n] != '\0')
  381. {
  382. szbuflower[n] = toupper(szbuf[n]);
  383. n++;
  384. }
  385. szbuflower[n] = '\0';
  386. _tcscpy( szComputerName, _T("\\\\") );
  387. _tcscat( szComputerName, &szbuflower[0] );
  388. }