Home | Info | Community | Development | myReactOS | Contact Us
Definition at line 150 of file events.c.
Referenced by PoInitSystem().
{ PDEVICE_INTERFACE_CHANGE_NOTIFICATION Notification; PSYS_BUTTON_CONTEXT SysButtonContext; OBJECT_ATTRIBUTES ObjectAttributes; HANDLE FileHandle; PDEVICE_OBJECT DeviceObject; PFILE_OBJECT FileObject; PIRP Irp; IO_STATUS_BLOCK IoStatusBlock; KEVENT Event; BOOLEAN Arrival; ULONG Caps; NTSTATUS Status; UNICODE_STRING DeviceName; UNICODE_STRING DeviceNamePrefix = RTL_CONSTANT_STRING(L"\\??\\"); DPRINT("PopAddRemoveSysCapsCallback(%p %p)\n", NotificationStructure, Context); Notification = (PDEVICE_INTERFACE_CHANGE_NOTIFICATION)NotificationStructure; if (Notification->Version != 1) return STATUS_REVISION_MISMATCH; if (Notification->Size != sizeof(DEVICE_INTERFACE_CHANGE_NOTIFICATION)) return STATUS_INVALID_PARAMETER; if (RtlCompareMemory(&Notification->Event, &GUID_DEVICE_INTERFACE_ARRIVAL, sizeof(GUID)) == sizeof(GUID)) Arrival = TRUE; else if (RtlCompareMemory(&Notification->Event, &GUID_DEVICE_INTERFACE_REMOVAL, sizeof(GUID)) == sizeof(GUID)) Arrival = FALSE; else return STATUS_INVALID_PARAMETER; if (Arrival) { DPRINT("Arrival of %wZ\n", Notification->SymbolicLinkName); DeviceName.Length = 0; DeviceName.MaximumLength = Notification->SymbolicLinkName->MaximumLength + DeviceNamePrefix.MaximumLength; DeviceName.Buffer = ExAllocatePool(PagedPool, DeviceName.MaximumLength); if (!DeviceName.Buffer) return STATUS_INSUFFICIENT_RESOURCES; RtlCopyUnicodeString(&DeviceName, &DeviceNamePrefix); RtlAppendUnicodeStringToString(&DeviceName, Notification->SymbolicLinkName); DPRINT("Opening handle to %wZ\n", &DeviceName); /* Open the device */ InitializeObjectAttributes( &ObjectAttributes, &DeviceName, OBJ_KERNEL_HANDLE, NULL, NULL); Status = ZwOpenFile( &FileHandle, FILE_READ_DATA, &ObjectAttributes, &IoStatusBlock, FILE_SHARE_READ | FILE_SHARE_WRITE, 0); RtlFreeUnicodeString(&DeviceName); if (!NT_SUCCESS(Status)) { DPRINT1("ZwOpenFile() failed with status 0x%08lx\n", Status); return Status; } Status = ObReferenceObjectByHandle( FileHandle, FILE_READ_DATA, IoFileObjectType, KernelMode, (PVOID*)&FileObject, NULL); if (!NT_SUCCESS(Status)) { DPRINT1("ObReferenceObjectByHandle() failed with status 0x%08lx\n", Status); ZwClose(FileHandle); return Status; } DeviceObject = IoGetRelatedDeviceObject(FileObject); ObDereferenceObject(FileObject); /* Get capabilities (IOCTL_GET_SYS_BUTTON_CAPS) */ KeInitializeEvent(&Event, NotificationEvent, FALSE); Irp = IoBuildDeviceIoControlRequest( IOCTL_GET_SYS_BUTTON_CAPS, DeviceObject, NULL, 0, &Caps, sizeof(Caps), FALSE, &Event, &IoStatusBlock); if (!Irp) { DPRINT1("IoBuildDeviceIoControlRequest() failed\n"); ZwClose(FileHandle); return STATUS_INSUFFICIENT_RESOURCES; } Status = IoCallDriver(DeviceObject, Irp); if (Status == STATUS_PENDING) { DPRINT("IOCTL_GET_SYS_BUTTON_CAPS pending\n"); KeWaitForSingleObject(&Event, Suspended, KernelMode, FALSE, NULL); Status = IoStatusBlock.Status; } if (!NT_SUCCESS(Status)) { DPRINT1("Sending IOCTL_GET_SYS_BUTTON_CAPS failed with status 0x%08x\n", Status); ZwClose(FileHandle); return STATUS_INSUFFICIENT_RESOURCES; } /* FIXME: What do do with the capabilities? */ { DPRINT1("Device capabilities: 0x%x (", Caps); if (Caps & SYS_BUTTON_POWER) DbgPrint(" POWER"); if (Caps & SYS_BUTTON_SLEEP) DbgPrint(" SLEEP"); if (Caps & SYS_BUTTON_LID) DbgPrint(" LID"); DbgPrint(" )\n"); } SysButtonContext = ExAllocatePool(NonPagedPool, sizeof(SYS_BUTTON_CONTEXT)); if (!SysButtonContext) { DPRINT1("ExAllocatePool() failed\n"); ZwClose(FileHandle); return STATUS_INSUFFICIENT_RESOURCES; } /* Queue a work item to get sys button event */ SysButtonContext->WorkItem = IoAllocateWorkItem(DeviceObject); SysButtonContext->DeviceObject = DeviceObject; if (!SysButtonContext->WorkItem) { DPRINT1("IoAllocateWorkItem() failed\n"); ZwClose(FileHandle); ExFreePool(SysButtonContext); return STATUS_INSUFFICIENT_RESOURCES; } IoQueueWorkItem( SysButtonContext->WorkItem, PopGetSysButton, DelayedWorkQueue, SysButtonContext); ZwClose(FileHandle); return STATUS_SUCCESS; } else { DPRINT1("Removal of a power capable device not implemented\n"); return STATUS_NOT_IMPLEMENTED; } }