VirtualBox

source: vbox/trunk/src/VBox/HostDrivers/VBoxUSB/win/cmn/VBoxDrvTool.cpp@ 54558

Last change on this file since 54558 was 38356, checked in by vboxsync, 13 years ago

usb/win: more logging

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 6.5 KB
Line 
1/* $Id: VBoxDrvTool.cpp 38356 2011-08-08 15:49:01Z vboxsync $ */
2/** @file
3 * Windows Driver R0 Tooling.
4 */
5
6/*
7 * Copyright (C) 2011 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18#include "VBoxDrvTool.h"
19
20#include <iprt/assert.h>
21#include <VBox/log.h>
22
23#include "../../../win/VBoxDbgLog.h"
24
25#define VBOXDRVTOOL_MEMTAG 'TDBV'
26
27static PVOID vboxDrvToolMemAlloc(SIZE_T cbBytes)
28{
29 PVOID pvMem = ExAllocatePoolWithTag(NonPagedPool, cbBytes, VBOXDRVTOOL_MEMTAG);
30 Assert(pvMem);
31 return pvMem;
32}
33
34static PVOID vboxDrvToolMemAllocZ(SIZE_T cbBytes)
35{
36 PVOID pvMem = vboxDrvToolMemAlloc(cbBytes);
37 if (pvMem)
38 {
39 RtlZeroMemory(pvMem, cbBytes);
40 }
41 return pvMem;
42}
43
44static VOID vboxDrvToolMemFree(PVOID pvMem)
45{
46 ExFreePoolWithTag(pvMem, VBOXDRVTOOL_MEMTAG);
47}
48
49VBOXDRVTOOL_DECL(NTSTATUS) VBoxDrvToolRegOpenKeyU(OUT PHANDLE phKey, IN PUNICODE_STRING pName, IN ACCESS_MASK fAccess)
50{
51 OBJECT_ATTRIBUTES ObjAttr;
52
53 InitializeObjectAttributes(&ObjAttr, pName, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL);
54
55 return ZwOpenKey(phKey, fAccess, &ObjAttr);
56}
57
58VBOXDRVTOOL_DECL(NTSTATUS) VBoxDrvToolRegOpenKey(OUT PHANDLE phKey, IN PWCHAR pName, IN ACCESS_MASK fAccess)
59{
60 UNICODE_STRING RtlStr;
61 RtlInitUnicodeString(&RtlStr, pName);
62
63 return VBoxDrvToolRegOpenKeyU(phKey, &RtlStr, fAccess);
64}
65
66VBOXDRVTOOL_DECL(NTSTATUS) VBoxDrvToolRegCloseKey(IN HANDLE hKey)
67{
68 return ZwClose(hKey);
69}
70
71VBOXDRVTOOL_DECL(NTSTATUS) VBoxDrvToolRegQueryValueDword(IN HANDLE hKey, IN PWCHAR pName, OUT PULONG pDword)
72{
73 struct
74 {
75 KEY_VALUE_PARTIAL_INFORMATION Info;
76 UCHAR Buf[32]; /* should be enough */
77 } Buf;
78 ULONG cbBuf;
79 UNICODE_STRING RtlStr;
80 RtlInitUnicodeString(&RtlStr, pName);
81 NTSTATUS Status = ZwQueryValueKey(hKey,
82 &RtlStr,
83 KeyValuePartialInformation,
84 &Buf.Info,
85 sizeof(Buf),
86 &cbBuf);
87 if (Status == STATUS_SUCCESS)
88 {
89 if (Buf.Info.Type == REG_DWORD)
90 {
91 Assert(Buf.Info.DataLength == 4);
92 *pDword = *((PULONG)Buf.Info.Data);
93 return STATUS_SUCCESS;
94 }
95 }
96
97 return STATUS_INVALID_PARAMETER;
98}
99
100VBOXDRVTOOL_DECL(NTSTATUS) VBoxDrvToolRegSetValueDword(IN HANDLE hKey, IN PWCHAR pName, OUT ULONG val)
101{
102 UNICODE_STRING RtlStr;
103 RtlInitUnicodeString(&RtlStr, pName);
104 return ZwSetValueKey(hKey, &RtlStr,
105 NULL, /* IN ULONG TitleIndex OPTIONAL, reserved */
106 REG_DWORD,
107 &val,
108 sizeof(val));
109}
110
111static NTSTATUS vboxDrvToolIoCompletionSetEvent(IN PDEVICE_OBJECT pDevObj, IN PIRP pIrp, IN PVOID pvContext)
112{
113 PKEVENT pEvent = (PKEVENT)pvContext;
114 KeSetEvent(pEvent, 0, FALSE);
115 return STATUS_MORE_PROCESSING_REQUIRED;
116}
117
118VBOXDRVTOOL_DECL(NTSTATUS) VBoxDrvToolIoPostAsync(PDEVICE_OBJECT pDevObj, PIRP pIrp, PKEVENT pEvent)
119{
120 IoSetCompletionRoutine(pIrp, vboxDrvToolIoCompletionSetEvent, pEvent, TRUE, TRUE, TRUE);
121 return IoCallDriver(pDevObj, pIrp);
122}
123
124VBOXDRVTOOL_DECL(NTSTATUS) VBoxDrvToolIoPostSync(PDEVICE_OBJECT pDevObj, PIRP pIrp)
125{
126 KEVENT Event;
127 KeInitializeEvent(&Event, NotificationEvent, FALSE);
128 NTSTATUS Status = VBoxDrvToolIoPostAsync(pDevObj, pIrp, &Event);
129 if (Status == STATUS_PENDING)
130 {
131 KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
132 Status = pIrp->IoStatus.Status;
133 }
134 return Status;
135}
136
137/* !!!NOTE: the caller MUST be the IRP owner!!! *
138 * !! one can not post threaded IRPs this way!! */
139VBOXDRVTOOL_DECL(NTSTATUS) VBoxDrvToolIoPostSyncWithTimeout(PDEVICE_OBJECT pDevObj, PIRP pIrp, ULONG dwTimeoutMs)
140{
141 KEVENT Event;
142 LOG(("post irp (0x%p) to DevObj(0x%p) with timeout (%u)", pIrp, pDevObj, dwTimeoutMs));
143
144 KeInitializeEvent(&Event, NotificationEvent, FALSE);
145 NTSTATUS Status = VBoxDrvToolIoPostAsync(pDevObj, pIrp, &Event);
146 if (Status == STATUS_PENDING)
147 {
148 LARGE_INTEGER Interval;
149 PLARGE_INTEGER pInterval = NULL;
150 if (dwTimeoutMs != RT_INDEFINITE_WAIT)
151 {
152 Interval.QuadPart = -(int64_t) dwTimeoutMs /* ms */ * 10000;
153 pInterval = &Interval;
154 }
155
156 Status = KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, pInterval);
157 if (Status == STATUS_TIMEOUT)
158 {
159 WARN(("irp (0x%p) to DevObj(0x%p) was not completed within timeout (%u), cancelling", pIrp, pDevObj, dwTimeoutMs));
160 if (!IoCancelIrp(pIrp))
161 {
162 /* this may happen, but this is something the caller with timeout is not expecting */
163 WARN(("IoCancelIrp failed"));
164 }
165
166 /* wait for the IRP to complete */
167 KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
168 }
169 else
170 {
171 ASSERT_WARN(Status == STATUS_SUCCESS, ("uunexpected Status (0x%x)", Status));
172 }
173
174 /* by this time the IRP is completed */
175 Status = pIrp->IoStatus.Status;
176 LOG(("Pending IRP(0x%p) completed with status(0x%x)", pIrp, Status));
177 }
178 else
179 {
180 LOG(("IRP(0x%p) completed with status(0x%x)", pIrp, Status));
181 }
182 return Status;
183}
184
185VBOXDRVTOOL_DECL(VOID) VBoxDrvToolRefWaitEqual(PVBOXDRVTOOL_REF pRef, uint32_t u32Val)
186{
187 LARGE_INTEGER Interval;
188 Interval.QuadPart = -(int64_t) 2 /* ms */ * 10000;
189 uint32_t cRefs;
190
191 while ((cRefs = ASMAtomicReadU32(&pRef->cRefs)) != u32Val)
192 {
193 Assert(cRefs >= u32Val);
194 Assert(cRefs < UINT32_MAX/2);
195
196 KeDelayExecutionThread(KernelMode, FALSE, &Interval);
197 }
198}
199
200VBOXDRVTOOL_DECL(NTSTATUS) VBoxDrvToolStrCopy(PUNICODE_STRING pDst, CONST PUNICODE_STRING pSrc)
201{
202 USHORT cbLength = pSrc->Length + sizeof (pDst->Buffer[0]);
203 pDst->Buffer = (PWCHAR)vboxDrvToolMemAlloc(cbLength);
204 Assert(pDst->Buffer);
205 if (pDst->Buffer)
206 {
207 RtlMoveMemory(pDst->Buffer, pSrc->Buffer, pSrc->Length);
208 pDst->Buffer[pSrc->Length / sizeof (pDst->Buffer[0])] = L'\0';
209 pDst->Length = pSrc->Length;
210 pDst->MaximumLength = cbLength;
211 return STATUS_SUCCESS;
212 }
213 return STATUS_NO_MEMORY;
214}
215
216VBOXDRVTOOL_DECL(VOID) VBoxDrvToolStrFree(PUNICODE_STRING pStr)
217{
218 vboxDrvToolMemFree(pStr->Buffer);
219}
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