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.

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