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

NTSTATUS NTAPI PopAddRemoveSysCapsCallback ( IN PVOID  NotificationStructure,
IN PVOID  Context 
)

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;
    }
}

Generated on Sun May 27 2012 06:07:08 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.