VirtualBox

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

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

wddm: autoresize fixes

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 6.1 KB
Line 
1/* $Id: VBoxDrvTool.cpp 37490 2011-06-16 10:58:27Z 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
22#define VBOXDRVTOOL_MEMTAG 'TDBV'
23
24static PVOID vboxDrvToolMemAlloc(SIZE_T cbBytes)
25{
26 PVOID pvMem = ExAllocatePoolWithTag(NonPagedPool, cbBytes, VBOXDRVTOOL_MEMTAG);
27 Assert(pvMem);
28 return pvMem;
29}
30
31static PVOID vboxDrvToolMemAllocZ(SIZE_T cbBytes)
32{
33 PVOID pvMem = vboxDrvToolMemAlloc(cbBytes);
34 if (pvMem)
35 {
36 RtlZeroMemory(pvMem, cbBytes);
37 }
38 return pvMem;
39}
40
41static VOID vboxDrvToolMemFree(PVOID pvMem)
42{
43 ExFreePoolWithTag(pvMem, VBOXDRVTOOL_MEMTAG);
44}
45
46VBOXDRVTOOL_DECL(NTSTATUS) VBoxDrvToolRegOpenKeyU(OUT PHANDLE phKey, IN PUNICODE_STRING pName, IN ACCESS_MASK fAccess)
47{
48 OBJECT_ATTRIBUTES ObjAttr;
49
50 InitializeObjectAttributes(&ObjAttr, pName, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL);
51
52 return ZwOpenKey(phKey, fAccess, &ObjAttr);
53}
54
55VBOXDRVTOOL_DECL(NTSTATUS) VBoxDrvToolRegOpenKey(OUT PHANDLE phKey, IN PWCHAR pName, IN ACCESS_MASK fAccess)
56{
57 UNICODE_STRING RtlStr;
58 RtlInitUnicodeString(&RtlStr, pName);
59
60 return VBoxDrvToolRegOpenKeyU(phKey, &RtlStr, fAccess);
61}
62
63VBOXDRVTOOL_DECL(NTSTATUS) VBoxDrvToolRegCloseKey(IN HANDLE hKey)
64{
65 return ZwClose(hKey);
66}
67
68VBOXDRVTOOL_DECL(NTSTATUS) VBoxDrvToolRegQueryValueDword(IN HANDLE hKey, IN PWCHAR pName, OUT PULONG pDword)
69{
70 struct
71 {
72 KEY_VALUE_PARTIAL_INFORMATION Info;
73 UCHAR Buf[32]; /* should be enough */
74 } Buf;
75 ULONG cbBuf;
76 UNICODE_STRING RtlStr;
77 RtlInitUnicodeString(&RtlStr, pName);
78 NTSTATUS Status = ZwQueryValueKey(hKey,
79 &RtlStr,
80 KeyValuePartialInformation,
81 &Buf.Info,
82 sizeof(Buf),
83 &cbBuf);
84 if (Status == STATUS_SUCCESS)
85 {
86 if (Buf.Info.Type == REG_DWORD)
87 {
88 Assert(Buf.Info.DataLength == 4);
89 *pDword = *((PULONG)Buf.Info.Data);
90 return STATUS_SUCCESS;
91 }
92 }
93
94 return STATUS_INVALID_PARAMETER;
95}
96
97VBOXDRVTOOL_DECL(NTSTATUS) VBoxDrvToolRegSetValueDword(IN HANDLE hKey, IN PWCHAR pName, OUT ULONG val)
98{
99 UNICODE_STRING RtlStr;
100 RtlInitUnicodeString(&RtlStr, pName);
101 return ZwSetValueKey(hKey, &RtlStr,
102 NULL, /* IN ULONG TitleIndex OPTIONAL, reserved */
103 REG_DWORD,
104 &val,
105 sizeof(val));
106}
107
108static NTSTATUS vboxDrvToolIoCompletionSetEvent(IN PDEVICE_OBJECT pDevObj, IN PIRP pIrp, IN PVOID pvContext)
109{
110 PKEVENT pEvent = (PKEVENT)pvContext;
111 KeSetEvent(pEvent, 0, FALSE);
112 return STATUS_MORE_PROCESSING_REQUIRED;
113}
114
115VBOXDRVTOOL_DECL(NTSTATUS) VBoxDrvToolIoPostAsync(PDEVICE_OBJECT pDevObj, PIRP pIrp, PKEVENT pEvent)
116{
117 IoSetCompletionRoutine(pIrp, vboxDrvToolIoCompletionSetEvent, pEvent, TRUE, TRUE, TRUE);
118 return IoCallDriver(pDevObj, pIrp);
119}
120
121VBOXDRVTOOL_DECL(NTSTATUS) VBoxDrvToolIoPostSync(PDEVICE_OBJECT pDevObj, PIRP pIrp)
122{
123 KEVENT Event;
124 KeInitializeEvent(&Event, NotificationEvent, FALSE);
125 NTSTATUS Status = VBoxDrvToolIoPostAsync(pDevObj, pIrp, &Event);
126 if (Status == STATUS_PENDING)
127 {
128 KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
129 Status = pIrp->IoStatus.Status;
130 }
131 return Status;
132}
133
134/* !!!NOTE: the caller MUST be the IRP owner!!! *
135 * !! one can not post threaded IRPs this way!! */
136VBOXDRVTOOL_DECL(NTSTATUS) VBoxDrvToolIoPostSyncWithTimeout(PDEVICE_OBJECT pDevObj, PIRP pIrp, ULONG dwTimeoutMs)
137{
138 KEVENT Event;
139 KeInitializeEvent(&Event, NotificationEvent, FALSE);
140 NTSTATUS Status = VBoxDrvToolIoPostAsync(pDevObj, pIrp, &Event);
141 if (Status == STATUS_PENDING)
142 {
143 LARGE_INTEGER Interval;
144 PLARGE_INTEGER pInterval = NULL;
145 if (dwTimeoutMs != RT_INDEFINITE_WAIT)
146 {
147 Interval.QuadPart = -(int64_t) dwTimeoutMs /* ms */ * 10000;
148 pInterval = &Interval;
149 }
150
151 Status = KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, pInterval);
152 if (Status == STATUS_TIMEOUT)
153 {
154#ifdef DEBUG_misha
155 /* debugging only */
156 AssertFailed();
157#endif
158 if (!IoCancelIrp(pIrp))
159 {
160 /* this may happen, but this is something the caller with timeout is not expecting */
161 AssertFailed();
162 }
163
164 /* wait for the IRP to complete */
165 KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
166 }
167 else
168 {
169 Assert(Status == STATUS_SUCCESS);
170 }
171
172 /* by this time the IRP is completed */
173 Status = pIrp->IoStatus.Status;
174 }
175 return Status;
176}
177
178VBOXDRVTOOL_DECL(VOID) VBoxDrvToolRefWaitEqual(PVBOXDRVTOOL_REF pRef, uint32_t u32Val)
179{
180 LARGE_INTEGER Interval;
181 Interval.QuadPart = -(int64_t) 2 /* ms */ * 10000;
182 uint32_t cRefs;
183
184 while ((cRefs = ASMAtomicReadU32(&pRef->cRefs)) != u32Val)
185 {
186 Assert(cRefs >= u32Val);
187 Assert(cRefs < UINT32_MAX/2);
188
189 KeDelayExecutionThread(KernelMode, FALSE, &Interval);
190 }
191}
192
193VBOXDRVTOOL_DECL(NTSTATUS) VBoxDrvToolStrCopy(PUNICODE_STRING pDst, CONST PUNICODE_STRING pSrc)
194{
195 USHORT cbLength = pSrc->Length + sizeof (pDst->Buffer[0]);
196 pDst->Buffer = (PWCHAR)vboxDrvToolMemAlloc(cbLength);
197 Assert(pDst->Buffer);
198 if (pDst->Buffer)
199 {
200 RtlMoveMemory(pDst->Buffer, pSrc->Buffer, pSrc->Length);
201 pDst->Buffer[pSrc->Length / sizeof (pDst->Buffer[0])] = L'\0';
202 pDst->Length = pSrc->Length;
203 pDst->MaximumLength = cbLength;
204 return STATUS_SUCCESS;
205 }
206 return STATUS_NO_MEMORY;
207}
208
209VBOXDRVTOOL_DECL(VOID) VBoxDrvToolStrFree(PUNICODE_STRING pStr)
210{
211 vboxDrvToolMemFree(pStr->Buffer);
212}
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