Source code of Windows XP (NT5)
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.

293 lines
9.8 KiB

  1. // acqmgr.h : Declaration of the CAcquisitionManager
  2. #ifndef __AcquisitionManager_H_INCLUDED
  3. #define __AcquisitionManager_H_INCLUDED
  4. #include "resource.h" // main symbols
  5. #include "acqthrd.h"
  6. #include "shmemsec.h"
  7. #include "mintrans.h"
  8. #include "stievent.h"
  9. //
  10. // Number of times we will spin before giving up on
  11. // getting the window of the previous wizard's instance
  12. //
  13. const int c_nMaxActivationRetryCount = 40;
  14. //
  15. // Amount of time to wait between efforts to obtain the previous
  16. // wizard's instance
  17. //
  18. const DWORD c_nActivationRetryWait = 500;
  19. /////////////////////////////////////////////////////////////////////////////
  20. // CAcquisitionManager
  21. class ATL_NO_VTABLE CAcquisitionManager :
  22. public CComObjectRootEx<CComSingleThreadModel>,
  23. public CComCoClass<CAcquisitionManager, &CLSID_AcquisitionManager>,
  24. public IWiaEventCallback
  25. {
  26. public:
  27. CAcquisitionManager()
  28. {
  29. }
  30. ~CAcquisitionManager()
  31. {
  32. }
  33. DECLARE_REGISTRY_RESOURCEID(IDR_ACQUISITIONMANAGER)
  34. DECLARE_PROTECT_FINAL_CONSTRUCT()
  35. BEGIN_COM_MAP(CAcquisitionManager)
  36. COM_INTERFACE_ENTRY(IWiaEventCallback)
  37. END_COM_MAP()
  38. public:
  39. // IManager
  40. HRESULT STDMETHODCALLTYPE ImageEventCallback( const GUID *pEventGUID,
  41. BSTR bstrEventDescription,
  42. BSTR bstrDeviceID,
  43. BSTR bstrDeviceDescription,
  44. DWORD dwDeviceType,
  45. BSTR bstrFullItemName,
  46. ULONG *pulEventType,
  47. ULONG ulReserved
  48. )
  49. {
  50. WIA_PUSHFUNCTION((TEXT("CAcquisitionManager::ImageEventCallback")));
  51. //
  52. // Don't want to run if this is a scanner connection event
  53. //
  54. if (pEventGUID && *pEventGUID==WIA_EVENT_DEVICE_CONNECTED && GET_STIDEVICE_TYPE(dwDeviceType)==StiDeviceTypeScanner)
  55. {
  56. return S_FALSE;
  57. }
  58. //
  59. // Try to create or open the shared memory section.
  60. //
  61. CSharedMemorySection<HWND> *pWizardSharedMemory = new CSharedMemorySection<HWND>;
  62. if (pWizardSharedMemory)
  63. {
  64. //
  65. // Assume we'll be running the wizard.
  66. //
  67. bool bRun = true;
  68. //
  69. // If we were able to open the memory section
  70. //
  71. if (CSharedMemorySection<HWND>::SmsOpened == pWizardSharedMemory->Open( CSimpleStringConvert::NaturalString(CSimpleStringWide(bstrDeviceID)), true ))
  72. {
  73. //
  74. // Try to get the previous instance
  75. //
  76. for (int i=0;i<c_nMaxActivationRetryCount;i++)
  77. {
  78. //
  79. // if we were able to open the shared memory section, there is already one running.
  80. // so get a mutex'ed pointer to the shared memory.
  81. //
  82. HWND *pHwnd = pWizardSharedMemory->Lock();
  83. if (pHwnd)
  84. {
  85. //
  86. // If we were able to get the pointer, get the window handle stored in it.
  87. // Set bRun to false, so we don't start up a new wizard
  88. //
  89. bRun = false;
  90. if (*pHwnd && IsWindow(*pHwnd))
  91. {
  92. //
  93. // If it is a valid window, bring it to the foreground.
  94. //
  95. SetForegroundWindow(*pHwnd);
  96. }
  97. //
  98. // Release the mutex
  99. //
  100. pWizardSharedMemory->Release();
  101. //
  102. // We found the window the window handle, so we can exit the loop now.
  103. //
  104. break;
  105. }
  106. //
  107. // Wait a while for the previous instance to be created
  108. //
  109. Sleep(c_nActivationRetryWait);
  110. }
  111. }
  112. //
  113. // We only do this if we need to open a new instance
  114. //
  115. if (bRun)
  116. {
  117. //
  118. // Prepare the event data
  119. //
  120. CEventParameters EventParameters;
  121. EventParameters.EventGUID = *pEventGUID;
  122. EventParameters.strEventDescription = static_cast<LPCWSTR>(bstrEventDescription);
  123. EventParameters.strDeviceID = static_cast<LPCWSTR>(bstrDeviceID);
  124. EventParameters.strDeviceDescription = static_cast<LPCWSTR>(bstrDeviceDescription);
  125. EventParameters.ulReserved = ulReserved;
  126. EventParameters.ulEventType = *pulEventType;
  127. EventParameters.hwndParent = NULL;
  128. EventParameters.pWizardSharedMemory = pWizardSharedMemory;
  129. //
  130. // If we are started manually, it will be with the IID_NULL event
  131. // If this is the case, we are going to treat the number stored as text as
  132. // the "parent" window handle, over which all windows will be centered
  133. //
  134. if (pEventGUID && *pEventGUID==IID_NULL)
  135. {
  136. EventParameters.hwndParent = reinterpret_cast<HWND>(static_cast<UINT_PTR>(WiaUiUtil::StringToLong(CSimpleStringConvert::NaturalString(CSimpleStringWide(bstrEventDescription)))));
  137. }
  138. //
  139. // Start up the thread that actually displays the wizard
  140. //
  141. HANDLE hThread = CAcquisitionThread::Create( EventParameters );
  142. if (hThread)
  143. {
  144. //
  145. // Prevent deletion of this structure later
  146. //
  147. pWizardSharedMemory = NULL;
  148. //
  149. // Don't need this anymore
  150. //
  151. CloseHandle(hThread);
  152. }
  153. }
  154. else
  155. {
  156. WIA_TRACE((TEXT("There is already an instance of %ws running"), bstrDeviceID ));
  157. }
  158. //
  159. // Delete this memory mapped file, to prevent leaks
  160. //
  161. if (pWizardSharedMemory)
  162. {
  163. delete pWizardSharedMemory;
  164. }
  165. }
  166. return S_OK;
  167. }
  168. };
  169. class ATL_NO_VTABLE CMinimalTransfer :
  170. public CComObjectRootEx<CComSingleThreadModel>,
  171. public CComCoClass<CMinimalTransfer, &CLSID_MinimalTransfer>,
  172. public IWiaEventCallback
  173. {
  174. public:
  175. CMinimalTransfer()
  176. {
  177. }
  178. ~CMinimalTransfer()
  179. {
  180. }
  181. DECLARE_REGISTRY_RESOURCEID(IDR_MINIMALTRANSFER)
  182. DECLARE_PROTECT_FINAL_CONSTRUCT()
  183. BEGIN_COM_MAP(CMinimalTransfer)
  184. COM_INTERFACE_ENTRY(IWiaEventCallback)
  185. END_COM_MAP()
  186. public:
  187. // IManager
  188. HRESULT STDMETHODCALLTYPE ImageEventCallback( const GUID *pEventGUID,
  189. BSTR bstrEventDescription,
  190. BSTR bstrDeviceID,
  191. BSTR bstrDeviceDescription,
  192. DWORD dwDeviceType,
  193. BSTR bstrFullItemName,
  194. ULONG *pulEventType,
  195. ULONG ulReserved
  196. )
  197. {
  198. if (pEventGUID && *pEventGUID==WIA_EVENT_DEVICE_CONNECTED && GET_STIDEVICE_TYPE(dwDeviceType)==StiDeviceTypeScanner)
  199. {
  200. return S_FALSE;
  201. }
  202. DWORD dwThreadId;
  203. _Module.Lock();
  204. HANDLE hThread = CreateThread( NULL, 0, reinterpret_cast<LPTHREAD_START_ROUTINE>(MinimalTransferThreadProc), SysAllocString(bstrDeviceID), 0, &dwThreadId );
  205. if (hThread)
  206. {
  207. CloseHandle(hThread);
  208. return S_OK;
  209. }
  210. else
  211. {
  212. _Module.Unlock();
  213. return HRESULT_FROM_WIN32(GetLastError());
  214. }
  215. }
  216. };
  217. class ATL_NO_VTABLE CStiEventHandler :
  218. public CComObjectRootEx<CComSingleThreadModel>,
  219. public CComCoClass<CStiEventHandler, &CLSID_StiEventHandler>,
  220. public IWiaEventCallback
  221. {
  222. public:
  223. CStiEventHandler()
  224. {
  225. }
  226. ~CStiEventHandler()
  227. {
  228. }
  229. DECLARE_REGISTRY_RESOURCEID(IDR_STIEVENTHANDLER)
  230. DECLARE_PROTECT_FINAL_CONSTRUCT()
  231. BEGIN_COM_MAP(CStiEventHandler)
  232. COM_INTERFACE_ENTRY(IWiaEventCallback)
  233. END_COM_MAP()
  234. public:
  235. HRESULT STDMETHODCALLTYPE ImageEventCallback( const GUID *pEventGUID,
  236. BSTR bstrEventDescription,
  237. BSTR bstrDeviceID,
  238. BSTR bstrDeviceDescription,
  239. DWORD dwDeviceType,
  240. BSTR bstrFullItemName,
  241. ULONG *pulEventType,
  242. ULONG ulReserved
  243. )
  244. {
  245. //
  246. // Package the event data for the handler
  247. //
  248. CStiEventData StiEventData( pEventGUID, bstrEventDescription, bstrDeviceID, bstrDeviceDescription, dwDeviceType, bstrFullItemName, pulEventType, ulReserved );
  249. //
  250. // Just call the handler and return it.
  251. //
  252. return StiEventHandler( StiEventData );
  253. }
  254. };
  255. #endif //__AcquisitionManager_H_INCLUDED