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.

273 lines
7.5 KiB

  1. //==============================================================;
  2. //
  3. // This source code is only intended as a supplement to
  4. // existing Microsoft documentation.
  5. //
  6. //
  7. //
  8. //
  9. // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
  10. // KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
  11. // IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
  12. // PURPOSE.
  13. //
  14. // Copyright (C) 1999 Microsoft Corporation. All Rights Reserved.
  15. //
  16. //
  17. //
  18. //==============================================================;
  19. #include <stdio.h>
  20. #include "Backgrnd.h"
  21. const GUID CBackgroundFolder::thisGuid = { 0x2974380f, 0x4c4b, 0x11d2, { 0x89, 0xd8, 0x0, 0x0, 0x21, 0x47, 0x31, 0x28 } };
  22. const GUID CBackground::thisGuid = { 0x2974380f, 0x4c4b, 0x11d2, { 0x89, 0xd8, 0x0, 0x0, 0x21, 0x47, 0x31, 0x28 } };
  23. #define WM_NEWOBJECT WM_APP
  24. #define WM_DISCOVERYCOMPLETE (WM_APP + 1)
  25. //==============================================================
  26. //
  27. // CBackgroundFolder implementation
  28. //
  29. //
  30. CBackgroundFolder::CBackgroundFolder()
  31. : m_pConsoleNameSpace(NULL), m_scopeitem(0), m_threadId(0), m_thread(NULL),
  32. m_running(false), m_bViewUpdated(false)
  33. {
  34. ZeroMemory(m_children, sizeof(m_children));
  35. WNDCLASS wndClass;
  36. ZeroMemory(&wndClass, sizeof(WNDCLASS));
  37. wndClass.lpfnWndProc = WindowProc;
  38. wndClass.lpszClassName = _T("backgroundthreadwindow");
  39. wndClass.hInstance = g_hinst;
  40. ATOM atom = RegisterClass(&wndClass);
  41. m_backgroundHwnd = CreateWindow(
  42. _T("backgroundthreadwindow"), // pointer to registered class name
  43. NULL, // pointer to window name
  44. 0, // window style
  45. 0, // horizontal position of window
  46. 0, // vertical position of window
  47. 0, // window width
  48. 0, // window height
  49. NULL, // handle to parent or owner window
  50. NULL, // handle to menu or child-window identifier
  51. g_hinst, // handle to application instance
  52. (void *)this // pointer to window-creation data
  53. );
  54. if (m_backgroundHwnd)
  55. SetWindowLong(m_backgroundHwnd, GWL_USERDATA, (LONG)this);
  56. InitializeCriticalSection(&m_critSect);
  57. }
  58. CBackgroundFolder::~CBackgroundFolder()
  59. {
  60. StopThread();
  61. for (int n = 0; n < MAX_CHILDREN; n++)
  62. if (m_children[n] != NULL)
  63. delete m_children[n];
  64. if (m_backgroundHwnd != NULL)
  65. DestroyWindow(m_backgroundHwnd);
  66. UnregisterClass(_T("backgroundthreadwindow"), NULL);
  67. DeleteCriticalSection(&m_critSect);
  68. }
  69. LRESULT CALLBACK CBackgroundFolder::WindowProc(
  70. HWND hwnd, // handle to window
  71. UINT uMsg, // message identifier
  72. WPARAM wParam, // first message parameter
  73. LPARAM lParam // second message parameter
  74. )
  75. {
  76. CBackgroundFolder *pThis = (CBackgroundFolder *)GetWindowLong(hwnd, GWL_USERDATA);
  77. switch (uMsg) {
  78. case WM_NEWOBJECT:
  79. _ASSERT(pThis != NULL);
  80. pThis->AddItem(lParam);
  81. break;
  82. case WM_DISCOVERYCOMPLETE:
  83. _ASSERT(pThis != NULL);
  84. pThis->m_bViewUpdated = true;
  85. pThis->StopThread();
  86. break;
  87. }
  88. return DefWindowProc(hwnd, uMsg, wParam, lParam);
  89. }
  90. DWORD WINAPI CBackgroundFolder::ThreadProc(
  91. LPVOID lpParameter // thread data
  92. )
  93. {
  94. CBackgroundFolder *pThis = (CBackgroundFolder *)lpParameter;
  95. EnterCriticalSection(&pThis->m_critSect);
  96. pThis->m_running = true;
  97. LeaveCriticalSection(&pThis->m_critSect);
  98. for (int n = 0; n < MAX_CHILDREN; n++) {
  99. EnterCriticalSection(&pThis->m_critSect);
  100. bool running = pThis->m_running;
  101. LeaveCriticalSection(&pThis->m_critSect);
  102. if (running == false)
  103. return 0;
  104. PostMessage(pThis->m_backgroundHwnd, WM_NEWOBJECT, 0, n);
  105. Sleep(500);
  106. }
  107. PostMessage(pThis->m_backgroundHwnd, WM_DISCOVERYCOMPLETE, 0, 0);
  108. return 0;
  109. }
  110. void CBackgroundFolder::StartThread()
  111. {
  112. EnterCriticalSection(&m_critSect);
  113. m_thread = CreateThread(NULL, 0, ThreadProc, (void *)this, 0, &m_threadId);
  114. LeaveCriticalSection(&m_critSect);
  115. }
  116. void CBackgroundFolder::StopThread()
  117. {
  118. EnterCriticalSection(&m_critSect);
  119. m_running = false;
  120. if (m_thread != NULL) {
  121. // this is ugly, wait for 10 seconds, then kill the thread
  122. DWORD res = WaitForSingleObject(m_thread, 10000);
  123. if (res == WAIT_TIMEOUT)
  124. TerminateThread(m_thread, 0);
  125. CloseHandle(m_thread);
  126. m_thread = NULL;
  127. }
  128. LeaveCriticalSection(&m_critSect);
  129. }
  130. void CBackgroundFolder::AddItem(int id)
  131. {
  132. HRESULT hr;
  133. EnterCriticalSection(&m_critSect);
  134. _ASSERT(m_children[id] == NULL);
  135. m_children[id] = new CBackground(id);
  136. SCOPEDATAITEM sdi;
  137. // insert items here
  138. ZeroMemory(&sdi, sizeof(SCOPEDATAITEM));
  139. sdi.mask = SDI_STR | // Displayname is valid
  140. SDI_PARAM | // lParam is valid
  141. SDI_IMAGE | // nImage is valid
  142. SDI_OPENIMAGE | // nOpenImage is valid
  143. SDI_PARENT |
  144. SDI_CHILDREN;
  145. sdi.relativeID = (HSCOPEITEM)m_scopeitem;
  146. sdi.nImage = m_children[id]->GetBitmapIndex();
  147. sdi.nOpenImage = INDEX_OPENFOLDER;
  148. sdi.displayname = MMC_CALLBACK;
  149. sdi.lParam = (LPARAM)m_children[id]; // The cookie
  150. sdi.cChildren = 0;
  151. hr = m_pConsoleNameSpace->InsertItem( &sdi );
  152. _ASSERT( SUCCEEDED(hr) );
  153. m_children[id]->SetHandle((HANDLE)sdi.ID);
  154. LeaveCriticalSection(&m_critSect);
  155. return;
  156. }
  157. HRESULT CBackgroundFolder::OnAddImages(IImageList *pImageList, HSCOPEITEM hsi)
  158. {
  159. return pImageList->ImageListSetStrip((long *)m_pBMapSm, // pointer to a handle
  160. (long *)m_pBMapLg, // pointer to a handle
  161. 0, // index of the first image in the strip
  162. RGB(0, 128, 128) // color of the icon mask
  163. );
  164. }
  165. HRESULT CBackgroundFolder::OnExpand(IConsoleNameSpace *pConsoleNameSpace, IConsole *pConsole, HSCOPEITEM parent)
  166. {
  167. // cache the stuff
  168. m_pConsoleNameSpace = pConsoleNameSpace;
  169. m_scopeitem = parent;
  170. if (m_bViewUpdated == false && m_running == false)
  171. StartThread();
  172. return S_OK;
  173. }
  174. HRESULT CBackgroundFolder::OnSelect(IConsole *pConsole, BOOL bScope, BOOL bSelect)
  175. {
  176. m_bSelected = (bSelect && bScope) ? true : false;
  177. if (bSelect && !m_running) {
  178. IConsoleVerb *pConsoleVerb;
  179. HRESULT hr = pConsole->QueryConsoleVerb(&pConsoleVerb);
  180. _ASSERT(SUCCEEDED(hr));
  181. hr = pConsoleVerb->SetVerbState(MMC_VERB_REFRESH, ENABLED, TRUE);
  182. pConsoleVerb->Release();
  183. }
  184. return S_OK;
  185. }
  186. HRESULT CBackgroundFolder::OnRefresh()
  187. {
  188. HRESULT hr = S_OK;
  189. StopThread();
  190. EnterCriticalSection(&m_critSect);
  191. for (int n = 0; n < MAX_CHILDREN; n++) {
  192. if (m_children[n] != NULL) {
  193. HSCOPEITEM hItem = (HSCOPEITEM)m_children[n]->GetHandle();
  194. hr = m_pConsoleNameSpace->DeleteItem(hItem, TRUE);
  195. delete m_children[n];
  196. m_children[n] = NULL;
  197. }
  198. }
  199. LeaveCriticalSection(&m_critSect);
  200. m_bViewUpdated = false;
  201. StartThread();
  202. return S_OK;
  203. }
  204. const _TCHAR *CBackground::GetDisplayName(int nCol)
  205. {
  206. static _TCHAR buf[128];
  207. _stprintf(buf, _T("Background object #%d"), m_id);
  208. return buf;
  209. }