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.

568 lines
12 KiB

  1. /*++
  2. Copyright (c) 1997 Microsoft Corporation
  3. Module Name:
  4. device.h
  5. Abstract:
  6. Handling opened device object on the monitor side
  7. Author:
  8. Vlad Sadovsky (vlads) 10-Jan-1997
  9. Environment:
  10. User Mode - Win32
  11. Revision History:
  12. 26-Jan-1997 VladS created
  13. --*/
  14. #ifndef _DEVICE_H_
  15. #define _DEVICE_H_
  16. #include <base.h>
  17. #include <buffer.h>
  18. class CWiaDrvItem;
  19. //
  20. // If this code is moved into dll, methods will need to be exported in order to instantiate
  21. // objects of those classes outside module scope. Then we will need to replace line below
  22. //
  23. // #define dllexp __declspec( dllexport )
  24. //
  25. #undef dllexp
  26. #define dllexp
  27. //
  28. #define PRIVATE_FOR_NO_SERVICE_UI
  29. //
  30. // Type of syncronization for accessing device object
  31. //
  32. #define USE_CRITICAL_SECTION 1
  33. /***********************************************************
  34. * Type Definitions
  35. ************************************************************/
  36. #define ADEV_SIGNATURE (DWORD)'ADEV'
  37. #define ADEV_SIGNATURE_FREE (DWORD)'FDEV'
  38. //
  39. // Values for flags field for device object
  40. //
  41. #define STIMON_AD_FLAG_POLLING 0x000001 // Device requires polling
  42. #define STIMON_AD_FLAG_OPENED_FOR_DATA 0x000002 // Device is opened for data access
  43. #define STIMON_AD_FLAG_LAUNCH_PENDING 0x000004 // Auto launch is pending
  44. #define STIMON_AD_FLAG_REMOVING 0x000008 // Device is being removed
  45. #define STIMON_AD_FLAG_NOTIFY_ENABLED 0x000010 // Nobody disabled notifications
  46. #define STIMON_AD_FLAG_NOTIFY_CAPABLE 0x000020 // Device is capable to notify
  47. #define STIMON_AD_FLAG_NOTIFY_RUNNING 0x000040 // Currently monitor is receiving notificaitons from device
  48. #define STIMON_AD_FLAG_MARKED_INACTIVE 0x000080 // Currently monitor is receiving notificaitons from device
  49. #define STIMON_AD_FLAG_DELAYED_INIT 0x000100 // Currently monitor is receiving notificaitons from device
  50. #define STIDEV_POLL_FAILURE_REPORT_COUNT 25 // Skip reporting errors on each polling attempt
  51. #define STIDEV_DELAYED_INTIT_TIME 10 // No. of milliseconds to schedule delayed init
  52. #define STIDEV_MIN_POLL_TIME 100 // Shortest poll interval allowed
  53. //
  54. // Forward declarations
  55. //
  56. class STI_CONN;
  57. class ACTIVE_DEVICE;
  58. class FakeStiDevice;
  59. //
  60. // Device Event code structure. A list of these is maintained for each
  61. // active device. This list is initialized from the registry when the
  62. // device becomes active (in the ACTIVE_DEVICE constructor).
  63. // Each even code structure contains an event code that the device
  64. // can issue. This event code is validated against this list. If valid,
  65. // the action assoicated with the event is triggered.
  66. //
  67. typedef struct _DEVICEEVENT {
  68. LIST_ENTRY m_ListEntry;
  69. GUID m_EventGuid;
  70. StiCString m_EventSubKey;
  71. StiCString m_EventName;
  72. StiCString m_EventData;
  73. BOOL m_fLaunchable;
  74. } DEVICEEVENT, *PDEVICEEVENT;
  75. //
  76. // Container to pass parameters to auto launch thread
  77. //
  78. typedef struct _AUTO_LAUNCH_PARAM_CONTAINER {
  79. ACTIVE_DEVICE *pActiveDevice;
  80. PDEVICEEVENT pLaunchEvent;
  81. LPCTSTR pAppName;
  82. } AUTO_LAUNCH_PARAM_CONTAINER,*PAUTO_LAUNCH_PARAM_CONTAINER;
  83. class ACTIVE_DEVICE : public BASE {
  84. friend class TAKE_ACTIVE_DEVICE;
  85. friend VOID CALLBACK
  86. DumpActiveDevicesCallback(
  87. ACTIVE_DEVICE *pActiveDevice,
  88. VOID *pContext
  89. );
  90. public:
  91. // *** IUnknown methods ***
  92. STDMETHODIMP QueryInterface( REFIID riid, LPVOID * ppvObj);
  93. STDMETHODIMP_(ULONG) AddRef( void);
  94. STDMETHODIMP_(ULONG) Release( void);
  95. //
  96. ACTIVE_DEVICE(IN LPCTSTR lpszDeviceName, DEVICE_INFO *pInfo = NULL);
  97. ~ACTIVE_DEVICE( VOID ) ;
  98. inline BOOL
  99. IsValid(
  100. VOID
  101. )
  102. {
  103. return (m_fValid) && (m_dwSignature == ADEV_SIGNATURE);
  104. }
  105. inline BOOL
  106. EnterCrit(VOID)
  107. {
  108. return m_dwDeviceCritSec.Lock();
  109. }
  110. inline void
  111. LeaveCrit(VOID)
  112. {
  113. m_dwDeviceCritSec.Unlock();
  114. }
  115. inline DWORD
  116. SetFlags(
  117. DWORD dwNewFlags
  118. )
  119. {
  120. DWORD dwTemp = m_dwFlags;
  121. m_dwFlags = dwNewFlags;
  122. return dwTemp;
  123. }
  124. inline DWORD
  125. QueryFlags(
  126. VOID
  127. )
  128. {
  129. return m_dwFlags;
  130. }
  131. inline DWORD
  132. QueryPollingInterval(VOID) // get current polling interval
  133. {
  134. return m_dwPollingInterval;
  135. }
  136. inline DWORD
  137. SetPollingInterval(
  138. IN DWORD dwNewInterval) // Set new interval for polling
  139. {
  140. DWORD dwTemp = m_dwPollingInterval;
  141. m_dwPollingInterval = dwNewInterval;
  142. return dwTemp;
  143. }
  144. inline BOOL
  145. IsConnectedTo(
  146. VOID
  147. )
  148. {
  149. return !IsListEmpty(&m_ConnectionListHead);
  150. }
  151. BOOL
  152. NotificationsNeeded(
  153. VOID
  154. )
  155. {
  156. if (!IsListEmpty(&m_ConnectionListHead)) {
  157. return TRUE;
  158. }
  159. //
  160. // If setup is running - block all events
  161. //
  162. if ( IsSetupInProgressMode() ) {
  163. return FALSE;
  164. }
  165. //
  166. // For async. notification devices always assume they need support for notificaitons
  167. // It is rather hacky , but all USB devices we have now, need to initialize notifications
  168. // support on startup, otherwise their initialization routines would not complete properly.
  169. // It is not expensive to monitor async events and do nothing when they arrive
  170. // For polled devices on the ontrary , it is quite expensive to keep monitoring
  171. // events ,when they are really not needed
  172. if ((QueryFlags() & STIMON_AD_FLAG_NOTIFY_CAPABLE) &&
  173. !(QueryFlags() & STIMON_AD_FLAG_POLLING) ) {
  174. return TRUE;
  175. }
  176. else {
  177. // If there are no connections, then check whether user does not want notifications or
  178. // event list is empty
  179. return ( !m_dwUserDisableNotifications && m_fLaunchableEventListNotEmpty );
  180. }
  181. }
  182. WCHAR* GetDeviceID()
  183. {
  184. return m_DrvWrapper.getDeviceId();
  185. }
  186. HANDLE GetNotificationsSink()
  187. {
  188. return m_hDeviceNotificationSink;
  189. }
  190. VOID
  191. GetDeviceSettings(
  192. VOID
  193. );
  194. //
  195. // Device notifications spport
  196. //
  197. BOOL
  198. BuildEventList(
  199. VOID
  200. );
  201. BOOL
  202. DestroyEventList(
  203. VOID
  204. );
  205. DWORD
  206. DisableDeviceNotifications(
  207. VOID
  208. );
  209. DWORD
  210. EnableDeviceNotifications(
  211. VOID
  212. );
  213. DWORD
  214. StopNotifications(
  215. VOID
  216. );
  217. DWORD
  218. StartRunningNotifications(
  219. VOID
  220. );
  221. BOOL
  222. FlushDeviceNotifications(
  223. VOID
  224. );
  225. BOOL
  226. DoPoll(
  227. VOID
  228. );
  229. BOOL
  230. DoAsyncEvent(
  231. VOID
  232. );
  233. BOOL
  234. ProcessEvent(
  235. STINOTIFY *psNotify,
  236. BOOL fForceLaunch=FALSE,
  237. LPCTSTR pszAppName=NULL
  238. );
  239. BOOL
  240. AutoLaunch(
  241. PAUTO_LAUNCH_PARAM_CONTAINER pAutoContainer
  242. );
  243. BOOL
  244. RetrieveSTILaunchInformation(
  245. PDEVICEEVENT pev,
  246. LPCTSTR pAppName,
  247. STRArray& saAppList,
  248. STRArray& saCommandLine,
  249. BOOL fForceSelection=FALSE
  250. );
  251. BOOL
  252. IsDeviceAvailable(
  253. VOID
  254. );
  255. BOOL
  256. RemoveConnection(
  257. STI_CONN *pConnection
  258. );
  259. BOOL
  260. AddConnection(
  261. STI_CONN *pConnection
  262. );
  263. STI_CONN *
  264. FindMyConnection(
  265. HANDLE hConnection
  266. );
  267. BOOL
  268. FillEventFromUSD(
  269. STINOTIFY *psNotify
  270. );
  271. BOOL
  272. SetHandleForUSD(
  273. HANDLE hEvent
  274. );
  275. BOOL
  276. IsEventOnArrivalNeeded(
  277. VOID
  278. );
  279. //
  280. // Load/Unload STI device
  281. //
  282. BOOL
  283. LoadDriver(
  284. BOOL bReReadDevInfo = FALSE
  285. );
  286. BOOL
  287. UnLoadDriver(
  288. BOOL bForceUnload
  289. );
  290. //
  291. // PnP support methods
  292. //
  293. BOOL
  294. InitPnPNotifications(
  295. HWND hwnd
  296. );
  297. BOOL
  298. StopPnPNotifications(
  299. VOID
  300. );
  301. BOOL IsRegisteredForDeviceRemoval(
  302. VOID
  303. );
  304. //
  305. // Update WIA cached device information
  306. //
  307. BOOL UpdateDeviceInformation(
  308. VOID
  309. );
  310. VOID SetDriverItem(
  311. CWiaDrvItem *pRootDrvItem)
  312. {
  313. //
  314. // Note: Technically, we should follow proper ref-counting
  315. // procedure for this this object. However, we should NEVER have
  316. // the case where this object goes out of scope (or otherwise
  317. // destroyed) without our knowledge, therefore there is no need.
  318. //
  319. m_pRootDrvItem = pRootDrvItem;
  320. };
  321. //
  322. LIST_ENTRY m_ListEntry;
  323. LIST_ENTRY m_ConnectionListHead;
  324. DWORD m_dwSignature;
  325. StiCString m_strLaunchCommandLine;
  326. LONG m_lDeviceId;
  327. PVOID m_pLockInfo;
  328. DWORD m_dwDelayedOpCookie;
  329. FakeStiDevice *m_pFakeStiDevice;
  330. CDrvWrap m_DrvWrapper;
  331. CWiaDrvItem *m_pRootDrvItem;
  332. private:
  333. BOOL m_fValid;
  334. BOOL m_fLaunchableEventListNotEmpty;
  335. BOOL m_fRefreshedBusOnFailure;
  336. CRIT_SECT m_dwDeviceCritSec;
  337. DWORD m_dwFlags;
  338. DWORD m_dwPollingInterval;
  339. DWORD m_dwUserDisableNotifications;
  340. DWORD m_dwSchedulerCookie;
  341. DWORD m_dwLaunchEventTimeExpire;
  342. UINT m_uiSubscribersCount;
  343. UINT m_uiPollFailureCount;
  344. HANDLE m_hDeviceEvent;
  345. HANDLE m_hDeviceNotificationSink;
  346. HANDLE m_hDeviceInterface;
  347. STI_DEVICE_STATUS m_DevStatus;
  348. LIST_ENTRY m_DeviceEventListHead;
  349. PDEVICEEVENT m_pLastLaunchEvent;
  350. };
  351. //
  352. // Take device class
  353. //
  354. class TAKE_ACTIVE_DEVICE
  355. {
  356. private:
  357. ACTIVE_DEVICE* m_pDev;
  358. BOOL m_bLocked;
  359. public:
  360. inline TAKE_ACTIVE_DEVICE(ACTIVE_DEVICE* pdev) : m_pDev(pdev), m_bLocked(FALSE)
  361. {
  362. if (m_pDev) {
  363. m_bLocked = m_pDev->EnterCrit();
  364. }
  365. }
  366. inline ~TAKE_ACTIVE_DEVICE()
  367. {
  368. if (m_bLocked) {
  369. m_pDev->LeaveCrit();
  370. }
  371. }
  372. };
  373. //
  374. // Linked list for active STI devices, known to monitor
  375. //
  376. extern LIST_ENTRY g_pDeviceListHead;
  377. //
  378. //
  379. // Add/Remove device object from the list
  380. //
  381. BOOL
  382. AddDeviceByName(
  383. LPCTSTR pszDeviceName,
  384. BOOL fPnPInitiated = FALSE
  385. );
  386. BOOL
  387. RemoveDeviceByName(
  388. LPTSTR pszDeviceName
  389. );
  390. BOOL
  391. MarkDeviceForRemoval(
  392. LPTSTR pszDeviceName
  393. );
  394. // Reload device list in response to PnP or ACPI notifications
  395. //
  396. VOID
  397. RefreshDeviceList(
  398. WORD wCommand,
  399. WORD wFlags
  400. );
  401. //
  402. // Initialize/Terminate linked list
  403. //
  404. VOID
  405. InitializeDeviceList(
  406. VOID
  407. );
  408. VOID
  409. TerminateDeviceList(
  410. VOID
  411. );
  412. VOID
  413. DebugDumpDeviceList(
  414. VOID
  415. );
  416. BOOL
  417. ResetAllPollIntervals(
  418. UINT dwNewPollInterval
  419. );
  420. //
  421. // Enumerators with callbacks
  422. //
  423. typedef
  424. VOID
  425. (*PFN_DEVINFO_CALLBACK)(
  426. PSTI_DEVICE_INFORMATION pDevInfo,
  427. VOID *pContext
  428. );
  429. typedef
  430. VOID
  431. (* PFN_ACTIVEDEVICE_CALLBACK)(
  432. ACTIVE_DEVICE *pActiveDevice,
  433. VOID *pContext
  434. );
  435. /*
  436. VOID
  437. WINAPI
  438. EnumerateStiDevicesWithCallback(
  439. PFN_DEVINFO_CALLBACK pfn,
  440. VOID *pContext
  441. );
  442. */
  443. VOID
  444. WINAPI
  445. EnumerateActiveDevicesWithCallback(
  446. PFN_ACTIVEDEVICE_CALLBACK pfn,
  447. VOID *pContext
  448. );
  449. #endif // _DEVICE_H_