ReactOS 0.4.15-dev-7842-g558ab78
fbtusb.c
Go to the documentation of this file.
1// Copyright (c) 2004, Antony C. Roberts
2
3// Use of this file is subject to the terms
4// described in the LICENSE.TXT file that
5// accompanies this file.
6//
7// Your use of this file indicates your
8// acceptance of the terms described in
9// LICENSE.TXT.
10//
11// http://www.freebt.net
12
13#include "stdio.h"
14#include "fbtusb.h"
15#include "fbtpnp.h"
16#include "fbtpwr.h"
17#include "fbtdev.h"
18#include "fbtwmi.h"
19#include "fbtrwr.h"
20
21#include "fbtusr.h"
22
23
24// Globals
27
28// Forward declaration
32
33#ifdef PAGE_CODE
34#ifdef ALLOC_PRAGMA
35#pragma alloc_text(INIT, DriverEntry)
36#pragma alloc_text(PAGE, FreeBT_DriverUnload)
37#endif
38#endif
39
41{
42 NTSTATUS ntStatus;
44
46
47 registryPath->MaximumLength = UniRegistryPath->Length + sizeof(UNICODE_NULL);
48 registryPath->Length = UniRegistryPath->Length;
49 registryPath->Buffer = (PWSTR) ExAllocatePool(PagedPool, registryPath->MaximumLength);
50
51 if (!registryPath->Buffer)
52 {
53 FreeBT_DbgPrint(1, ("FBTUSB: Failed to allocate memory for registryPath\n"));
55 goto DriverEntry_Exit;
56
57 }
58
59
60 RtlZeroMemory (registryPath->Buffer, registryPath->MaximumLength);
61 RtlMoveMemory (registryPath->Buffer, UniRegistryPath->Buffer, UniRegistryPath->Length);
62
63 ntStatus = STATUS_SUCCESS;
64
65 // Initialize the driver object with this driver's entry points.
74#ifdef ENABLE_WMI
76#endif
77 DriverObject->DriverUnload = FreeBT_DriverUnload;
78 DriverObject->DriverExtension->AddDevice = (PDRIVER_ADD_DEVICE) FreeBT_AddDevice;
79
80DriverEntry_Exit:
81 return ntStatus;
82
83}
84
86{
88
89 FreeBT_DbgPrint(3, ("FBTUSB: FreeBT_DriverUnload: Entered\n"));
90
92 if(registryPath->Buffer)
93 {
94 ExFreePool(registryPath->Buffer);
95 registryPath->Buffer = NULL;
96
97 }
98
99 FreeBT_DbgPrint(3, ("FBTUSB: FreeBT_DriverUnload: Leaving\n"));
100
101 return;
102
103}
104
105// AddDevice, called when an instance of our supported hardware is found
106// Returning anything other than NT_SUCCESS here causes the device to fail
107// to initialise
109{
110 NTSTATUS ntStatus;
112 PDEVICE_EXTENSION deviceExtension;
114 //KIRQL oldIrql;
115 UNICODE_STRING uniDeviceName;
116 WCHAR wszDeviceName[255]={0};
117 UNICODE_STRING uniDosDeviceName;
118 LONG instanceNumber=0;
119
120 FreeBT_DbgPrint(3, ("FBTUSB: FreeBT_AddDevice: Entered\n"));
121
123
124 swprintf(wszDeviceName, L"\\Device\\FbtUsb%02d", instanceNumber);
125 RtlInitUnicodeString(&uniDeviceName, wszDeviceName);
127 while (instanceNumber<99 && !NT_SUCCESS(ntStatus))
128 {
129 swprintf(wszDeviceName, L"\\Device\\FbtUsb%02d", instanceNumber);
130 uniDeviceName.Length = wcslen(wszDeviceName) * sizeof(WCHAR);
131 FreeBT_DbgPrint(1, ("FBTUSB: Attempting to create device %ws\n", wszDeviceName));
132 ntStatus = IoCreateDevice(
133 DriverObject, // our driver object
134 sizeof(DEVICE_EXTENSION), // extension size for us
135 &uniDeviceName, // name for this device
137 0, // device characteristics
138 FALSE, // Not exclusive
139 &deviceObject); // Our device object
140
141 if (!NT_SUCCESS(ntStatus))
142 instanceNumber++;
143
144 }
145
146 if (!NT_SUCCESS(ntStatus))
147 {
148 FreeBT_DbgPrint(1, ("FBTUSB: Failed to create device object\n"));
149 return ntStatus;
150
151 }
152
153 FreeBT_DbgPrint(1, ("FBTUSB: Created device %ws\n", wszDeviceName));
154
155 deviceExtension = (PDEVICE_EXTENSION) deviceObject->DeviceExtension;
156 deviceExtension->FunctionalDeviceObject = deviceObject;
157 deviceExtension->PhysicalDeviceObject = PhysicalDeviceObject;
158 deviceObject->Flags |= DO_DIRECT_IO;
159
160 swprintf(deviceExtension->wszDosDeviceName, L"\\DosDevices\\FbtUsb%02d", instanceNumber);
161 RtlInitUnicodeString(&uniDosDeviceName, deviceExtension->wszDosDeviceName);
162 ntStatus=IoCreateSymbolicLink(&uniDosDeviceName, &uniDeviceName);
163 if (!NT_SUCCESS(ntStatus))
164 {
165 FreeBT_DbgPrint(1, ("FBTUSB: Failed to create symbolic link %ws to %ws, status=0x%08x\n", deviceExtension->wszDosDeviceName, wszDeviceName, ntStatus));
167 return ntStatus;
168
169 }
170
171 FreeBT_DbgPrint(1, ("FBTUSB: Created symbolic link %ws\n", deviceExtension->wszDosDeviceName));
172
173 KeInitializeSpinLock(&deviceExtension->DevStateLock);
174
175 INITIALIZE_PNP_STATE(deviceExtension);
176
177 deviceExtension->OpenHandleCount = 0;
178
179 // Initialize the selective suspend variables
180 KeInitializeSpinLock(&deviceExtension->IdleReqStateLock);
181 deviceExtension->IdleReqPend = 0;
182 deviceExtension->PendingIdleIrp = NULL;
183
184 // Hold requests until the device is started
185 deviceExtension->QueueState = HoldRequests;
186
187 // Initialize the queue and the queue spin lock
188 InitializeListHead(&deviceExtension->NewRequestsQueue);
189 KeInitializeSpinLock(&deviceExtension->QueueLock);
190
191 // Initialize the remove event to not-signaled.
192 KeInitializeEvent(&deviceExtension->RemoveEvent, SynchronizationEvent, FALSE);
193
194 // Initialize the stop event to signaled.
195 // This event is signaled when the OutstandingIO becomes 1
196 KeInitializeEvent(&deviceExtension->StopEvent, SynchronizationEvent, TRUE);
197
198 // OutstandingIo count biased to 1.
199 // Transition to 0 during remove device means IO is finished.
200 // Transition to 1 means the device can be stopped
201 deviceExtension->OutStandingIO = 1;
202 KeInitializeSpinLock(&deviceExtension->IOCountLock);
203
204#ifdef ENABLE_WMI
205 // Delegating to WMILIB
206 ntStatus = FreeBT_WmiRegistration(deviceExtension);
207 if (!NT_SUCCESS(ntStatus))
208 {
209 FreeBT_DbgPrint(1, ("FBTUSB: FreeBT_WmiRegistration failed with %X\n", ntStatus));
211 IoDeleteSymbolicLink(&uniDosDeviceName);
212 return ntStatus;
213
214 }
215#endif
216
217 // Set the flags as underlying PDO
219 {
221
222 }
223
224 // Typically, the function driver for a device is its
225 // power policy owner, although for some devices another
226 // driver or system component may assume this role.
227 // Set the initial power state of the device, if known, by calling
228 // PoSetPowerState.
229 deviceExtension->DevPower = PowerDeviceD0;
230 deviceExtension->SysPower = PowerSystemWorking;
231
232 state.DeviceState = PowerDeviceD0;
234
235 // attach our driver to device stack
236 // The return value of IoAttachDeviceToDeviceStack is the top of the
237 // attachment chain. This is where all the IRPs should be routed.
238 deviceExtension->TopOfStackDeviceObject = IoAttachDeviceToDeviceStack(deviceObject, PhysicalDeviceObject);
239 if (NULL == deviceExtension->TopOfStackDeviceObject)
240 {
241#ifdef ENABLE_WMI
242 FreeBT_WmiDeRegistration(deviceExtension);
243#endif
245 IoDeleteSymbolicLink(&uniDosDeviceName);
247
248 }
249
250 // Register device interfaces
251 ntStatus = IoRegisterDeviceInterface(deviceExtension->PhysicalDeviceObject,
252 &GUID_CLASS_FREEBT_USB,
253 NULL,
254 &deviceExtension->InterfaceName);
255 if (!NT_SUCCESS(ntStatus))
256 {
257#ifdef ENABLE_WMI
258 FreeBT_WmiDeRegistration(deviceExtension);
259#endif
260 IoDetachDevice(deviceExtension->TopOfStackDeviceObject);
262 IoDeleteSymbolicLink(&uniDosDeviceName);
263 return ntStatus;
264
265 }
266
267 if (IoIsWdmVersionAvailable(1, 0x20))
268 {
269 deviceExtension->WdmVersion = WinXpOrBetter;
270
271 }
272
273 else if (IoIsWdmVersionAvailable(1, 0x10))
274 {
275 deviceExtension->WdmVersion = Win2kOrBetter;
276
277 }
278
279 else if (IoIsWdmVersionAvailable(1, 0x5))
280 {
281 deviceExtension->WdmVersion = WinMeOrBetter;
282
283 }
284
285 else if (IoIsWdmVersionAvailable(1, 0x0))
286 {
287 deviceExtension->WdmVersion = Win98OrBetter;
288
289 }
290
291 deviceExtension->SSRegistryEnable = 0;
292 deviceExtension->SSEnable = 0;
293
294 // WinXP only: check the registry flag indicating whether
295 // the device should selectively suspend when idle
296 if (WinXpOrBetter == deviceExtension->WdmVersion)
297 {
299 L"BulkUsbEnable",
300 (PULONG)(&deviceExtension->SSRegistryEnable));
301 if (deviceExtension->SSRegistryEnable)
302 {
303 // initialize DPC
304 KeInitializeDpc(&deviceExtension->DeferredProcCall, DpcRoutine, deviceObject);
305
306 // initialize the timer.
307 // the DPC and the timer in conjunction,
308 // monitor the state of the device to
309 // selectively suspend the device.
310 KeInitializeTimerEx(&deviceExtension->Timer, NotificationTimer);
311
312 // Initialize the NoDpcWorkItemPendingEvent to signaled state.
313 // This event is cleared when a Dpc is fired and signaled
314 // on completion of the work-item.
315 KeInitializeEvent(&deviceExtension->NoDpcWorkItemPendingEvent, NotificationEvent, TRUE);
316
317 // Initialize the NoIdleReqPendEvent to ensure that the idle request
318 // is indeed complete before we unload the drivers.
319 KeInitializeEvent(&deviceExtension->NoIdleReqPendEvent, NotificationEvent, TRUE);
320
321 }
322
323 }
324
325 // Initialize the NoIdleReqPendEvent to ensure that the idle request
326 // is indeed complete before we unload the drivers.
327 KeInitializeEvent(&deviceExtension->DelayEvent, NotificationEvent, FALSE);
328
329 // Clear the DO_DEVICE_INITIALIZING flag.
330 // Note: Do not clear this flag until the driver has set the
331 // device power state and the power DO flags.
332 deviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
333 InterlockedIncrement(&instanceNumber);
334
335 FreeBT_DbgPrint(3, ("FBTUSB: FreeBT_AddDevice: Leaving\n"));
336
337 return ntStatus;
338
339}
340
341
static int state
Definition: maze.c:121
#define InterlockedIncrement
Definition: armddk.h:53
LONG NTSTATUS
Definition: precomp.h:26
PDEVICE_OBJECT PhysicalDeviceObject
Definition: btrfs_drv.h:1157
LPCTSTR registryPath
Definition: butterflies.c:17
#define IRP_MJ_PNP
Definition: cdrw_usr.h:52
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define swprintf
Definition: precomp.h:40
VOID NTAPI KeInitializeDpc(IN PKDPC Dpc, IN PKDEFERRED_ROUTINE DeferredRoutine, IN PVOID DeferredContext)
Definition: dpc.c:712
struct _BEEP_DEVICE_EXTENSION * PDEVICE_EXTENSION
DRIVER_INITIALIZE DriverEntry
Definition: condrv.c:21
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
#define DO_DIRECT_IO
Definition: env_spec_w32.h:396
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define KeInitializeSpinLock(sl)
Definition: env_spec_w32.h:604
#define PagedPool
Definition: env_spec_w32.h:308
NTSTATUS NTAPI FreeBT_DispatchCreate(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: fbtdev.c:23
NTSTATUS NTAPI FreeBT_DispatchClose(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: fbtdev.c:102
NTSTATUS NTAPI FreeBT_DispatchDevCtrl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: fbtdev.c:412
NTSTATUS NTAPI FreeBT_DispatchPnP(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: fbtpnp.c:24
NTSTATUS NTAPI FreeBT_GetRegistryDword(IN PWCHAR RegPath, IN PWCHAR ValueName, IN OUT PULONG Value)
Definition: fbtpnp.c:1517
NTSTATUS NTAPI FreeBT_DispatchClean(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: fbtpnp.c:1565
VOID NTAPI DpcRoutine(IN PKDPC Dpc, IN PVOID DeferredContext, IN PVOID SystemArgument1, IN PVOID SystemArgument2)
Definition: fbtpnp.c:1298
NTSTATUS NTAPI FreeBT_DispatchPower(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: fbtpwr.c:23
NTSTATUS NTAPI FreeBT_DispatchWrite(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: fbtrwr.c:253
NTSTATUS NTAPI FreeBT_DispatchRead(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: fbtrwr.c:23
ULONG DebugLevel
Definition: fbtusb.c:26
NTSTATUS NTAPI FreeBT_AddDevice(IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT PhysicalDeviceObject)
Definition: fbtusb.c:108
VOID NTAPI FreeBT_DriverUnload(IN PDRIVER_OBJECT DriverObject)
Definition: fbtusb.c:85
GLOBALS Globals
Definition: fbtusb.c:25
#define FreeBT_DbgPrint(level, _x_)
Definition: fbtusb.h:55
@ WinXpOrBetter
Definition: fbtusb.h:100
@ Win2kOrBetter
Definition: fbtusb.h:101
@ Win98OrBetter
Definition: fbtusb.h:103
@ WinMeOrBetter
Definition: fbtusb.h:102
#define FREEBT_REGISTRY_PARAMETERS_PATH
Definition: fbtusb.h:121
#define INITIALIZE_PNP_STATE(_Data_)
Definition: fbtusb.h:107
@ HoldRequests
Definition: fbtusb.h:92
#define ExAllocatePool(type, size)
Definition: fbtusb.h:44
NTSTATUS NTAPI FreeBT_WmiRegistration(IN OUT PDEVICE_EXTENSION DeviceExtension)
Definition: fbtwmi.c:37
NTSTATUS NTAPI FreeBT_WmiDeRegistration(IN OUT PDEVICE_EXTENSION DeviceExtension)
Definition: fbtwmi.c:59
NTSTATUS NTAPI FreeBT_DispatchSysCtrl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: fbtwmi.c:66
MxDeviceObject deviceObject
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define UNICODE_NULL
@ NotificationEvent
@ SynchronizationEvent
@ NotificationTimer
PDEVICE_OBJECT NTAPI IoAttachDeviceToDeviceStack(IN PDEVICE_OBJECT SourceDevice, IN PDEVICE_OBJECT TargetDevice)
Definition: device.c:966
NTSTATUS NTAPI IoCreateDevice(IN PDRIVER_OBJECT DriverObject, IN ULONG DeviceExtensionSize, IN PUNICODE_STRING DeviceName, IN DEVICE_TYPE DeviceType, IN ULONG DeviceCharacteristics, IN BOOLEAN Exclusive, OUT PDEVICE_OBJECT *DeviceObject)
Definition: device.c:1031
VOID NTAPI IoDetachDevice(IN PDEVICE_OBJECT TargetDevice)
Definition: device.c:1296
VOID NTAPI IoDeleteDevice(IN PDEVICE_OBJECT DeviceObject)
Definition: device.c:1251
NTSTATUS NTAPI IoRegisterDeviceInterface(IN PDEVICE_OBJECT PhysicalDeviceObject, IN CONST GUID *InterfaceClassGuid, IN PUNICODE_STRING ReferenceString OPTIONAL, OUT PUNICODE_STRING SymbolicLinkName)
Definition: deviface.c:955
BOOLEAN NTAPI IoIsWdmVersionAvailable(IN UCHAR MajorVersion, IN UCHAR MinorVersion)
Definition: util.c:126
POWER_STATE NTAPI PoSetPowerState(IN PDEVICE_OBJECT DeviceObject, IN POWER_STATE_TYPE Type, IN POWER_STATE State)
Definition: power.c:729
@ PowerSystemWorking
Definition: ntpoapi.h:36
@ DevicePowerState
Definition: ntpoapi.h:63
@ PowerDeviceD0
Definition: ntpoapi.h:49
#define L(x)
Definition: ntvdm.h:50
long LONG
Definition: pedump.c:60
#define FILE_DEVICE_UNKNOWN
Definition: winioctl.h:140
#define IRP_MJ_CLOSE
Definition: rdpdr.c:45
#define IRP_MJ_READ
Definition: rdpdr.c:46
#define IRP_MJ_DEVICE_CONTROL
Definition: rdpdr.c:52
#define IRP_MJ_WRITE
Definition: rdpdr.c:47
#define IRP_MJ_CREATE
Definition: rdpdr.c:44
#define STATUS_SUCCESS
Definition: shellext.h:65
UNICODE_STRING FreeBT_RegistryPath
Definition: fbtusb.h:61
VOID NTAPI KeInitializeTimerEx(OUT PKTIMER Timer, IN TIMER_TYPE Type)
Definition: timerobj.c:244
uint16_t * PWSTR
Definition: typedefs.h:56
uint32_t * PULONG
Definition: typedefs.h:59
#define NTAPI
Definition: typedefs.h:36
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define IN
Definition: typedefs.h:39
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:264
uint32_t ULONG
Definition: typedefs.h:59
#define STATUS_NO_SUCH_DEVICE
Definition: udferr_usr.h:136
#define STATUS_OBJECT_NAME_COLLISION
Definition: udferr_usr.h:150
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_Must_inspect_result_ _In_ PDRIVER_OBJECT DriverObject
Definition: wdfdriver.h:213
DRIVER_ADD_DEVICE * PDRIVER_ADD_DEVICE
Definition: iotypes.h:2216
#define DO_POWER_PAGABLE
#define IRP_MJ_SYSTEM_CONTROL
#define IRP_MJ_POWER
#define IRP_MJ_CLEANUP
__wchar_t WCHAR
Definition: xmlstorage.h:180