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.

787 lines
24 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1997.
  5. //
  6. // File: N O T I F Y . C P P
  7. //
  8. // Contents: Implementation of INetConnectionNotifySink
  9. //
  10. // Notes:
  11. //
  12. // Author: shaunco 21 Aug 1998
  13. //
  14. //----------------------------------------------------------------------------
  15. #include "pch.h"
  16. #pragma hdrstop
  17. #include "foldinc.h"
  18. #include "nccom.h"
  19. #include "notify.h"
  20. #include "shutil.h"
  21. #include "smcent.h"
  22. #include "ctrayui.h"
  23. #include "traymsgs.h"
  24. #include "wzcdlg.h"
  25. extern HWND g_hwndTray;
  26. enum EVENT_LEVELS
  27. {
  28. EVT_LVL_DISABLE_ALL = 0,
  29. EVT_LVL_ENABLE_PRIVATE = 1,
  30. EVT_LVL_ENABLE_ALL = 2
  31. };
  32. DWORD g_dwCurrentEventLevel = EVT_LVL_ENABLE_ALL;
  33. //static
  34. HRESULT
  35. CConnectionNotifySink::CreateInstance (
  36. IN REFIID riid,
  37. OUT VOID** ppv)
  38. {
  39. TraceFileFunc(ttidNotifySink);
  40. HRESULT hr = E_OUTOFMEMORY;
  41. // Initialize the output parameter.
  42. //
  43. *ppv = NULL;
  44. CConnectionNotifySink* pObj;
  45. pObj = new CComObject <CConnectionNotifySink>;
  46. if (pObj)
  47. {
  48. // Do the standard CComCreator::CreateInstance stuff.
  49. //
  50. pObj->SetVoid (NULL);
  51. pObj->InternalFinalConstructAddRef ();
  52. hr = pObj->FinalConstruct ();
  53. pObj->InternalFinalConstructRelease ();
  54. if (SUCCEEDED(hr))
  55. {
  56. // Call the PidlInitialize function to allow the enumeration
  57. // object to copy the list.
  58. //
  59. hr = HrGetConnectionsFolderPidl(pObj->m_pidlFolder);
  60. if (SUCCEEDED(hr))
  61. {
  62. hr = pObj->QueryInterface (riid, ppv);
  63. }
  64. }
  65. if (FAILED(hr))
  66. {
  67. delete pObj;
  68. }
  69. }
  70. TraceHr(ttidError, FAL, hr, (S_FALSE == hr), "CConnectionNotifySink::CreateInstance");
  71. return hr;
  72. }
  73. //+---------------------------------------------------------------------------
  74. //
  75. // Member: CConnectionNotifySink::~CConnectionNotifySink
  76. //
  77. // Purpose: Clean up the sink object, deleting the folder pidl and any
  78. // alloc'd junk we might add in the future.
  79. //
  80. // Arguments:
  81. // (none)
  82. //
  83. // Returns:
  84. //
  85. // Author: jeffspr 26 Aug 1998
  86. //
  87. // Notes:
  88. //
  89. CConnectionNotifySink::~CConnectionNotifySink() throw()
  90. {
  91. TraceFileFunc(ttidNotifySink);
  92. if (FIsDebugFlagSet (dfidBreakOnNotifySinkRelease))
  93. {
  94. AssertSz(FALSE, "THIS IS NOT A BUG! The debug flag "
  95. "\"BreakOnNotifySinkRelease\" has been set. Set your breakpoints now.");
  96. }
  97. TraceTag(ttidNotifySink, "Connection notify sink destroyed");
  98. }
  99. HRESULT CConnectionNotifySink::HrUpdateIncomingConnection()
  100. {
  101. HRESULT hr = S_OK;
  102. ConnListEntry cle;
  103. hr = g_ccl.HrFindRasServerConnection(cle);
  104. if (S_OK == hr)
  105. {
  106. hr = HrOnNotifyUpdateConnection(
  107. m_pidlFolder,
  108. &(cle.ccfe.GetGuidID()),
  109. cle.ccfe.GetNetConMediaType(),
  110. cle.ccfe.GetNetConSubMediaType(),
  111. cle.ccfe.GetNetConStatus(),
  112. cle.ccfe.GetCharacteristics(),
  113. cle.ccfe.GetName(),
  114. cle.ccfe.GetDeviceName(),
  115. cle.ccfe.GetPhoneOrHostAddress()
  116. );
  117. if (SUCCEEDED(hr))
  118. {
  119. PCONFOLDPIDL pidlShellNotify;
  120. hr = cle.ccfe.ConvertToPidl(pidlShellNotify);
  121. if (SUCCEEDED(hr))
  122. {
  123. GenerateEvent(SHCNE_UPDATEITEM, m_pidlFolder, pidlShellNotify, NULL);
  124. }
  125. }
  126. }
  127. return hr;
  128. }
  129. HRESULT
  130. CConnectionNotifySink::ConnectionAdded (
  131. IN const NETCON_PROPERTIES_EX* pPropsEx)
  132. {
  133. TraceFileFunc(ttidNotifySink);
  134. #ifdef DBG
  135. OLECHAR szGuidString[MAX_GUID_STRING_LEN];
  136. StringFromGUID2(pPropsEx->guidId, szGuidString, MAX_GUID_STRING_LEN);
  137. TraceTag(ttidNotifySink, "INetConnectionNotifySink::ConnectionAdded - %S %S [%s:%s:%s:%s]",
  138. szGuidString, pPropsEx->bstrName, DbgNcm(pPropsEx->ncMediaType), DbgNcsm(pPropsEx->ncSubMediaType), DbgNcs(pPropsEx->ncStatus), DbgNccf(pPropsEx->dwCharacter) );
  139. #endif
  140. if (g_dwCurrentEventLevel <= EVT_LVL_DISABLE_ALL)
  141. {
  142. TraceTag(ttidNotifySink, "Last event ignored due to g_dwCurrentEventLevel == %d", g_dwCurrentEventLevel);
  143. return S_FALSE;
  144. }
  145. HRESULT hr = S_OK; // Only used for code paths. We don't return this.
  146. HRESULT hrFind = S_OK; // Only for finding the connection.
  147. PCONFOLDPIDL pidlNew;
  148. ConnListEntry cleDontCare;
  149. hrFind = g_ccl.HrFindConnectionByGuid(&(pPropsEx->guidId), cleDontCare);
  150. if (S_OK == hrFind)
  151. {
  152. // We already know about this connection. Don't bother added it.
  153. TraceTag(ttidShellFolder, "Ignoring known connection on ConnectionAdded notify");
  154. }
  155. else
  156. {
  157. // Create the entry in the connection list and get the returned pidl
  158. //
  159. hr = HrCreateConFoldPidl(
  160. *pPropsEx,
  161. pidlNew);
  162. if (SUCCEEDED(hr) && (!pidlNew.empty()))
  163. {
  164. CONFOLDENTRY cfe;
  165. Assert(!m_pidlFolder.empty());
  166. // Convert to the confoldentry
  167. //
  168. hr = pidlNew.ConvertToConFoldEntry(cfe);
  169. if (SUCCEEDED(hr))
  170. {
  171. // Insert the connection in the connection list
  172. //
  173. hr = g_ccl.HrInsert(cfe);
  174. if (SUCCEEDED(hr))
  175. {
  176. // Notify the shell that we have a new object
  177. //
  178. PCONFOLDPIDL pidlShellNotify;
  179. hr = cfe.ConvertToPidl(pidlShellNotify);
  180. if (SUCCEEDED(hr))
  181. {
  182. GenerateEvent(SHCNE_CREATE, m_pidlFolder, pidlShellNotify, NULL);
  183. }
  184. }
  185. // Don't delete the cfe here because the connection list now owns it.
  186. }
  187. }
  188. }
  189. if (SUCCEEDED(hr) &&
  190. (NCM_NONE != pPropsEx->ncMediaType) &&
  191. (pPropsEx->dwCharacter & NCCF_INCOMING_ONLY) )
  192. {
  193. hr = HrUpdateIncomingConnection();
  194. }
  195. return S_OK;
  196. }
  197. HRESULT
  198. CConnectionNotifySink::ConnectionBandWidthChange (
  199. IN const GUID* pguidId)
  200. {
  201. TraceFileFunc(ttidNotifySink);
  202. #ifdef DBG
  203. OLECHAR szGuidString[MAX_GUID_STRING_LEN];
  204. StringFromGUID2(*pguidId, szGuidString, MAX_GUID_STRING_LEN);
  205. TraceTag(ttidNotifySink, "INetConnectionNotifySink::ConnectionBandWidthChange - %S", szGuidString);
  206. #endif
  207. if (g_dwCurrentEventLevel <= EVT_LVL_DISABLE_ALL)
  208. {
  209. TraceTag(ttidNotifySink, "Last event ignored due to g_dwCurrentEventLevel == %d", g_dwCurrentEventLevel);
  210. return S_FALSE;
  211. }
  212. HRESULT hr = S_OK;
  213. CNetStatisticsCentral * pnsc = NULL;
  214. hr = CNetStatisticsCentral::HrGetNetStatisticsCentral(&pnsc, FALSE);
  215. if (SUCCEEDED(hr))
  216. {
  217. pnsc->UpdateRasLinkList(pguidId);
  218. ReleaseObj(pnsc);
  219. }
  220. return S_OK;
  221. }
  222. HRESULT
  223. CConnectionNotifySink::ConnectionDeleted (
  224. IN const GUID* pguidId)
  225. {
  226. TraceFileFunc(ttidNotifySink);
  227. HRESULT hr = S_OK;
  228. HRESULT hrFind = S_OK;
  229. ConnListEntry cle;
  230. PCONFOLDPIDL pidlFind;
  231. BOOL fFlushPosts = FALSE;
  232. Assert(pguidId);
  233. Assert(!m_pidlFolder.empty());
  234. if (g_dwCurrentEventLevel <= EVT_LVL_DISABLE_ALL)
  235. {
  236. TraceTag(ttidNotifySink, "CConnectionNotifySink::ConnectionDeleted event ignored due to g_dwCurrentEventLevel == %d", g_dwCurrentEventLevel);
  237. return S_FALSE;
  238. }
  239. // Find the connection using the GUID.
  240. //
  241. hrFind = g_ccl.HrFindConnectionByGuid(pguidId, cle);
  242. if (S_OK == hrFind)
  243. {
  244. #ifdef DBG
  245. OLECHAR szGuidString[MAX_GUID_STRING_LEN];
  246. StringFromGUID2(cle.ccfe.GetGuidID(), szGuidString, MAX_GUID_STRING_LEN);
  247. TraceTag(ttidNotifySink, "INetConnectionNotifySink::ConnectionDeleted - %S %S [%s:%s:%s:%s]", szGuidString, cle.ccfe.GetName(),
  248. DbgNcm(cle.ccfe.GetNetConMediaType()), DbgNcsm(cle.ccfe.GetNetConSubMediaType()), DbgNcs(cle.ccfe.GetNetConStatus()), DbgNccf(cle.ccfe.GetCharacteristics()));
  249. #endif
  250. // Very important to release the lock before doing any thing which
  251. // calls back into the shell. (e.g. GenerateEvent)
  252. const CONFOLDENTRY &ccfe = cle.ccfe;
  253. // Get the pidl for the connection so we can use it to notify
  254. // the shell further below.
  255. //
  256. ccfe.ConvertToPidl(pidlFind);
  257. // Remove this connection from the global list while we
  258. // have the lock held.
  259. //
  260. hr = g_ccl.HrRemove(cle.ccfe, &fFlushPosts);
  261. }
  262. else
  263. {
  264. TraceTag(ttidShellFolder, "Notify: Delete <item not found in cache>. hr = 0x%08x", hr);
  265. }
  266. // If we need to flush the posts after making tray icon changes, do so
  267. //
  268. if (g_hwndTray && fFlushPosts)
  269. {
  270. FlushTrayPosts(g_hwndTray);
  271. }
  272. if (SUCCEEDED(hr) && (!pidlFind.empty()))
  273. {
  274. GenerateEvent(SHCNE_DELETE, m_pidlFolder, pidlFind, NULL);
  275. }
  276. if (SUCCEEDED(hr))
  277. {
  278. hr = HrUpdateIncomingConnection();
  279. }
  280. // Only return S_OK from here.
  281. //
  282. return S_OK;
  283. }
  284. HRESULT
  285. CConnectionNotifySink::ConnectionModified (
  286. IN const NETCON_PROPERTIES_EX* pPropsEx)
  287. {
  288. TraceFileFunc(ttidNotifySink);
  289. Assert(pPropsEx);
  290. Assert(!m_pidlFolder.empty());
  291. #ifdef DBG
  292. OLECHAR szGuidString[MAX_GUID_STRING_LEN];
  293. StringFromGUID2(pPropsEx->guidId, szGuidString, MAX_GUID_STRING_LEN);
  294. TraceTag(ttidNotifySink, "INetConnectionNotifySink::ConnectionModified - %S %S [%s:%s:%s:%s]", szGuidString, pPropsEx->bstrName,
  295. DbgNcm(pPropsEx->ncMediaType), DbgNcsm(pPropsEx->ncSubMediaType), DbgNcs(pPropsEx->ncStatus), DbgNccf(pPropsEx->dwCharacter));
  296. #endif
  297. if (g_dwCurrentEventLevel <= EVT_LVL_ENABLE_PRIVATE)
  298. {
  299. TraceTag(ttidNotifySink, "Last event ignored due to g_dwCurrentEventLevel == %d", g_dwCurrentEventLevel);
  300. return S_FALSE;
  301. }
  302. // Get the result for debugging only. We never want to fail this function
  303. //
  304. HRESULT hrTmp = HrOnNotifyUpdateConnection(
  305. m_pidlFolder,
  306. (GUID *)&(pPropsEx->guidId),
  307. pPropsEx->ncMediaType,
  308. pPropsEx->ncSubMediaType,
  309. pPropsEx->ncStatus,
  310. pPropsEx->dwCharacter,
  311. pPropsEx->bstrName,
  312. pPropsEx->bstrDeviceName,
  313. pPropsEx->bstrPhoneOrHostAddress);
  314. return S_OK;
  315. }
  316. HRESULT
  317. CConnectionNotifySink::ConnectionRenamed (
  318. IN const GUID* pguidId,
  319. IN PCWSTR pszwNewName)
  320. {
  321. TraceFileFunc(ttidNotifySink);
  322. HRESULT hr = S_OK;
  323. PCONFOLDPIDL pidlNew;
  324. Assert(pguidId);
  325. Assert(pszwNewName);
  326. if (g_dwCurrentEventLevel <= EVT_LVL_DISABLE_ALL)
  327. {
  328. TraceTag(ttidNotifySink, "CConnectionNotifySink::ConnectionRenamed event ignored due to g_dwCurrentEventLevel == %d", g_dwCurrentEventLevel);
  329. return S_FALSE;
  330. }
  331. // Update the name in the cache
  332. //
  333. // Note: There exists a race condition with shutil.cpp:
  334. // HrRenameConnectionInternal\HrUpdateNameByGuid can also update the cache.
  335. ConnListEntry cle;
  336. hr = g_ccl.HrFindConnectionByGuid(pguidId, cle);
  337. if (FAILED(hr))
  338. {
  339. return E_INVALIDARG;
  340. }
  341. #ifdef DBG
  342. OLECHAR szGuidString[MAX_GUID_STRING_LEN];
  343. StringFromGUID2(cle.ccfe.GetGuidID(), szGuidString, MAX_GUID_STRING_LEN);
  344. TraceTag(ttidNotifySink, "INetConnectionNotifySink::ConnectionRenamed - %S %S (to %S) [%s:%s:%s:%s]", szGuidString, cle.ccfe.GetName(), pszwNewName,
  345. DbgNcm(cle.ccfe.GetNetConMediaType()), DbgNcsm(cle.ccfe.GetNetConSubMediaType()), DbgNcs(cle.ccfe.GetNetConStatus()), DbgNccf(cle.ccfe.GetCharacteristics()));
  346. #endif
  347. hr = g_ccl.HrUpdateNameByGuid(
  348. (GUID *) pguidId,
  349. (PWSTR) pszwNewName,
  350. pidlNew,
  351. TRUE); // Force the update -- this is a notification, not a request
  352. if (S_OK == hr)
  353. {
  354. PCONFOLDPIDL pidl;
  355. cle.ccfe.ConvertToPidl(pidl);
  356. GenerateEvent(
  357. SHCNE_RENAMEITEM,
  358. m_pidlFolder,
  359. pidl,
  360. pidlNew.GetItemIdList());
  361. // Update status monitor title (RAS case)
  362. CNetStatisticsCentral * pnsc = NULL;
  363. hr = CNetStatisticsCentral::HrGetNetStatisticsCentral(&pnsc, FALSE);
  364. if (SUCCEEDED(hr))
  365. {
  366. pnsc->UpdateTitle(pguidId, pszwNewName);
  367. ReleaseObj(pnsc);
  368. }
  369. }
  370. else
  371. {
  372. // If the connection wasn't found in the cache, then it's likely that
  373. // the notification engine is giving us a notification for a connection
  374. // that hasn't yet been given to us.
  375. //
  376. if (S_FALSE == hr)
  377. {
  378. TraceHr(ttidShellFolder, FAL, hr, FALSE, "Rename notification received on a connection we don't know about");
  379. }
  380. }
  381. return S_OK;
  382. }
  383. HRESULT
  384. CConnectionNotifySink::ConnectionStatusChange (
  385. IN const GUID* pguidId,
  386. IN NETCON_STATUS Status)
  387. {
  388. TraceFileFunc(ttidNotifySink);
  389. HRESULT hr = S_OK;
  390. HRESULT hrFind = S_OK;
  391. PCONFOLDPIDL pidlFind;
  392. if (g_dwCurrentEventLevel <= EVT_LVL_ENABLE_PRIVATE)
  393. {
  394. TraceTag(ttidNotifySink, "CConnectionNotifySink::ConnectionStatusChange event ignored due to g_dwCurrentEventLevel == %d", g_dwCurrentEventLevel);
  395. return S_FALSE;
  396. }
  397. // Find the connection using the GUID. Cast the const away from the GUID
  398. //
  399. hrFind = g_ccl.HrFindPidlByGuid((GUID *) pguidId, pidlFind);
  400. if( S_OK != hrFind )
  401. {
  402. GUID guidOwner;
  403. // We did not find the guid in connection folder. Try finding the connection in the
  404. // hidden connectiod list on netmans side.
  405. //
  406. hr = g_ccl.HrMapCMHiddenConnectionToOwner(*pguidId, &guidOwner);
  407. if (S_OK == hr)
  408. {
  409. // The conection has a parent!!!! Use the childs status instead of the parents status.
  410. //
  411. if (Status == NCS_CONNECTED)
  412. {
  413. // This means that the child has connected and the parent still has to connect
  414. // the overall status should stay as connected. This was done to overrule the Multi-link
  415. // hack in HrOnNotifyUpdateStatus. If we did not do this it would say :
  416. // Child( Connecting, Connected) and then Parent(Connecting, Connected)
  417. //
  418. Status = NCS_CONNECTING;
  419. }
  420. // Get the pidl of the parent.
  421. //
  422. hrFind = g_ccl.HrFindPidlByGuid(&guidOwner, pidlFind);
  423. }
  424. }
  425. if (S_OK == hrFind)
  426. {
  427. #ifdef DBG
  428. OLECHAR szGuidString[MAX_GUID_STRING_LEN];
  429. StringFromGUID2(pidlFind->guidId, szGuidString, MAX_GUID_STRING_LEN);
  430. TraceTag(ttidNotifySink, "INetConnectionNotifySink::ConnectionStatusChange - %S %S [%s:%s:%s:%s]", szGuidString, pidlFind->PszGetNamePointer(),
  431. DbgNcm(pidlFind->ncm), DbgNcsm(pidlFind->ncsm), DbgNcs(Status), DbgNccf(pidlFind->dwCharacteristics));
  432. #endif
  433. hr = HrOnNotifyUpdateStatus(m_pidlFolder, pidlFind, Status);
  434. }
  435. return S_OK;
  436. }
  437. HRESULT
  438. CConnectionNotifySink::RefreshAll ()
  439. {
  440. TraceFileFunc(ttidNotifySink);
  441. #ifdef DBG
  442. TraceTag(ttidNotifySink, "INetConnectionNotifySink::RefreshAll");
  443. #endif
  444. if (g_dwCurrentEventLevel <= EVT_LVL_DISABLE_ALL)
  445. {
  446. TraceTag(ttidNotifySink, "Last event ignored due to g_dwCurrentEventLevel == %d", g_dwCurrentEventLevel);
  447. return S_FALSE;
  448. }
  449. // Refresh the connections folder, without having to hook the shell view.
  450. // In this case, we do a non-flush refresh where we compare the new set
  451. // of items to the cached set and do the merge (with the correct set
  452. // of individual notifications).
  453. //
  454. (VOID) HrForceRefreshNoFlush(m_pidlFolder);
  455. return S_OK;
  456. }
  457. HRESULT CConnectionNotifySink::ConnectionAddressChange (
  458. IN const GUID* pguidId )
  459. {
  460. // Find the connection using the GUID.
  461. //
  462. PCONFOLDPIDL pidlFind;
  463. HRESULT hr = g_ccl.HrFindPidlByGuid(pguidId, pidlFind);
  464. if (S_OK != hr)
  465. {
  466. return E_INVALIDARG;
  467. }
  468. #ifdef DBG
  469. OLECHAR szGuidString[MAX_GUID_STRING_LEN];
  470. StringFromGUID2(pidlFind->guidId, szGuidString, MAX_GUID_STRING_LEN);
  471. TraceTag(ttidNotifySink, "INetConnectionNotifySink::ConnectionAddressChange - %S %S [%s:%s:%s:%s]", szGuidString, pidlFind->PszGetNamePointer(),
  472. DbgNcm(pidlFind->ncm), DbgNcsm(pidlFind->ncsm), DbgNcs(pidlFind->ncs), DbgNccf(pidlFind->dwCharacteristics));
  473. #endif
  474. if (g_dwCurrentEventLevel <= EVT_LVL_DISABLE_ALL)
  475. {
  476. TraceTag(ttidNotifySink, "Last event ignored due to g_dwCurrentEventLevel == %d", g_dwCurrentEventLevel);
  477. return S_FALSE;
  478. }
  479. PCONFOLDPIDLFOLDER pidlFolder;
  480. hr = HrGetConnectionsFolderPidl(pidlFolder);
  481. if (SUCCEEDED(hr))
  482. {
  483. GenerateEvent(SHCNE_UPDATEITEM, pidlFolder, pidlFind, NULL);
  484. }
  485. return hr;
  486. }
  487. DWORD WINAPI OnTaskBarIconBalloonClickThread(IN LPVOID lpParam);
  488. STDMETHODIMP CConnectionNotifySink::ShowBalloon(
  489. IN const GUID* pguidId,
  490. IN const BSTR szCookie,
  491. IN const BSTR szBalloonText)
  492. {
  493. HRESULT hr;
  494. #ifdef DBG
  495. OLECHAR szGuidString[MAX_GUID_STRING_LEN];
  496. StringFromGUID2(*pguidId, szGuidString, MAX_GUID_STRING_LEN);
  497. TraceTag(ttidNotifySink, "INetConnectionNotifySink::ShowBalloon - %S (%S)", szGuidString, szBalloonText);
  498. #endif
  499. if (g_dwCurrentEventLevel <= EVT_LVL_DISABLE_ALL)
  500. {
  501. TraceTag(ttidNotifySink, "Last event ignored due to g_dwCurrentEventLevel == %d", g_dwCurrentEventLevel);
  502. return S_FALSE;
  503. }
  504. CComBSTR szBalloonTextTmp = szBalloonText;
  505. BSTR szCookieTmp = NULL;
  506. if (szCookie)
  507. {
  508. szCookieTmp = SysAllocStringByteLen(reinterpret_cast<LPCSTR>(szCookie), SysStringByteLen(szCookie));
  509. if (szCookieTmp)
  510. {
  511. ConnListEntry cleFind;
  512. hr = g_ccl.HrFindConnectionByGuid(pguidId, cleFind);
  513. if (S_OK == hr)
  514. {
  515. hr = WZCCanShowBalloon(pguidId, cleFind.ccfe.GetName(), &szBalloonTextTmp, &szCookieTmp);
  516. if ( (S_OK == hr) || (S_OBJECT_NO_LONGER_VALID == hr) )
  517. {
  518. CTrayBalloon *pTrayBalloon = new CTrayBalloon();
  519. if (!pTrayBalloon)
  520. {
  521. hr = E_OUTOFMEMORY;
  522. }
  523. else
  524. {
  525. pTrayBalloon->m_gdGuid = *pguidId;
  526. pTrayBalloon->m_dwTimeOut = 30 * 1000;
  527. pTrayBalloon->m_szMessage = szBalloonTextTmp;
  528. pTrayBalloon->m_pfnFuncCallback = WZCOnBalloonClick;
  529. pTrayBalloon->m_szCookie = szCookieTmp;
  530. pTrayBalloon->m_szAdapterName = cleFind.ccfe.GetName();
  531. if (S_OK == hr)
  532. {
  533. PostMessage(g_hwndTray, MYWM_SHOWBALLOON,
  534. NULL,
  535. (LPARAM) pTrayBalloon);
  536. }
  537. else // S_OBJECT_NO_LONGER_VALID == hr
  538. {
  539. CreateThread(NULL, STACK_SIZE_SMALL, OnTaskBarIconBalloonClickThread, pTrayBalloon, 0, NULL);
  540. }
  541. }
  542. }
  543. }
  544. if (S_OK != hr && S_OBJECT_NO_LONGER_VALID != hr)
  545. {
  546. SysFreeString(szCookieTmp);
  547. }
  548. }
  549. }
  550. TraceHr(ttidError, FAL, hr, FALSE,
  551. "CConnectionNotifySink::ShowBalloon");
  552. return hr;
  553. }
  554. UINT_PTR uipTimer = NULL;
  555. VOID CALLBACK EventTimerProc(
  556. IN HWND hwnd, // handle to window
  557. IN UINT uMsg, // WM_TIMER message
  558. IN UINT_PTR idEvent, // timer identifier
  559. IN DWORD dwTime // current system time
  560. )
  561. {
  562. HRESULT hr = S_OK;
  563. TraceTag(ttidNotifySink, "Refreshing the folder due to DisableEvents timeout reached");
  564. g_dwCurrentEventLevel = EVT_LVL_ENABLE_ALL;
  565. if (uipTimer)
  566. {
  567. KillTimer(NULL, uipTimer);
  568. uipTimer = NULL;
  569. }
  570. PCONFOLDPIDLFOLDER pcfpFolder;
  571. hr = HrGetConnectionsFolderPidl(pcfpFolder);
  572. if (SUCCEEDED(hr))
  573. {
  574. HrForceRefreshNoFlush(pcfpFolder);
  575. }
  576. }
  577. STDMETHODIMP CConnectionNotifySink::DisableEvents (
  578. IN const BOOL fDisable,
  579. IN const ULONG ulDisableTimeout)
  580. {
  581. #ifdef DBG
  582. TraceTag(ttidNotifySink, "INetConnectionNotifySink::DisableEvents - %s 0x%08x", fDisable ? "DISABLE" : "ENABLE", ulDisableTimeout);
  583. #endif
  584. HRESULT hr = S_OK;
  585. if (fDisable)
  586. {
  587. if (HIWORD(ulDisableTimeout) & 0x8000)
  588. {
  589. // Called from private interface - disable all the events
  590. g_dwCurrentEventLevel = EVT_LVL_DISABLE_ALL;
  591. }
  592. else
  593. {
  594. // Called from public interface - only disable connection modified & status change events
  595. g_dwCurrentEventLevel = EVT_LVL_ENABLE_PRIVATE;
  596. }
  597. UINT uiEventTimeOut = LOWORD(ulDisableTimeout);
  598. if (uipTimer)
  599. {
  600. KillTimer(NULL, uipTimer);
  601. uipTimer = NULL;
  602. }
  603. uipTimer = SetTimer(NULL, NULL, uiEventTimeOut, EventTimerProc);
  604. }
  605. else
  606. {
  607. g_dwCurrentEventLevel = EVT_LVL_ENABLE_ALL;
  608. if (uipTimer)
  609. {
  610. KillTimer(NULL, uipTimer);
  611. uipTimer = NULL;
  612. }
  613. else
  614. {
  615. hr = S_FALSE; // Timer no more.
  616. }
  617. HrForceRefreshNoFlush(m_pidlFolder);
  618. }
  619. return hr;
  620. }
  621. //+---------------------------------------------------------------------------
  622. //
  623. // Function: HrGetNotifyConPoint
  624. //
  625. // Purpose: Common code for getting the connection point for use in
  626. // NotifyAdd and NotifyRemove
  627. //
  628. // Arguments:
  629. // ppConPoint [out] Return ptr for IConnectionPoint
  630. //
  631. // Returns:
  632. //
  633. // Author: jeffspr 24 Aug 1998
  634. //
  635. // Notes:
  636. //
  637. HRESULT HrGetNotifyConPoint(
  638. IConnectionPoint ** ppConPoint)
  639. {
  640. TraceFileFunc(ttidNotifySink);
  641. HRESULT hr = S_OK;
  642. IConnectionPointContainer * pContainer = NULL;
  643. Assert(ppConPoint);
  644. // Get the debug interface from the connection manager
  645. //
  646. hr = HrCreateInstance(
  647. CLSID_ConnectionManager,
  648. CLSCTX_LOCAL_SERVER | CLSCTX_NO_CODE_DOWNLOAD,
  649. &pContainer);
  650. TraceHr(ttidError, FAL, hr, FALSE,
  651. "HrCreateInstance(CLSID_ConnectionManager) for IConnectionPointContainer");
  652. if (SUCCEEDED(hr))
  653. {
  654. IConnectionPoint * pConPoint = NULL;
  655. // Get the connection point itself and fill in the return param
  656. // on success
  657. //
  658. hr = pContainer->FindConnectionPoint(
  659. IID_INetConnectionNotifySink,
  660. &pConPoint);
  661. TraceHr(ttidError, FAL, hr, FALSE, "pContainer->FindConnectionPoint");
  662. if (SUCCEEDED(hr))
  663. {
  664. NcSetProxyBlanket (pConPoint);
  665. *ppConPoint = pConPoint;
  666. }
  667. ReleaseObj(pContainer);
  668. }
  669. TraceHr(ttidError, FAL, hr, FALSE, "HrGetNotifyConPoint");
  670. return hr;
  671. }