Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenfbtusb.c
Go to the documentation of this file.
00001 // Copyright (c) 2004, Antony C. Roberts 00002 00003 // Use of this file is subject to the terms 00004 // described in the LICENSE.TXT file that 00005 // accompanies this file. 00006 // 00007 // Your use of this file indicates your 00008 // acceptance of the terms described in 00009 // LICENSE.TXT. 00010 // 00011 // http://www.freebt.net 00012 00013 #include "stdio.h" 00014 #include "fbtusb.h" 00015 #include "fbtpnp.h" 00016 #include "fbtpwr.h" 00017 #include "fbtdev.h" 00018 #include "fbtwmi.h" 00019 #include "fbtrwr.h" 00020 00021 #include "fbtusr.h" 00022 00023 00024 // Globals 00025 GLOBALS Globals; 00026 ULONG DebugLevel=255; 00027 00028 // Forward declaration 00029 NTSTATUS NTAPI DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING UniRegistryPath ); 00030 VOID NTAPI FreeBT_DriverUnload(IN PDRIVER_OBJECT DriverObject); 00031 NTSTATUS NTAPI FreeBT_AddDevice(IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT PhysicalDeviceObject); 00032 00033 #ifdef PAGE_CODE 00034 #ifdef ALLOC_PRAGMA 00035 #pragma alloc_text(INIT, DriverEntry) 00036 #pragma alloc_text(PAGE, FreeBT_DriverUnload) 00037 #endif 00038 #endif 00039 00040 NTSTATUS NTAPI DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING UniRegistryPath) 00041 { 00042 NTSTATUS ntStatus; 00043 PUNICODE_STRING registryPath; 00044 00045 registryPath = &Globals.FreeBT_RegistryPath; 00046 00047 registryPath->MaximumLength = UniRegistryPath->Length + sizeof(UNICODE_NULL); 00048 registryPath->Length = UniRegistryPath->Length; 00049 registryPath->Buffer = (PWSTR) ExAllocatePool(PagedPool, registryPath->MaximumLength); 00050 00051 if (!registryPath->Buffer) 00052 { 00053 FreeBT_DbgPrint(1, ("FBTUSB: Failed to allocate memory for registryPath\n")); 00054 ntStatus = STATUS_INSUFFICIENT_RESOURCES; 00055 goto DriverEntry_Exit; 00056 00057 } 00058 00059 00060 RtlZeroMemory (registryPath->Buffer, registryPath->MaximumLength); 00061 RtlMoveMemory (registryPath->Buffer, UniRegistryPath->Buffer, UniRegistryPath->Length); 00062 00063 ntStatus = STATUS_SUCCESS; 00064 00065 // Initialize the driver object with this driver's entry points. 00066 DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = FreeBT_DispatchDevCtrl; 00067 DriverObject->MajorFunction[IRP_MJ_POWER] = FreeBT_DispatchPower; 00068 DriverObject->MajorFunction[IRP_MJ_PNP] = FreeBT_DispatchPnP; 00069 DriverObject->MajorFunction[IRP_MJ_CREATE] = FreeBT_DispatchCreate; 00070 DriverObject->MajorFunction[IRP_MJ_CLOSE] = FreeBT_DispatchClose; 00071 DriverObject->MajorFunction[IRP_MJ_CLEANUP] = FreeBT_DispatchClean; 00072 DriverObject->MajorFunction[IRP_MJ_READ] = FreeBT_DispatchRead; 00073 DriverObject->MajorFunction[IRP_MJ_WRITE] = FreeBT_DispatchWrite; 00074 #ifdef ENABLE_WMI 00075 DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = FreeBT_DispatchSysCtrl; 00076 #endif 00077 DriverObject->DriverUnload = FreeBT_DriverUnload; 00078 DriverObject->DriverExtension->AddDevice = (PDRIVER_ADD_DEVICE) FreeBT_AddDevice; 00079 00080 DriverEntry_Exit: 00081 return ntStatus; 00082 00083 } 00084 00085 VOID NTAPI FreeBT_DriverUnload(IN PDRIVER_OBJECT DriverObject) 00086 { 00087 PUNICODE_STRING registryPath; 00088 00089 FreeBT_DbgPrint(3, ("FBTUSB: FreeBT_DriverUnload: Entered\n")); 00090 00091 registryPath = &Globals.FreeBT_RegistryPath; 00092 if(registryPath->Buffer) 00093 { 00094 ExFreePool(registryPath->Buffer); 00095 registryPath->Buffer = NULL; 00096 00097 } 00098 00099 FreeBT_DbgPrint(3, ("FBTUSB: FreeBT_DriverUnload: Leaving\n")); 00100 00101 return; 00102 00103 } 00104 00105 // AddDevice, called when an instance of our supported hardware is found 00106 // Returning anything other than NT_SUCCESS here causes the device to fail 00107 // to initialise 00108 NTSTATUS NTAPI FreeBT_AddDevice(IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT PhysicalDeviceObject) 00109 { 00110 NTSTATUS ntStatus; 00111 PDEVICE_OBJECT deviceObject; 00112 PDEVICE_EXTENSION deviceExtension; 00113 POWER_STATE state; 00114 //KIRQL oldIrql; 00115 UNICODE_STRING uniDeviceName; 00116 WCHAR wszDeviceName[255]={0}; 00117 UNICODE_STRING uniDosDeviceName; 00118 LONG instanceNumber=0; 00119 00120 FreeBT_DbgPrint(3, ("FBTUSB: FreeBT_AddDevice: Entered\n")); 00121 00122 deviceObject = NULL; 00123 00124 swprintf(wszDeviceName, L"\\Device\\FbtUsb%02d", instanceNumber); 00125 RtlInitUnicodeString(&uniDeviceName, wszDeviceName); 00126 ntStatus=STATUS_OBJECT_NAME_COLLISION; 00127 while (instanceNumber<99 && !NT_SUCCESS(ntStatus)) 00128 { 00129 swprintf(wszDeviceName, L"\\Device\\FbtUsb%02d", instanceNumber); 00130 uniDeviceName.Length = wcslen(wszDeviceName) * sizeof(WCHAR); 00131 FreeBT_DbgPrint(1, ("FBTUSB: Attempting to create device %ws\n", wszDeviceName)); 00132 ntStatus = IoCreateDevice( 00133 DriverObject, // our driver object 00134 sizeof(DEVICE_EXTENSION), // extension size for us 00135 &uniDeviceName, // name for this device 00136 FILE_DEVICE_UNKNOWN, 00137 0, // device characteristics 00138 FALSE, // Not exclusive 00139 &deviceObject); // Our device object 00140 00141 if (!NT_SUCCESS(ntStatus)) 00142 instanceNumber++; 00143 00144 } 00145 00146 if (!NT_SUCCESS(ntStatus)) 00147 { 00148 FreeBT_DbgPrint(1, ("FBTUSB: Failed to create device object\n")); 00149 return ntStatus; 00150 00151 } 00152 00153 FreeBT_DbgPrint(1, ("FBTUSB: Created device %ws\n", wszDeviceName)); 00154 00155 deviceExtension = (PDEVICE_EXTENSION) deviceObject->DeviceExtension; 00156 deviceExtension->FunctionalDeviceObject = deviceObject; 00157 deviceExtension->PhysicalDeviceObject = PhysicalDeviceObject; 00158 deviceObject->Flags |= DO_DIRECT_IO; 00159 00160 swprintf(deviceExtension->wszDosDeviceName, L"\\DosDevices\\FbtUsb%02d", instanceNumber); 00161 RtlInitUnicodeString(&uniDosDeviceName, deviceExtension->wszDosDeviceName); 00162 ntStatus=IoCreateSymbolicLink(&uniDosDeviceName, &uniDeviceName); 00163 if (!NT_SUCCESS(ntStatus)) 00164 { 00165 FreeBT_DbgPrint(1, ("FBTUSB: Failed to create symbolic link %ws to %ws, status=0x%08x\n", deviceExtension->wszDosDeviceName, wszDeviceName, ntStatus)); 00166 IoDeleteDevice(deviceObject); 00167 return ntStatus; 00168 00169 } 00170 00171 FreeBT_DbgPrint(1, ("FBTUSB: Created symbolic link %ws\n", deviceExtension->wszDosDeviceName)); 00172 00173 KeInitializeSpinLock(&deviceExtension->DevStateLock); 00174 00175 INITIALIZE_PNP_STATE(deviceExtension); 00176 00177 deviceExtension->OpenHandleCount = 0; 00178 00179 // Initialize the selective suspend variables 00180 KeInitializeSpinLock(&deviceExtension->IdleReqStateLock); 00181 deviceExtension->IdleReqPend = 0; 00182 deviceExtension->PendingIdleIrp = NULL; 00183 00184 // Hold requests until the device is started 00185 deviceExtension->QueueState = HoldRequests; 00186 00187 // Initialize the queue and the queue spin lock 00188 InitializeListHead(&deviceExtension->NewRequestsQueue); 00189 KeInitializeSpinLock(&deviceExtension->QueueLock); 00190 00191 // Initialize the remove event to not-signaled. 00192 KeInitializeEvent(&deviceExtension->RemoveEvent, SynchronizationEvent, FALSE); 00193 00194 // Initialize the stop event to signaled. 00195 // This event is signaled when the OutstandingIO becomes 1 00196 KeInitializeEvent(&deviceExtension->StopEvent, SynchronizationEvent, TRUE); 00197 00198 // OutstandingIo count biased to 1. 00199 // Transition to 0 during remove device means IO is finished. 00200 // Transition to 1 means the device can be stopped 00201 deviceExtension->OutStandingIO = 1; 00202 KeInitializeSpinLock(&deviceExtension->IOCountLock); 00203 00204 #ifdef ENABLE_WMI 00205 // Delegating to WMILIB 00206 ntStatus = FreeBT_WmiRegistration(deviceExtension); 00207 if (!NT_SUCCESS(ntStatus)) 00208 { 00209 FreeBT_DbgPrint(1, ("FBTUSB: FreeBT_WmiRegistration failed with %X\n", ntStatus)); 00210 IoDeleteDevice(deviceObject); 00211 IoDeleteSymbolicLink(&uniDosDeviceName); 00212 return ntStatus; 00213 00214 } 00215 #endif 00216 00217 // Set the flags as underlying PDO 00218 if (PhysicalDeviceObject->Flags & DO_POWER_PAGABLE) 00219 { 00220 deviceObject->Flags |= DO_POWER_PAGABLE; 00221 00222 } 00223 00224 // Typically, the function driver for a device is its 00225 // power policy owner, although for some devices another 00226 // driver or system component may assume this role. 00227 // Set the initial power state of the device, if known, by calling 00228 // PoSetPowerState. 00229 deviceExtension->DevPower = PowerDeviceD0; 00230 deviceExtension->SysPower = PowerSystemWorking; 00231 00232 state.DeviceState = PowerDeviceD0; 00233 PoSetPowerState(deviceObject, DevicePowerState, state); 00234 00235 // attach our driver to device stack 00236 // The return value of IoAttachDeviceToDeviceStack is the top of the 00237 // attachment chain. This is where all the IRPs should be routed. 00238 deviceExtension->TopOfStackDeviceObject = IoAttachDeviceToDeviceStack(deviceObject, PhysicalDeviceObject); 00239 if (NULL == deviceExtension->TopOfStackDeviceObject) 00240 { 00241 #ifdef ENABLE_WMI 00242 FreeBT_WmiDeRegistration(deviceExtension); 00243 #endif 00244 IoDeleteDevice(deviceObject); 00245 IoDeleteSymbolicLink(&uniDosDeviceName); 00246 return STATUS_NO_SUCH_DEVICE; 00247 00248 } 00249 00250 // Register device interfaces 00251 ntStatus = IoRegisterDeviceInterface(deviceExtension->PhysicalDeviceObject, 00252 &GUID_CLASS_FREEBT_USB, 00253 NULL, 00254 &deviceExtension->InterfaceName); 00255 if (!NT_SUCCESS(ntStatus)) 00256 { 00257 #ifdef ENABLE_WMI 00258 FreeBT_WmiDeRegistration(deviceExtension); 00259 #endif 00260 IoDetachDevice(deviceExtension->TopOfStackDeviceObject); 00261 IoDeleteDevice(deviceObject); 00262 IoDeleteSymbolicLink(&uniDosDeviceName); 00263 return ntStatus; 00264 00265 } 00266 00267 if (IoIsWdmVersionAvailable(1, 0x20)) 00268 { 00269 deviceExtension->WdmVersion = WinXpOrBetter; 00270 00271 } 00272 00273 else if (IoIsWdmVersionAvailable(1, 0x10)) 00274 { 00275 deviceExtension->WdmVersion = Win2kOrBetter; 00276 00277 } 00278 00279 else if (IoIsWdmVersionAvailable(1, 0x5)) 00280 { 00281 deviceExtension->WdmVersion = WinMeOrBetter; 00282 00283 } 00284 00285 else if (IoIsWdmVersionAvailable(1, 0x0)) 00286 { 00287 deviceExtension->WdmVersion = Win98OrBetter; 00288 00289 } 00290 00291 deviceExtension->SSRegistryEnable = 0; 00292 deviceExtension->SSEnable = 0; 00293 00294 // WinXP only: check the registry flag indicating whether 00295 // the device should selectively suspend when idle 00296 if (WinXpOrBetter == deviceExtension->WdmVersion) 00297 { 00298 FreeBT_GetRegistryDword(FREEBT_REGISTRY_PARAMETERS_PATH, 00299 L"BulkUsbEnable", 00300 (PULONG)(&deviceExtension->SSRegistryEnable)); 00301 if (deviceExtension->SSRegistryEnable) 00302 { 00303 // initialize DPC 00304 KeInitializeDpc(&deviceExtension->DeferredProcCall, DpcRoutine, deviceObject); 00305 00306 // initialize the timer. 00307 // the DPC and the timer in conjunction, 00308 // monitor the state of the device to 00309 // selectively suspend the device. 00310 KeInitializeTimerEx(&deviceExtension->Timer, NotificationTimer); 00311 00312 // Initialize the NoDpcWorkItemPendingEvent to signaled state. 00313 // This event is cleared when a Dpc is fired and signaled 00314 // on completion of the work-item. 00315 KeInitializeEvent(&deviceExtension->NoDpcWorkItemPendingEvent, NotificationEvent, TRUE); 00316 00317 // Initialize the NoIdleReqPendEvent to ensure that the idle request 00318 // is indeed complete before we unload the drivers. 00319 KeInitializeEvent(&deviceExtension->NoIdleReqPendEvent, NotificationEvent, TRUE); 00320 00321 } 00322 00323 } 00324 00325 // Initialize the NoIdleReqPendEvent to ensure that the idle request 00326 // is indeed complete before we unload the drivers. 00327 KeInitializeEvent(&deviceExtension->DelayEvent, NotificationEvent, FALSE); 00328 00329 // Clear the DO_DEVICE_INITIALIZING flag. 00330 // Note: Do not clear this flag until the driver has set the 00331 // device power state and the power DO flags. 00332 deviceObject->Flags &= ~DO_DEVICE_INITIALIZING; 00333 InterlockedIncrement(&instanceNumber); 00334 00335 FreeBT_DbgPrint(3, ("FBTUSB: FreeBT_AddDevice: Leaving\n")); 00336 00337 return ntStatus; 00338 00339 } 00340 00341 Generated on Sun May 27 2012 04:27:13 for ReactOS by
1.7.6.1
|