VirtualBox

source: vbox/trunk/src/VBox/HostDrivers/VBoxUSB/win/Device/vboxusb.cpp@ 32671

最後變更 在這個檔案從32671是 31896,由 vboxsync 提交於 15 年 前

export the VBoxUSB host driver to OSE

  • 屬性 svn:eol-style 設為 native
  • 屬性 svn:keywords 設為 Author Date Id Revision
檔案大小: 14.4 KB
 
1/*++
2
3Copyright (c) 2000 Microsoft Corporation
4
5Module Name:
6
7 VBoxUSB.c
8
9Abstract:
10
11 Bulk USB device driver for Intel 82930 USB test board
12 Main module
13
14Author:
15
16Environment:
17
18 kernel mode only
19
20Notes:
21
22 Copyright (c) 2000 Microsoft Corporation.
23 All Rights Reserved.
24
25--*/
26
27#include "vboxusb.h"
28#include "vboxpnp.h"
29#include "vboxpwr.h"
30#include "vboxdev.h"
31#include "vboxrwr.h"
32#include <iprt/assert.h>
33
34//
35// Globals
36//
37
38GLOBALS Globals;
39ULONG DebugLevel = 3;
40
41/*******************************************************************************
42* Exported Functions *
43*******************************************************************************/
44RT_C_DECLS_BEGIN
45NTSTATUS DriverEntry(PDRIVER_OBJECT pDrvObj, PUNICODE_STRING pRegPath);
46RT_C_DECLS_END
47
48VOID
49VBoxUSB_DriverUnload(
50 IN PDRIVER_OBJECT DriverObject
51 );
52
53NTSTATUS
54VBoxUSB_AddDevice(
55 IN PDRIVER_OBJECT DriverObject,
56 IN PDEVICE_OBJECT PhysicalDeviceObject
57 );
58
59NTSTATUS
60VBoxUSB_DispatchSysCtrl(
61 IN PDEVICE_OBJECT DeviceObject,
62 IN PIRP Irp
63 );
64
65
66#ifdef DEBUG
67PCHAR
68WMIMinorFunctionString (
69 UCHAR MinorFunction
70 );
71#endif
72
73#ifdef PAGE_CODE
74#ifdef ALLOC_PRAGMA
75#pragma alloc_text(INIT, DriverEntry)
76#pragma alloc_text(PAGE, VBoxUSB_DriverUnload)
77#endif
78#endif
79
80
81NTSTATUS
82DriverEntry(
83 IN PDRIVER_OBJECT DriverObject,
84 IN PUNICODE_STRING UniRegistryPath
85 )
86/*++
87
88Routine Description:
89
90 Installable driver initialization entry point.
91 This entry point is called directly by the I/O system.
92
93Arguments:
94
95 DriverObject - pointer to driver object
96
97 RegistryPath - pointer to a unicode string representing the path to driver
98 specific key in the registry.
99
100Return Values:
101
102 NT status value
103
104--*/
105{
106
107 NTSTATUS ntStatus;
108 PUNICODE_STRING registryPath;
109
110 dprintf(("VBoxUSB: DriverEntry (DriverObject=%p)\n", DriverObject));
111
112 //
113 // initialization of variables
114 //
115
116 registryPath = &Globals.VBoxUSB_RegistryPath;
117
118 //
119 // Allocate pool to hold a null-terminated copy of the path.
120 // Safe in paged pool since all registry routines execute at
121 // PASSIVE_LEVEL.
122 //
123
124 registryPath->MaximumLength = UniRegistryPath->Length + sizeof(UNICODE_NULL);
125 registryPath->Length = UniRegistryPath->Length;
126 registryPath->Buffer = (LPWSTR)ExAllocatePool(PagedPool, registryPath->MaximumLength);
127
128 if (!registryPath->Buffer) {
129
130 dprintf(("Failed to allocate memory for registryPath\n"));
131 ntStatus = STATUS_INSUFFICIENT_RESOURCES;
132 goto DriverEntry_Exit;
133 }
134
135
136 RtlZeroMemory (registryPath->Buffer,
137 registryPath->MaximumLength);
138 RtlMoveMemory (registryPath->Buffer,
139 UniRegistryPath->Buffer,
140 UniRegistryPath->Length);
141
142 ntStatus = STATUS_SUCCESS;
143
144 //
145 // Initialize the driver object with this driver's entry points.
146 //
147 DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = VBoxUSB_DispatchDevCtrl;
148 DriverObject->MajorFunction[IRP_MJ_POWER] = VBoxUSB_DispatchPower;
149 DriverObject->MajorFunction[IRP_MJ_PNP] = VBoxUSB_DispatchPnP;
150 DriverObject->MajorFunction[IRP_MJ_CREATE] = VBoxUSB_DispatchCreate;
151 DriverObject->MajorFunction[IRP_MJ_CLOSE] = VBoxUSB_DispatchClose;
152 DriverObject->MajorFunction[IRP_MJ_CLEANUP] = VBoxUSB_DispatchClean;
153 DriverObject->MajorFunction[IRP_MJ_READ] =
154 DriverObject->MajorFunction[IRP_MJ_WRITE] = VBoxUSB_DispatchReadWrite;
155 DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = VBoxUSB_DispatchSysCtrl;
156 DriverObject->DriverUnload = VBoxUSB_DriverUnload;
157 DriverObject->DriverExtension->AddDevice = VBoxUSB_AddDevice;
158DriverEntry_Exit:
159
160 return ntStatus;
161}
162
163VOID
164VBoxUSB_DriverUnload(
165 IN PDRIVER_OBJECT DriverObject
166 )
167/*++
168
169Description:
170
171 This function will free the memory allocations in DriverEntry.
172
173Arguments:
174
175 DriverObject - pointer to driver object
176
177Return:
178
179 None
180
181--*/
182{
183 PUNICODE_STRING registryPath;
184
185 dprintf(("vboxUsb_DriverUnload - begins\n"));
186
187 registryPath = &Globals.VBoxUSB_RegistryPath;
188
189 if(registryPath->Buffer) {
190
191 ExFreePool(registryPath->Buffer);
192 registryPath->Buffer = NULL;
193 }
194
195 dprintf(("vboxUsb_DriverUnload - ends\n"));
196
197 return;
198}
199
200NTSTATUS
201VBoxUSB_AddDevice(
202 IN PDRIVER_OBJECT DriverObject,
203 IN PDEVICE_OBJECT PhysicalDeviceObject
204 )
205/*++
206
207Description:
208
209Arguments:
210
211 DriverObject - Store the pointer to the object representing us.
212
213 PhysicalDeviceObject - Pointer to the device object created by the
214 undelying bus driver.
215
216Return:
217
218 STATUS_SUCCESS - if successful
219 STATUS_UNSUCCESSFUL - otherwise
220
221--*/
222{
223 NTSTATUS ntStatus;
224 PDEVICE_OBJECT deviceObject;
225 PDEVICE_EXTENSION deviceExtension;
226 POWER_STATE state;
227
228 dprintf(("vboxUsb_AddDevice - begins\n"));
229
230 deviceObject = NULL;
231
232 ntStatus = IoCreateDevice(
233 DriverObject, // our driver object
234 sizeof(DEVICE_EXTENSION), // extension size for us
235 NULL, // name for this device
236 FILE_DEVICE_UNKNOWN,
237 FILE_AUTOGENERATED_DEVICE_NAME, // device characteristics
238 FALSE, // Not exclusive
239 &deviceObject); // Our device object
240
241 if(!NT_SUCCESS(ntStatus)) {
242 //
243 // returning failure here prevents the entire stack from functioning,
244 // but most likely the rest of the stack will not be able to create
245 // device objects either, so it is still OK.
246 //
247 dprintf(("Failed to create device object\n"));
248 return ntStatus;
249 }
250
251 //
252 // Initialize the device extension
253 //
254
255 deviceExtension = (PDEVICE_EXTENSION) deviceObject->DeviceExtension;
256 deviceExtension->FunctionalDeviceObject = deviceObject;
257 deviceExtension->PhysicalDeviceObject = PhysicalDeviceObject;
258 deviceObject->Flags |= DO_DIRECT_IO;
259
260 //
261 // initialize the device state lock and set the device state
262 //
263
264 KeInitializeSpinLock(&deviceExtension->DevStateLock);
265 INITIALIZE_PNP_STATE(deviceExtension);
266
267 //
268 //initialize OpenHandleCount
269 //
270 deviceExtension->OpenHandleCount = 0;
271
272 //
273 // Initialize the selective suspend variables
274 //
275 KeInitializeSpinLock(&deviceExtension->IdleReqStateLock);
276 deviceExtension->IdleReqPend = 0;
277 deviceExtension->PendingIdleIrp = NULL;
278
279 //
280 // Hold requests until the device is started
281 //
282
283 deviceExtension->QueueState = HoldRequests;
284
285 //
286 // Initialize the queue and the queue spin lock
287 //
288
289 InitializeListHead(&deviceExtension->NewRequestsQueue);
290 KeInitializeSpinLock(&deviceExtension->QueueLock);
291
292 //
293 // Initialize the remove event to not-signaled.
294 //
295
296 KeInitializeEvent(&deviceExtension->RemoveEvent,
297 SynchronizationEvent,
298 FALSE);
299
300 //
301 // Initialize the stop event to signaled.
302 // This event is signaled when the OutstandingIO becomes 1
303 //
304
305 KeInitializeEvent(&deviceExtension->StopEvent,
306 SynchronizationEvent,
307 TRUE);
308
309 //
310 // OutstandingIo count biased to 1.
311 // Transition to 0 during remove device means IO is finished.
312 // Transition to 1 means the device can be stopped
313 //
314
315 deviceExtension->OutStandingIO = 1;
316 KeInitializeSpinLock(&deviceExtension->IOCountLock);
317
318#ifdef SUPPORT_WMI
319 //
320 // Delegating to WMILIB
321 //
322 ntStatus = VBoxUSB_WmiRegistration(deviceExtension);
323
324 if(!NT_SUCCESS(ntStatus)) {
325
326 dprintf(("vboxUsb_WmiRegistration failed with %X\n", ntStatus));
327 IoDeleteDevice(deviceObject);
328 return ntStatus;
329 }
330#endif
331 //
332 // set the flags as underlying PDO
333 //
334
335 if(PhysicalDeviceObject->Flags & DO_POWER_PAGABLE) {
336
337 deviceObject->Flags |= DO_POWER_PAGABLE;
338 }
339
340 //
341 // Typically, the function driver for a device is its
342 // power policy owner, although for some devices another
343 // driver or system component may assume this role.
344 // Set the initial power state of the device, if known, by calling
345 // PoSetPowerState.
346 //
347
348 deviceExtension->DevPower = PowerDeviceD0;
349 deviceExtension->SysPower = PowerSystemWorking;
350
351 state.DeviceState = PowerDeviceD0;
352 PoSetPowerState(deviceObject, DevicePowerState, state);
353
354 //
355 // attach our driver to device stack
356 // The return value of IoAttachDeviceToDeviceStack is the top of the
357 // attachment chain. This is where all the IRPs should be routed.
358 //
359
360 deviceExtension->TopOfStackDeviceObject =
361 IoAttachDeviceToDeviceStack(deviceObject,
362 PhysicalDeviceObject);
363
364 if(NULL == deviceExtension->TopOfStackDeviceObject) {
365#ifdef SUPPORT_WMI
366 VBoxUSB_WmiDeRegistration(deviceExtension);
367#endif
368 IoDeleteDevice(deviceObject);
369 return STATUS_NO_SUCH_DEVICE;
370 }
371
372 //
373 // Register device interfaces
374 //
375
376 ntStatus = IoRegisterDeviceInterface(deviceExtension->PhysicalDeviceObject,
377 &GUID_CLASS_VBOXUSB,
378 NULL,
379 &deviceExtension->InterfaceName);
380
381 if(!NT_SUCCESS(ntStatus)) {
382
383#ifdef SUPPORT_WMI
384 VBoxUSB_WmiDeRegistration(deviceExtension);
385#endif
386 IoDetachDevice(deviceExtension->TopOfStackDeviceObject);
387 IoDeleteDevice(deviceObject);
388 return ntStatus;
389 }
390
391 if(IoIsWdmVersionAvailable(1, 0x20)) {
392
393 deviceExtension->WdmVersion = WinXpOrBetter;
394 }
395 else if(IoIsWdmVersionAvailable(1, 0x10)) {
396
397 deviceExtension->WdmVersion = Win2kOrBetter;
398 }
399 else if(IoIsWdmVersionAvailable(1, 0x5)) {
400
401 deviceExtension->WdmVersion = WinMeOrBetter;
402 }
403 else if(IoIsWdmVersionAvailable(1, 0x0)) {
404
405 deviceExtension->WdmVersion = Win98OrBetter;
406 }
407
408 deviceExtension->SSRegistryEnable = 0;
409 deviceExtension->SSEnable = 0;
410
411 //
412 // WinXP only
413 // check the registry flag -
414 // whether the device should selectively
415 // suspend when idle
416 //
417
418 if(WinXpOrBetter == deviceExtension->WdmVersion) {
419
420 VBoxUSB_GetRegistryDword(VBOXUSB_REGISTRY_PARAMETERS_PATH,
421 L"vboxUsbEnable",
422 (PULONG)&deviceExtension->SSRegistryEnable);
423
424 if(deviceExtension->SSRegistryEnable) {
425
426 //
427 // initialize DPC
428 //
429 KeInitializeDpc(&deviceExtension->DeferredProcCall,
430 DpcRoutine,
431 deviceObject);
432
433 //
434 // initialize the timer.
435 // the DPC and the timer in conjunction,
436 // monitor the state of the device to
437 // selectively suspend the device.
438 //
439 KeInitializeTimerEx(&deviceExtension->Timer,
440 NotificationTimer);
441
442 //
443 // Initialize the NoDpcWorkItemPendingEvent to signaled state.
444 // This event is cleared when a Dpc is fired and signaled
445 // on completion of the work-item.
446 //
447 KeInitializeEvent(&deviceExtension->NoDpcWorkItemPendingEvent,
448 NotificationEvent,
449 TRUE);
450
451 //
452 // Initialize the NoIdleReqPendEvent to ensure that the idle request
453 // is indeed complete before we unload the drivers.
454 //
455 KeInitializeEvent(&deviceExtension->NoIdleReqPendEvent,
456 NotificationEvent,
457 TRUE);
458 }
459 }
460
461 //
462 // Clear the DO_DEVICE_INITIALIZING flag.
463 // Note: Do not clear this flag until the driver has set the
464 // device power state and the power DO flags.
465 //
466
467 deviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
468
469 /* Clear all VBox USB device data. */
470 memset(&deviceExtension->usbdev, 0, sizeof(deviceExtension->usbdev));
471
472 dprintf(("vboxUsb_AddDevice - ends\n"));
473
474 return ntStatus;
475}
476
477
478NTSTATUS
479VBoxUSB_DispatchSysCtrl(
480 IN PDEVICE_OBJECT DeviceObject,
481 IN PIRP Irp
482 )
483/*++
484
485Routine Description:
486
487Arguments:
488
489Return Value:
490
491--*/
492{
493 PDEVICE_EXTENSION deviceExtension;
494 NTSTATUS ntStatus;
495 PIO_STACK_LOCATION irpStack;
496
497 PAGED_CODE();
498
499 irpStack = IoGetCurrentIrpStackLocation (Irp);
500 deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
501
502 dprintf((WMIMinorFunctionString(irpStack->MinorFunction)));
503
504 if (Removed == deviceExtension->DeviceState)
505 {
506 ntStatus = STATUS_DELETE_PENDING;
507
508 Irp->IoStatus.Status = ntStatus;
509 Irp->IoStatus.Information = 0;
510
511 IoCompleteRequest(Irp, IO_NO_INCREMENT);
512
513 return ntStatus;
514 }
515
516 dprintf(("VBoxUSB_DispatchSysCtrl::"));
517 VBoxUSB_IoIncrement(deviceExtension);
518
519 /* Always pass it on to the next driver. */
520 IoSkipCurrentIrpStackLocation (Irp);
521
522 ntStatus = IoCallDriver(deviceExtension->TopOfStackDeviceObject, Irp);
523
524 dprintf(("VBoxUSB_DispatchSysCtrl::"));
525 VBoxUSB_IoDecrement(deviceExtension);
526
527 return ntStatus;
528}
529
530
531#ifdef DEBUG
532PCHAR
533WMIMinorFunctionString (
534 UCHAR MinorFunction
535 )
536/*++
537
538Routine Description:
539
540Arguments:
541
542Return Value:
543
544--*/
545{
546 switch (MinorFunction) {
547
548 case IRP_MN_CHANGE_SINGLE_INSTANCE:
549 return "IRP_MN_CHANGE_SINGLE_INSTANCE\n";
550
551 case IRP_MN_CHANGE_SINGLE_ITEM:
552 return "IRP_MN_CHANGE_SINGLE_ITEM\n";
553
554 case IRP_MN_DISABLE_COLLECTION:
555 return "IRP_MN_DISABLE_COLLECTION\n";
556
557 case IRP_MN_DISABLE_EVENTS:
558 return "IRP_MN_DISABLE_EVENTS\n";
559
560 case IRP_MN_ENABLE_COLLECTION:
561 return "IRP_MN_ENABLE_COLLECTION\n";
562
563 case IRP_MN_ENABLE_EVENTS:
564 return "IRP_MN_ENABLE_EVENTS\n";
565
566 case IRP_MN_EXECUTE_METHOD:
567 return "IRP_MN_EXECUTE_METHOD\n";
568
569 case IRP_MN_QUERY_ALL_DATA:
570 return "IRP_MN_QUERY_ALL_DATA\n";
571
572 case IRP_MN_QUERY_SINGLE_INSTANCE:
573 return "IRP_MN_QUERY_SINGLE_INSTANCE\n";
574
575 case IRP_MN_REGINFO:
576 return "IRP_MN_REGINFO\n";
577
578 default:
579 return "IRP_MN_?????\n";
580 }
581}
582#endif
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

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