ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

fbtusb.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.