VirtualBox

source: vbox/trunk/src/VBox/Additions/WINNT/SharedFolders/driver/vbsfhlp.cpp

Last change on this file was 106061, checked in by vboxsync, 3 months ago

Copyright year updates by scm.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 11.3 KB
Line 
1/* $Id: vbsfhlp.cpp 106061 2024-09-16 14:03:52Z vboxsync $ */
2/** @file
3 * VirtualBox Windows Guest Shared Folders - File System Driver system helpers
4 */
5
6/*
7 * Copyright (C) 2012-2024 Oracle and/or its affiliates.
8 *
9 * This file is part of VirtualBox base platform packages, as
10 * available from https://www.virtualbox.org.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation, in version 3 of the
15 * License.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, see <https://www.gnu.org/licenses>.
24 *
25 * SPDX-License-Identifier: GPL-3.0-only
26 */
27
28
29/*********************************************************************************************************************************
30* Header Files *
31*********************************************************************************************************************************/
32#include "vbsf.h"
33#include <iprt/err.h>
34
35
36/*********************************************************************************************************************************
37* Global Variables *
38*********************************************************************************************************************************/
39#ifdef DEBUG
40static int volatile g_cAllocations = 0;
41#endif
42
43
44/**
45 * Convert VBox error code to NT status code
46 *
47 * @returns NT status code
48 * @param vrc VBox status code.
49 *
50 */
51NTSTATUS vbsfNtVBoxStatusToNt(int vrc)
52{
53 NTSTATUS Status;
54
55 switch (vrc)
56 {
57 case VINF_SUCCESS:
58 Status = STATUS_SUCCESS;
59 break;
60
61 case VERR_ACCESS_DENIED:
62 Status = STATUS_ACCESS_DENIED;
63 break;
64
65 case VERR_NO_MORE_FILES:
66 Status = STATUS_NO_MORE_FILES;
67 break;
68
69 case VERR_PATH_NOT_FOUND:
70 Status = STATUS_OBJECT_PATH_NOT_FOUND;
71 break;
72
73 case VERR_FILE_NOT_FOUND:
74 Status = STATUS_OBJECT_NAME_NOT_FOUND;
75 break;
76
77 case VERR_DIR_NOT_EMPTY:
78 Status = STATUS_DIRECTORY_NOT_EMPTY;
79 break;
80
81 case VERR_SHARING_VIOLATION:
82 Status = STATUS_SHARING_VIOLATION;
83 break;
84
85 case VERR_FILE_LOCK_VIOLATION:
86 Status = STATUS_FILE_LOCK_CONFLICT;
87 break;
88
89 case VERR_FILE_LOCK_FAILED:
90 Status = STATUS_LOCK_NOT_GRANTED;
91 break;
92
93 case VINF_BUFFER_OVERFLOW:
94 Status = STATUS_BUFFER_OVERFLOW;
95 break;
96
97 case VERR_EOF:
98 case VINF_EOF:
99 Status = STATUS_END_OF_FILE;
100 break;
101
102 case VERR_READ_ERROR:
103 case VERR_WRITE_ERROR:
104 case VERR_FILE_IO_ERROR:
105 Status = STATUS_UNEXPECTED_IO_ERROR;
106 break;
107
108 case VERR_WRITE_PROTECT:
109 Status = STATUS_MEDIA_WRITE_PROTECTED;
110 break;
111
112 case VERR_ALREADY_EXISTS:
113 Status = STATUS_OBJECT_NAME_COLLISION;
114 break;
115
116 case VERR_NOT_A_DIRECTORY:
117 Status = STATUS_NOT_A_DIRECTORY;
118 break;
119
120 case VERR_SEEK:
121 Status = STATUS_INVALID_PARAMETER;
122 break;
123
124 case VERR_INVALID_PARAMETER:
125 Status = STATUS_INVALID_PARAMETER;
126 break;
127
128 case VERR_NOT_SUPPORTED:
129 Status = STATUS_NOT_SUPPORTED;
130 break;
131
132 case VERR_INVALID_NAME:
133 Status = STATUS_OBJECT_NAME_INVALID;
134 break;
135
136 default:
137 Status = STATUS_INVALID_PARAMETER;
138 Log(("Unexpected vbox error %Rrc\n",
139 vrc));
140 break;
141 }
142 return Status;
143}
144
145/**
146 * Wrapper around ExAllocatePoolWithTag.
147 */
148PVOID vbsfNtAllocNonPagedMem(ULONG cbMemory)
149{
150 /* Tag is reversed (a.k.a "SHFL") to display correctly in debuggers, so search for "SHFL" */
151 PVOID pMemory = ExAllocatePoolWithTag(NonPagedPool, cbMemory, 'LFHS');
152 if (NULL != pMemory)
153 {
154 RtlZeroMemory(pMemory, cbMemory);
155#ifdef DEBUG
156 int const cAllocations = g_cAllocations += 1;
157 Log(("vbsfNtAllocNonPagedMem: Allocated %u bytes of memory at %p (g_iAllocRefCount=%d)\n", cbMemory, pMemory, cAllocations));
158#endif
159 }
160#ifdef DEBUG
161 else
162 Log(("vbsfNtAllocNonPagedMem: ERROR: Could not allocate %u bytes of memory!\n", cbMemory));
163#endif
164 return pMemory;
165}
166
167/**
168 * Wrapper around ExFreePoolWithTag.
169 */
170void vbsfNtFreeNonPagedMem(PVOID pvMemory)
171{
172#ifdef DEBUG
173 int cAllocations = g_cAllocations -= 1;
174 Log(("vbsfNtFreeNonPagedMem: %p (g_cAllocations=%d)\n", pvMemory, cAllocations));
175#endif
176 AssertPtr(pvMemory);
177
178 /* Tagged allocations must be freed using the same tag as used when allocating the memory. */
179 ExFreePoolWithTag(pvMemory, 'LFHS');
180}
181
182/** Allocate and initialize a SHFLSTRING from a UNICODE string.
183 *
184 * @param ppShflString Where to store the pointer to the allocated SHFLSTRING structure.
185 * The structure must be deallocated with vbsfNtFreeNonPagedMem.
186 * @param pwc The UNICODE string. If NULL then SHFL is only allocated.
187 * @param cb Size of the UNICODE string in bytes without the trailing nul.
188 *
189 * @return Status code.
190 */
191NTSTATUS vbsfNtShflStringFromUnicodeAlloc(PSHFLSTRING *ppShflString, const WCHAR *pwc, uint16_t cb)
192{
193 NTSTATUS Status;
194
195 /* Calculate length required for the SHFL structure: header + chars + nul. */
196 ULONG const cbShflString = SHFLSTRING_HEADER_SIZE + cb + sizeof(WCHAR);
197 PSHFLSTRING pShflString = (PSHFLSTRING)vbsfNtAllocNonPagedMem(cbShflString);
198 if (pShflString)
199 {
200 if (ShflStringInitBuffer(pShflString, cbShflString))
201 {
202 if (pwc)
203 {
204 RtlCopyMemory(pShflString->String.ucs2, pwc, cb);
205 pShflString->String.ucs2[cb / sizeof(WCHAR)] = 0;
206 pShflString->u16Length = cb; /* without terminating null */
207 AssertMsg(pShflString->u16Length + sizeof(WCHAR) == pShflString->u16Size,
208 ("u16Length %d, u16Size %d\n", pShflString->u16Length, pShflString->u16Size));
209 }
210 else
211 {
212 /** @todo r=bird: vbsfNtAllocNonPagedMem already zero'ed it... */
213 RtlZeroMemory(pShflString->String.ucs2, cb + sizeof(WCHAR));
214 pShflString->u16Length = 0; /* without terminating null */
215 AssertMsg(pShflString->u16Size >= sizeof(WCHAR),
216 ("u16Size %d\n", pShflString->u16Size));
217 }
218
219 *ppShflString = pShflString;
220 Status = STATUS_SUCCESS;
221 }
222 else
223 {
224 vbsfNtFreeNonPagedMem(pShflString);
225 Status = STATUS_INSUFFICIENT_RESOURCES;
226 }
227 }
228 else
229 Status = STATUS_INSUFFICIENT_RESOURCES;
230
231 return Status;
232}
233
234#if defined(DEBUG) || defined(LOG_ENABLED)
235
236/** Debug routine for translating a minor PNP function to a string. */
237static const char *vbsfNtMinorPnpFunctionName(LONG MinorFunction)
238{
239 switch (MinorFunction)
240 {
241 case IRP_MN_START_DEVICE:
242 return "IRP_MJ_PNP - IRP_MN_START_DEVICE";
243 case IRP_MN_QUERY_REMOVE_DEVICE:
244 return "IRP_MJ_PNP - IRP_MN_QUERY_REMOVE_DEVICE";
245 case IRP_MN_REMOVE_DEVICE:
246 return "IRP_MJ_PNP - IRP_MN_REMOVE_DEVICE";
247 case IRP_MN_CANCEL_REMOVE_DEVICE:
248 return "IRP_MJ_PNP - IRP_MN_CANCEL_REMOVE_DEVICE";
249 case IRP_MN_STOP_DEVICE:
250 return "IRP_MJ_PNP - IRP_MN_STOP_DEVICE";
251 case IRP_MN_QUERY_STOP_DEVICE:
252 return "IRP_MJ_PNP - IRP_MN_QUERY_STOP_DEVICE";
253 case IRP_MN_CANCEL_STOP_DEVICE:
254 return "IRP_MJ_PNP - IRP_MN_CANCEL_STOP_DEVICE";
255 case IRP_MN_QUERY_DEVICE_RELATIONS:
256 return "IRP_MJ_PNP - IRP_MN_QUERY_DEVICE_RELATIONS";
257 case IRP_MN_QUERY_INTERFACE:
258 return "IRP_MJ_PNP - IRP_MN_QUERY_INTERFACE";
259 case IRP_MN_QUERY_CAPABILITIES:
260 return "IRP_MJ_PNP - IRP_MN_QUERY_CAPABILITIES";
261 case IRP_MN_QUERY_RESOURCES:
262 return "IRP_MJ_PNP - IRP_MN_QUERY_RESOURCES";
263 case IRP_MN_QUERY_RESOURCE_REQUIREMENTS:
264 return "IRP_MJ_PNP - IRP_MN_QUERY_RESOURCE_REQUIREMENTS";
265 case IRP_MN_QUERY_DEVICE_TEXT:
266 return "IRP_MJ_PNP - IRP_MN_QUERY_DEVICE_TEXT";
267 case IRP_MN_FILTER_RESOURCE_REQUIREMENTS:
268 return "IRP_MJ_PNP - IRP_MN_FILTER_RESOURCE_REQUIREMENTS";
269 case IRP_MN_READ_CONFIG:
270 return "IRP_MJ_PNP - IRP_MN_READ_CONFIG";
271 case IRP_MN_WRITE_CONFIG:
272 return "IRP_MJ_PNP - IRP_MN_WRITE_CONFIG";
273 case IRP_MN_EJECT:
274 return "IRP_MJ_PNP - IRP_MN_EJECT";
275 case IRP_MN_SET_LOCK:
276 return "IRP_MJ_PNP - IRP_MN_SET_LOCK";
277 case IRP_MN_QUERY_ID:
278 return "IRP_MJ_PNP - IRP_MN_QUERY_ID";
279 case IRP_MN_QUERY_PNP_DEVICE_STATE:
280 return "IRP_MJ_PNP - IRP_MN_QUERY_PNP_DEVICE_STATE";
281 case IRP_MN_QUERY_BUS_INFORMATION:
282 return "IRP_MJ_PNP - IRP_MN_QUERY_BUS_INFORMATION";
283 case IRP_MN_DEVICE_USAGE_NOTIFICATION:
284 return "IRP_MJ_PNP - IRP_MN_DEVICE_USAGE_NOTIFICATION";
285 case IRP_MN_SURPRISE_REMOVAL:
286 return "IRP_MJ_PNP - IRP_MN_SURPRISE_REMOVAL";
287 default:
288 return "IRP_MJ_PNP - unknown_pnp_irp";
289 }
290}
291
292/** Debug routine for translating a major+minor IPR function to a string. */
293const char *vbsfNtMajorFunctionName(UCHAR MajorFunction, LONG MinorFunction)
294{
295 switch (MajorFunction)
296 {
297 RT_CASE_RET_STR(IRP_MJ_CREATE);
298 RT_CASE_RET_STR(IRP_MJ_CREATE_NAMED_PIPE);
299 RT_CASE_RET_STR(IRP_MJ_CLOSE);
300 RT_CASE_RET_STR(IRP_MJ_READ);
301 RT_CASE_RET_STR(IRP_MJ_WRITE);
302 RT_CASE_RET_STR(IRP_MJ_QUERY_INFORMATION);
303 RT_CASE_RET_STR(IRP_MJ_SET_INFORMATION);
304 RT_CASE_RET_STR(IRP_MJ_QUERY_EA);
305 RT_CASE_RET_STR(IRP_MJ_SET_EA);
306 RT_CASE_RET_STR(IRP_MJ_FLUSH_BUFFERS);
307 RT_CASE_RET_STR(IRP_MJ_QUERY_VOLUME_INFORMATION);
308 RT_CASE_RET_STR(IRP_MJ_SET_VOLUME_INFORMATION);
309 RT_CASE_RET_STR(IRP_MJ_DIRECTORY_CONTROL);
310 RT_CASE_RET_STR(IRP_MJ_FILE_SYSTEM_CONTROL);
311 RT_CASE_RET_STR(IRP_MJ_DEVICE_CONTROL);
312 RT_CASE_RET_STR(IRP_MJ_INTERNAL_DEVICE_CONTROL);
313 RT_CASE_RET_STR(IRP_MJ_SHUTDOWN);
314 RT_CASE_RET_STR(IRP_MJ_LOCK_CONTROL);
315 RT_CASE_RET_STR(IRP_MJ_CLEANUP);
316 RT_CASE_RET_STR(IRP_MJ_CREATE_MAILSLOT);
317 RT_CASE_RET_STR(IRP_MJ_QUERY_SECURITY);
318 RT_CASE_RET_STR(IRP_MJ_SET_SECURITY);
319 RT_CASE_RET_STR(IRP_MJ_POWER);
320 RT_CASE_RET_STR(IRP_MJ_SYSTEM_CONTROL);
321 RT_CASE_RET_STR(IRP_MJ_DEVICE_CHANGE);
322 RT_CASE_RET_STR(IRP_MJ_QUERY_QUOTA);
323 RT_CASE_RET_STR(IRP_MJ_SET_QUOTA);
324 case IRP_MJ_PNP:
325 return vbsfNtMinorPnpFunctionName(MinorFunction);
326 default:
327 return "IRP_MJ_UNKNOWN";
328 }
329}
330
331#endif /* DEBUG || LOG_ENABLED */
332
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