Use device::irp_mj.pnp(), instead.
This is the last of the IRP_MJ_* major functions that were
previously handled with the mini IRP handling scheme.
[Project]\r
FileName=WinVBlock.dev\r
Name=WinVBlock\r
-UnitCount=66\r
+UnitCount=64\r
PchHead=-1\r
PchSource=-1\r
Ver=3\r
BuildCmd=\r
\r
[Unit30]\r
-FileName=src\include\debug.h\r
-CompileCpp=1\r
-Folder=Include\r
-Compile=1\r
-Link=1\r
-Priority=1000\r
-OverrideBuildCmd=0\r
-BuildCmd=\r
-\r
-[Unit31]\r
FileName=src\include\disk.h\r
CompileCpp=1\r
Folder=Include\r
BuildCmd=\r
\r
[Unit34]\r
-FileName=src\include\filedisk.h\r
+FileName=src\include\httpdisk.h\r
CompileCpp=1\r
Folder=Include\r
Compile=1\r
BuildCmd=\r
\r
[Unit35]\r
-FileName=src\include\grub4dos.h\r
+FileName=src\include\irp.h\r
CompileCpp=1\r
Folder=Include\r
Compile=1\r
BuildCmd=\r
\r
[Unit36]\r
-FileName=src\include\httpdisk.h\r
+FileName=src\include\mdi.h\r
CompileCpp=1\r
Folder=Include\r
Compile=1\r
BuildCmd=\r
\r
[Unit37]\r
-FileName=src\include\irp.h\r
+FileName=src\include\memdisk.h\r
CompileCpp=1\r
Folder=Include\r
Compile=1\r
BuildCmd=\r
\r
[Unit38]\r
-FileName=src\include\mdi.h\r
+FileName=src\include\mount.h\r
CompileCpp=1\r
Folder=Include\r
Compile=1\r
BuildCmd=\r
\r
[Unit39]\r
-FileName=src\include\memdisk.h\r
+FileName=src\include\portable.h\r
CompileCpp=1\r
Folder=Include\r
Compile=1\r
BuildCmd=\r
\r
[Unit40]\r
-FileName=src\include\mount.h\r
+FileName=src\include\probe.h\r
CompileCpp=1\r
Folder=Include\r
Compile=1\r
BuildCmd=\r
\r
[Unit41]\r
-FileName=src\include\portable.h\r
+FileName=src\include\protocol.h\r
CompileCpp=1\r
Folder=Include\r
Compile=1\r
BuildCmd=\r
\r
[Unit42]\r
-FileName=src\include\probe.h\r
+FileName=src\include\ramdisk.h\r
CompileCpp=1\r
Folder=Include\r
Compile=1\r
BuildCmd=\r
\r
[Unit43]\r
-FileName=src\include\protocol.h\r
+FileName=src\include\registry.h\r
Folder=Include\r
Compile=1\r
Link=1\r
CompileCpp=1\r
\r
[Unit44]\r
-FileName=src\include\ramdisk.h\r
+FileName=src\include\resource.h\r
CompileCpp=1\r
Folder=Include\r
Compile=1\r
BuildCmd=\r
\r
[Unit45]\r
-FileName=src\include\registry.h\r
+FileName=src\include\winvblock.h\r
CompileCpp=1\r
Folder=Include\r
Compile=1\r
BuildCmd=\r
\r
[Unit46]\r
-FileName=src\include\resource.h\r
+FileName=src\util\mount.c\r
CompileCpp=1\r
-Folder=Include\r
+Folder=Util\r
Compile=1\r
Link=1\r
Priority=1000\r
BuildCmd=\r
\r
[Unit47]\r
-FileName=src\include\winvblock.h\r
-Folder=Include\r
+FileName=src\aoe\aoe.rc\r
+Folder=AoE\r
Compile=1\r
-Link=1\r
+Link=0\r
Priority=1000\r
OverrideBuildCmd=0\r
BuildCmd=\r
CompileCpp=1\r
\r
[Unit48]\r
-FileName=src\util\mount.c\r
+FileName=src\include\device.h\r
CompileCpp=1\r
-Folder=Util\r
+Folder=Include\r
Compile=1\r
Link=1\r
Priority=1000\r
BuildCmd=\r
\r
[Unit49]\r
-FileName=src\aoe\aoe.rc\r
+FileName=src\winvblock\device.c\r
CompileCpp=1\r
-Folder=AoE\r
+Folder=WinVBlock\r
Compile=1\r
-Link=0\r
+Link=1\r
Priority=1000\r
OverrideBuildCmd=0\r
BuildCmd=\r
\r
[Unit50]\r
-FileName=src\include\device.h\r
+FileName=src\winvblock\filedisk\filedisk.c\r
CompileCpp=1\r
-Folder=Include\r
+Folder=WinVBlock/FileDisk\r
Compile=1\r
Link=1\r
Priority=1000\r
BuildCmd=\r
\r
[Unit51]\r
-FileName=src\winvblock\device.c\r
-Folder=WinVBlock\r
+FileName=src\winvblock\filedisk\grub4dos.c\r
+Folder=WinVBlock/FileDisk\r
Compile=1\r
Link=1\r
Priority=1000\r
CompileCpp=1\r
\r
[Unit52]\r
-FileName=src\winvblock\filedisk\filedisk.c\r
+FileName=src\include\byte.h\r
CompileCpp=1\r
-Folder=WinVBlock/FileDisk\r
+Folder=Include\r
Compile=1\r
Link=1\r
Priority=1000\r
BuildCmd=\r
\r
[Unit53]\r
-FileName=src\winvblock\filedisk\grub4dos.c\r
-Folder=WinVBlock/FileDisk\r
+FileName=src\include\msvhd.h\r
+Folder=Include\r
Compile=1\r
Link=1\r
Priority=1000\r
CompileCpp=1\r
\r
[Unit54]\r
-FileName=src\include\byte.h\r
+FileName=src\util\winvblock.rc\r
CompileCpp=1\r
-Folder=Include\r
+Folder=Util\r
Compile=1\r
-Link=1\r
+Link=0\r
Priority=1000\r
OverrideBuildCmd=0\r
BuildCmd=\r
\r
[Unit55]\r
-FileName=src\include\msvhd.h\r
+FileName=src\include\wv_stdlib.h\r
CompileCpp=1\r
Folder=Include\r
Compile=1\r
BuildCmd=\r
\r
[Unit56]\r
-FileName=src\util\winvblock.rc\r
+FileName=src\winvblock\wv_stdlib.c\r
CompileCpp=1\r
-Folder=Util\r
+Folder=WinVBlock\r
Compile=1\r
-Link=0\r
+Link=1\r
Priority=1000\r
OverrideBuildCmd=0\r
BuildCmd=\r
\r
[Unit57]\r
-FileName=src\include\wv_stdlib.h\r
+FileName=src\include\wv_stddef.h\r
CompileCpp=1\r
Folder=Include\r
Compile=1\r
BuildCmd=\r
\r
[Unit58]\r
-FileName=src\winvblock\wv_stdlib.c\r
+FileName=src\aoe\wv_stdlib.c\r
CompileCpp=1\r
-Folder=WinVBlock\r
+Folder=AoE\r
Compile=1\r
Link=1\r
Priority=1000\r
BuildCmd=\r
\r
[Unit59]\r
-FileName=src\include\wv_stddef.h\r
+FileName=src\include\wv_string.h\r
Folder=Include\r
Compile=1\r
Link=1\r
CompileCpp=1\r
\r
[Unit61]\r
-FileName=src\include\wv_string.h\r
+FileName=src\include\wv_stdbool.h\r
CompileCpp=1\r
Folder=Include\r
Compile=1\r
BuildCmd=\r
\r
[Unit60]\r
-FileName=src\aoe\wv_stdlib.c\r
+FileName=src\winvblock\wv_string.c\r
CompileCpp=1\r
-Folder=AoE\r
+Folder=WinVBlock\r
Compile=1\r
Link=1\r
Priority=1000\r
BuildCmd=\r
\r
[Unit62]\r
-FileName=src\winvblock\wv_string.c\r
+FileName=src\aoe\wv_string.c\r
CompileCpp=1\r
-Folder=WinVBlock\r
+Folder=AoE\r
Compile=1\r
Link=1\r
Priority=1000\r
BuildCmd=\r
\r
[Unit63]\r
-FileName=src\include\wv_stdbool.h\r
+FileName=src\aoe\bus.c\r
CompileCpp=1\r
-Folder=Include\r
+Folder=AoE\r
Compile=1\r
Link=1\r
Priority=1000\r
BuildCmd=\r
\r
[Unit64]\r
-FileName=src\aoe\wv_string.c\r
+FileName=src\include\aoe_bus.h\r
CompileCpp=1\r
-Folder=AoE\r
+Folder=Include\r
Compile=1\r
Link=1\r
Priority=1000\r
OverrideBuildCmd=0\r
BuildCmd=\r
\r
-[Unit29]\r
-FileName=src\include\bus_pnp.h\r
+[Unit32]\r
+FileName=src\include\filedisk.h\r
CompileCpp=1\r
Folder=Include\r
Compile=1\r
OverrideBuildCmd=0\r
BuildCmd=\r
\r
-[Unit32]\r
-FileName=src\include\disk_pnp.h\r
+[Unit33]\r
+FileName=src\include\grub4dos.h\r
CompileCpp=1\r
Folder=Include\r
Compile=1\r
OverrideBuildCmd=0\r
BuildCmd=\r
\r
-[Unit33]\r
+[Unit29]\r
+FileName=src\include\debug.h\r
+CompileCpp=1\r
+Folder=Include\r
+Compile=1\r
+Link=1\r
+Priority=1000\r
+OverrideBuildCmd=0\r
+BuildCmd=\r
+\r
+[Unit31]\r
FileName=src\include\driver.h\r
CompileCpp=1\r
Folder=Include\r
+++ /dev/null
-/**
- * Copyright (C) 2009-2010, Shao Miller <shao.miller@yrdsb.edu.on.ca>.
- * Copyright 2006-2008, V.
- * For WinAoE contact information, see http://winaoe.org/
- *
- * This file is part of WinVBlock, derived from WinAoE.
- *
- * WinVBlock is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * WinVBlock is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with WinVBlock. If not, see <http://www.gnu.org/licenses/>.
- */
-#ifndef _BUS_PNP_H
-# define _BUS_PNP_H
-
-/**
- * @file
- *
- * Bus PnP IRP handling.
- */
-
-extern irp__handler bus_pnp__start_dev;
-extern irp__handler bus_pnp__remove_dev;
-extern irp__handler bus_pnp__query_dev_relations;
-extern irp__handler bus_pnp__simple;
-
-#endif /* _BUS_PNP_H */
* @v dev Points to the device.
* @v irp Points to the IRP.
* @v code The SCSI function.
- * @v srb The SCSI request block.
* @ret NTSTATUS The status of processing the IRP for the device.
*/
typedef NTSTATUS STDCALL device__scsi_func(
IN UCHAR
);
+/**
+ * The prototype for a device IRP_MJ_PNP dispatch.
+ *
+ * @v dev Points to the device.
+ * @v irp Points to the IRP.
+ * @v code The minor function.
+ * @ret NTSTATUS The status of processing the IRP for the device.
+ */
+typedef NTSTATUS STDCALL device__pnp_func(
+ IN struct device__type *,
+ IN PIRP,
+ IN UCHAR
+ );
+
/* IRP major function handler table. */
struct device__irp_mj {
device__dispatch_func * power;
device__dispatch_func * sys_ctl;
device__dev_ctl_func * dev_ctl;
device__scsi_func * scsi;
+ device__pnp_func * pnp;
};
/* Details common to all devices this driver works with */
PDEVICE_OBJECT,
struct device__type *
);
-extern irp__handler device__pnp_query_id;
+extern device__dispatch_func device__pnp_query_id;
#endif /* _DEVICE_H */
+++ /dev/null
-/**
- * Copyright (C) 2009-2010, Shao Miller <shao.miller@yrdsb.edu.on.ca>.
- * Copyright 2006-2008, V.
- * For WinAoE contact information, see http://winaoe.org/
- *
- * This file is part of WinVBlock, derived from WinAoE.
- *
- * WinVBlock is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * WinVBlock is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with WinVBlock. If not, see <http://www.gnu.org/licenses/>.
- */
-#ifndef _DISK_PNP_H
-# define _DISK_PNP_H
-
-/**
- * @file
- *
- * Disk PnP IRP handling.
- */
-
-extern irp__handler disk_pnp__query_id;
-extern irp__handler disk_pnp__query_dev_text;
-extern irp__handler disk_pnp__query_dev_relations;
-extern irp__handler disk_pnp__query_bus_info;
-extern irp__handler disk_pnp__query_capabilities;
-extern irp__handler disk_pnp__simple;
-
-#endif /* _DISK_PNP_H */
#include "driver.h"
#include "device.h"
#include "bus.h"
-#include "bus_pnp.h"
#include "debug.h"
/* IRP_MJ_DEVICE_CONTROL dispatcher from bus/dev_ctl.c */
extern device__dev_ctl_func bus_dev_ctl__dispatch;
+/* IRP_MJ_PNP dispatcher from bus/pnp.c */
+extern device__pnp_func bus_pnp__dispatch;
/* Forward declarations. */
static device__free_func bus__free_;
static device__create_pdo_func bus__create_pdo_;
static device__dispatch_func bus__power_;
static device__dispatch_func bus__sys_ctl_;
+static device__pnp_func bus__pnp_dispatch_;
/* Globals. */
struct device__irp_mj bus__irp_mj_ = {
bus__sys_ctl_,
bus_dev_ctl__dispatch,
(device__scsi_func *) 0,
+ bus_pnp__dispatch,
};
/**
return status;
}
-/* Bus dispatch routine. */
-static NTSTATUS STDCALL bus_dispatch(
- IN PDEVICE_OBJECT dev,
- IN PIRP irp
- ) {
- NTSTATUS status;
- winvblock__bool completion = FALSE;
- static const irp__handling handling_table[] = {
- /*
- * Major, minor, any major?, any minor?, handler
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- * Note that the fall-through case must come FIRST!
- * Why? It sets completion to true, so others won't be called.
- */
- { 0, 0, TRUE, TRUE, driver__not_supported },
- { IRP_MJ_PNP, 0, FALSE, TRUE, bus_pnp__simple },
- { IRP_MJ_PNP,
- IRP_MN_START_DEVICE, FALSE, FALSE, bus_pnp__start_dev },
- { IRP_MJ_PNP,
- IRP_MN_REMOVE_DEVICE, FALSE, FALSE, bus_pnp__remove_dev },
- { IRP_MJ_PNP,
- IRP_MN_QUERY_DEVICE_RELATIONS, FALSE, FALSE,
- bus_pnp__query_dev_relations },
- { IRP_MJ_PNP,
- IRP_MN_QUERY_ID, FALSE, FALSE, device__pnp_query_id },
- };
-
- /* Try registered mini IRP handling tables first. Deprecated. */
- status = irp__process(
- dev,
- irp,
- IoGetCurrentIrpStackLocation(irp),
- device__get(dev),
- &completion
- );
- /* Fall through to the bus defaults, if needed. */
- if (status == STATUS_NOT_SUPPORTED && !completion)
- status = irp__process_with_table(
- dev,
- irp,
- handling_table,
- sizeof handling_table,
- &completion
- );
- #ifdef DEBUGIRPS
- if (status != STATUS_PENDING)
- Debug_IrpEnd(irp, status);
- #endif
-
- return status;
- }
-
/* Initialize a bus. */
static winvblock__bool STDCALL bus__init_(IN struct device__type * dev) {
return TRUE;
/* Populate non-zero device defaults. */
bus_ptr->device = dev_ptr;
bus_ptr->prev_free = dev_ptr->ops.free;
- dev_ptr->dispatch = bus_dispatch;
dev_ptr->ops.create_pdo = bus__create_pdo_;
dev_ptr->ops.init = bus__init_;
dev_ptr->ops.free = bus__free_;
#include "debug.h"
#include "probe.h"
+/* Forward declarations. */
+static device__dispatch_func bus_pnp__start_dev_;
+static device__dispatch_func bus_pnp__remove_dev_;
+static device__dispatch_func bus_pnp__query_dev_relations_;
+static device__pnp_func bus_pnp__simple_;
+device__pnp_func bus_pnp__dispatch;
+
static NTSTATUS STDCALL bus_pnp__io_completion_(
IN PDEVICE_OBJECT dev_obj,
IN PIRP irp,
return STATUS_MORE_PROCESSING_REQUIRED;
}
-NTSTATUS STDCALL bus_pnp__start_dev(
- IN PDEVICE_OBJECT dev_obj,
- IN PIRP irp,
- IN PIO_STACK_LOCATION io_stack_loc,
+static NTSTATUS STDCALL bus_pnp__start_dev_(
IN struct device__type * dev,
- OUT winvblock__bool_ptr completion
+ IN PIRP irp
) {
NTSTATUS status;
KEVENT event;
struct bus__type * bus = bus__get(dev);
PDEVICE_OBJECT lower = bus->LowerDeviceObject;
- if (!lower) {
- *completion = TRUE;
- return STATUS_SUCCESS;
- }
+ if (!lower)
+ return driver__complete_irp(irp, 0, STATUS_SUCCESS);
KeInitializeEvent(&event, NotificationEvent, FALSE);
IoCopyCurrentIrpStackLocationToNext(irp);
IoSetCompletionRoutine(
dev->old_state = dev->state;
dev->state = device__state_started;
}
- status = STATUS_SUCCESS;
- irp->IoStatus.Status = status;
- IoCompleteRequest(irp, IO_NO_INCREMENT);
- *completion = TRUE;
- return status;
+ return driver__complete_irp(
+ irp,
+ irp->IoStatus.Information,
+ STATUS_SUCCESS
+ );
}
-NTSTATUS STDCALL bus_pnp__remove_dev(
- IN PDEVICE_OBJECT dev_obj,
- IN PIRP irp,
- IN PIO_STACK_LOCATION io_stack_loc,
+static NTSTATUS STDCALL bus_pnp__remove_dev_(
IN struct device__type * dev,
- OUT winvblock__bool_ptr completion
+ IN PIRP irp
) {
- NTSTATUS status;
- struct bus__type * bus;
+ NTSTATUS status = STATUS_SUCCESS;
+ struct bus__type * bus = bus__get(dev);
+ PDEVICE_OBJECT lower = bus->LowerDeviceObject;
struct device__type * walker, * next;
- PDEVICE_OBJECT lower;
dev->old_state = dev->state;
dev->state = device__state_deleted;
- irp->IoStatus.Information = 0;
- irp->IoStatus.Status = STATUS_SUCCESS;
- IoSkipCurrentIrpStackLocation(irp);
- bus = bus__get(dev);
- status = IoCallDriver(bus->LowerDeviceObject, irp);
+ /* Pass the IRP on to any lower DEVICE_OBJECT */
+ if (lower) {
+ irp->IoStatus.Information = 0;
+ irp->IoStatus.Status = STATUS_SUCCESS;
+ IoSkipCurrentIrpStackLocation(irp);
+ status = IoCallDriver(lower, irp);
+ }
+ /* Remove all children. */
walker = bus->first_child;
while (walker != NULL) {
next = walker->next_sibling_ptr;
device__free(walker);
walker = next;
}
+ /* Somewhat redundant, since the bus will be freed shortly. */
bus->Children = 0;
bus->first_child = NULL;
- lower = bus->LowerDeviceObject;
+ /* Detach from any lower DEVICE_OBJECT */
if (lower)
IoDetachDevice(lower);
+ /* Delete and free. */
IoDeleteDevice(dev->Self);
device__free(dev);
- *completion = TRUE;
return status;
}
-NTSTATUS STDCALL bus_pnp__query_dev_relations(
- IN PDEVICE_OBJECT dev_obj,
- IN PIRP irp,
- IN PIO_STACK_LOCATION io_stack_loc,
+static NTSTATUS STDCALL bus_pnp__query_dev_relations_(
IN struct device__type * dev,
- OUT winvblock__bool_ptr completion
+ IN PIRP irp
) {
NTSTATUS status;
- struct bus__type * bus;
+ struct bus__type * bus = bus__get(dev);
+ PDEVICE_OBJECT lower = bus->LowerDeviceObject;
+ PIO_STACK_LOCATION io_stack_loc = IoGetCurrentIrpStackLocation(irp);
winvblock__uint32 count;
struct device__type * walker;
PDEVICE_RELATIONS dev_relations;
- PDEVICE_OBJECT lower;
- bus = bus__get(dev);
- lower = bus->LowerDeviceObject;
if (
io_stack_loc->Parameters.QueryDeviceRelations.Type != BusRelations ||
irp->IoStatus.Information
) {
- status = irp->IoStatus.Status;
if (lower) {
IoSkipCurrentIrpStackLocation(irp);
- status = IoCallDriver(lower, irp);
+ return IoCallDriver(lower, irp);
}
- *completion = TRUE;
- return status;
+ return driver__complete_irp(
+ irp,
+ irp->IoStatus.Information,
+ irp->IoStatus.Status
+ );
}
probe__disks();
count = 0;
sizeof *dev_relations + (sizeof (PDEVICE_OBJECT) * count)
);
if (dev_relations == NULL) {
- irp->IoStatus.Information = 0;
- status = STATUS_SUCCESS;
- irp->IoStatus.Status = status;
+ /* Couldn't allocate dev_relations, but silently succeed. */
if (lower) {
IoSkipCurrentIrpStackLocation(irp);
- status = IoCallDriver(lower, irp);
+ return IoCallDriver(lower, irp);
}
- *completion = TRUE;
- return status;
+ return driver__complete_irp(irp, 0, STATUS_SUCCESS);
}
dev_relations->Count = count;
walker = walker->next_sibling_ptr;
}
irp->IoStatus.Information = (ULONG_PTR) dev_relations;
- status = STATUS_SUCCESS;
- irp->IoStatus.Status = status;
+ irp->IoStatus.Status = status = STATUS_SUCCESS;
if (lower) {
IoSkipCurrentIrpStackLocation(irp);
- status = IoCallDriver(lower, irp);
+ return IoCallDriver(lower, irp);
}
- *completion = TRUE;
- return status;
+ return driver__complete_irp(irp, irp->IoStatus.Information, status);
}
-NTSTATUS STDCALL bus_pnp__simple(
- IN PDEVICE_OBJECT dev_obj,
- IN PIRP irp,
- IN PIO_STACK_LOCATION io_stack_loc,
+static NTSTATUS STDCALL bus_pnp__simple_(
IN struct device__type * dev,
- OUT winvblock__bool_ptr completion
+ IN PIRP irp,
+ IN UCHAR code
) {
NTSTATUS status;
- struct bus__type * bus;
- PDEVICE_OBJECT lower;
+ struct bus__type * bus = bus__get(dev);
+ PDEVICE_OBJECT lower = bus->LowerDeviceObject;
- bus = bus__get(dev);
- lower = bus->LowerDeviceObject;
- switch (io_stack_loc->MinorFunction) {
+ switch (code) {
case IRP_MN_QUERY_PNP_DEVICE_STATE:
irp->IoStatus.Information = 0;
status = STATUS_SUCCESS;
irp->IoStatus.Status = status;
if (lower) {
IoSkipCurrentIrpStackLocation(irp);
- status = IoCallDriver(lower, irp);
+ return IoCallDriver(lower, irp);
+ }
+ return driver__complete_irp(irp, irp->IoStatus.Information, status);
+ }
+
+/* Bus PnP dispatch routine. */
+NTSTATUS STDCALL bus_pnp__dispatch(
+ IN struct device__type * dev,
+ IN PIRP irp,
+ IN UCHAR code
+ ) {
+ switch (code) {
+ case IRP_MN_QUERY_ID:
+ return device__pnp_query_id(dev, irp);
+
+ case IRP_MN_QUERY_DEVICE_RELATIONS:
+ return bus_pnp__query_dev_relations_(dev, irp);
+
+ case IRP_MN_REMOVE_DEVICE:
+ return bus_pnp__remove_dev_(dev, irp);
+
+ case IRP_MN_START_DEVICE:
+ return bus_pnp__start_dev_(dev, irp);
+
+ default:
+ return bus_pnp__simple_(dev, irp, code);
}
- *completion = TRUE;
- return status;
}
/* An IRP handler for a PnP ID query. */
NTSTATUS STDCALL device__pnp_query_id(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp,
- IN PIO_STACK_LOCATION Stack,
IN struct device__type * dev,
- OUT winvblock__bool_ptr completion
+ IN PIRP irp
) {
NTSTATUS status;
WCHAR (*str)[512];
winvblock__uint32 str_len;
+ PIO_STACK_LOCATION io_stack_loc = IoGetCurrentIrpStackLocation(irp);
/* Allocate the working buffer. */
str = wv_mallocz(sizeof *str);
/* Invoke the specific device's ID query. */
str_len = device__pnp_id(
dev,
- Stack->Parameters.QueryId.IdType,
+ io_stack_loc->Parameters.QueryId.IdType,
str
);
if (str_len == 0) {
- Irp->IoStatus.Information = 0;
+ irp->IoStatus.Information = 0;
status = STATUS_NOT_SUPPORTED;
goto alloc_info;
}
/* Allocate the return buffer. */
- Irp->IoStatus.Information = (ULONG_PTR) wv_palloc(str_len * sizeof **str);
- if (Irp->IoStatus.Information == 0) {
+ irp->IoStatus.Information = (ULONG_PTR) wv_palloc(str_len * sizeof **str);
+ if (irp->IoStatus.Information == 0) {
DBG("wv_palloc failed.\n");
status = STATUS_INSUFFICIENT_RESOURCES;
goto alloc_info;
}
/* Copy the working buffer to the return buffer. */
RtlCopyMemory(
- (void *) Irp->IoStatus.Information,
+ (void *) irp->IoStatus.Information,
str,
str_len * sizeof **str
);
status = STATUS_SUCCESS;
- /* Irp->IoStatus.Information not freed. */
+ /* irp->IoStatus.Information not freed. */
alloc_info:
wv_free(str);
alloc_str:
- Irp->IoStatus.Status = status;
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
- *completion = TRUE;
- return status;
+ return driver__complete_irp(irp, irp->IoStatus.Information, status);
}
/**
#include "driver.h"
#include "device.h"
#include "disk.h"
-#include "disk_pnp.h"
#include "debug.h"
#ifndef _MSC_VER
extern device__dev_ctl_func disk_dev_ctl__dispatch;
/* IRP_MJ_SCSI dispatcher from disk/scsi.c */
extern device__scsi_func disk_scsi__dispatch;
+/* IRP_MJ_PNP dispatcher from disk/pnp.c */
+extern device__pnp_func disk_pnp__dispatch;
/* Forward declarations. */
static device__free_func free_disk;
disk__sys_ctl_,
disk_dev_ctl__dispatch,
disk_scsi__dispatch,
+ disk_pnp__dispatch,
};
static
disk_ptr->Cylinders = disk_ptr->LBADiskSize / ( heads * sects_per_track );
}
-/* Disk dispatch routine. */
-static NTSTATUS STDCALL (disk_dispatch)(
- IN PDEVICE_OBJECT (dev),
- IN PIRP (irp)
- ) {
- NTSTATUS (status);
- winvblock__bool (completion) = FALSE;
- static const irp__handling (handling_table)[] = {
- /*
- * Major, minor, any major?, any minor?, handler
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- * Note that the fall-through case must come FIRST!
- * Why? It sets completion to true, so others won't be called.
- */
- { 0, 0, TRUE, TRUE, driver__not_supported },
- { IRP_MJ_PNP, 0, FALSE, TRUE, disk_pnp__simple },
- { IRP_MJ_PNP,
- IRP_MN_QUERY_CAPABILITIES, FALSE, FALSE,
- disk_pnp__query_capabilities },
- { IRP_MJ_PNP,
- IRP_MN_QUERY_BUS_INFORMATION, FALSE, FALSE,
- disk_pnp__query_bus_info },
- { IRP_MJ_PNP,
- IRP_MN_QUERY_DEVICE_RELATIONS, FALSE, FALSE,
- disk_pnp__query_dev_relations },
- { IRP_MJ_PNP,
- IRP_MN_QUERY_DEVICE_TEXT, FALSE, FALSE,
- disk_pnp__query_dev_text },
- { IRP_MJ_PNP,
- IRP_MN_QUERY_ID, FALSE, FALSE, device__pnp_query_id },
- };
-
- status = irp__process_with_table(
- dev,
- irp,
- handling_table,
- sizeof handling_table,
- &completion
- );
- #ifdef DEBUGIRPS
- if (status != STATUS_PENDING)
- Debug_IrpEnd(irp, status);
- #endif
-
- return status;
- }
-
/**
* Create a new disk
*
disk_ptr->disk_ops.max_xfer_len = default_max_xfer_len;
disk_ptr->disk_ops.init = default_init;
disk_ptr->disk_ops.close = default_close;
- dev_ptr->dispatch = disk_dispatch;
dev_ptr->ops.close = disk__close_;
dev_ptr->ops.create_pdo = create_pdo;
dev_ptr->ops.free = free_disk;
#include "bus.h"
#include "debug.h"
-NTSTATUS STDCALL disk_pnp__query_dev_text(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp,
- IN PIO_STACK_LOCATION Stack,
- IN struct device__type * dev_ptr,
- OUT winvblock__bool_ptr completion_ptr
- )
-{
- PWCHAR string;
- NTSTATUS status;
- winvblock__uint32 string_length;
- disk__type_ptr disk_ptr;
-
- string = wv_mallocz(512 * sizeof *string);
- disk_ptr = disk__get_ptr ( dev_ptr );
-
- if ( string == NULL )
- {
- DBG("wv_malloc IRP_MN_QUERY_DEVICE_TEXT\n");
- status = STATUS_INSUFFICIENT_RESOURCES;
- goto alloc_string;
- }
-
- switch ( Stack->Parameters.QueryDeviceText.DeviceTextType )
- {
- case DeviceTextDescription:
- string_length = swprintf ( string, winvblock__literal_w L" Disk" ) + 1;
- Irp->IoStatus.Information = (ULONG_PTR) wv_palloc(
- string_length * sizeof *string
- );
- if ( Irp->IoStatus.Information == 0 )
- {
- DBG("wv_palloc DeviceTextDescription\n");
- status = STATUS_INSUFFICIENT_RESOURCES;
- goto alloc_info;
- }
- RtlCopyMemory(
- (PWCHAR) Irp->IoStatus.Information,
- (WCHAR (*)[512]) string,
- string_length * sizeof (WCHAR)
- );
- status = STATUS_SUCCESS;
- goto alloc_info;
-
- case DeviceTextLocationInformation:
- string_length = device__pnp_id(
- dev_ptr,
- BusQueryInstanceID,
- (WCHAR (*)[512]) string
+/* Forward declarations. */
+static device__dispatch_func disk_pnp__query_dev_text_;
+static device__dispatch_func disk_pnp__query_dev_relations_;
+static device__dispatch_func disk_pnp__query_bus_info_;
+static device__dispatch_func disk_pnp__query_capabilities_;
+static device__pnp_func disk_pnp__simple_;
+device__pnp_func disk_pnp__dispatch;
+
+static NTSTATUS STDCALL disk_pnp__query_dev_text_(
+ IN struct device__type * dev,
+ IN PIRP irp
+ ) {
+ disk__type_ptr disk;
+ WCHAR (*str)[512];
+ PIO_STACK_LOCATION io_stack_loc = IoGetCurrentIrpStackLocation(irp);
+ NTSTATUS status;
+ winvblock__uint32 str_len;
+
+ disk = disk__get_ptr(dev);
+ /* Allocate a string buffer. */
+ str = wv_mallocz(sizeof *str);
+ if (str == NULL) {
+ DBG("wv_malloc IRP_MN_QUERY_DEVICE_TEXT\n");
+ status = STATUS_INSUFFICIENT_RESOURCES;
+ goto alloc_str;
+ }
+ /* Determine the query type. */
+ switch (io_stack_loc->Parameters.QueryDeviceText.DeviceTextType) {
+ case DeviceTextDescription:
+ str_len = swprintf(*str, winvblock__literal_w L" Disk") + 1;
+ irp->IoStatus.Information =
+ (ULONG_PTR) wv_palloc(str_len * sizeof *str);
+ if (irp->IoStatus.Information == 0) {
+ DBG("wv_palloc DeviceTextDescription\n");
+ status = STATUS_INSUFFICIENT_RESOURCES;
+ goto alloc_info;
+ }
+ RtlCopyMemory(
+ (PWCHAR) irp->IoStatus.Information,
+ str,
+ str_len * sizeof (WCHAR)
+ );
+ status = STATUS_SUCCESS;
+ goto alloc_info;
+
+ case DeviceTextLocationInformation:
+ str_len = device__pnp_id(
+ dev,
+ BusQueryInstanceID,
+ str
+ );
+ irp->IoStatus.Information =
+ (ULONG_PTR) wv_palloc(str_len * sizeof *str);
+ if (irp->IoStatus.Information == 0) {
+ DBG("wv_palloc DeviceTextLocationInformation\n");
+ status = STATUS_INSUFFICIENT_RESOURCES;
+ goto alloc_info;
+ }
+ RtlCopyMemory(
+ (PWCHAR) irp->IoStatus.Information,
+ str,
+ str_len * sizeof (WCHAR)
+ );
+ status = STATUS_SUCCESS;
+ goto alloc_info;
+
+ default:
+ irp->IoStatus.Information = 0;
+ status = STATUS_NOT_SUPPORTED;
+ }
+ /* irp->IoStatus.Information not freed. */
+ alloc_info:
+
+ wv_free(str);
+ alloc_str:
+
+ return driver__complete_irp(irp, irp->IoStatus.Information, status);
+ }
+
+static NTSTATUS STDCALL disk_pnp__query_dev_relations_(
+ IN struct device__type * dev,
+ IN PIRP irp
+ ) {
+ PIO_STACK_LOCATION io_stack_loc = IoGetCurrentIrpStackLocation(irp);
+ NTSTATUS status;
+ PDEVICE_RELATIONS dev_relations;
+
+ if (io_stack_loc->Parameters.QueryDeviceRelations.Type !=
+ TargetDeviceRelation
+ ) {
+ status = irp->IoStatus.Status;
+ goto out;
+ }
+ dev_relations = wv_palloc(sizeof *dev_relations + sizeof dev->Self);
+ if (dev_relations == NULL) {
+ DBG("wv_palloc IRP_MN_QUERY_DEVICE_RELATIONS\n");
+ status = STATUS_INSUFFICIENT_RESOURCES;
+ goto alloc_dev_relations;
+ }
+ dev_relations->Objects[0] = dev->Self;
+ dev_relations->Count = 1;
+ ObReferenceObject(dev->Self);
+ irp->IoStatus.Information = (ULONG_PTR) dev_relations;
+ status = STATUS_SUCCESS;
+
+ /* irp->IoStatus.Information (dev_relations) not freed. */
+ alloc_dev_relations:
+
+ out:
+
+ irp->IoStatus.Status = status;
+ IoCompleteRequest(irp, IO_NO_INCREMENT);
+ return status;
+ }
+
+DEFINE_GUID(
+ GUID_BUS_TYPE_INTERNAL,
+ 0x2530ea73L,
+ 0x086b,
+ 0x11d1,
+ 0xa0,
+ 0x9f,
+ 0x00,
+ 0xc0,
+ 0x4f,
+ 0xc3,
+ 0x40,
+ 0xb1
+ );
+
+static NTSTATUS STDCALL disk_pnp__query_bus_info_(
+ IN struct device__type * dev,
+ IN PIRP irp
+ ) {
+ PPNP_BUS_INFORMATION pnp_bus_info;
+ NTSTATUS status;
+
+ pnp_bus_info = wv_palloc(sizeof *pnp_bus_info);
+ if (pnp_bus_info == NULL) {
+ DBG("wv_palloc IRP_MN_QUERY_BUS_INFORMATION\n");
+ status = STATUS_INSUFFICIENT_RESOURCES;
+ goto alloc_pnp_bus_info;
+ }
+ pnp_bus_info->BusTypeGuid = GUID_BUS_TYPE_INTERNAL;
+ pnp_bus_info->LegacyBusType = PNPBus;
+ pnp_bus_info->BusNumber = 0;
+ irp->IoStatus.Information = (ULONG_PTR) pnp_bus_info;
+ status = STATUS_SUCCESS;
+
+ /* irp-IoStatus.Information (pnp_bus_info) not freed. */
+ alloc_pnp_bus_info:
+
+ irp->IoStatus.Status = status;
+ IoCompleteRequest(irp, IO_NO_INCREMENT);
+ return status;
+ }
+
+static NTSTATUS STDCALL disk_pnp__query_capabilities_(
+ IN struct device__type * dev,
+ IN PIRP irp
+ ) {
+ PIO_STACK_LOCATION io_stack_loc = IoGetCurrentIrpStackLocation(irp);
+ PDEVICE_CAPABILITIES DeviceCapabilities =
+ io_stack_loc->Parameters.DeviceCapabilities.Capabilities;
+ NTSTATUS status;
+ disk__type_ptr disk;
+ struct bus__type * bus;
+ DEVICE_CAPABILITIES ParentDeviceCapabilities;
+ PDEVICE_OBJECT bus_lower;
+
+ if (DeviceCapabilities->Version != 1 ||
+ DeviceCapabilities->Size < sizeof (DEVICE_CAPABILITIES)
+ ) {
+ status = STATUS_UNSUCCESSFUL;
+ goto out;
+ }
+ disk = disk__get_ptr(dev);
+ bus = bus__get(device__get(dev->Parent));
+ bus_lower = bus->LowerDeviceObject;
+ if (bus_lower) {
+ status = bus__get_dev_capabilities(
+ bus_lower,
+ &ParentDeviceCapabilities
);
- Irp->IoStatus.Information = (ULONG_PTR) wv_palloc(
- string_length * sizeof *string
+ } else {
+ status = bus__get_dev_capabilities(
+ bus->device->Self,
+ &ParentDeviceCapabilities
);
- if ( Irp->IoStatus.Information == 0 )
- {
- DBG("wv_palloc DeviceTextLocationInformation\n");
- status = STATUS_INSUFFICIENT_RESOURCES;
- goto alloc_info;
- }
- RtlCopyMemory ( ( PWCHAR ) Irp->IoStatus.Information, string,
- string_length * sizeof ( WCHAR ) );
- status = STATUS_SUCCESS;
- goto alloc_info;
-
- default:
- Irp->IoStatus.Information = 0;
- status = STATUS_NOT_SUPPORTED;
- }
- /*
- * Irp->IoStatus.Information not freed
- */
-alloc_info:
-
- wv_free(string);
-alloc_string:
-
- Irp->IoStatus.Status = status;
- IoCompleteRequest ( Irp, IO_NO_INCREMENT );
- *completion_ptr = TRUE;
- return status;
-}
-
-NTSTATUS STDCALL disk_pnp__query_dev_relations(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp,
- IN PIO_STACK_LOCATION Stack,
- IN struct device__type * dev_ptr,
- OUT winvblock__bool_ptr completion_ptr
- )
-{
- NTSTATUS status;
- PDEVICE_RELATIONS dev_relations;
-
- if ( Stack->Parameters.QueryDeviceRelations.Type != TargetDeviceRelation )
- {
- status = Irp->IoStatus.Status;
- goto ret_path;
- }
- dev_relations = wv_palloc(sizeof *dev_relations + sizeof dev_ptr->Self);
- if ( dev_relations == NULL )
- {
- DBG("wv_palloc IRP_MN_QUERY_DEVICE_RELATIONS\n");
- status = STATUS_INSUFFICIENT_RESOURCES;
- goto alloc_dev_relations;
- }
- dev_relations->Objects[0] = dev_ptr->Self;
- dev_relations->Count = 1;
- ObReferenceObject ( dev_ptr->Self );
- Irp->IoStatus.Information = ( ULONG_PTR ) dev_relations;
- status = STATUS_SUCCESS;
-
- /*
- * Irp->IoStatus.Information (dev_relations) not freed
- */
-alloc_dev_relations:
-
-ret_path:
- Irp->IoStatus.Status = status;
- IoCompleteRequest ( Irp, IO_NO_INCREMENT );
- *completion_ptr = TRUE;
- return status;
-}
-
-DEFINE_GUID ( GUID_BUS_TYPE_INTERNAL, 0x2530ea73L, 0x086b, 0x11d1, 0xa0, 0x9f,
- 0x00, 0xc0, 0x4f, 0xc3, 0x40, 0xb1 );
-
-NTSTATUS STDCALL disk_pnp__query_bus_info(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp,
- IN PIO_STACK_LOCATION Stack,
- IN struct device__type * dev_ptr,
- OUT winvblock__bool_ptr completion_ptr
- )
-{
- PPNP_BUS_INFORMATION pnp_bus_info;
- NTSTATUS status;
-
- pnp_bus_info = wv_palloc(sizeof *pnp_bus_info);
- if ( pnp_bus_info == NULL )
- {
- DBG("wv_palloc IRP_MN_QUERY_BUS_INFORMATION\n");
- status = STATUS_INSUFFICIENT_RESOURCES;
- goto alloc_pnp_bus_info;
- }
- pnp_bus_info->BusTypeGuid = GUID_BUS_TYPE_INTERNAL;
- pnp_bus_info->LegacyBusType = PNPBus;
- pnp_bus_info->BusNumber = 0;
- Irp->IoStatus.Information = ( ULONG_PTR ) pnp_bus_info;
- status = STATUS_SUCCESS;
-
- /*
- * Irp-IoStatus.Information (pnp_bus_info) not freed
- */
-alloc_pnp_bus_info:
-
- Irp->IoStatus.Status = status;
- IoCompleteRequest ( Irp, IO_NO_INCREMENT );
- *completion_ptr = TRUE;
- return status;
-}
-
-NTSTATUS STDCALL disk_pnp__query_capabilities(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp,
- IN PIO_STACK_LOCATION Stack,
- IN struct device__type * dev_ptr,
- OUT winvblock__bool_ptr completion_ptr
- )
-{
- PDEVICE_CAPABILITIES DeviceCapabilities =
- Stack->Parameters.DeviceCapabilities.Capabilities;
- NTSTATUS status;
- disk__type_ptr disk_ptr;
- struct bus__type * bus_ptr;
- DEVICE_CAPABILITIES ParentDeviceCapabilities;
- PDEVICE_OBJECT bus_lower;
-
- if ( DeviceCapabilities->Version != 1
- || DeviceCapabilities->Size < sizeof ( DEVICE_CAPABILITIES ) )
- {
- status = STATUS_UNSUCCESSFUL;
- goto ret_path;
- }
- disk_ptr = disk__get_ptr ( dev_ptr );
- bus_ptr = bus__get(device__get(dev_ptr->Parent));
- bus_lower = bus_ptr->LowerDeviceObject;
- if (bus_lower) {
- status = bus__get_dev_capabilities(
- bus_lower,
- &ParentDeviceCapabilities
- );
- } else {
- status = bus__get_dev_capabilities(
- bus_ptr->device->Self,
- &ParentDeviceCapabilities
- );
- }
- if ( !NT_SUCCESS ( status ) )
- goto ret_path;
-
- RtlCopyMemory ( DeviceCapabilities->DeviceState,
- ParentDeviceCapabilities.DeviceState,
- ( PowerSystemShutdown +
- 1 ) * sizeof ( DEVICE_POWER_STATE ) );
- DeviceCapabilities->DeviceState[PowerSystemWorking] = PowerDeviceD0;
- if ( DeviceCapabilities->DeviceState[PowerSystemSleeping1] != PowerDeviceD0 )
- DeviceCapabilities->DeviceState[PowerSystemSleeping1] = PowerDeviceD1;
- if ( DeviceCapabilities->DeviceState[PowerSystemSleeping2] != PowerDeviceD0 )
- DeviceCapabilities->DeviceState[PowerSystemSleeping2] = PowerDeviceD3;
-#if 0
- if ( DeviceCapabilities->DeviceState[PowerSystemSleeping3] != PowerDeviceD0 )
- DeviceCapabilities->DeviceState[PowerSystemSleeping3] = PowerDeviceD3;
-#endif
- DeviceCapabilities->DeviceWake = PowerDeviceD1;
- DeviceCapabilities->DeviceD1 = TRUE;
- DeviceCapabilities->DeviceD2 = FALSE;
- DeviceCapabilities->WakeFromD0 = FALSE;
- DeviceCapabilities->WakeFromD1 = FALSE;
- DeviceCapabilities->WakeFromD2 = FALSE;
- DeviceCapabilities->WakeFromD3 = FALSE;
- DeviceCapabilities->D1Latency = 0;
- DeviceCapabilities->D2Latency = 0;
- DeviceCapabilities->D3Latency = 0;
- DeviceCapabilities->EjectSupported = FALSE;
- DeviceCapabilities->HardwareDisabled = FALSE;
- DeviceCapabilities->Removable = disk__removable[disk_ptr->media];
- DeviceCapabilities->SurpriseRemovalOK = FALSE;
- DeviceCapabilities->UniqueID = FALSE;
- DeviceCapabilities->SilentInstall = FALSE;
-#if 0
- DeviceCapabilities->Address = DeviceObject->SerialNo;
- DeviceCapabilities->UINumber = DeviceObject->SerialNo;
-#endif
- status = STATUS_SUCCESS;
-
-ret_path:
- Irp->IoStatus.Status = status;
- IoCompleteRequest ( Irp, IO_NO_INCREMENT );
- *completion_ptr = TRUE;
- return status;
-}
-
-NTSTATUS STDCALL disk_pnp__simple(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp,
- IN PIO_STACK_LOCATION Stack,
- IN struct device__type * dev_ptr,
- OUT winvblock__bool_ptr completion_ptr
- )
-{
- NTSTATUS status;
- disk__type_ptr disk_ptr;
-
- disk_ptr = disk__get_ptr ( dev_ptr );
- switch ( Stack->MinorFunction )
- {
- case IRP_MN_DEVICE_USAGE_NOTIFICATION:
- if ( Stack->Parameters.UsageNotification.InPath )
- {
- disk_ptr->SpecialFileCount++;
- }
- else
- {
- disk_ptr->SpecialFileCount--;
- }
- Irp->IoStatus.Information = 0;
- status = STATUS_SUCCESS;
- break;
- case IRP_MN_QUERY_PNP_DEVICE_STATE:
- Irp->IoStatus.Information = 0;
- status = STATUS_SUCCESS;
- break;
- case IRP_MN_START_DEVICE:
- dev_ptr->old_state = dev_ptr->state;
- dev_ptr->state = device__state_started;
- status = STATUS_SUCCESS;
- break;
- case IRP_MN_QUERY_STOP_DEVICE:
- dev_ptr->old_state = dev_ptr->state;
- dev_ptr->state = device__state_stop_pending;
- status = STATUS_SUCCESS;
- break;
- case IRP_MN_CANCEL_STOP_DEVICE:
- dev_ptr->state = dev_ptr->old_state;
- status = STATUS_SUCCESS;
- break;
- case IRP_MN_STOP_DEVICE:
- dev_ptr->old_state = dev_ptr->state;
- dev_ptr->state = device__state_stopped;
- status = STATUS_SUCCESS;
- break;
- case IRP_MN_QUERY_REMOVE_DEVICE:
- dev_ptr->old_state = dev_ptr->state;
- dev_ptr->state = device__state_remove_pending;
- status = STATUS_SUCCESS;
- break;
- case IRP_MN_REMOVE_DEVICE:
- dev_ptr->old_state = dev_ptr->state;
- dev_ptr->state = device__state_not_started;
- if ( disk_ptr->Unmount )
- {
- device__close ( dev_ptr );
- IoDeleteDevice ( dev_ptr->Self );
- device__free ( dev_ptr );
- status = STATUS_NO_SUCH_DEVICE;
- }
- else
- {
- status = STATUS_SUCCESS;
- }
- break;
- case IRP_MN_CANCEL_REMOVE_DEVICE:
- dev_ptr->state = dev_ptr->old_state;
- status = STATUS_SUCCESS;
- break;
- case IRP_MN_SURPRISE_REMOVAL:
- dev_ptr->old_state = dev_ptr->state;
- dev_ptr->state = device__state_surprise_remove_pending;
- status = STATUS_SUCCESS;
- break;
- default:
- status = Irp->IoStatus.Status;
- }
-
- Irp->IoStatus.Status = status;
- IoCompleteRequest ( Irp, IO_NO_INCREMENT );
- *completion_ptr = TRUE;
- return status;
-}
+ }
+ if (!NT_SUCCESS(status))
+ goto out;
+
+ RtlCopyMemory(
+ DeviceCapabilities->DeviceState,
+ ParentDeviceCapabilities.DeviceState,
+ (PowerSystemShutdown + 1) * sizeof (DEVICE_POWER_STATE)
+ );
+ DeviceCapabilities->DeviceState[PowerSystemWorking] = PowerDeviceD0;
+ if (DeviceCapabilities->DeviceState[PowerSystemSleeping1] != PowerDeviceD0)
+ DeviceCapabilities->DeviceState[PowerSystemSleeping1] = PowerDeviceD1;
+ if (DeviceCapabilities->DeviceState[PowerSystemSleeping2] != PowerDeviceD0)
+ DeviceCapabilities->DeviceState[PowerSystemSleeping2] = PowerDeviceD3;
+ #if 0
+ if (DeviceCapabilities->DeviceState[PowerSystemSleeping3] != PowerDeviceD0)
+ DeviceCapabilities->DeviceState[PowerSystemSleeping3] = PowerDeviceD3;
+ #endif
+ DeviceCapabilities->DeviceWake = PowerDeviceD1;
+ DeviceCapabilities->DeviceD1 = TRUE;
+ DeviceCapabilities->DeviceD2 = FALSE;
+ DeviceCapabilities->WakeFromD0 = FALSE;
+ DeviceCapabilities->WakeFromD1 = FALSE;
+ DeviceCapabilities->WakeFromD2 = FALSE;
+ DeviceCapabilities->WakeFromD3 = FALSE;
+ DeviceCapabilities->D1Latency = 0;
+ DeviceCapabilities->D2Latency = 0;
+ DeviceCapabilities->D3Latency = 0;
+ DeviceCapabilities->EjectSupported = FALSE;
+ DeviceCapabilities->HardwareDisabled = FALSE;
+ DeviceCapabilities->Removable = disk__removable[disk->media];
+ DeviceCapabilities->SurpriseRemovalOK = FALSE;
+ DeviceCapabilities->UniqueID = FALSE;
+ DeviceCapabilities->SilentInstall = FALSE;
+ #if 0
+ DeviceCapabilities->Address = dev->Self->SerialNo;
+ DeviceCapabilities->UINumber = dev->Self->SerialNo;
+ #endif
+ status = STATUS_SUCCESS;
+
+ out:
+ irp->IoStatus.Status = status;
+ IoCompleteRequest(irp, IO_NO_INCREMENT);
+ return status;
+ }
+
+static NTSTATUS STDCALL disk_pnp__simple_(
+ IN struct device__type * dev,
+ IN PIRP irp,
+ IN UCHAR code
+ ) {
+ disk__type_ptr disk = disk__get_ptr(dev);
+ PIO_STACK_LOCATION io_stack_loc = IoGetCurrentIrpStackLocation(irp);
+ NTSTATUS status;
+
+ switch (code) {
+ case IRP_MN_DEVICE_USAGE_NOTIFICATION:
+ if (io_stack_loc->Parameters.UsageNotification.InPath) {
+ disk->SpecialFileCount++;
+ } else {
+ disk->SpecialFileCount--;
+ }
+ irp->IoStatus.Information = 0;
+ status = STATUS_SUCCESS;
+ break;
+
+ case IRP_MN_QUERY_PNP_DEVICE_STATE:
+ irp->IoStatus.Information = 0;
+ status = STATUS_SUCCESS;
+ break;
+
+ case IRP_MN_START_DEVICE:
+ dev->old_state = dev->state;
+ dev->state = device__state_started;
+ status = STATUS_SUCCESS;
+ break;
+
+ case IRP_MN_QUERY_STOP_DEVICE:
+ dev->old_state = dev->state;
+ dev->state = device__state_stop_pending;
+ status = STATUS_SUCCESS;
+ break;
+
+ case IRP_MN_CANCEL_STOP_DEVICE:
+ dev->state = dev->old_state;
+ status = STATUS_SUCCESS;
+ break;
+
+ case IRP_MN_STOP_DEVICE:
+ dev->old_state = dev->state;
+ dev->state = device__state_stopped;
+ status = STATUS_SUCCESS;
+ break;
+
+ case IRP_MN_QUERY_REMOVE_DEVICE:
+ dev->old_state = dev->state;
+ dev->state = device__state_remove_pending;
+ status = STATUS_SUCCESS;
+ break;
+
+ case IRP_MN_REMOVE_DEVICE:
+ dev->old_state = dev->state;
+ dev->state = device__state_not_started;
+ if (disk->Unmount) {
+ device__close(dev);
+ IoDeleteDevice(dev->Self);
+ device__free(dev);
+ status = STATUS_NO_SUCH_DEVICE;
+ } else {
+ status = STATUS_SUCCESS;
+ }
+ break;
+
+ case IRP_MN_CANCEL_REMOVE_DEVICE:
+ dev->state = dev->old_state;
+ status = STATUS_SUCCESS;
+ break;
+
+ case IRP_MN_SURPRISE_REMOVAL:
+ dev->old_state = dev->state;
+ dev->state = device__state_surprise_remove_pending;
+ status = STATUS_SUCCESS;
+ break;
+
+ default:
+ status = irp->IoStatus.Status;
+ }
+
+ irp->IoStatus.Status = status;
+ IoCompleteRequest(irp, IO_NO_INCREMENT);
+ return status;
+ }
+
+/* Disk PnP dispatch routine. */
+NTSTATUS STDCALL disk_pnp__dispatch(
+ IN struct device__type * dev,
+ IN PIRP irp,
+ IN UCHAR code
+ ) {
+ switch (code) {
+ case IRP_MN_QUERY_ID:
+ return device__pnp_query_id(dev, irp);
+
+ case IRP_MN_QUERY_DEVICE_TEXT:
+ return disk_pnp__query_dev_text_(dev, irp);
+
+ case IRP_MN_QUERY_DEVICE_RELATIONS:
+ return disk_pnp__query_dev_relations_(dev, irp);
+
+ case IRP_MN_QUERY_BUS_INFORMATION:
+ return disk_pnp__query_bus_info_(dev, irp);
+
+ case IRP_MN_QUERY_CAPABILITIES:
+ return disk_pnp__query_capabilities_(dev, irp);
+
+ default:
+ return disk_pnp__simple_(dev, irp, code);
+ }
+ }
static driver__dispatch_func driver__dispatch_sys_ctl_;
static driver__dispatch_func driver__dispatch_dev_ctl_;
static driver__dispatch_func driver__dispatch_scsi_;
+static driver__dispatch_func driver__dispatch_pnp_;
static driver__dispatch_func driver__dispatch_;
static void STDCALL driver__unload_(IN PDRIVER_OBJECT);
*/
for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)
DriverObject->MajorFunction[i] = driver__dispatch_not_supported_;
- DriverObject->MajorFunction[IRP_MJ_PNP] = driver__dispatch_;
+ DriverObject->MajorFunction[IRP_MJ_PNP] = driver__dispatch_pnp_;
DriverObject->MajorFunction[IRP_MJ_POWER] = driver__dispatch_power_;
DriverObject->MajorFunction[IRP_MJ_CREATE] = driver__dispatch_create_close_;
DriverObject->MajorFunction[IRP_MJ_CLOSE] = driver__dispatch_create_close_;
return driver__complete_irp(irp, 0, STATUS_NOT_SUPPORTED);
}
+/* Handle an IRP_MJ_PNP IRP. */
+static NTSTATUS driver__dispatch_pnp_(
+ IN PDEVICE_OBJECT dev_obj,
+ IN PIRP irp
+ ) {
+ /* device__get() checks for a NULL dev_obj */
+ struct device__type * dev = device__get(dev_obj);
+ PIO_STACK_LOCATION io_stack_loc = IoGetCurrentIrpStackLocation(irp);
+
+ #ifdef DEBUGIRPS
+ Debug_IrpStart(dev_obj, irp);
+ #endif
+ /* Check that the device exists. */
+ if (!dev || dev->state == device__state_deleted)
+ return driver__complete_irp(irp, 0, STATUS_NO_SUCH_DEVICE);
+ /* Call the particular device's power handler. */
+ if (dev->irp_mj && dev->irp_mj->pnp) {
+ return dev->irp_mj->pnp(
+ dev,
+ irp,
+ io_stack_loc->MinorFunction
+ );
+ }
+ /* Otherwise, we don't support the IRP. */
+ return driver__complete_irp(irp, 0, STATUS_NOT_SUPPORTED);
+ }
+
static NTSTATUS STDCALL driver__dispatch_(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp