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.

197 lines
4.8 KiB

  1. #include "stdafx.h"
  2. #include "stobject.h"
  3. #include "systray.h"
  4. #include <initguid.h>
  5. // 7007ACCF-3202-11D1-AAD2-00805FC1270E CLSID_ConnectionTray
  6. DEFINE_GUID(CLSID_ConnectionTray, 0x7007ACCF,0x3202,0x11D1,0xAA,0xD2,0x00,0x80,0x5F,0xC1,0x27,0x0E);
  7. IOleCommandTarget *g_pctNetShell = NULL;
  8. extern "C"
  9. {
  10. void StartNetShell()
  11. {
  12. ASSERT(!g_pctNetShell);
  13. HRESULT hr = CoCreateInstance(CLSID_ConnectionTray, NULL, CLSCTX_INPROC_SERVER,
  14. IID_IOleCommandTarget, (void **)&g_pctNetShell);
  15. if (SUCCEEDED(hr))
  16. {
  17. g_pctNetShell->Exec(&CGID_ShellServiceObject, SSOCMDID_OPEN, 0, NULL, NULL);
  18. }
  19. }
  20. void StopNetShell()
  21. {
  22. if (g_pctNetShell)
  23. {
  24. g_pctNetShell->Exec(&CGID_ShellServiceObject, SSOCMDID_CLOSE, 0, NULL, NULL);
  25. g_pctNetShell->Release();
  26. g_pctNetShell = NULL;
  27. }
  28. }
  29. } // extern C
  30. /************************************************************************************
  31. IUnknown Implementation
  32. ************************************************************************************/
  33. HRESULT CSysTray::QueryInterface(REFIID iid, void** ppvObject)
  34. {
  35. HRESULT hr = S_OK;
  36. if ((iid == IID_IOleCommandTarget) || (iid == IID_IUnknown))
  37. {
  38. *ppvObject = (IOleCommandTarget*) this;
  39. }
  40. else
  41. {
  42. *ppvObject = NULL;
  43. hr = E_NOINTERFACE;
  44. }
  45. if (hr == S_OK)
  46. {
  47. ((IUnknown*) (*ppvObject))->AddRef();
  48. }
  49. return hr;
  50. }
  51. ULONG CSysTray::AddRef()
  52. {
  53. return InterlockedIncrement(&m_cRef);
  54. }
  55. ULONG CSysTray::Release()
  56. {
  57. ASSERT( 0 != m_cRef );
  58. ULONG cRef = InterlockedDecrement(&m_cRef);
  59. if ( 0 == cRef )
  60. {
  61. delete this;
  62. }
  63. return cRef;
  64. }
  65. /************************************************************************************
  66. IOleCommandTarget Implementation
  67. ************************************************************************************/
  68. HRESULT CSysTray::QueryStatus(const GUID* pguidCmdGroup, ULONG cCmds, OLECMD prgCmds[], OLECMDTEXT* pCmdText)
  69. {
  70. HRESULT hr = OLECMDERR_E_UNKNOWNGROUP;
  71. if (*pguidCmdGroup == CGID_ShellServiceObject)
  72. {
  73. // We like Shell Service Object notifications...
  74. hr = S_OK;
  75. }
  76. return hr;
  77. }
  78. HRESULT CSysTray::Exec(const GUID* pguidCmdGroup, DWORD nCmdID, DWORD nCmdExecOpt, VARIANTARG* pvaIn, VARIANTARG* pvaOut)
  79. {
  80. HRESULT hr = OLECMDERR_E_UNKNOWNGROUP;
  81. if (*pguidCmdGroup == CGID_ShellServiceObject)
  82. {
  83. // Handle Shell Service Object notifications here.
  84. switch (nCmdID)
  85. {
  86. case SSOCMDID_OPEN:
  87. hr = CreateSysTrayThread();
  88. break;
  89. case SSOCMDID_CLOSE:
  90. hr = DestroySysTrayWindow();
  91. break;
  92. default:
  93. hr = S_OK;
  94. break;
  95. }
  96. }
  97. return hr;
  98. }
  99. /************************************************************************************
  100. Constructor/Destructor Implementation
  101. ************************************************************************************/
  102. CSysTray::CSysTray(BOOL fRunTrayOnConstruct)
  103. {
  104. m_cRef = 1;
  105. InterlockedIncrement(&g_cLocks);
  106. if (fRunTrayOnConstruct)
  107. {
  108. // We are being called through SHLoadInProc - Launch the systray thread immediately
  109. CreateSysTrayThread();
  110. }
  111. }
  112. CSysTray::~CSysTray()
  113. {
  114. ASSERT( 0 != g_cLocks );
  115. InterlockedDecrement(&g_cLocks);
  116. }
  117. /************************************************************************************
  118. Private Function Implementation
  119. ************************************************************************************/
  120. HRESULT CSysTray::CreateSysTrayThread()
  121. {
  122. HRESULT hr = S_OK;
  123. HANDLE hThread;
  124. DWORD dwThreadId;
  125. hThread = CreateThread(NULL, 0, CSysTray::SysTrayThreadProc, NULL, 0, &dwThreadId);
  126. if (hThread != NULL)
  127. {
  128. CloseHandle(hThread);
  129. }
  130. else
  131. hr = E_FAIL;
  132. return hr;
  133. }
  134. DWORD CSysTray::SysTrayThreadProc(void* lpv)
  135. {
  136. // We pass a "" for the command line to so that the tray applets don't start.
  137. TCHAR szModule[MAX_PATH];
  138. GetModuleFileName(g_hinstDll, szModule, ARRAYSIZE(szModule));
  139. HINSTANCE hInstThis = LoadLibrary(szModule);
  140. int Result = SysTrayMain(g_hinstDll, NULL, TEXT(""), SW_SHOWNORMAL);
  141. FreeLibraryAndExitThread(hInstThis, (DWORD) Result);
  142. // Never gets here
  143. return 0;
  144. }
  145. HRESULT CSysTray::DestroySysTrayWindow()
  146. {
  147. HWND hExistWnd = FindWindow(SYSTRAY_CLASSNAME, NULL);
  148. if (hExistWnd)
  149. {
  150. // Destroy the window. Note that we can't use DestroyWindow since
  151. // the window is on a different thread and DestroyWindow fails.
  152. SendMessage(hExistWnd, WM_CLOSE, 0, 0);
  153. }
  154. return S_OK;
  155. }