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.

508 lines
14 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1997.
  5. //
  6. // File: O N C O M M A N D _ D B G . C P P
  7. //
  8. // Contents: Debug command handlers
  9. //
  10. // Notes:
  11. //
  12. // Author: jeffspr 23 Jul 1998
  13. //
  14. //----------------------------------------------------------------------------
  15. #include "pch.h"
  16. #pragma hdrstop
  17. #include "foldinc.h" // Standard shell\folder includes
  18. #include "advcfg.h"
  19. #include "conprops.h"
  20. #include "foldres.h"
  21. #include "ncnetcon.h"
  22. #include "oncommand.h"
  23. #include "notify.h"
  24. #include "ctrayui.h"
  25. #include <nctraceui.h>
  26. #if DBG // Debug menu commands
  27. #include "oncommand_dbg.h" //
  28. #endif
  29. #include "shutil.h"
  30. #include "traymsgs.h"
  31. #include <nsres.h>
  32. //---[ Externs ]--------------------------------------------------------------
  33. extern HWND g_hwndTray;
  34. //---[ Globals ]--------------------------------------------------------------
  35. // We allow X number (hardcoded) advises. This is all debug code, so no real
  36. // need to build an expensive STL list
  37. //
  38. const DWORD c_dwMaxNotifyAdvises = 16;
  39. DWORD g_dwCookieCount = 0;
  40. DWORD g_dwAdviseCookies[c_dwMaxNotifyAdvises];
  41. // Used as the caption for all debugging message boxes
  42. //
  43. const WCHAR c_szDebugCaption[] = L"Net Config Debugging";
  44. //+---------------------------------------------------------------------------
  45. //
  46. // Function: HrOnCommandDebugTray
  47. //
  48. // Purpose: Toggle the presence of the tray object
  49. //
  50. // Arguments:
  51. // apidl [in] Ignored
  52. // cidl [in] Ignored
  53. // hwndOwner [in] Ignored
  54. // psf [in] Ignored
  55. //
  56. // Returns:
  57. //
  58. // Author: jeffspr 23 Jul 1998
  59. //
  60. // Notes:
  61. //
  62. HRESULT HrOnCommandDebugTray(
  63. const PCONFOLDPIDLVEC& apidl,
  64. HWND hwndOwner,
  65. LPSHELLFOLDER psf)
  66. {
  67. HRESULT hr = S_OK;
  68. IOleCommandTarget * pOleCmdTarget = NULL;
  69. // Create an instance of the tray
  70. hr = CoCreateInstance(CLSID_ConnectionTray,
  71. NULL,
  72. CLSCTX_INPROC_SERVER | CLSCTX_NO_CODE_DOWNLOAD,
  73. IID_IOleCommandTarget,
  74. (LPVOID *)&pOleCmdTarget);
  75. TraceHr(ttidError, FAL, hr, FALSE,
  76. "CoCreateInstance(CLSID_ConnectionTray) for IOleCommandTarget");
  77. if (SUCCEEDED(hr))
  78. {
  79. // If the tray object exists, try to remove it.
  80. //
  81. if (g_pCTrayUI)
  82. {
  83. TraceTag(ttidShellFolder, "Removing tray object");
  84. pOleCmdTarget->Exec(&CGID_ShellServiceObject, SSOCMDID_CLOSE, 0, NULL, NULL);
  85. hr = HrRemoveTrayExtension();
  86. }
  87. else
  88. {
  89. // Try to create the tray object
  90. //
  91. TraceTag(ttidShellFolder, "Creating tray object");
  92. pOleCmdTarget->Exec(&CGID_ShellServiceObject, SSOCMDID_OPEN, 0, NULL, NULL);
  93. hr = HrAddTrayExtension();
  94. }
  95. ReleaseObj(pOleCmdTarget);
  96. }
  97. TraceHr(ttidShellFolder, FAL, hr, FALSE, "HrOnCommandDebugTray");
  98. return hr;
  99. }
  100. //+---------------------------------------------------------------------------
  101. //
  102. // Function: HrOnCommandDebugTracing
  103. //
  104. // Purpose: Command handler for CMIDM_DEBUG_TRACING. It will eventually
  105. // bring up the tracing change dialog.
  106. //
  107. // Arguments:
  108. // apidl [] Ignored
  109. // cidl [] Ignored
  110. // hwndOwner [] Ignored
  111. // psf [] Ignored
  112. //
  113. // Returns:
  114. //
  115. // Author: jeffspr 24 Aug 1998
  116. //
  117. // Notes:
  118. //
  119. HRESULT HrOnCommandDebugTracing(
  120. const PCONFOLDPIDLVEC& apidl,
  121. HWND hwndOwner,
  122. LPSHELLFOLDER psf)
  123. {
  124. HRESULT hr = S_OK;
  125. hr = HrOpenTracingUI(hwndOwner);
  126. TraceHr(ttidShellFolder, FAL, hr, FALSE, "HrOnCommandDebugTracing");
  127. return hr;
  128. }
  129. //+---------------------------------------------------------------------------
  130. //
  131. // Function: HrOnCommandDebugNotifyAdd
  132. //
  133. // Purpose: Command handler for CMIDM_DEBUG_NOTIFYADD. Adds an additional
  134. // advise for connection notifications
  135. //
  136. // Arguments:
  137. // apidl [in] Ignored
  138. // cidl [in] Ignored
  139. // hwndOwner [in] Ignored
  140. // psf [in] Ignored
  141. //
  142. // Returns:
  143. //
  144. // Author: jeffspr 24 Aug 1998
  145. //
  146. // Notes:
  147. //
  148. HRESULT HrOnCommandDebugNotifyAdd(
  149. const PCONFOLDPIDLVEC& apidl,
  150. HWND hwndOwner,
  151. LPSHELLFOLDER psf)
  152. {
  153. HRESULT hr = S_OK;
  154. IConnectionPoint * pConPoint = NULL;
  155. INetConnectionNotifySink * pSink = NULL;
  156. DWORD dwCookie = 0;
  157. if (g_dwCookieCount >= c_dwMaxNotifyAdvises)
  158. {
  159. MessageBox(hwndOwner,
  160. L"You're over the max advise count. If you REALLY need to test more advises than "
  161. L"we've hardcoded, then set c_dwMaxNotifyAdvises to something larger in oncommand_dbg.cpp",
  162. c_szDebugCaption,
  163. MB_OK | MB_ICONERROR);
  164. }
  165. else
  166. {
  167. hr = HrGetNotifyConPoint(&pConPoint);
  168. if (SUCCEEDED(hr))
  169. {
  170. // Create the notify sink
  171. //
  172. hr = CConnectionNotifySink::CreateInstance(
  173. IID_INetConnectionNotifySink,
  174. (LPVOID*)&pSink);
  175. if (SUCCEEDED(hr))
  176. {
  177. Assert(pSink);
  178. hr = pConPoint->Advise(pSink, &dwCookie);
  179. if (SUCCEEDED(hr))
  180. {
  181. WCHAR szMB[256];
  182. g_dwAdviseCookies[g_dwCookieCount++] = dwCookie;
  183. wsprintfW(szMB, L"Advise succeeded. You now have %d active advises", g_dwCookieCount);
  184. MessageBox(hwndOwner,
  185. szMB,
  186. c_szDebugCaption,
  187. MB_OK | MB_ICONEXCLAMATION);
  188. }
  189. ReleaseObj(pSink);
  190. }
  191. ReleaseObj(pConPoint);
  192. }
  193. else
  194. {
  195. AssertSz(FALSE, "Couldn't get connection point or sink in HrOnCommandDebugNotifyAdd");
  196. }
  197. }
  198. TraceHr(ttidShellFolder, FAL, hr, FALSE, "HrOnCommandDebugNotifyAdd");
  199. return hr;
  200. }
  201. //+---------------------------------------------------------------------------
  202. //
  203. // Function: HrOnCommandDebugNotifyRemove
  204. //
  205. // Purpose: Command handler for CMIDM_DEBUG_NOTIFYREMOVE
  206. //
  207. // Arguments:
  208. // apidl [] Ignored
  209. // cidl [] Ignored
  210. // hwndOwner [] Ignored
  211. // psf [] Ignored
  212. //
  213. // Returns:
  214. //
  215. // Author: jeffspr 24 Aug 1998
  216. //
  217. // Notes:
  218. //
  219. HRESULT HrOnCommandDebugNotifyRemove(
  220. const PCONFOLDPIDLVEC& apidl,
  221. HWND hwndOwner,
  222. LPSHELLFOLDER psf)
  223. {
  224. HRESULT hr = S_OK;
  225. IConnectionPoint * pConPoint = NULL;
  226. DWORD dwCookie = 0;
  227. if (g_dwCookieCount == 0)
  228. {
  229. MessageBox(hwndOwner,
  230. L"Hey, you don't have any active advises",
  231. c_szDebugCaption,
  232. MB_OK | MB_ICONERROR);
  233. }
  234. else
  235. {
  236. hr = HrGetNotifyConPoint(&pConPoint);
  237. if (SUCCEEDED(hr))
  238. {
  239. hr = pConPoint->Unadvise(g_dwAdviseCookies[g_dwCookieCount-1]);
  240. if (SUCCEEDED(hr))
  241. {
  242. WCHAR szMB[256];
  243. g_dwAdviseCookies[--g_dwCookieCount] = 0;
  244. wsprintfW(szMB, L"Unadvise succeeded. You have %d remaining advises", g_dwCookieCount);
  245. MessageBox(hwndOwner,
  246. szMB,
  247. c_szDebugCaption,
  248. MB_OK | MB_ICONEXCLAMATION);
  249. }
  250. ReleaseObj(pConPoint);
  251. }
  252. else
  253. {
  254. AssertSz(FALSE, "Couldn't get connection point or sink in HrOnCommandDebugNotifyRemove");
  255. }
  256. }
  257. TraceHr(ttidShellFolder, FAL, hr, FALSE, "HrOnCommandDebugNotifyRemove");
  258. return hr;
  259. }
  260. //+---------------------------------------------------------------------------
  261. //
  262. // Function: HrOnCommandDebugNotifyTest
  263. //
  264. // Purpose: Command handler for CMIDM_DEBUG_NOTIFYTEST. Runs the
  265. // NotifyTestStart on the ConManDebug interface.
  266. //
  267. // Arguments:
  268. // apidl [] Ignored
  269. // cidl [] Ignored
  270. // hwndOwner [] Ignored
  271. // psf [] Ignored
  272. //
  273. // Returns:
  274. //
  275. // Author: jeffspr 24 Aug 1998
  276. //
  277. // Notes:
  278. //
  279. HRESULT HrOnCommandDebugNotifyTest(
  280. const PCONFOLDPIDLVEC& apidl,
  281. HWND hwndOwner,
  282. LPSHELLFOLDER psf)
  283. {
  284. HRESULT hr = S_OK;
  285. INetConnectionManagerDebug * pConManDebug = NULL;
  286. hr = HrCreateInstance(
  287. CLSID_ConnectionManager,
  288. CLSCTX_LOCAL_SERVER | CLSCTX_NO_CODE_DOWNLOAD,
  289. &pConManDebug);
  290. TraceHr(ttidError, FAL, hr, FALSE,
  291. "HrCreateInstance(CLSID_ConnectionManager) for INetConnectionManagerDebug");
  292. if (SUCCEEDED(hr))
  293. {
  294. (VOID) pConManDebug->NotifyTestStart();
  295. }
  296. ReleaseObj(pConManDebug);
  297. TraceHr(ttidShellFolder, FAL, hr, FALSE, "HrOnCommandDebugNotifyAdd");
  298. return hr;
  299. }
  300. //+---------------------------------------------------------------------------
  301. //
  302. // Function: HrOnCommandDebugRefresh
  303. //
  304. // Purpose: Test the flushing of the connection cache (does the folder
  305. // still work properly)? This will simulate the current response
  306. // to an external refresh request
  307. //
  308. // Arguments:
  309. // apidl [in] Ignored
  310. // cidl [in] Ignored
  311. // hwndOwner [in] Ignored
  312. // psf [in] Ignored
  313. //
  314. // Returns:
  315. //
  316. // Author: jeffspr 17 Nov 1998
  317. //
  318. // Notes:
  319. //
  320. HRESULT HrOnCommandDebugRefresh(
  321. const PCONFOLDPIDLVEC& apidl,
  322. HWND hwndOwner,
  323. LPSHELLFOLDER psf)
  324. {
  325. HRESULT hr = S_OK;
  326. TraceFileFunc(ttidShellFolder);
  327. // Force a refresh without having the window to work with.
  328. //
  329. ForceRefresh(NULL);
  330. TraceHr(ttidShellFolder, FAL, hr, FALSE, "HrOnCommandDebugFlushCache");
  331. return hr;
  332. }
  333. //+---------------------------------------------------------------------------
  334. //
  335. // Function: HrOnCommandDebugRefreshNoFlush
  336. //
  337. // Purpose: Test the building of an external CConnectionList. When this
  338. // is working, it will be used to update the global list.
  339. //
  340. // Arguments:
  341. // apidl [in] Ignored
  342. // cidl [in] Ignored
  343. // hwndOwner [in] Ignored
  344. // psf [in] Ignored
  345. //
  346. // Returns:
  347. //
  348. // Author: jeffspr 17 Nov 1998
  349. //
  350. // Notes:
  351. //
  352. HRESULT HrOnCommandDebugRefreshNoFlush(
  353. const PCONFOLDPIDLVEC& apidl,
  354. HWND hwndOwner,
  355. LPSHELLFOLDER psf)
  356. {
  357. // Refresh the folder. Pass in NULL to let the shell code do it's own
  358. // folder pidl lookup
  359. //
  360. PCONFOLDPIDLFOLDER pidlEmpty;
  361. HRESULT hr = HrForceRefreshNoFlush(pidlEmpty);
  362. TraceHr(ttidShellFolder, FAL, hr, FALSE, "HrOnCommandDebugRefreshNoFlush");
  363. return hr;
  364. }
  365. //+---------------------------------------------------------------------------
  366. //
  367. // Function: HrOnCommandDebugRefreshSelected
  368. //
  369. // Purpose: Refresh the selected connection objects (in place)
  370. //
  371. // Arguments:
  372. // apidl [in] Selected object pidls
  373. // cidl [in] Count of selected objects
  374. // hwndOwner [in] Parent hwnd
  375. // psf [in] Ignored
  376. //
  377. // Returns:
  378. //
  379. // Author: jeffspr 29 Apr 1999
  380. //
  381. // Notes:
  382. //
  383. HRESULT HrOnCommandDebugRefreshSelected(
  384. const PCONFOLDPIDLVEC& apidl,
  385. HWND hwndOwner,
  386. LPSHELLFOLDER psf)
  387. {
  388. HRESULT hr = S_OK;
  389. PCONFOLDPIDLFOLDER pidlFolder;
  390. if (!apidl.empty())
  391. {
  392. hr = HrGetConnectionsFolderPidl(pidlFolder);
  393. if (SUCCEEDED(hr))
  394. {
  395. PCONFOLDPIDLVEC::const_iterator ulLoop;
  396. for (ulLoop = apidl.begin(); ulLoop != apidl.end(); ulLoop++)
  397. {
  398. const PCONFOLDPIDL& pcfp = *ulLoop;
  399. // If it's not a wizard pidl, then update the
  400. // icon data.
  401. //
  402. if (WIZARD_NOT_WIZARD == pcfp->wizWizard)
  403. {
  404. // Refresh this item -- this will make the desktop shortcuts
  405. // update to the correct state.
  406. //
  407. RefreshFolderItem(pidlFolder, *ulLoop, *ulLoop);
  408. }
  409. }
  410. }
  411. }
  412. TraceHr(ttidError, FAL, hr, FALSE, "HrOnCommandDebugRefreshSelected");
  413. return hr;
  414. }
  415. HRESULT HrOnCommandDebugRemoveTrayIcons(
  416. const PCONFOLDPIDLVEC& apidl,
  417. HWND hwndOwner,
  418. LPSHELLFOLDER psf)
  419. {
  420. HRESULT hr = S_OK;
  421. NOTIFYICONDATA nid;
  422. TraceTag(ttidShellFolder, "In OnMyWMRemoveTrayIcon message handler");
  423. if (g_hwndTray)
  424. {
  425. UINT uiTrayIconId = 0;
  426. // We're going to remove icons until we can't remove icons any more
  427. // If HrShell_NotifyIcon screws up though and is returning S_OK
  428. // on invalid icon ids, make sure that we are able to bail this loop.
  429. // Hence the 10000
  430. //
  431. while (hr == S_OK && uiTrayIconId < 10000)
  432. {
  433. TraceTag(ttidShellFolder, "Attempting to remove icon: %d", uiTrayIconId);
  434. ZeroMemory (&nid, sizeof(nid));
  435. nid.cbSize = sizeof(NOTIFYICONDATA);
  436. nid.hWnd = g_hwndTray;
  437. nid.uID = uiTrayIconId++;
  438. hr = HrShell_NotifyIcon(NIM_DELETE, &nid);
  439. }
  440. g_pCTrayUI->ResetIconCount();
  441. }
  442. TraceHr(ttidShellFolder, FAL, hr, FALSE, "HrOnCommandDebugRemoveTrayIcons");
  443. return hr;
  444. }