[bus] Remove Dev member from WV_S_BUS_T
[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 WV_S_DEV_T AoeBusMainDev_ = {0};
56 static UNICODE_STRING AoeBusName_ = {
57     sizeof AOE_M_BUS_NAME_,
58     sizeof AOE_M_BUS_NAME_,
59     AOE_M_BUS_NAME_
60   };
61 static UNICODE_STRING AoeBusDosname_ = {
62     sizeof AOE_M_BUS_DOSNAME_,
63     sizeof AOE_M_BUS_DOSNAME_,
64     AOE_M_BUS_DOSNAME_
65   };
66
67 static NTSTATUS STDCALL AoeBusDevCtlDispatch_(
68     IN WV_SP_DEV_T dev,
69     IN PIRP irp,
70     IN ULONG POINTER_ALIGNMENT code
71   ) {
72     switch(code) {
73         case IOCTL_AOE_SCAN:
74           return aoe__scan(dev, irp);
75
76         case IOCTL_AOE_SHOW:
77           return aoe__show(dev, irp);
78
79         case IOCTL_AOE_MOUNT:
80           return aoe__mount(dev, irp);
81
82         case IOCTL_AOE_UMOUNT:
83           /* Pretend it's an IOCTL_FILE_DETACH. */
84           return AoeBusMainDev_.IrpMj->DevCtl(
85               &AoeBusMainDev_,
86               irp,
87               IOCTL_FILE_DETACH
88             );
89
90         default:
91           DBG("Unsupported IOCTL\n");
92           return driver__complete_irp(irp, 0, STATUS_NOT_SUPPORTED);
93       }
94   }
95
96 /**
97  * Create the AoE bus.
98  *
99  * @ret         TRUE for success, else FALSE.
100  */
101 winvblock__bool AoeBusCreate(void) {
102     NTSTATUS status;
103
104     /* Initialize the AoE bus. */
105     WvBusInit(&AoeBusMain);
106     WvDevInit(&AoeBusMainDev_);
107     /* When the PDO is created, we need to handle PnP ID queries. */
108     AoeBusMainDev_.Ops.PnpId = AoeBusPnpId_;
109     /* Add it as a sub-bus to WinVBlock. */
110     if (!WvDriverBusAddDev(&AoeBusMainDev_)) {
111         DBG("Couldn't add AoE bus to WinVBlock bus!\n");
112         goto err_add_child;
113       }
114     /* DosDevice symlink. */
115     status = IoCreateSymbolicLink(
116         &AoeBusDosname_,
117         &AoeBusName_
118       );
119     if (!NT_SUCCESS(status)) {
120         DBG("IoCreateSymbolicLink() failed!\n");
121         goto err_dos_symlink;
122       }
123     /* All done. */
124     return TRUE;
125
126     IoDeleteSymbolicLink(&AoeBusDosname_);
127     err_dos_symlink:
128
129     IoDeleteDevice(AoeBusMain.Fdo);
130     err_add_child:
131
132     return FALSE;
133   }
134
135 /* Destroy the AoE bus. */
136 void AoeBusFree(void) {
137     IoDeleteSymbolicLink(&AoeBusDosname_);
138     IoDeleteDevice(AoeBusMain.Fdo);
139     WvBusRemoveNode(AoeBusMainDev_.BusNode);
140     return;
141   }
142
143 static winvblock__uint32 STDCALL AoeBusPnpId_(
144     IN WV_SP_DEV_T dev,
145     IN BUS_QUERY_ID_TYPE query_type,
146     IN OUT WCHAR (*buf)[512]
147   ) {
148     switch (query_type) {
149         case BusQueryDeviceID:
150           return swprintf(*buf, winvblock__literal_w L"\\AoE") + 1;
151
152         case BusQueryInstanceID:
153           return swprintf(*buf, L"0") + 1;
154
155         case BusQueryHardwareIDs:
156           return swprintf(*buf, winvblock__literal_w L"\\AoE") + 2;
157
158         case BusQueryCompatibleIDs:
159           return swprintf(*buf, winvblock__literal_w L"\\AoE") + 4;
160
161         default:
162           return 0;
163       }
164   }