2 * Copyright (C) 2010, Shao Miller <shao.miller@yrdsb.edu.on.ca>.
4 * This file is part of WinVBlock, originally derived from WinAoE.
6 * WinVBlock is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * WinVBlock is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with WinVBlock. If not, see <http://www.gnu.org/licenses/>.
29 #include "winvblock.h"
38 /* Names for the AoE bus. */
39 #define AOE_M_BUS_NAME_ (L"\\Device\\AoE")
40 #define AOE_M_BUS_DOSNAME_ (L"\\DosDevices\\AoE")
42 /* TODO: Remove this pull from aoe/driver.c */
43 extern WV_F_DEV_DISPATCH aoe__scan;
44 extern WV_F_DEV_DISPATCH aoe__show;
45 extern WV_F_DEV_DISPATCH aoe__mount;
47 /* Forward declarations. */
48 static WV_F_DEV_CTL aoe_bus__dev_ctl_dispatch_;
49 static WV_F_DEV_PNP_ID aoe_bus__pnp_id_;
50 winvblock__bool aoe_bus__create(void);
51 void aoe_bus__free(void);
54 WV_SP_BUS_T aoe_bus = NULL;
55 static UNICODE_STRING AoeBusName_ = {
56 sizeof AOE_M_BUS_NAME_,
57 sizeof AOE_M_BUS_NAME_,
60 static UNICODE_STRING AoeBusDosname_ = {
61 sizeof AOE_M_BUS_DOSNAME_,
62 sizeof AOE_M_BUS_DOSNAME_,
66 static NTSTATUS STDCALL aoe_bus__dev_ctl_dispatch_(
69 IN ULONG POINTER_ALIGNMENT code
73 return aoe__scan(dev, irp);
76 return aoe__show(dev, irp);
79 return aoe__mount(dev, irp);
81 case IOCTL_AOE_UMOUNT: {
82 WV_SP_BUS_T bus = WvBusFromDev(dev);
84 /* Pretend it's an IOCTL_FILE_DETACH. */
85 return WvDevFromDevObj(bus->LowerDeviceObject)->IrpMj->DevCtl(
92 DBG("Unsupported IOCTL\n");
93 return driver__complete_irp(irp, 0, STATUS_NOT_SUPPORTED);
100 * @ret TRUE for success, else FALSE.
102 winvblock__bool aoe_bus__create(void) {
106 /* We should only be called once. */
108 DBG("AoE bus already created\n");
111 /* Try to create the AoE bus. */
112 new_bus = WvBusCreate();
114 DBG("Failed to create AoE bus!\n");
117 /* When the PDO is created, we need to handle PnP ID queries. */
118 new_bus->Dev->Ops.PnpId = aoe_bus__pnp_id_;
119 /* Add it as a sub-bus to WinVBlock. */
120 if (!WvBusAddChild(driver__bus(), new_bus->Dev)) {
121 DBG("Couldn't add AoE bus to WinVBlock bus!\n");
124 /* DosDevice symlink. */
125 status = IoCreateSymbolicLink(
129 if (!NT_SUCCESS(status)) {
130 DBG("IoCreateSymbolicLink() failed!\n");
131 goto err_dos_symlink;
137 IoDeleteSymbolicLink(&AoeBusDosname_);
140 IoDeleteDevice(aoe_bus->Dev->Self);
143 WvDevFree(new_bus->Dev);
149 /* Destroy the AoE bus. */
150 void aoe_bus__free(void) {
155 IoDeleteSymbolicLink(&AoeBusDosname_);
156 IoDeleteDevice(aoe_bus->Dev->Self);
158 bus__remove_child(driver__bus(), aoe_bus->Dev);
160 WvDevFree(aoe_bus->Dev);
164 static winvblock__uint32 STDCALL aoe_bus__pnp_id_(
166 IN BUS_QUERY_ID_TYPE query_type,
167 IN OUT WCHAR (*buf)[512]
169 switch (query_type) {
170 case BusQueryDeviceID:
171 return swprintf(*buf, winvblock__literal_w L"\\AoE") + 1;
173 case BusQueryInstanceID:
174 return swprintf(*buf, L"0") + 1;
176 case BusQueryHardwareIDs:
177 return swprintf(*buf, winvblock__literal_w L"\\AoE") + 2;
179 case BusQueryCompatibleIDs:
180 return swprintf(*buf, winvblock__literal_w L"\\AoE") + 4;