2 * Copyright (C) 2009-2010, Shao Miller <shao.miller@yrdsb.edu.on.ca>.
3 * Copyright 2006-2008, V.
4 * For WinAoE contact information, see http://winaoe.org/
6 * This file is part of WinVBlock, derived from WinAoE.
8 * WinVBlock is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, either version 3 of the License, or
11 * (at your option) any later version.
13 * WinVBlock is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with WinVBlock. If not, see <http://www.gnu.org/licenses/>.
30 #include "winvblock.h"
31 #include "wv_stdlib.h"
37 /* Forward declarations. */
38 static WV_F_DEV_FREE WvDevFreeDev_;
39 static WV_F_DEV_CREATE_PDO WvDevMakePdo_;
42 * Initialize device defaults.
44 * @v dev Points to the device to initialize with defaults.
46 winvblock__lib_func void WvDevInit(WV_SP_DEV_T dev) {
47 RtlZeroMemory(dev, sizeof *dev);
48 /* Populate non-zero device defaults. */
49 dev->DriverObject = WvDriverObj;
50 dev->Ops.CreatePdo = WvDevMakePdo_;
51 dev->Ops.Free = WvDevFreeDev_;
55 * Create a new device.
57 * @ret dev The address of a new device, or NULL for failure.
59 * This function should not be confused with a PDO creation routine, which is
60 * actually implemented for each device type. This routine will allocate a
61 * WV_DEV_T and populate the device with default values.
63 winvblock__lib_func WV_SP_DEV_T WvDevCreate(void) {
67 * Devices might be used for booting and should
68 * not be allocated from a paged memory pool.
70 dev = wv_malloc(sizeof *dev);
79 * Create a device PDO.
81 * @v dev Points to the device that needs a PDO.
83 winvblock__lib_func PDEVICE_OBJECT STDCALL WvDevCreatePdo(IN WV_SP_DEV_T dev) {
84 return dev->Ops.CreatePdo(dev);
88 * Default PDO creation operation.
90 * @v dev Points to the device that needs a PDO.
91 * @ret NULL Reports failure, no matter what.
93 * This function does nothing, since it doesn't make sense to create a PDO
94 * for an unknown type of device.
96 static PDEVICE_OBJECT STDCALL WvDevMakePdo_(IN WV_SP_DEV_T dev) {
97 DBG("No specific PDO creation operation for this device!\n");
102 * Respond to a device PnP ID query.
104 * @v dev The device being queried for PnP IDs.
105 * @v query_type The query type.
106 * @v buf Wide character, 512-element buffer for the
108 * @ret winvblock__uint32 The number of wide characters in the response,
109 * or 0 upon a failure.
111 winvblock__uint32 STDCALL WvDevPnpId(
113 IN BUS_QUERY_ID_TYPE query_type,
114 IN OUT WCHAR (*buf)[512]
116 return dev->Ops.PnpId ? dev->Ops.PnpId(dev, query_type, buf) : 0;
119 /* An IRP handler for a PnP ID query. */
120 NTSTATUS STDCALL WvDevPnpQueryId(IN WV_SP_DEV_T dev, IN PIRP irp) {
123 winvblock__uint32 str_len;
124 PIO_STACK_LOCATION io_stack_loc = IoGetCurrentIrpStackLocation(irp);
126 /* Allocate the working buffer. */
127 str = wv_mallocz(sizeof *str);
129 DBG("wv_malloc IRP_MN_QUERY_ID\n");
130 status = STATUS_INSUFFICIENT_RESOURCES;
133 /* Invoke the specific device's ID query. */
134 str_len = WvDevPnpId(
136 io_stack_loc->Parameters.QueryId.IdType,
140 irp->IoStatus.Information = 0;
141 status = STATUS_NOT_SUPPORTED;
144 /* Allocate the return buffer. */
145 irp->IoStatus.Information = (ULONG_PTR) wv_palloc(str_len * sizeof **str);
146 if (irp->IoStatus.Information == 0) {
147 DBG("wv_palloc failed.\n");
148 status = STATUS_INSUFFICIENT_RESOURCES;
151 /* Copy the working buffer to the return buffer. */
153 (void *) irp->IoStatus.Information,
155 str_len * sizeof **str
157 status = STATUS_SUCCESS;
159 /* irp->IoStatus.Information not freed. */
165 return driver__complete_irp(irp, irp->IoStatus.Information, status);
171 * @v dev Points to the device to close.
173 winvblock__lib_func void STDCALL WvDevClose(IN WV_SP_DEV_T dev) {
174 /* Call the device's close routine. */
182 * @v dev Points to the device to delete.
184 winvblock__lib_func void STDCALL WvDevFree(IN WV_SP_DEV_T dev) {
185 /* Call the device's free routine. */
190 * Default device deletion operation.
192 * @v dev Points to the device to delete.
194 static void STDCALL WvDevFreeDev_(IN WV_SP_DEV_T dev) {
199 * Get a device from a DEVICE_OBJECT.
201 * @v dev_obj Points to the DEVICE_OBJECT to get the device from.
202 * @ret Returns a pointer to the device on success, else NULL.
204 winvblock__lib_func WV_SP_DEV_T WvDevFromDevObj(PDEVICE_OBJECT dev_obj) {
205 driver__dev_ext_ptr dev_ext;
209 dev_ext = dev_obj->DeviceExtension;
210 return dev_ext->device;
214 * Set the device for a DEVICE_OBJECT.
216 * @v dev_obj Points to the DEVICE_OBJECT to set the device for.
217 * @v dev Points to the device to associate with.
219 winvblock__lib_func void WvDevForDevObj(PDEVICE_OBJECT dev_obj, WV_SP_DEV_T dev) {
220 driver__dev_ext_ptr dev_ext = dev_obj->DeviceExtension;
221 dev_ext->device = dev;