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

main.c
Go to the documentation of this file.
00001 #include <ntddk.h>
00002 
00003 #include <acpi.h>
00004 #include <acpisys.h>
00005 
00006 #include <acpi_bus.h>
00007 #include <acpi_drivers.h>
00008 
00009 #include <acpiioct.h>
00010 #include <poclass.h>
00011 
00012 #define NDEBUG
00013 #include <debug.h>
00014 
00015 NTSTATUS
00016 NTAPI
00017 DriverEntry (
00018     PDRIVER_OBJECT  DriverObject,
00019     PUNICODE_STRING RegistryPath
00020     );
00021 
00022 #ifdef ALLOC_PRAGMA
00023 #pragma alloc_text (INIT, DriverEntry)
00024 #pragma alloc_text (PAGE, Bus_AddDevice)
00025 
00026 #endif
00027 
00028 extern struct acpi_device *sleep_button;
00029 extern struct acpi_device *power_button;
00030 
00031 NTSTATUS
00032 NTAPI
00033 Bus_AddDevice(
00034     PDRIVER_OBJECT DriverObject,
00035     PDEVICE_OBJECT PhysicalDeviceObject
00036     )
00037 
00038 {
00039     NTSTATUS            status;
00040     PDEVICE_OBJECT      deviceObject = NULL;
00041     PFDO_DEVICE_DATA    deviceData = NULL;
00042     PWCHAR              deviceName = NULL;
00043 #ifndef NDEBUG
00044     ULONG               nameLength;
00045 #endif
00046 
00047     PAGED_CODE ();
00048 
00049     DPRINT("Add Device: 0x%p\n",  PhysicalDeviceObject);
00050 
00051     DPRINT("#################### Bus_CreateClose Creating FDO Device ####################\n");
00052     status = IoCreateDevice(DriverObject,
00053                       sizeof(FDO_DEVICE_DATA),
00054                       NULL,
00055                       FILE_DEVICE_ACPI,
00056                       FILE_DEVICE_SECURE_OPEN,
00057                       TRUE,
00058                       &deviceObject);
00059     if (!NT_SUCCESS(status))
00060     {
00061         DPRINT1("IoCreateDevice() failed with status 0x%X\n", status);
00062         goto End;
00063     }
00064 
00065     deviceData = (PFDO_DEVICE_DATA) deviceObject->DeviceExtension;
00066     RtlZeroMemory (deviceData, sizeof (FDO_DEVICE_DATA));
00067 
00068     //
00069     // Set the initial state of the FDO
00070     //
00071 
00072     INITIALIZE_PNP_STATE(deviceData->Common);
00073 
00074     deviceData->Common.IsFDO = TRUE;
00075 
00076     deviceData->Common.Self = deviceObject;
00077 
00078     ExInitializeFastMutex (&deviceData->Mutex);
00079 
00080     InitializeListHead (&deviceData->ListOfPDOs);
00081 
00082     // Set the PDO for use with PlugPlay functions
00083 
00084     deviceData->UnderlyingPDO = PhysicalDeviceObject;
00085 
00086     //
00087     // Set the initial powerstate of the FDO
00088     //
00089 
00090     deviceData->Common.DevicePowerState = PowerDeviceUnspecified;
00091     deviceData->Common.SystemPowerState = PowerSystemWorking;
00092 
00093     deviceObject->Flags |= DO_POWER_PAGABLE;
00094 
00095     //
00096     // Attach our FDO to the device stack.
00097     // The return value of IoAttachDeviceToDeviceStack is the top of the
00098     // attachment chain.  This is where all the IRPs should be routed.
00099     //
00100 
00101     deviceData->NextLowerDriver = IoAttachDeviceToDeviceStack (
00102                                     deviceObject,
00103                                     PhysicalDeviceObject);
00104 
00105     if (NULL == deviceData->NextLowerDriver) {
00106 
00107         status = STATUS_NO_SUCH_DEVICE;
00108         goto End;
00109     }
00110 
00111 
00112 #ifndef NDEBUG
00113     //
00114     // We will demonstrate here the step to retrieve the name of the PDO
00115     //
00116 
00117     status = IoGetDeviceProperty (PhysicalDeviceObject,
00118                                   DevicePropertyPhysicalDeviceObjectName,
00119                                   0,
00120                                   NULL,
00121                                   &nameLength);
00122 
00123     if (status != STATUS_BUFFER_TOO_SMALL)
00124     {
00125         DPRINT1("AddDevice:IoGDP failed (0x%x)\n", status);
00126         goto End;
00127     }
00128 
00129     deviceName = ExAllocatePoolWithTag (NonPagedPool,
00130                             nameLength, 'IPCA');
00131 
00132     if (NULL == deviceName) {
00133         DPRINT1("AddDevice: no memory to alloc for deviceName(0x%x)\n", nameLength);
00134         status =  STATUS_INSUFFICIENT_RESOURCES;
00135         goto End;
00136     }
00137 
00138     status = IoGetDeviceProperty (PhysicalDeviceObject,
00139                          DevicePropertyPhysicalDeviceObjectName,
00140                          nameLength,
00141                          deviceName,
00142                          &nameLength);
00143 
00144     if (!NT_SUCCESS (status)) {
00145 
00146         DPRINT1("AddDevice:IoGDP(2) failed (0x%x)", status);
00147         goto End;
00148     }
00149 
00150     DPRINT("AddDevice: %p to %p->%p (%ws) \n",
00151                    deviceObject,
00152                    deviceData->NextLowerDriver,
00153                    PhysicalDeviceObject,
00154                    deviceName);
00155 
00156 #endif
00157 
00158     //
00159     // We are done with initializing, so let's indicate that and return.
00160     // This should be the final step in the AddDevice process.
00161     //
00162     deviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
00163 
00164 End:
00165     if (deviceName){
00166         ExFreePoolWithTag(deviceName, 'IPCA');
00167     }
00168     if (!NT_SUCCESS(status) && deviceObject){
00169         if (deviceData && deviceData->NextLowerDriver){
00170             IoDetachDevice (deviceData->NextLowerDriver);
00171         }
00172         IoDeleteDevice (deviceObject);
00173     }
00174     return status;
00175 
00176 }
00177 
00178 NTSTATUS
00179 NTAPI
00180 ACPIDispatchCreateClose(
00181    IN PDEVICE_OBJECT DeviceObject,
00182    IN PIRP Irp)
00183 {
00184    Irp->IoStatus.Status = STATUS_SUCCESS;
00185    Irp->IoStatus.Information = 0;
00186 
00187    IoCompleteRequest(Irp, IO_NO_INCREMENT);
00188 
00189    return STATUS_SUCCESS;
00190 }
00191 
00192 VOID
00193 NTAPI
00194 ButtonWaitThread(PVOID Context)
00195 {
00196     PIRP Irp = Context;
00197     int result;
00198     struct acpi_bus_event event;
00199     ULONG ButtonEvent;
00200 
00201     while (ACPI_SUCCESS(result = acpi_bus_receive_event(&event)) &&
00202            event.type != ACPI_BUTTON_NOTIFY_STATUS);
00203 
00204     if (!ACPI_SUCCESS(result))
00205     {
00206        Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
00207     }
00208     else
00209     {
00210        if (strstr(event.bus_id, "PWRF"))
00211            ButtonEvent = SYS_BUTTON_POWER;
00212        else if (strstr(event.bus_id, "SLPF"))
00213            ButtonEvent = SYS_BUTTON_SLEEP;
00214        else
00215            ButtonEvent = 0;
00216 
00217        RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer, &ButtonEvent, sizeof(ButtonEvent));
00218        Irp->IoStatus.Status = STATUS_SUCCESS;
00219        Irp->IoStatus.Information = sizeof(ULONG);
00220     }
00221 
00222     IoCompleteRequest(Irp, IO_NO_INCREMENT);
00223 }
00224     
00225 
00226 NTSTATUS
00227 NTAPI
00228 ACPIDispatchDeviceControl(
00229    IN PDEVICE_OBJECT DeviceObject,
00230    IN PIRP Irp)
00231 {
00232     PIO_STACK_LOCATION      irpStack;
00233     NTSTATUS                status = STATUS_NOT_SUPPORTED;
00234     PCOMMON_DEVICE_DATA     commonData;
00235     ULONG Caps = 0;
00236     HANDLE ThreadHandle;
00237 
00238     PAGED_CODE ();
00239 
00240     irpStack = IoGetCurrentIrpStackLocation (Irp);
00241     ASSERT (IRP_MJ_DEVICE_CONTROL == irpStack->MajorFunction);
00242 
00243     commonData = (PCOMMON_DEVICE_DATA) DeviceObject->DeviceExtension;
00244 
00245     Irp->IoStatus.Information = 0;
00246 
00247     if (!commonData->IsFDO)
00248     {
00249        switch (irpStack->Parameters.DeviceIoControl.IoControlCode)
00250        {
00251            case IOCTL_ACPI_EVAL_METHOD:
00252               status = Bus_PDO_EvalMethod((PPDO_DEVICE_DATA)commonData,
00253                                           Irp);
00254               break;
00255 
00256            case IOCTL_GET_SYS_BUTTON_CAPS:
00257               if (irpStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(ULONG))
00258               {
00259                   status = STATUS_BUFFER_TOO_SMALL;
00260                   break;
00261               }
00262 
00263               if (wcsstr(((PPDO_DEVICE_DATA)commonData)->HardwareIDs, L"PNP0C0D"))
00264               {
00265                   DPRINT1("Lid button reported to power manager\n");
00266                   Caps |= SYS_BUTTON_LID;
00267               }
00268               else if (((PPDO_DEVICE_DATA)commonData)->AcpiHandle == NULL)
00269               {
00270                   /* We have to return both at the same time because since we
00271                    * have a NULL handle we are the fixed feature DO and we will
00272                    * only be called once (not once per device)
00273                    */
00274                   if (power_button)
00275                   {
00276                       DPRINT1("Fixed power button reported to power manager\n");
00277                       Caps |= SYS_BUTTON_POWER;
00278                   }
00279                   if (sleep_button)
00280                   {
00281                       DPRINT1("Fixed sleep button reported to power manager\n");
00282                       Caps |= SYS_BUTTON_SLEEP;
00283                   }
00284               }
00285               else if (wcsstr(((PPDO_DEVICE_DATA)commonData)->HardwareIDs, L"PNP0C0C"))
00286               {
00287                   DPRINT1("Control method power button reported to power manager\n");
00288                   Caps |= SYS_BUTTON_POWER;
00289               }
00290               else if (wcsstr(((PPDO_DEVICE_DATA)commonData)->HardwareIDs, L"PNP0C0E"))
00291               {
00292                   DPRINT1("Control method sleep reported to power manager\n");
00293                   Caps |= SYS_BUTTON_SLEEP;
00294               }
00295               else
00296               {
00297                   DPRINT1("IOCTL_GET_SYS_BUTTON_CAPS sent to a non-button device\n");
00298                   status = STATUS_INVALID_PARAMETER;
00299               }
00300 
00301               if (Caps != 0)
00302               {
00303                   RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer, &Caps, sizeof(Caps));
00304                   Irp->IoStatus.Information = sizeof(Caps);
00305                   status = STATUS_SUCCESS;
00306               }
00307               break;
00308 
00309            case IOCTL_GET_SYS_BUTTON_EVENT:
00310               PsCreateSystemThread(&ThreadHandle, THREAD_ALL_ACCESS, 0, 0, 0, ButtonWaitThread, Irp);
00311               ZwClose(ThreadHandle);
00312 
00313               status = STATUS_PENDING;
00314               break;
00315 
00316            default:
00317               DPRINT1("Unsupported IOCTL: %x\n", irpStack->Parameters.DeviceIoControl.IoControlCode);
00318               break;
00319        }
00320     }
00321     else
00322        DPRINT1("IOCTL sent to the ACPI FDO! Kill the caller!\n");
00323 
00324     if (status != STATUS_PENDING)
00325     {
00326        Irp->IoStatus.Status = status;
00327        IoCompleteRequest(Irp, IO_NO_INCREMENT);
00328     }
00329     else
00330        IoMarkIrpPending(Irp);
00331 
00332     return status;
00333 }
00334 
00335 NTSTATUS
00336 NTAPI
00337 DriverEntry (
00338     PDRIVER_OBJECT  DriverObject,
00339     PUNICODE_STRING RegistryPath
00340     )
00341 {
00342     DPRINT("Driver Entry \n");
00343 
00344     //
00345     // Set entry points into the driver
00346     //
00347     DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = ACPIDispatchDeviceControl;
00348     DriverObject->MajorFunction [IRP_MJ_PNP] = Bus_PnP;
00349     DriverObject->MajorFunction [IRP_MJ_POWER] = Bus_Power;
00350     DriverObject->MajorFunction [IRP_MJ_CREATE] = ACPIDispatchCreateClose;
00351     DriverObject->MajorFunction [IRP_MJ_CLOSE] = ACPIDispatchCreateClose;
00352 
00353     DriverObject->DriverExtension->AddDevice = Bus_AddDevice;
00354 
00355     return STATUS_SUCCESS;
00356 }

Generated on Sun May 27 2012 04:16:44 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.