Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenmain.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
1.7.6.1
|