VirtualBox

source: vbox/trunk/src/VBox/HostDrivers/VBoxUSB/win/dev/VBoxUsbDev.cpp@ 48306

Last change on this file since 48306 was 36968, checked in by vboxsync, 14 years ago

rework usb

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 9.9 KB
Line 
1/* $Id: VBoxUsbDev.cpp 36968 2011-05-05 08:55:16Z vboxsync $ */
2/** @file
3 * VBoxUsbDev.cpp - USB device.
4 */
5/*
6 * Copyright (C) 2011 Oracle Corporation
7 *
8 * This file is part of VirtualBox Open Source Edition (OSE), as
9 * available from http://www.virtualbox.org. This file is free software;
10 * you can redistribute it and/or modify it under the terms of the GNU
11 * General Public License (GPL) as published by the Free Software
12 * Foundation, in version 2 as it comes in the "COPYING" file of the
13 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
14 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
15 */
16#include "VBoxUsbCmn.h"
17#include <iprt/assert.h>
18#include <VBox/log.h>
19
20#define VBOXUSB_MEMTAG 'bUBV'
21
22DECLHIDDEN(PVOID) vboxUsbMemAlloc(SIZE_T cbBytes)
23{
24 PVOID pvMem = ExAllocatePoolWithTag(NonPagedPool, cbBytes, VBOXUSB_MEMTAG);
25 Assert(pvMem);
26 return pvMem;
27}
28
29DECLHIDDEN(PVOID) vboxUsbMemAllocZ(SIZE_T cbBytes)
30{
31 PVOID pvMem = vboxUsbMemAlloc(cbBytes);
32 if (pvMem)
33 {
34 RtlZeroMemory(pvMem, cbBytes);
35 }
36 return pvMem;
37}
38
39DECLHIDDEN(VOID) vboxUsbMemFree(PVOID pvMem)
40{
41 ExFreePoolWithTag(pvMem, VBOXUSB_MEMTAG);
42}
43
44VBOXUSB_GLOBALS g_VBoxUsbGlobals = {0};
45
46static NTSTATUS vboxUsbDdiAddDevice(PDRIVER_OBJECT pDriverObject,
47 PDEVICE_OBJECT pPDO)
48{
49 PDEVICE_OBJECT pFDO = NULL;
50 NTSTATUS Status = IoCreateDevice(pDriverObject,
51 sizeof (VBOXUSBDEV_EXT),
52 NULL, /* IN PUNICODE_STRING pDeviceName OPTIONAL */
53 FILE_DEVICE_UNKNOWN, /* IN DEVICE_TYPE DeviceType */
54 FILE_AUTOGENERATED_DEVICE_NAME, /* IN ULONG DeviceCharacteristics */
55 FALSE, /* IN BOOLEAN fExclusive */
56 &pFDO);
57 Assert(Status == STATUS_SUCCESS);
58 if (Status == STATUS_SUCCESS)
59 {
60 PVBOXUSBDEV_EXT pDevExt = (PVBOXUSBDEV_EXT)pFDO->DeviceExtension;
61 /* init Device Object bits */
62 pFDO->Flags |= DO_DIRECT_IO;
63 if (pPDO->Flags & DO_POWER_PAGABLE)
64 pFDO->Flags |= DO_POWER_PAGABLE;
65
66
67 /* now init our state bits */
68
69 pDevExt->cHandles = 0;
70
71 pDevExt->pFDO = pFDO;
72 pDevExt->pPDO = pPDO;
73 pDevExt->pLowerDO = IoAttachDeviceToDeviceStack(pFDO, pPDO);
74 Assert(pDevExt->pLowerDO);
75 if (pDevExt->pLowerDO)
76 {
77 vboxUsbDdiStateInit(pDevExt);
78 Status = vboxUsbRtInit(pDevExt);
79 if (Status == STATUS_SUCCESS)
80 {
81 /* we're done! */
82 pFDO->Flags &= ~DO_DEVICE_INITIALIZING;
83 return STATUS_SUCCESS;
84 }
85
86 IoDetachDevice(pDevExt->pLowerDO);
87 }
88 else
89 Status = STATUS_NO_SUCH_DEVICE;
90
91 IoDeleteDevice(pFDO);
92 }
93
94 return Status;
95}
96
97static VOID vboxUsbDdiUnload(PDRIVER_OBJECT pDriverObject)
98{
99 LogRel(("VBoxUsb::DriverUnload. Built Date (%s) Time (%s)\n", __DATE__, __TIME__));
100 VBoxDrvToolStrFree(&g_VBoxUsbGlobals.RegPath);
101
102 vboxUsbRtGlobalsTerm();
103
104 PRTLOGGER pLogger = RTLogRelSetDefaultInstance(NULL);
105 if (pLogger)
106 {
107 RTLogDestroy(pLogger);
108 }
109 pLogger = RTLogSetDefaultInstance(NULL);
110 if (pLogger)
111 {
112 RTLogDestroy(pLogger);
113 }
114}
115
116static NTSTATUS vboxUsbDispatchCreate(IN PDEVICE_OBJECT pDeviceObject, IN PIRP pIrp)
117{
118 PVBOXUSBDEV_EXT pDevExt = (PVBOXUSBDEV_EXT)pDeviceObject->DeviceExtension;
119 NTSTATUS Status = STATUS_INVALID_HANDLE;
120 do
121 {
122 if (vboxUsbPnPStateGet(pDevExt) != ENMVBOXUSB_PNPSTATE_STARTED)
123 {
124 Status = STATUS_INVALID_DEVICE_STATE;
125 break;
126 }
127
128 PIO_STACK_LOCATION pSl = IoGetCurrentIrpStackLocation(pIrp);
129 PFILE_OBJECT pFObj = pSl->FileObject;
130 if (!pFObj)
131 {
132 Status = STATUS_INVALID_PARAMETER;
133 break;
134 }
135
136 pFObj->FsContext = NULL;
137
138 if (pFObj->FileName.Length)
139 {
140 Status = STATUS_INVALID_PARAMETER;
141 break;
142 }
143
144 Status = vboxUsbRtCreate(pDevExt, pIrp);
145 if (!NT_SUCCESS(Status))
146 {
147 AssertFailed();
148 break;
149 }
150
151 ASMAtomicIncU32(&pDevExt->cHandles);
152 Status = STATUS_SUCCESS;
153 break;
154 } while (0);
155
156 Status = VBoxDrvToolIoComplete(pIrp, Status, 0);
157 return Status;
158}
159
160static NTSTATUS vboxUsbDispatchClose(IN PDEVICE_OBJECT pDeviceObject, IN PIRP pIrp)
161{
162 PVBOXUSBDEV_EXT pDevExt = (PVBOXUSBDEV_EXT)pDeviceObject->DeviceExtension;
163 PIO_STACK_LOCATION pSl = IoGetCurrentIrpStackLocation(pIrp);
164 PFILE_OBJECT pFObj = pSl->FileObject;
165 NTSTATUS Status = STATUS_SUCCESS;
166 Assert(pFObj);
167 Assert(!pFObj->FileName.Length);
168 Status = vboxUsbRtClose(pDevExt, pIrp);
169 if (NT_SUCCESS(Status))
170 {
171 ASMAtomicDecU32(&pDevExt->cHandles);
172 }
173 else
174 {
175 AssertFailed();
176 }
177 Status = VBoxDrvToolIoComplete(pIrp, Status, 0);
178 return Status;
179}
180
181static NTSTATUS vboxUsbDispatchDeviceControl(IN PDEVICE_OBJECT pDeviceObject, IN PIRP pIrp)
182{
183 PVBOXUSBDEV_EXT pDevExt = (PVBOXUSBDEV_EXT)pDeviceObject->DeviceExtension;
184 NTSTATUS Status = STATUS_INVALID_HANDLE;
185 if (vboxUsbDdiStateRetainIfStarted(pDevExt))
186 {
187 return vboxUsbRtDispatch(pDevExt, pIrp);
188 }
189 else
190 {
191 Status = STATUS_INVALID_DEVICE_STATE;
192 }
193
194 Status = VBoxDrvToolIoComplete(pIrp, Status, 0);
195 return Status;
196}
197
198static NTSTATUS vboxUsbDispatchCleanup(IN PDEVICE_OBJECT pDeviceObject, IN PIRP pIrp)
199{
200 PVBOXUSBDEV_EXT pDevExt = (PVBOXUSBDEV_EXT)pDeviceObject->DeviceExtension;
201 NTSTATUS Status = STATUS_SUCCESS;
202 Status = VBoxDrvToolIoComplete(pIrp, Status, 0);
203 return Status;
204}
205
206static NTSTATUS vboxUsbDevAccessDeviedDispatchStub(IN PDEVICE_OBJECT pDeviceObject, IN PIRP pIrp)
207{
208 PVBOXUSBDEV_EXT pDevExt = (PVBOXUSBDEV_EXT)pDeviceObject->DeviceExtension;
209 if (!vboxUsbDdiStateRetainIfNotRemoved(pDevExt))
210 {
211 VBoxDrvToolIoComplete(pIrp, STATUS_DELETE_PENDING, 0);
212 return STATUS_DELETE_PENDING;
213 }
214
215 NTSTATUS Status = STATUS_ACCESS_DENIED;
216 Status = VBoxDrvToolIoComplete(pIrp, Status, 0);
217
218 vboxUsbDdiStateRelease(pDevExt);
219
220 return Status;
221}
222
223static NTSTATUS vboxUsbDispatchSystemControl(IN PDEVICE_OBJECT pDeviceObject, IN PIRP pIrp)
224{
225 PVBOXUSBDEV_EXT pDevExt = (PVBOXUSBDEV_EXT)pDeviceObject->DeviceExtension;
226 if (!vboxUsbDdiStateRetainIfNotRemoved(pDevExt))
227 {
228 VBoxDrvToolIoComplete(pIrp, STATUS_DELETE_PENDING, 0);
229 return STATUS_DELETE_PENDING;
230 }
231
232 IoSkipCurrentIrpStackLocation(pIrp);
233
234 NTSTATUS Status = IoCallDriver(pDevExt->pLowerDO, pIrp);
235
236 vboxUsbDdiStateRelease(pDevExt);
237
238 return Status;
239}
240
241static NTSTATUS vboxUsbDispatchRead(IN PDEVICE_OBJECT pDeviceObject, IN PIRP pIrp)
242{
243#ifdef DEBUG_misha
244 AssertFailed();
245#endif
246 return vboxUsbDevAccessDeviedDispatchStub(pDeviceObject, pIrp);
247}
248
249static NTSTATUS vboxUsbDispatchWrite(IN PDEVICE_OBJECT pDeviceObject, IN PIRP pIrp)
250{
251#ifdef DEBUG_misha
252 AssertFailed();
253#endif
254 return vboxUsbDevAccessDeviedDispatchStub(pDeviceObject, pIrp);
255}
256
257RT_C_DECLS_BEGIN
258
259NTSTATUS DriverEntry(IN PDRIVER_OBJECT pDriverObject, IN PUNICODE_STRING pRegistryPath);
260
261RT_C_DECLS_END
262
263NTSTATUS DriverEntry(IN PDRIVER_OBJECT pDriverObject, IN PUNICODE_STRING pRegistryPath)
264{
265 LogRel(("VBoxUsb::DriverEntry. Built Date (%s) Time (%s)\n", __DATE__, __TIME__));
266
267 NTSTATUS Status = vboxUsbRtGlobalsInit();
268 Assert(Status == STATUS_SUCCESS);
269 if (Status == STATUS_SUCCESS)
270 {
271 Status = VBoxDrvToolStrCopy(&g_VBoxUsbGlobals.RegPath, pRegistryPath);
272 Assert(Status == STATUS_SUCCESS);
273 if (Status == STATUS_SUCCESS)
274 {
275 g_VBoxUsbGlobals.pDrvObj = pDriverObject;
276
277 pDriverObject->DriverExtension->AddDevice = vboxUsbDdiAddDevice;
278
279 pDriverObject->DriverUnload = vboxUsbDdiUnload;
280
281 pDriverObject->MajorFunction[IRP_MJ_CREATE] = vboxUsbDispatchCreate;
282 pDriverObject->MajorFunction[IRP_MJ_CLOSE] = vboxUsbDispatchClose;
283 pDriverObject->MajorFunction[IRP_MJ_READ] = vboxUsbDispatchRead;
284 pDriverObject->MajorFunction[IRP_MJ_WRITE] = vboxUsbDispatchWrite;
285 pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = vboxUsbDispatchDeviceControl;
286 pDriverObject->MajorFunction[IRP_MJ_CLEANUP] = vboxUsbDispatchCleanup;
287 pDriverObject->MajorFunction[IRP_MJ_POWER] = vboxUsbDispatchPower;
288 pDriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = vboxUsbDispatchSystemControl;
289 pDriverObject->MajorFunction[IRP_MJ_PNP] = vboxUsbDispatchPnP;
290
291 return STATUS_SUCCESS;
292 }
293 vboxUsbRtGlobalsTerm();
294 }
295
296 LogRel(("VBoxUsb::DriverEntry. failed with Status (0x%x)\n", Status));
297
298 return Status;
299}
300
301#ifdef DEBUG
302DECLHIDDEN(VOID) vboxUsbPnPStateGbgChange(ENMVBOXUSB_PNPSTATE enmOldState, ENMVBOXUSB_PNPSTATE enmNewState)
303{
304 /* *ensure the state change is valid */
305 switch (enmNewState)
306 {
307 case ENMVBOXUSB_PNPSTATE_STARTED:
308 Assert(enmOldState == ENMVBOXUSB_PNPSTATE_START_PENDING
309 || ENMVBOXUSB_PNPSTATE_REMOVE_PENDING
310 || ENMVBOXUSB_PNPSTATE_STOPPED
311 || ENMVBOXUSB_PNPSTATE_STOP_PENDING);
312 break;
313 case ENMVBOXUSB_PNPSTATE_STOP_PENDING:
314 Assert(enmOldState == ENMVBOXUSB_PNPSTATE_STARTED);
315 break;
316 case ENMVBOXUSB_PNPSTATE_STOPPED:
317 Assert(enmOldState == ENMVBOXUSB_PNPSTATE_STOP_PENDING);
318 break;
319 case ENMVBOXUSB_PNPSTATE_SURPRISE_REMOVED:
320 Assert(enmOldState == ENMVBOXUSB_PNPSTATE_STARTED);
321 break;
322 case ENMVBOXUSB_PNPSTATE_REMOVE_PENDING:
323 Assert(enmOldState == ENMVBOXUSB_PNPSTATE_STARTED);
324 break;
325 case ENMVBOXUSB_PNPSTATE_REMOVED:
326 Assert(enmOldState == ENMVBOXUSB_PNPSTATE_REMOVE_PENDING
327 || enmOldState == ENMVBOXUSB_PNPSTATE_SURPRISE_REMOVED);
328 break;
329 default:
330 AssertBreakpoint();
331 break;
332 }
333
334}
335#endif
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette