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.

312 lines
7.9 KiB

  1. //
  2. // Driver Verifier UI
  3. // Copyright (c) Microsoft Corporation, 1999
  4. //
  5. //
  6. //
  7. // module: SlowDlg.cpp
  8. // author: DMihai
  9. // created: 11/1/00
  10. //
  11. // Description:
  12. //
  13. #include "stdafx.h"
  14. #include "verifier.h"
  15. #include "SlowDlg.h"
  16. #include "VrfUtil.h"
  17. #include "VGlobal.h"
  18. #ifdef _DEBUG
  19. #define new DEBUG_NEW
  20. #undef THIS_FILE
  21. static char THIS_FILE[] = __FILE__;
  22. #endif
  23. /////////////////////////////////////////////////////////////////////////////
  24. // CSlowProgressDlg dialog
  25. CSlowProgressDlg::CSlowProgressDlg( CWnd* pParent /*=NULL*/ )
  26. : CDialog(CSlowProgressDlg::IDD, pParent)
  27. {
  28. //{{AFX_DATA_INIT(CSlowProgressDlg)
  29. // NOTE: the ClassWizard will add member initialization here
  30. //}}AFX_DATA_INIT
  31. m_hWorkerThread = NULL;
  32. //
  33. // Create the event used for killing the worker thread
  34. //
  35. m_hKillThreadEvent = CreateEvent(
  36. NULL,
  37. TRUE,
  38. FALSE,
  39. NULL );
  40. }
  41. CSlowProgressDlg::~CSlowProgressDlg()
  42. {
  43. if( NULL != m_hKillThreadEvent )
  44. {
  45. CloseHandle( m_hKillThreadEvent );
  46. }
  47. }
  48. void CSlowProgressDlg::DoDataExchange(CDataExchange* pDX)
  49. {
  50. CDialog::DoDataExchange(pDX);
  51. //{{AFX_DATA_MAP(CSlowProgressDlg)
  52. DDX_Control(pDX, IDC_UNSIGNED_PROGRESS, m_ProgressCtl);
  53. DDX_Control(pDX, IDC_UNSIGNED_STATIC, m_CurrentActionStatic);
  54. //}}AFX_DATA_MAP
  55. }
  56. BEGIN_MESSAGE_MAP(CSlowProgressDlg, CDialog)
  57. //{{AFX_MSG_MAP(CSlowProgressDlg)
  58. ON_BN_CLICKED(IDC_UNSIGNED_CANCEL_BUTTON, OnCancelButton)
  59. ON_WM_SHOWWINDOW()
  60. ON_WM_HELPINFO()
  61. //}}AFX_MSG_MAP
  62. END_MESSAGE_MAP()
  63. /////////////////////////////////////////////////////////////////////////////
  64. DWORD WINAPI CSlowProgressDlg::LoadDriverDataWorkerThread( PVOID p )
  65. {
  66. CSlowProgressDlg *pThis;
  67. pThis = (CSlowProgressDlg *)p;
  68. //
  69. // Cannot ASSERT_VALID for a CWnd from a thread that didn't create the window in MFC...
  70. //
  71. ASSERT( NULL != pThis );
  72. //
  73. // Load all the drivers information (name, version, etc.)
  74. // if we haven't don that already
  75. //
  76. g_NewVerifierSettings.m_DriversSet.LoadAllDriversData( pThis->m_hKillThreadEvent,
  77. pThis->m_ProgressCtl );
  78. //
  79. // Done - hide the "slow progress" dialog and press the wizard "next" button
  80. //
  81. pThis->ShowWindow( SW_HIDE );
  82. if( g_NewVerifierSettings.m_DriversSet.m_bDriverDataInitialized )
  83. {
  84. AfxGetMainWnd()->PostMessage(PSM_PRESSBUTTON, (WPARAM)PSBTN_NEXT, 0) ;
  85. }
  86. return 0;
  87. }
  88. /////////////////////////////////////////////////////////////////////////////
  89. DWORD WINAPI CSlowProgressDlg::SearchUnsignedDriversWorkerThread( PVOID p )
  90. {
  91. CSlowProgressDlg *pThis;
  92. pThis = (CSlowProgressDlg *)p;
  93. //
  94. // Cannot ASSERT_VALID for a CWnd from a thread that didn't create the window in MFC...
  95. //
  96. ASSERT( NULL != pThis );
  97. //
  98. // Find out the unsigned drivers if we didn't do that already
  99. //
  100. g_NewVerifierSettings.m_DriversSet.FindUnsignedDrivers( pThis->m_hKillThreadEvent,
  101. pThis->m_ProgressCtl );
  102. //
  103. // Done - hide the "slow progress" dialog and press the wizard "next" button
  104. //
  105. pThis->ShowWindow( SW_HIDE );
  106. if( g_NewVerifierSettings.m_DriversSet.m_bUnsignedDriverDataInitialized )
  107. {
  108. AfxGetMainWnd()->PostMessage(PSM_PRESSBUTTON, (WPARAM)PSBTN_NEXT, 0) ;
  109. }
  110. return 0;
  111. }
  112. /////////////////////////////////////////////////////////////////////////////
  113. BOOL CSlowProgressDlg::StartWorkerThread( LPTHREAD_START_ROUTINE pThreadStart,
  114. ULONG uMessageResourceId )
  115. {
  116. DWORD dwThreadId;
  117. CString strWorkMessage;
  118. //
  119. // Load a description of the current "work item"
  120. // and show it to the user
  121. //
  122. VERIFY( strWorkMessage.LoadString( uMessageResourceId ) );
  123. m_CurrentActionStatic.SetWindowText( strWorkMessage );
  124. m_CurrentActionStatic.RedrawWindow();
  125. //
  126. // Kill a possible currently running worker thread
  127. //
  128. KillWorkerThread();
  129. ASSERT( NULL == m_hWorkerThread );
  130. //
  131. // Make sure the "kill thread" event is not signaled
  132. //
  133. if( NULL != m_hKillThreadEvent )
  134. {
  135. ResetEvent( m_hKillThreadEvent );
  136. }
  137. //
  138. // Create the new worker thread
  139. //
  140. m_hWorkerThread = CreateThread(
  141. NULL,
  142. 0,
  143. pThreadStart,
  144. this,
  145. 0,
  146. &dwThreadId );
  147. if( NULL == m_hWorkerThread )
  148. {
  149. //
  150. // Could not create the worker thread - bail out
  151. //
  152. VrfErrorResourceFormat( IDS_NOT_ENOUGH_MEMORY );
  153. PostMessage( WM_COMMAND,
  154. IDC_UNSIGNED_CANCEL_BUTTON );
  155. return FALSE;
  156. }
  157. return TRUE;
  158. }
  159. /////////////////////////////////////////////////////////////////////////////
  160. VOID CSlowProgressDlg::KillWorkerThread()
  161. {
  162. DWORD dwWaitResult;
  163. MSG msg;
  164. if( NULL != m_hWorkerThread )
  165. {
  166. if( NULL != m_hKillThreadEvent )
  167. {
  168. //
  169. // Ask the worker thread to die asap
  170. //
  171. SetEvent( m_hKillThreadEvent );
  172. }
  173. //
  174. // Wait forever for a decent death from the worker thread.
  175. //
  176. // We cannot TerminateThread on our worker thread because
  177. // it could be killed while holding locks (e.g. the heap lock)
  178. // and that would deadlock our whole process.
  179. //
  180. while( m_hWorkerThread != NULL )
  181. {
  182. dwWaitResult = MsgWaitForMultipleObjects( 1,
  183. &m_hWorkerThread,
  184. FALSE,
  185. INFINITE,
  186. QS_ALLINPUT );
  187. ASSERT( NULL != WAIT_FAILED );
  188. if( WAIT_OBJECT_0 != dwWaitResult )
  189. {
  190. //
  191. // Our thread didn't exit but we have some messages to dispatch.
  192. //
  193. while( PeekMessage( &msg, NULL, NULL, NULL, PM_REMOVE ) )
  194. {
  195. TranslateMessage( &msg );
  196. DispatchMessage( &msg );
  197. }
  198. //
  199. // During the DispatchMessage above we could process another
  200. // click of the Cancel button or the Back button of the wizard.
  201. // The KillWorkerThread recursive call will wait until the worker
  202. // thread dies then will sets m_hWorkerThread to NULL.
  203. // So we need to check for m_hWorkerThread != NULL before each new
  204. // MsgWaitForMultipleObjects.
  205. //
  206. }
  207. else
  208. {
  209. //
  210. // The worker thread finished execution.
  211. //
  212. break;
  213. }
  214. }
  215. if( m_hWorkerThread != NULL )
  216. {
  217. //
  218. // Close the thread handle
  219. //
  220. CloseHandle( m_hWorkerThread );
  221. m_hWorkerThread = NULL;
  222. }
  223. }
  224. }
  225. /////////////////////////////////////////////////////////////////////////////
  226. // CSlowProgressDlg message handlers
  227. void CSlowProgressDlg::OnCancelButton()
  228. {
  229. KillWorkerThread();
  230. ShowWindow( SW_HIDE );
  231. }
  232. /////////////////////////////////////////////////////////////////////////////
  233. void CSlowProgressDlg::OnShowWindow(BOOL bShow, UINT nStatus)
  234. {
  235. CDialog::OnShowWindow(bShow, nStatus);
  236. if( TRUE == bShow )
  237. {
  238. CenterWindow();
  239. }
  240. }
  241. /////////////////////////////////////////////////////////////////////////////
  242. BOOL CSlowProgressDlg::OnHelpInfo(HELPINFO* pHelpInfo)
  243. {
  244. return TRUE;
  245. }