[driver] Remove driver__bus
[people/sha0/winvblock.git] / src / aoe / bus.c
1 /**
2  * Copyright (C) 2010, Shao Miller <shao.miller@yrdsb.edu.on.ca>.
3  *
4  * This file is part of WinVBlock, originally derived from WinAoE.
5  *
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.
10  *
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.
15  *
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/>.
18  */
19
20 /**
21  * @file
22  *
23  * AoE bus specifics.
24  */
25
26 #include <stdio.h>
27 #include <ntddk.h>
28
29 #include "winvblock.h"
30 #include "portable.h"
31 #include "driver.h"
32 #include "device.h"
33 #include "bus.h"
34 #include "aoe.h"
35 #include "mount.h"
36 #include "debug.h"
37
38 /* Names for the AoE bus. */
39 #define AOE_M_BUS_NAME_ (L"\\Device\\AoE")
40 #define AOE_M_BUS_DOSNAME_ (L"\\DosDevices\\AoE")
41
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;
46
47 /* Forward declarations. */
48 static WV_F_DEV_CTL AoeBusDevCtlDispatch_;
49 static WV_F_DEV_PNP_ID AoeBusPnpId_;
50 winvblock__bool AoeBusCreate(void);
51 void AoeBusFree(void);
52
53 /* Globals. */
54 WV_S_BUS_T AoeBusMain = {0};
55 static UNICODE_STRING AoeBusName_ = {
56     sizeof AOE_M_BUS_NAME_,
57     sizeof AOE_M_BUS_NAME_,
58     AOE_M_BUS_NAME_
59   };
60 static UNICODE_STRING AoeBusDosname_ = {
61     sizeof AOE_M_BUS_DOSNAME_,
62     sizeof AOE_M_BUS_DOSNAME_,
63     AOE_M_BUS_DOSNAME_
64   };
65
66 static NTSTATUS STDCALL AoeBusDevCtlDispatch_(
67     IN WV_SP_DEV_T dev,
68     IN PIRP irp,
69     IN ULONG POINTER_ALIGNMENT code
70   ) {
71     switch(code) {
72         case IOCTL_AOE_SCAN:
73           return aoe__scan(dev, irp);
74
75         case IOCTL_AOE_SHOW:
76           return aoe__show(dev, irp);
77
78         case IOCTL_AOE_MOUNT:
79           return aoe__mount(dev, irp);
80
81         case IOCTL_AOE_UMOUNT:
82           /* Pretend it's an IOCTL_FILE_DETACH. */
83           return AoeBusMain.Dev.IrpMj->DevCtl(
84               dev,
85               irp,
86               IOCTL_FILE_DETACH
87             );
88
89         default:
90           DBG("Unsupported IOCTL\n");
91           return driver__complete_irp(irp, 0, STATUS_NOT_SUPPORTED);
92       }
93   }
94
95 /**
96  * Create the AoE bus.
97  *
98  * @ret         TRUE for success, else FALSE.
99  */
100 winvblock__bool AoeBusCreate(void) {
101     NTSTATUS status;
102
103     /* Initialize the AoE bus. */
104     WvBusInit(&AoeBusMain);
105     /* When the PDO is created, we need to handle PnP ID queries. */
106     AoeBusMain.Dev.Ops.PnpId = AoeBusPnpId_;
107     /* Add it as a sub-bus to WinVBlock. */
108     if (!WvDriverBusAddDev(&AoeBusMain.Dev)) {
109         DBG("Couldn't add AoE bus to WinVBlock bus!\n");
110         goto err_add_child;
111       }
112     /* DosDevice symlink. */
113     status = IoCreateSymbolicLink(
114         &AoeBusDosname_,
115         &AoeBusName_
116       );
117     if (!NT_SUCCESS(status)) {
118         DBG("IoCreateSymbolicLink() failed!\n");
119         goto err_dos_symlink;
120       }
121     /* All done. */
122     return TRUE;
123
124     IoDeleteSymbolicLink(&AoeBusDosname_);
125     err_dos_symlink:
126
127     IoDeleteDevice(AoeBusMain.Dev.Self);
128     err_add_child:
129
130     return FALSE;
131   }
132
133 /* Destroy the AoE bus. */
134 void AoeBusFree(void) {
135     IoDeleteSymbolicLink(&AoeBusDosname_);
136     IoDeleteDevice(AoeBusMain.Dev.Self);
137     WvBusRemoveNode(AoeBusMain.Dev.BusNode);
138     return;
139   }
140
141 static winvblock__uint32 STDCALL AoeBusPnpId_(
142     IN WV_SP_DEV_T dev,
143     IN BUS_QUERY_ID_TYPE query_type,
144     IN OUT WCHAR (*buf)[512]
145   ) {
146     switch (query_type) {
147         case BusQueryDeviceID:
148           return swprintf(*buf, winvblock__literal_w L"\\AoE") + 1;
149
150         case BusQueryInstanceID:
151           return swprintf(*buf, L"0") + 1;
152
153         case BusQueryHardwareIDs:
154           return swprintf(*buf, winvblock__literal_w L"\\AoE") + 2;
155
156         case BusQueryCompatibleIDs:
157           return swprintf(*buf, winvblock__literal_w L"\\AoE") + 4;
158
159         default:
160           return 0;
161       }
162   }