VirtualBox

source: vbox/trunk/src/VBox/Additions/WINNT/SharedFolders/driver/vbsf.c@ 63078

Last change on this file since 63078 was 63078, checked in by vboxsync, 8 years ago

GA/NT/SharedFolders: warnings

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 56.3 KB
Line 
1/* $Id: vbsf.c 63078 2016-08-05 23:10:21Z vboxsync $ */
2/** @file
3 * VirtualBox Windows Guest Shared Folders.
4 *
5 * File System Driver initialization and generic routines
6 */
7
8/*
9 * Copyright (C) 2012-2016 Oracle Corporation
10 *
11 * This file is part of VirtualBox Open Source Edition (OSE), as
12 * available from http://www.virtualbox.org. This file is free software;
13 * you can redistribute it and/or modify it under the terms of the GNU
14 * General Public License (GPL) as published by the Free Software
15 * Foundation, in version 2 as it comes in the "COPYING" file of the
16 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
17 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
18 */
19
20#include "vbsf.h"
21
22/*
23 * The current state of the driver.
24 */
25typedef enum _MRX_VBOX_STATE_
26{
27 MRX_VBOX_STARTABLE,
28 MRX_VBOX_START_IN_PROGRESS,
29 MRX_VBOX_STARTED
30} MRX_VBOX_STATE, *PMRX_VBOX_STATE;
31
32static MRX_VBOX_STATE VBoxMRxState = MRX_VBOX_STARTABLE;
33
34/*
35 * The VBoxSF dispatch table.
36 */
37static struct _MINIRDR_DISPATCH VBoxMRxDispatch;
38
39/*
40 * The VBoxSF device object.
41 */
42PRDBSS_DEVICE_OBJECT VBoxMRxDeviceObject;
43
44static NTSTATUS VBoxMRxFsdDispatch(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
45{
46 NTSTATUS Status = STATUS_SUCCESS;
47 PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
48 UCHAR MajorFunctionCode = IrpSp->MajorFunction;
49 ULONG MinorFunctionCode = IrpSp->MinorFunction;
50
51 Log(("VBOXSF: MRxFsdDispatch: major %d, minor %d: %s\n",
52 MajorFunctionCode, MinorFunctionCode, MajorFunctionString(MajorFunctionCode, MinorFunctionCode)));
53
54 if (DeviceObject != (PDEVICE_OBJECT)VBoxMRxDeviceObject)
55 {
56 Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
57 Irp->IoStatus.Information = 0;
58 IoCompleteRequest(Irp, IO_NO_INCREMENT);
59
60 Log(("VBOXSF: MRxFsdDispatch: Invalid device request detected %p %p\n",
61 DeviceObject, (PDEVICE_OBJECT)VBoxMRxDeviceObject));
62
63 return STATUS_INVALID_DEVICE_REQUEST;
64 }
65
66 Status = RxFsdDispatch((PRDBSS_DEVICE_OBJECT)VBoxMRxDeviceObject, Irp);
67
68 Log(("VBOXSF: MRxFsdDispatch: Returned 0x%X\n",
69 Status));
70 return Status;
71}
72
73static void VBoxMRxUnload(IN PDRIVER_OBJECT DriverObject)
74{
75 NTSTATUS Status;
76 UNICODE_STRING UserModeDeviceName;
77
78 Log(("VBOXSF: MRxUnload\n"));
79
80 if (VBoxMRxDeviceObject)
81 {
82 PMRX_VBOX_DEVICE_EXTENSION pDeviceExtension;
83 pDeviceExtension = (PMRX_VBOX_DEVICE_EXTENSION)((PBYTE)VBoxMRxDeviceObject + sizeof(RDBSS_DEVICE_OBJECT));
84 VbglR0SfDisconnect(&pDeviceExtension->hgcmClient);
85 }
86
87 VbglR0SfTerm();
88
89 if (VBoxMRxDeviceObject)
90 {
91 PRX_CONTEXT RxContext;
92 RxContext = RxCreateRxContext(NULL, VBoxMRxDeviceObject, RX_CONTEXT_FLAG_IN_FSP);
93
94 if (RxContext != NULL)
95 {
96 Status = RxStopMinirdr(RxContext, &RxContext->PostRequest);
97
98 if (Status == STATUS_SUCCESS)
99 {
100 MRX_VBOX_STATE State;
101
102 State = (MRX_VBOX_STATE)InterlockedCompareExchange((LONG *)&VBoxMRxState, MRX_VBOX_STARTABLE, MRX_VBOX_STARTED);
103
104 if (State != MRX_VBOX_STARTABLE)
105 Status = STATUS_REDIRECTOR_STARTED;
106 }
107
108 RxDereferenceAndDeleteRxContext(RxContext);
109 }
110 else
111 Status = STATUS_INSUFFICIENT_RESOURCES;
112
113 RxUnregisterMinirdr(VBoxMRxDeviceObject);
114 }
115
116 RtlInitUnicodeString(&UserModeDeviceName, DD_MRX_VBOX_USERMODE_SHADOW_DEV_NAME_U);
117 Status = IoDeleteSymbolicLink(&UserModeDeviceName);
118 if (Status != STATUS_SUCCESS)
119 Log(("VBOXSF: MRxUnload: IoDeleteSymbolicLink Status 0x%08X\n", Status));
120
121 RxUnload(DriverObject);
122
123 Log(("VBOXSF: MRxUnload: VBoxSF.sys driver object %p unloaded\n", DriverObject));
124}
125
126static void vbsfInitMRxDispatch(void)
127{
128 Log(("VBOXSF: vbsfInitMRxDispatch: Called.\n"));
129
130 ZeroAndInitializeNodeType(&VBoxMRxDispatch, RDBSS_NTC_MINIRDR_DISPATCH, sizeof(MINIRDR_DISPATCH));
131
132 VBoxMRxDispatch.MRxFlags = (RDBSS_MANAGE_NET_ROOT_EXTENSION | RDBSS_MANAGE_FOBX_EXTENSION);
133
134 VBoxMRxDispatch.MRxSrvCallSize = 0;
135 VBoxMRxDispatch.MRxNetRootSize = sizeof(MRX_VBOX_NETROOT_EXTENSION);
136 VBoxMRxDispatch.MRxVNetRootSize = 0;
137 VBoxMRxDispatch.MRxFcbSize = 0;
138 VBoxMRxDispatch.MRxSrvOpenSize = 0;
139 VBoxMRxDispatch.MRxFobxSize = sizeof(MRX_VBOX_FOBX);
140
141 VBoxMRxDispatch.MRxStart = VBoxMRxStart;
142 VBoxMRxDispatch.MRxStop = VBoxMRxStop;
143
144 VBoxMRxDispatch.MRxCreate = VBoxMRxCreate;
145 VBoxMRxDispatch.MRxCollapseOpen = VBoxMRxCollapseOpen;
146 VBoxMRxDispatch.MRxShouldTryToCollapseThisOpen = VBoxMRxShouldTryToCollapseThisOpen;
147 VBoxMRxDispatch.MRxFlush = VBoxMRxFlush;
148 VBoxMRxDispatch.MRxTruncate = VBoxMRxTruncate;
149 VBoxMRxDispatch.MRxCleanupFobx = VBoxMRxCleanupFobx;
150 VBoxMRxDispatch.MRxCloseSrvOpen = VBoxMRxCloseSrvOpen;
151 VBoxMRxDispatch.MRxDeallocateForFcb = VBoxMRxDeallocateForFcb;
152 VBoxMRxDispatch.MRxDeallocateForFobx = VBoxMRxDeallocateForFobx;
153 VBoxMRxDispatch.MRxForceClosed = VBoxMRxForceClosed;
154
155 VBoxMRxDispatch.MRxQueryDirectory = VBoxMRxQueryDirectory;
156 VBoxMRxDispatch.MRxQueryFileInfo = VBoxMRxQueryFileInfo;
157 VBoxMRxDispatch.MRxSetFileInfo = VBoxMRxSetFileInfo;
158 VBoxMRxDispatch.MRxSetFileInfoAtCleanup = VBoxMRxSetFileInfoAtCleanup;
159 VBoxMRxDispatch.MRxQueryEaInfo = VBoxMRxQueryEaInfo;
160 VBoxMRxDispatch.MRxSetEaInfo = VBoxMRxSetEaInfo;
161 VBoxMRxDispatch.MRxQuerySdInfo = VBoxMRxQuerySdInfo;
162 VBoxMRxDispatch.MRxSetSdInfo = VBoxMRxSetSdInfo;
163 VBoxMRxDispatch.MRxQueryVolumeInfo = VBoxMRxQueryVolumeInfo;
164
165 VBoxMRxDispatch.MRxComputeNewBufferingState = VBoxMRxComputeNewBufferingState;
166
167 VBoxMRxDispatch.MRxLowIOSubmit[LOWIO_OP_READ] = VBoxMRxRead;
168 VBoxMRxDispatch.MRxLowIOSubmit[LOWIO_OP_WRITE] = VBoxMRxWrite;
169 VBoxMRxDispatch.MRxLowIOSubmit[LOWIO_OP_SHAREDLOCK] = VBoxMRxLocks;
170 VBoxMRxDispatch.MRxLowIOSubmit[LOWIO_OP_EXCLUSIVELOCK] = VBoxMRxLocks;
171 VBoxMRxDispatch.MRxLowIOSubmit[LOWIO_OP_UNLOCK] = VBoxMRxLocks;
172 VBoxMRxDispatch.MRxLowIOSubmit[LOWIO_OP_UNLOCK_MULTIPLE] = VBoxMRxLocks;
173 VBoxMRxDispatch.MRxLowIOSubmit[LOWIO_OP_FSCTL] = VBoxMRxFsCtl;
174 VBoxMRxDispatch.MRxLowIOSubmit[LOWIO_OP_IOCTL] = VBoxMRxIoCtl;
175 VBoxMRxDispatch.MRxLowIOSubmit[LOWIO_OP_NOTIFY_CHANGE_DIRECTORY] = VBoxMRxNotifyChangeDirectory;
176
177 VBoxMRxDispatch.MRxExtendForCache = VBoxMRxExtendStub;
178 VBoxMRxDispatch.MRxExtendForNonCache = VBoxMRxExtendStub;
179 VBoxMRxDispatch.MRxCompleteBufferingStateChangeRequest = VBoxMRxCompleteBufferingStateChangeRequest;
180
181 VBoxMRxDispatch.MRxCreateVNetRoot = VBoxMRxCreateVNetRoot;
182 VBoxMRxDispatch.MRxFinalizeVNetRoot = VBoxMRxFinalizeVNetRoot;
183 VBoxMRxDispatch.MRxFinalizeNetRoot = VBoxMRxFinalizeNetRoot;
184 VBoxMRxDispatch.MRxUpdateNetRootState = VBoxMRxUpdateNetRootState;
185 VBoxMRxDispatch.MRxExtractNetRootName = VBoxMRxExtractNetRootName;
186
187 VBoxMRxDispatch.MRxCreateSrvCall = VBoxMRxCreateSrvCall;
188 VBoxMRxDispatch.MRxSrvCallWinnerNotify = VBoxMRxSrvCallWinnerNotify;
189 VBoxMRxDispatch.MRxFinalizeSrvCall = VBoxMRxFinalizeSrvCall;
190
191 VBoxMRxDispatch.MRxDevFcbXXXControlFile = VBoxMRxDevFcbXXXControlFile;
192
193 Log(("VBOXSF: vbsfInitMRxDispatch: Success.\n"));
194 return;
195}
196
197static BOOL vboxIsPrefixOK (const WCHAR *FilePathName, ULONG PathNameLength)
198{
199 BOOL PrefixOK;
200
201 /* The FilePathName here looks like: \vboxsrv\... */
202 if (PathNameLength >= 8 * sizeof (WCHAR)) /* Number of bytes in '\vboxsrv' unicode string. */
203 {
204 PrefixOK = (FilePathName[0] == L'\\');
205 PrefixOK &= (FilePathName[1] == L'V') || (FilePathName[1] == L'v');
206 PrefixOK &= (FilePathName[2] == L'B') || (FilePathName[2] == L'b');
207 PrefixOK &= (FilePathName[3] == L'O') || (FilePathName[3] == L'o');
208 PrefixOK &= (FilePathName[4] == L'X') || (FilePathName[4] == L'x');
209 PrefixOK &= (FilePathName[5] == L'S') || (FilePathName[5] == L's');
210 /* Both vboxsvr & vboxsrv are now accepted */
211 if ((FilePathName[6] == L'V') || (FilePathName[6] == L'v'))
212 {
213 PrefixOK &= (FilePathName[6] == L'V') || (FilePathName[6] == L'v');
214 PrefixOK &= (FilePathName[7] == L'R') || (FilePathName[7] == L'r');
215 }
216 else
217 {
218 PrefixOK &= (FilePathName[6] == L'R') || (FilePathName[6] == L'r');
219 PrefixOK &= (FilePathName[7] == L'V') || (FilePathName[7] == L'v');
220 }
221 if (PathNameLength > 8 * sizeof (WCHAR))
222 {
223 /* There is something after '\vboxsrv'. */
224 PrefixOK &= (FilePathName[8] == L'\\') || (FilePathName[8] == 0);
225 }
226 }
227 else
228 PrefixOK = FALSE;
229
230 return PrefixOK;
231}
232
233static NTSTATUS VBoxMRXDeviceControl(PDEVICE_OBJECT pDevObj, PIRP pIrp)
234{
235 NTSTATUS Status = STATUS_SUCCESS;
236
237 QUERY_PATH_REQUEST *pReq = NULL;
238 QUERY_PATH_REQUEST_EX *pReqEx = NULL;
239 QUERY_PATH_RESPONSE *pResp = NULL;
240
241 BOOL PrefixOK = FALSE;
242
243 PIO_STACK_LOCATION pStack = IoGetCurrentIrpStackLocation(pIrp);
244
245 /* Make a local copy, it will be needed after the Irp completion. */
246 ULONG IoControlCode = pStack->Parameters.DeviceIoControl.IoControlCode;
247
248 PMRX_VBOX_DEVICE_EXTENSION pDeviceExtension = (PMRX_VBOX_DEVICE_EXTENSION)((PBYTE)pDevObj + sizeof(RDBSS_DEVICE_OBJECT));
249
250 Log(("VBOXSF: MRXDeviceControl: pDevObj %p, pDeviceExtension %p, code %x\n",
251 pDevObj, pDevObj->DeviceExtension, IoControlCode));
252
253 switch (IoControlCode)
254 {
255 case IOCTL_REDIR_QUERY_PATH_EX: /* Vista */
256 case IOCTL_REDIR_QUERY_PATH: /* XP and earlier */
257 {
258 /* This IOCTL is intercepted for 2 reasons:
259 * 1) Claim the vboxsvr and vboxsrv prefixes. All name-based operations for them
260 * will be routed to the VBox provider automatically without any prefix resolution
261 * since the prefix is already in the prefix cache.
262 * 2) Reject other prefixes immediately to speed up the UNC path resolution a bit,
263 * because RDBSS will not be involved then.
264 */
265
266 const WCHAR *FilePathName = NULL;
267 ULONG PathNameLength = 0;
268
269 if (pIrp->RequestorMode != KernelMode)
270 {
271 /* MSDN: Network redirectors should only honor kernel-mode senders of this IOCTL, by verifying
272 * that RequestorMode member of the IRP structure is KernelMode.
273 */
274 Log(("VBOXSF: MRxDeviceControl: IOCTL_REDIR_QUERY_PATH(_EX): not kernel mode!!!\n",
275 pStack->Parameters.DeviceIoControl.InputBufferLength));
276 /* Continue to RDBSS. */
277 break;
278 }
279
280 if (IoControlCode == IOCTL_REDIR_QUERY_PATH)
281 {
282 Log(("VBOXSF: MRxDeviceControl: IOCTL_REDIR_QUERY_PATH: Called (pid %x).\n", IoGetCurrentProcess()));
283
284 if (pStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(QUERY_PATH_REQUEST))
285 {
286 Log(("VBOXSF: MRxDeviceControl: IOCTL_REDIR_QUERY_PATH: short input buffer %d.\n",
287 pStack->Parameters.DeviceIoControl.InputBufferLength));
288 /* Continue to RDBSS. */
289 break;
290 }
291
292 pReq = (QUERY_PATH_REQUEST *)pStack->Parameters.DeviceIoControl.Type3InputBuffer;
293
294 Log(("VBOXSF: MRxDeviceControl: PathNameLength = %d.\n", pReq->PathNameLength));
295 Log(("VBOXSF: MRxDeviceControl: SecurityContext = %p.\n", pReq->SecurityContext));
296 Log(("VBOXSF: MRxDeviceControl: FilePathName = %.*ls.\n", pReq->PathNameLength / sizeof (WCHAR), pReq->FilePathName));
297
298 FilePathName = pReq->FilePathName;
299 PathNameLength = pReq->PathNameLength;
300 }
301 else
302 {
303 Log(("VBOXSF: MRxDeviceControl: IOCTL_REDIR_QUERY_PATH_EX: Called.\n"));
304
305 if (pStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(QUERY_PATH_REQUEST_EX))
306 {
307 Log(("VBOXSF: MRxDeviceControl: IOCTL_REDIR_QUERY_PATH_EX: short input buffer %d.\n",
308 pStack->Parameters.DeviceIoControl.InputBufferLength));
309 /* Continue to RDBSS. */
310 break;
311 }
312
313 pReqEx = (QUERY_PATH_REQUEST_EX *)pStack->Parameters.DeviceIoControl.Type3InputBuffer;
314
315 Log(("VBOXSF: MRxDeviceControl: pSecurityContext = %p.\n", pReqEx->pSecurityContext));
316 Log(("VBOXSF: MRxDeviceControl: EaLength = %d.\n", pReqEx->EaLength));
317 Log(("VBOXSF: MRxDeviceControl: pEaBuffer = %p.\n", pReqEx->pEaBuffer));
318 Log(("VBOXSF: MRxDeviceControl: PathNameLength = %d.\n", pReqEx->PathName.Length));
319 Log(("VBOXSF: MRxDeviceControl: FilePathName = %.*ls.\n", pReqEx->PathName.Length / sizeof (WCHAR), pReqEx->PathName.Buffer));
320
321 FilePathName = pReqEx->PathName.Buffer;
322 PathNameLength = pReqEx->PathName.Length;
323 }
324
325 pResp = (QUERY_PATH_RESPONSE *)pIrp->UserBuffer;
326
327 PrefixOK = vboxIsPrefixOK (FilePathName, PathNameLength);
328 Log(("VBOXSF: MRxDeviceControl PrefixOK %d\n", PrefixOK));
329
330 if (!PrefixOK)
331 {
332 /* Immediately fail the IOCTL with STATUS_BAD_NETWORK_NAME as recommended by MSDN.
333 * No need to involve RDBSS.
334 */
335 Status = STATUS_BAD_NETWORK_NAME;
336
337 pIrp->IoStatus.Status = Status;
338 pIrp->IoStatus.Information = 0;
339
340 IoCompleteRequest(pIrp, IO_NO_INCREMENT);
341
342 Log(("VBOXSF: MRxDeviceControl: returned STATUS_BAD_NETWORK_NAME\n"));
343 return Status;
344 }
345
346 Log(("VBOXSF: MRxDeviceControl pResp %p verifying the path.\n", pResp));
347 if (pResp)
348 {
349 /* Always claim entire \vboxsrv prefix. The LengthAccepted initially is equal to entire path.
350 * Here it is assigned to the length of \vboxsrv prefix.
351 */
352 pResp->LengthAccepted = 8 * sizeof (WCHAR);
353
354 Status = STATUS_SUCCESS;
355
356 pIrp->IoStatus.Status = Status;
357 pIrp->IoStatus.Information = 0;
358
359 IoCompleteRequest(pIrp, IO_NO_INCREMENT);
360
361 Log(("VBOXSF: MRxDeviceControl: claiming the path.\n"));
362 return Status;
363 }
364
365 /* No pResp pointer, should not happen. Just a precaution. */
366 Status = STATUS_INVALID_PARAMETER;
367
368 pIrp->IoStatus.Status = Status;
369 pIrp->IoStatus.Information = 0;
370
371 IoCompleteRequest(pIrp, IO_NO_INCREMENT);
372
373 Log(("VBOXSF: MRxDeviceControl: returned STATUS_INVALID_PARAMETER\n"));
374 return Status;
375 }
376
377 default:
378 break;
379 }
380
381 /* Pass the IOCTL to RDBSS. */
382 if (pDeviceExtension && pDeviceExtension->pfnRDBSSDeviceControl)
383 {
384 Log(("VBOXSF: MRxDeviceControl calling RDBSS %p\n", pDeviceExtension->pfnRDBSSDeviceControl));
385 Status = pDeviceExtension->pfnRDBSSDeviceControl (pDevObj, pIrp);
386 Log(("VBOXSF: MRxDeviceControl RDBSS status 0x%08X\n", Status));
387 }
388 else
389 {
390 /* No RDBSS, should not happen. Just a precaution. */
391 Status = STATUS_NOT_IMPLEMENTED;
392
393 pIrp->IoStatus.Status = Status;
394 pIrp->IoStatus.Information = 0;
395
396 IoCompleteRequest(pIrp, IO_NO_INCREMENT);
397
398 Log(("VBOXSF: MRxDeviceControl: returned STATUS_NOT_IMPLEMENTED\n"));
399 }
400
401 return Status;
402}
403
404NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject,
405 IN PUNICODE_STRING RegistryPath)
406{
407 NTSTATUS Status;
408 UNICODE_STRING VBoxMRxName;
409 UNICODE_STRING UserModeDeviceName;
410 PMRX_VBOX_DEVICE_EXTENSION pDeviceExtension = NULL;
411 ULONG i;
412 int vboxRC;
413 VBGLSFCLIENT hgcmClient;
414
415 Log(("VBOXSF: DriverEntry: Driver object %p\n", DriverObject));
416
417 if (!DriverObject)
418 {
419 Log(("VBOXSF: DriverEntry: driver object is NULL.\n"));
420 return STATUS_UNSUCCESSFUL;
421 }
422
423 /* Initialize VBox subsystem. */
424 vboxRC = VbglR0SfInit();
425 if (RT_FAILURE(vboxRC))
426 {
427 Log(("VBOXSF: DriverEntry: ERROR while initializing VBox subsystem (%Rrc)!\n", vboxRC));
428 return STATUS_UNSUCCESSFUL;
429 }
430
431 /* Connect the HGCM client */
432 RT_ZERO(hgcmClient);
433 vboxRC = VbglR0SfConnect(&hgcmClient);
434 if (RT_FAILURE(vboxRC))
435 {
436 Log(("VBOXSF: DriverEntry: ERROR while connecting to host (%Rrc)!\n",
437 vboxRC));
438 VbglR0SfTerm();
439 return STATUS_UNSUCCESSFUL;
440 }
441
442 /* Init the driver object. */
443 DriverObject->DriverUnload = VBoxMRxUnload;
444 for (i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++)
445 {
446 DriverObject->MajorFunction[i] = (PDRIVER_DISPATCH)VBoxMRxFsdDispatch;
447 }
448
449 /* Forward to RDBSS. */
450 Status = RxDriverEntry(DriverObject, RegistryPath);
451 if (Status != STATUS_SUCCESS)
452 {
453 Log(("VBOXSF: DriverEntry: RxDriverEntry failed: 0x%08X\n", Status));
454 goto failure;
455 }
456
457 __try
458 {
459 Log(("VBOXSF: DriverEntry: RxRegisterMinirdr: calling VBoxMRxDeviceObject %p\n",
460 VBoxMRxDeviceObject));
461
462 RtlInitUnicodeString(&VBoxMRxName, DD_MRX_VBOX_FS_DEVICE_NAME_U);
463
464 /* Don use RX_REGISTERMINI_FLAG_DONT_PROVIDE_UNCS or else
465 * UNC mappings don't work (including Windows explorer browsing).
466 */
467 Status = RxRegisterMinirdr(&VBoxMRxDeviceObject,
468 DriverObject,
469 &VBoxMRxDispatch,
470 RX_REGISTERMINI_FLAG_DONT_PROVIDE_MAILSLOTS,
471 &VBoxMRxName,
472 sizeof(MRX_VBOX_DEVICE_EXTENSION),
473 FILE_DEVICE_NETWORK_FILE_SYSTEM,
474 FILE_REMOTE_DEVICE);
475
476 Log(("VBOXSF: DriverEntry: RxRegisterMinirdr: returned 0x%08X VBoxMRxDeviceObject %p\n",
477 Status, VBoxMRxDeviceObject));
478
479 if (Status!=STATUS_SUCCESS)
480 {
481 Log(("VBOXSF: DriverEntry: RxRegisterMinirdr failed: 0x%08X\n", Status ));
482 try_return((void)Status);
483 }
484
485 /* Init the device extension.
486 * NOTE: the device extension actually points to fields
487 * in the RDBSS_DEVICE_OBJECT. Our space is past the end
488 * of this struct!!
489 */
490 pDeviceExtension = (PMRX_VBOX_DEVICE_EXTENSION)((PBYTE)VBoxMRxDeviceObject + sizeof(RDBSS_DEVICE_OBJECT));
491
492 pDeviceExtension->pDeviceObject = VBoxMRxDeviceObject;
493
494 for (i = 0; i < RT_ELEMENTS(pDeviceExtension->cLocalConnections); i++)
495 {
496 pDeviceExtension->cLocalConnections[i] = FALSE;
497 }
498
499 /* Mutex for synchronizining our connection list */
500 ExInitializeFastMutex(&pDeviceExtension->mtxLocalCon);
501
502 /* The device object has been created. Need to setup a symbolic
503 * link so that the device may be accessed from a Win32 user mode
504 * application.
505 */
506
507 RtlInitUnicodeString(&UserModeDeviceName, DD_MRX_VBOX_USERMODE_SHADOW_DEV_NAME_U);
508 Log(("VBOXSF: DriverEntry: Calling IoCreateSymbolicLink\n"));
509 Status = IoCreateSymbolicLink(&UserModeDeviceName, &VBoxMRxName);
510 if (Status != STATUS_SUCCESS)
511 {
512 Log(("VBOXSF: DriverEntry: IoCreateSymbolicLink: 0x%08X\n",
513 Status));
514 try_return((void)Status);
515 }
516 Log(("VBOXSF: DriverEntry: Symbolic link created.\n"));
517
518 /*
519 * Build the dispatch tables for the minirdr
520 */
521 vbsfInitMRxDispatch();
522
523 try_exit:
524 ;
525 }
526 __finally
527 {
528 ;
529 }
530
531 if (Status != STATUS_SUCCESS)
532 {
533 Log(("VBOXSF: DriverEntry: VBoxSF.sys failed to start with Status = 0x%08X\n",
534 Status));
535 goto failure;
536 }
537
538 AssertPtr(pDeviceExtension);
539 pDeviceExtension->hgcmClient = hgcmClient;
540
541 /* The redirector driver must intercept the IOCTL to avoid VBOXSVR name resolution
542 * by other redirectors. These additional name resolutions cause long delays.
543 */
544 Log(("VBOXSF: DriverEntry: VBoxMRxDeviceObject = %p, rdbss %p, devext %p\n",
545 VBoxMRxDeviceObject, DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL], pDeviceExtension));
546 pDeviceExtension->pfnRDBSSDeviceControl = DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL];
547 DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = VBoxMRXDeviceControl;
548
549 /* @todo start the redirector here RxStartMiniRdr. */
550
551 Log(("VBOXSF: DriverEntry: Init successful!\n"));
552 return STATUS_SUCCESS;
553
554failure:
555
556 Log(("VBOXSF: DriverEntry: Failure! Status = 0x%08X\n", Status));
557
558 VbglR0SfDisconnect(&hgcmClient);
559 VbglR0SfTerm();
560
561 if (VBoxMRxDeviceObject)
562 {
563 RxUnregisterMinirdr(VBoxMRxDeviceObject);
564 VBoxMRxDeviceObject = NULL;
565 }
566
567 return Status;
568}
569
570NTSTATUS VBoxMRxStart(PRX_CONTEXT RxContext, IN OUT PRDBSS_DEVICE_OBJECT RxDeviceObject)
571{
572 NTSTATUS Status;
573 MRX_VBOX_STATE CurrentState;
574 RT_NOREF(RxContext, RxDeviceObject);
575
576 Log(("VBOXSF: MRxStart\n"));
577
578 CurrentState = (MRX_VBOX_STATE)InterlockedCompareExchange((PLONG)&VBoxMRxState, MRX_VBOX_STARTED, MRX_VBOX_START_IN_PROGRESS);
579
580 if (CurrentState == MRX_VBOX_START_IN_PROGRESS)
581 {
582 Log(("VBOXSF: MRxStart: Start in progress -> started\n"));
583 Status = STATUS_SUCCESS;
584 }
585 else if (VBoxMRxState == MRX_VBOX_STARTED)
586 {
587 Log(("VBOXSF: MRxStart: Already started\n"));
588 Status = STATUS_REDIRECTOR_STARTED;
589 }
590 else
591 {
592 Log(("VBOXSF: MRxStart: Bad state! VBoxMRxState = %d\n", VBoxMRxState));
593 Status = STATUS_UNSUCCESSFUL;
594 }
595
596 return Status;
597}
598
599NTSTATUS VBoxMRxStop(PRX_CONTEXT RxContext, IN OUT PRDBSS_DEVICE_OBJECT RxDeviceObject)
600{
601 RT_NOREF(RxContext, RxDeviceObject);
602 Log(("VBOXSF: MRxStop\n"));
603 return STATUS_SUCCESS;
604}
605
606NTSTATUS VBoxMRxIoCtl(IN OUT PRX_CONTEXT RxContext)
607{
608 Log(("VBOXSF: MRxIoCtl: IoControlCode = 0x%08X\n",
609 RxContext->LowIoContext.ParamsFor.FsCtl.FsControlCode));
610 return STATUS_INVALID_DEVICE_REQUEST;
611}
612
613NTSYSAPI NTSTATUS NTAPI ZwSetSecurityObject(IN HANDLE Handle,
614 IN SECURITY_INFORMATION SecurityInformation,
615 IN PSECURITY_DESCRIPTOR SecurityDescriptor);
616
617NTSTATUS VBoxMRxDevFcbXXXControlFile(IN OUT PRX_CONTEXT RxContext)
618{
619 NTSTATUS Status = STATUS_SUCCESS;
620 RxCaptureFobx;
621 PMRX_VBOX_DEVICE_EXTENSION pDeviceExtension = VBoxMRxGetDeviceExtension(RxContext);
622 PLOWIO_CONTEXT LowIoContext = &RxContext->LowIoContext;
623
624 Log(("VBOXSF: MRxDevFcbXXXControlFile: MajorFunction = 0x%02X\n",
625 RxContext->MajorFunction));
626
627 switch (RxContext->MajorFunction)
628 {
629 case IRP_MJ_FILE_SYSTEM_CONTROL:
630 {
631 Log(("VBOXSF: MRxDevFcbXXXControlFile: IRP_MN_USER_FS_REQUEST: 0x%08X\n",
632 LowIoContext->ParamsFor.FsCtl.MinorFunction));
633 Status = STATUS_INVALID_DEVICE_REQUEST;
634 break;
635 }
636
637 case IRP_MJ_DEVICE_CONTROL:
638 {
639 Log(("VBOXSF: MRxDevFcbXXXControlFile: IRP_MJ_DEVICE_CONTROL: InputBuffer %p/%d, OutputBuffer %p/%d\n",
640 LowIoContext->ParamsFor.IoCtl.pInputBuffer,
641 LowIoContext->ParamsFor.IoCtl.InputBufferLength,
642 LowIoContext->ParamsFor.IoCtl.pOutputBuffer,
643 LowIoContext->ParamsFor.IoCtl.OutputBufferLength));
644
645 switch (LowIoContext->ParamsFor.IoCtl.IoControlCode)
646 {
647 case IOCTL_MRX_VBOX_ADDCONN:
648 {
649 Log(("VBOXSF: MRxDevFcbXXXControlFile: IOCTL_MRX_VBOX_ADDCONN\n"));
650 Status = vbsfCreateConnection(RxContext, &RxContext->PostRequest);
651 break;
652 }
653
654 case IOCTL_MRX_VBOX_DELCONN:
655 {
656 Log(("VBOXSF: MRxDevFcbXXXControlFile: IOCTL_MRX_VBOX_DELCONN\n"));
657 Status = vbsfDeleteConnection(RxContext, &RxContext->PostRequest);
658 break;
659 }
660
661 case IOCTL_MRX_VBOX_GETLIST:
662 {
663 ULONG cbOut = LowIoContext->ParamsFor.IoCtl.OutputBufferLength;
664 uint8_t *pu8Out = (uint8_t *)LowIoContext->ParamsFor.IoCtl.pOutputBuffer;
665
666 BOOLEAN fLocked = FALSE;
667
668 Log(("VBOXSF: MRxDevFcbXXXControlFile: IOCTL_MRX_VBOX_GETLIST\n"));
669
670 RxContext->InformationToReturn = 0;
671
672 if ( !pDeviceExtension
673 || cbOut < _MRX_MAX_DRIVE_LETTERS)
674 {
675 Status = STATUS_INVALID_PARAMETER;
676 break;
677 }
678
679 Log(("VBOXSF: MRxDevFcbXXXControlFile: IOCTL_MRX_VBOX_GETLIST: Copying local connections\n"));
680
681 fLocked = ExTryToAcquireFastMutex(&pDeviceExtension->mtxLocalCon);
682
683 __try
684 {
685 RtlCopyMemory(pu8Out, pDeviceExtension->cLocalConnections, _MRX_MAX_DRIVE_LETTERS);
686 RxContext->InformationToReturn = _MRX_MAX_DRIVE_LETTERS;
687 }
688 __except(EXCEPTION_EXECUTE_HANDLER)
689 {
690 Status = STATUS_INVALID_PARAMETER;
691 }
692
693 if (fLocked)
694 {
695 ExReleaseFastMutex(&pDeviceExtension->mtxLocalCon);
696 fLocked = FALSE;
697 }
698
699 break;
700 }
701
702 /*
703 * Returns the root IDs of shared folder mappings.
704 */
705 case IOCTL_MRX_VBOX_GETGLOBALLIST:
706 {
707 ULONG cbOut = LowIoContext->ParamsFor.IoCtl.OutputBufferLength;
708 uint8_t *pu8Out = (uint8_t *)LowIoContext->ParamsFor.IoCtl.pOutputBuffer;
709
710 int vboxRC;
711 SHFLMAPPING mappings[_MRX_MAX_DRIVE_LETTERS];
712 uint32_t cMappings = RT_ELEMENTS(mappings);
713
714 Log(("VBOXSF: MRxDevFcbXXXControlFile: IOCTL_MRX_VBOX_GETGLOBALLIST\n"));
715
716 RxContext->InformationToReturn = 0;
717
718 if ( !pDeviceExtension
719 || cbOut < _MRX_MAX_DRIVE_LETTERS)
720 {
721 Status = STATUS_INVALID_PARAMETER;
722 break;
723 }
724
725 vboxRC = VbglR0SfQueryMappings(&pDeviceExtension->hgcmClient, mappings, &cMappings);
726 if (vboxRC == VINF_SUCCESS)
727 {
728 __try
729 {
730 uint32_t i;
731
732 RtlZeroMemory(pu8Out, _MRX_MAX_DRIVE_LETTERS);
733
734 for (i = 0; i < RT_MIN(cMappings, cbOut); i++)
735 {
736 pu8Out[i] = mappings[i].root;
737 pu8Out[i] |= 0x80; /* mark active */ /** @todo fix properly */
738 }
739
740 RxContext->InformationToReturn = _MRX_MAX_DRIVE_LETTERS;
741 }
742 __except(EXCEPTION_EXECUTE_HANDLER)
743 {
744 Status = STATUS_INVALID_PARAMETER;
745 }
746 }
747 else
748 {
749 Status = VBoxErrorToNTStatus(vboxRC);
750 Log(("VBOXSF: MRxDevFcbXXXControlFile: IOCTL_MRX_VBOX_GETGLOBALLIST failed: 0x%08X\n",
751 Status));
752 }
753
754 break;
755 }
756
757 /*
758 * Translates a local connection name (e.g. drive "S:") to the
759 * corresponding remote name (e.g. \\vboxsrv\share).
760 */
761 case IOCTL_MRX_VBOX_GETCONN:
762 {
763 ULONG cbConnectName = LowIoContext->ParamsFor.IoCtl.InputBufferLength;
764 PWCHAR pwcConnectName = (PWCHAR)LowIoContext->ParamsFor.IoCtl.pInputBuffer;
765 ULONG cbRemoteName = LowIoContext->ParamsFor.IoCtl.OutputBufferLength;
766 PWCHAR pwcRemoteName = (PWCHAR)LowIoContext->ParamsFor.IoCtl.pOutputBuffer;
767
768 BOOLEAN fMutexAcquired = FALSE;
769
770 Log(("VBOXSF: MRxDevFcbXXXControlFile: IOCTL_MRX_VBOX_GETCONN\n"));
771
772 RxContext->InformationToReturn = 0;
773
774 if ( !pDeviceExtension
775 || cbConnectName < sizeof(WCHAR))
776 {
777 Status = STATUS_INVALID_PARAMETER;
778 break;
779 }
780
781 Log(("VBOXSF: MRxDevFcbXXXControlFile: IOCTL_MRX_VBOX_GETCONN: Looking up connection name and connections\n"));
782
783 __try
784 {
785 uint32_t idx = *pwcConnectName - L'A';
786
787 Log(("VBOXSF: MRxDevFcbXXXControlFile: IOCTL_MRX_VBOX_GETCONN: ConnectName = %.*ls, Len = %d, Index = %d\n",
788 cbConnectName / sizeof(WCHAR), pwcConnectName, cbConnectName, idx));
789
790 if (idx < RTL_NUMBER_OF(pDeviceExtension->wszLocalConnectionName))
791 {
792 ExAcquireFastMutex(&pDeviceExtension->mtxLocalCon);
793 fMutexAcquired = TRUE;
794
795 if (pDeviceExtension->wszLocalConnectionName[idx])
796 {
797 ULONG cbLocalConnectionName = pDeviceExtension->wszLocalConnectionName[idx]->Length;
798
799 Log(("VBOXSF: MRxDevFcbXXXControlFile: IOCTL_MRX_VBOX_GETCONN: LocalConnectionName = %.*ls\n",
800 cbLocalConnectionName / sizeof(WCHAR), pDeviceExtension->wszLocalConnectionName[idx]->Buffer));
801
802 if ((pDeviceExtension->cLocalConnections[idx]) && (cbLocalConnectionName <= cbRemoteName))
803 {
804 RtlZeroMemory(pwcRemoteName, cbRemoteName);
805 RtlCopyMemory(pwcRemoteName,
806 pDeviceExtension->wszLocalConnectionName[idx]->Buffer,
807 cbLocalConnectionName);
808
809 Log(("VBOXSF: MRxDevFcbXXXControlFile: IOCTL_MRX_VBOX_GETCONN: Remote name = %.*ls, Len = %d\n",
810 cbLocalConnectionName / sizeof(WCHAR), pwcRemoteName, cbLocalConnectionName));
811 }
812 else
813 {
814 Status = STATUS_BUFFER_TOO_SMALL;
815 }
816
817 RxContext->InformationToReturn = cbLocalConnectionName;
818 }
819 else
820 {
821 Log(("VBOXSF: MRxDevFcbXXXControlFile: IOCTL_MRX_VBOX_GETCONN: LocalConnectionName is NULL!\n"));
822 Status = STATUS_BAD_NETWORK_NAME;
823 }
824 }
825 else
826 {
827 Log(("VBOXSF: MRxDevFcbXXXControlFile: IOCTL_MRX_VBOX_GETCONN: Index is invalid!\n"));
828 Status = STATUS_INVALID_PARAMETER;
829 }
830 }
831 __except(EXCEPTION_EXECUTE_HANDLER)
832 {
833 Status = STATUS_INVALID_PARAMETER;
834 }
835
836 if (fMutexAcquired)
837 {
838 ExReleaseFastMutex(&pDeviceExtension->mtxLocalCon);
839 fMutexAcquired = FALSE;
840 }
841
842 break;
843 }
844
845 case IOCTL_MRX_VBOX_GETGLOBALCONN:
846 {
847 ULONG cbConnectId = LowIoContext->ParamsFor.IoCtl.InputBufferLength;
848 uint8_t *pu8ConnectId = (uint8_t *)LowIoContext->ParamsFor.IoCtl.pInputBuffer;
849 ULONG cbRemoteName = LowIoContext->ParamsFor.IoCtl.OutputBufferLength;
850 PWCHAR pwcRemoteName = (PWCHAR)LowIoContext->ParamsFor.IoCtl.pOutputBuffer;
851
852 int vboxRC;
853 PSHFLSTRING pString;
854
855 Log(("VBOXSF: MRxDevFcbXXXControlFile: IOCTL_MRX_VBOX_GETGLOBALCONN\n"));
856
857 RxContext->InformationToReturn = 0;
858
859 if ( !pDeviceExtension
860 || cbConnectId < sizeof(uint8_t))
861 {
862 Status = STATUS_INVALID_PARAMETER;
863 break;
864 }
865
866 /* Allocate empty string where the host can store cbRemoteName bytes. */
867 Status = vbsfShflStringFromUnicodeAlloc(&pString, NULL, (uint16_t)cbRemoteName);
868 if (Status != STATUS_SUCCESS)
869 break;
870
871 __try
872 {
873 Log(("VBOXSF: MRxDevFcbXXXControlFile: IOCTL_MRX_VBOX_GETGLOBALCONN: Connection ID = %d\n",
874 *pu8ConnectId));
875
876 vboxRC = VbglR0SfQueryMapName(&pDeviceExtension->hgcmClient,
877 (*pu8ConnectId) & ~0x80 /** @todo fix properly */,
878 pString, ShflStringSizeOfBuffer(pString));
879 if ( vboxRC == VINF_SUCCESS
880 && pString->u16Length < cbRemoteName)
881 {
882 RtlCopyMemory(pwcRemoteName, pString->String.ucs2, pString->u16Length);
883 Log(("VBOXSF: MRxDevFcbXXXControlFile: IOCTL_MRX_VBOX_GETGLOBALCONN: Returned name = %.*ls, Len = %d\n",
884 pString->u16Length / sizeof(WCHAR), pwcRemoteName, pString->u16Length));
885 RxContext->InformationToReturn = pString->u16Length;
886 }
887 else
888 {
889 Status = STATUS_BAD_NETWORK_NAME;
890 }
891 }
892 __except(EXCEPTION_EXECUTE_HANDLER)
893 {
894 Status = STATUS_INVALID_PARAMETER;
895 }
896
897 vbsfFreeNonPagedMem(pString);
898
899 break;
900 }
901
902 case IOCTL_MRX_VBOX_START:
903 {
904 Log(("VBOXSF: MRxDevFcbXXXControlFile: IOCTL_MRX_VBOX_START: capFobx %p\n",
905 capFobx));
906
907 Log(("VBOXSF: MRxDevFcbXXXControlFile: IOCTL_MRX_VBOX_START: process: current 0x%X, RDBSS 0x%X\n",
908 IoGetCurrentProcess(), RxGetRDBSSProcess()));
909
910 switch (VBoxMRxState)
911 {
912 case MRX_VBOX_STARTABLE:
913
914 Log(("VBOXSF: MRxDevFcbXXXControlFile: MRX_VBOX_STARTABLE\n"));
915
916 if (capFobx)
917 {
918 Status = STATUS_INVALID_DEVICE_REQUEST;
919 break;;
920 }
921
922 InterlockedCompareExchange((PLONG)&VBoxMRxState, MRX_VBOX_START_IN_PROGRESS, MRX_VBOX_STARTABLE);
923
924 case MRX_VBOX_START_IN_PROGRESS:
925 Status = RxStartMinirdr(RxContext, &RxContext->PostRequest);
926
927 Log(("VBOXSF: MRxDevFcbXXXControlFile: MRX_VBOX_START_IN_PROGRESS RxStartMiniRdr Status 0x%08X, post %d\n",
928 Status, RxContext->PostRequest));
929
930 if (Status == STATUS_REDIRECTOR_STARTED)
931 {
932 Status = STATUS_SUCCESS;
933 break;
934 }
935
936 if ( Status == STATUS_PENDING
937 && RxContext->PostRequest == TRUE)
938 {
939 /* Will be restarted in RDBSS process. */
940 Status = STATUS_MORE_PROCESSING_REQUIRED;
941 break;
942 }
943
944 /* Allow restricted users to use shared folders; works only in XP and Vista. (@@todo hack) */
945 if (Status == STATUS_SUCCESS)
946 {
947 SECURITY_DESCRIPTOR SecurityDescriptor;
948 OBJECT_ATTRIBUTES InitializedAttributes;
949 HANDLE hDevice;
950 IO_STATUS_BLOCK IoStatusBlock;
951 UNICODE_STRING UserModeDeviceName;
952
953 RtlInitUnicodeString(&UserModeDeviceName, DD_MRX_VBOX_USERMODE_SHADOW_DEV_NAME_U);
954
955 /* Create empty security descriptor */
956 RtlZeroMemory (&SecurityDescriptor, sizeof (SecurityDescriptor));
957 Status = RtlCreateSecurityDescriptor(&SecurityDescriptor, SECURITY_DESCRIPTOR_REVISION);
958 if (Status != STATUS_SUCCESS)
959 {
960 Log(("VBOXSF: MRxDevFcbXXXControlFile: IOCTL_MRX_VBOX_START: MRX_VBOX_START_IN_PROGRESS: RtlCreateSecurityDescriptor failed with 0x%08X!\n",
961 Status));
962 return Status;
963 }
964
965 RtlZeroMemory (&InitializedAttributes, sizeof (InitializedAttributes));
966 InitializeObjectAttributes(&InitializedAttributes, &UserModeDeviceName, OBJ_KERNEL_HANDLE, 0, 0);
967
968 /* Open our symbolic link device name */
969 Status = ZwOpenFile(&hDevice, WRITE_DAC, &InitializedAttributes, &IoStatusBlock, 0, 0);
970 if (Status != STATUS_SUCCESS)
971 {
972 Log(("VBOXSF: MRxDevFcbXXXControlFile: IOCTL_MRX_VBOX_START: MRX_VBOX_START_IN_PROGRESS: ZwOpenFile %ls failed with 0x%08X!\n",
973 DD_MRX_VBOX_USERMODE_SHADOW_DEV_NAME_U, Status));
974 return Status;
975 }
976
977 /* Override the discretionary access control list (DACL) settings */
978 Status = ZwSetSecurityObject(hDevice, DACL_SECURITY_INFORMATION, &SecurityDescriptor);
979 if (Status != STATUS_SUCCESS)
980 {
981 Log(("VBOXSF: MRxDevFcbXXXControlFile: IOCTL_MRX_VBOX_START: MRX_VBOX_START_IN_PROGRESS: ZwSetSecurityObject failed with 0x%08X!\n",
982 Status));
983 return Status;
984 }
985
986 Status = ZwClose(hDevice);
987 if (Status != STATUS_SUCCESS)
988 {
989 Log(("VBOXSF: MRxDevFcbXXXControlFile: IOCTL_MRX_VBOX_START: MRX_VBOX_START_IN_PROGRESS: ZwClose failed with 0x%08X\n",
990 Status));
991 return Status;
992 }
993 }
994 break;
995
996 case MRX_VBOX_STARTED:
997 Log(("VBOXSF: MRxDevFcbXXXControlFile: IOCTL_MRX_VBOX_START: MRX_VBOX_STARTED: Already started\n"));
998 Status = STATUS_SUCCESS;
999 break;
1000
1001 default:
1002 Log(("VBOXSF: MRxDevFcbXXXControlFile: IOCTL_MRX_VBOX_START: Invalid state (%d)!\n",
1003 VBoxMRxState));
1004 Status = STATUS_INVALID_PARAMETER;
1005 break;
1006 }
1007
1008 Log(("VBOXSF: MRxDevFcbXXXControlFile: IOCTL_MRX_VBOX_START: Returned 0x%08X\n",
1009 Status));
1010 break;
1011 }
1012
1013 case IOCTL_MRX_VBOX_STOP:
1014 {
1015 MRX_VBOX_STATE CurrentState;
1016
1017 Log(("VBOXSF: MRxDevFcbXXXControlFile: IOCTL_MRX_VBOX_STOP: capFobx %p\n",
1018 capFobx));
1019
1020 if (capFobx)
1021 {
1022 Status = STATUS_INVALID_DEVICE_REQUEST;
1023 break;
1024 }
1025
1026 if (RxContext->RxDeviceObject->NumberOfActiveFcbs > 0)
1027 {
1028 Log(("VBOXSF: MRxDevFcbXXXControlFile: IOCTL_MRX_VBOX_STOP: Open handles = %d\n",
1029 RxContext->RxDeviceObject->NumberOfActiveFcbs));
1030 Status = STATUS_REDIRECTOR_HAS_OPEN_HANDLES;
1031 break;
1032 }
1033
1034 CurrentState = (MRX_VBOX_STATE)InterlockedCompareExchange((PLONG) & VBoxMRxState, MRX_VBOX_STARTABLE, MRX_VBOX_STARTED);
1035
1036 Status = RxStopMinirdr(RxContext, &RxContext->PostRequest);
1037 Log(("VBOXSF: MRxDevFcbXXXControlFile: IOCTL_MRX_VBOX_STOP: Returned 0x%08X\n",
1038 Status));
1039
1040 if (Status == STATUS_PENDING && RxContext->PostRequest == TRUE)
1041 Status = STATUS_MORE_PROCESSING_REQUIRED;
1042 break;
1043 }
1044
1045 default:
1046 Status = STATUS_INVALID_DEVICE_REQUEST;
1047 break;
1048 }
1049 break;
1050 }
1051
1052 case IRP_MJ_INTERNAL_DEVICE_CONTROL:
1053 {
1054 Status = STATUS_INVALID_DEVICE_REQUEST;
1055 break;
1056 }
1057
1058 default:
1059 Log(("VBOXSF: MRxDevFcbXXXControlFile: unimplemented major function 0x%02X\n",
1060 RxContext->MajorFunction));
1061 Status = STATUS_INVALID_DEVICE_REQUEST;
1062 break;
1063 }
1064
1065 Log(("VBOXSF: MRxDevFcbXXXControlFile: Status = 0x%08X, Info = 0x%08X\n",
1066 Status, RxContext->InformationToReturn));
1067
1068 return Status;
1069}
1070
1071static NTSTATUS vbsfVerifyConnectionName(PUNICODE_STRING ConnectionName)
1072{
1073 /* Check that the connection name is valid:
1074 * "\Device\VBoxMiniRdr\;X:\vboxsvr\sf"
1075 */
1076 NTSTATUS Status = STATUS_BAD_NETWORK_NAME;
1077
1078 ULONG i;
1079 PWCHAR pwc;
1080 PWCHAR pwc1;
1081
1082 static PWCHAR spwszPrefix = L"\\Device\\VBoxMiniRdr\\;";
1083
1084 /* Unicode chars in the string. */
1085 ULONG cConnectionName = ConnectionName->Length / sizeof(WCHAR);
1086 ULONG cRemainingName;
1087
1088 /* Check that the name starts with correct prefix. */
1089 pwc1 = &spwszPrefix[0];
1090 pwc = ConnectionName->Buffer;
1091 for (i = 0; i < cConnectionName; i++, pwc1++, pwc++)
1092 {
1093 if (*pwc1 == 0 || *pwc == 0 || *pwc1 != *pwc)
1094 break;
1095 }
1096
1097 cRemainingName = cConnectionName - i;
1098
1099 Log(("VBOXSF: vbsfVerifyConnectionName: prefix %d remaining %d [%.*ls]\n",
1100 *pwc1 == 0, cRemainingName, cRemainingName, &ConnectionName->Buffer[i]));
1101
1102 if (*pwc1 == 0)
1103 {
1104 /* pwc should point to a drive letter followed by ':\' that is at least 3 chars more. */
1105 if (cRemainingName >= 3)
1106 {
1107 if ( pwc[0] >= L'A' && pwc[0] <= L'Z'
1108 && pwc[1] == L':')
1109 {
1110 pwc += 2;
1111 cRemainingName -= 2;
1112
1113 /* @todo should also check that the drive letter corresponds to the name. */
1114 if (vboxIsPrefixOK(pwc, cRemainingName * sizeof (WCHAR)))
1115 Status = STATUS_SUCCESS;
1116 }
1117 }
1118 }
1119
1120 return Status;
1121}
1122
1123static HANDLE vbsfOpenConnectionHandle(PUNICODE_STRING ConnectionName)
1124{
1125 NTSTATUS Status;
1126 IO_STATUS_BLOCK IoStatusBlock;
1127 OBJECT_ATTRIBUTES ObjectAttributes;
1128
1129 HANDLE Handle = INVALID_HANDLE_VALUE;
1130
1131 Log(("VBOXSF: vbsfOpenConnectionHandle: ConnectionName = %.*ls\n",
1132 ConnectionName->Length / sizeof(WCHAR), ConnectionName->Buffer));
1133
1134 Status = vbsfVerifyConnectionName(ConnectionName);
1135
1136 if (NT_SUCCESS(Status))
1137 {
1138 /* Have to create a OBJ_KERNEL_HANDLE. Otherwise the driver verifier on Windows 7 bugchecks. */
1139 InitializeObjectAttributes(&ObjectAttributes,
1140 ConnectionName,
1141 OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
1142 NULL,
1143 NULL);
1144
1145 Status = ZwCreateFile(&Handle,
1146 SYNCHRONIZE,
1147 &ObjectAttributes,
1148 &IoStatusBlock,
1149 NULL,
1150 FILE_ATTRIBUTE_NORMAL,
1151 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
1152 FILE_OPEN_IF,
1153 FILE_CREATE_TREE_CONNECTION | FILE_SYNCHRONOUS_IO_NONALERT,
1154 NULL,
1155 0);
1156 }
1157
1158 if ( Status != STATUS_SUCCESS
1159 || Handle == INVALID_HANDLE_VALUE)
1160 {
1161 Log(("VBOXSF: vbsfOpenConnectionHandle: ZwCreateFile failed status 0x%08X or invalid handle!\n",
1162 Status));
1163 Handle = INVALID_HANDLE_VALUE;
1164 }
1165
1166 return Handle;
1167}
1168
1169NTSTATUS vbsfCreateConnection(IN PRX_CONTEXT RxContext, OUT PBOOLEAN PostToFsp)
1170{
1171 NTSTATUS Status = STATUS_SUCCESS;
1172
1173 PMRX_VBOX_DEVICE_EXTENSION pDeviceExtension;
1174
1175 PLOWIO_CONTEXT LowIoContext;
1176 ULONG cbConnectName;
1177 PWCHAR pwcConnectName;
1178
1179 HANDLE Handle;
1180 UNICODE_STRING FileName;
1181
1182 BOOLEAN fMutexAcquired = FALSE;
1183
1184 Log(("VBOXSF: vbsfCreateConnection\n"));
1185
1186 if (!BooleanFlagOn(RxContext->Flags, RX_CONTEXT_FLAG_WAIT))
1187 {
1188 Log(("VBOXSF: vbsfCreateConnection: post to file system process\n"));
1189 *PostToFsp = TRUE;
1190 return STATUS_PENDING;
1191 }
1192
1193 pDeviceExtension = VBoxMRxGetDeviceExtension(RxContext);
1194 if (!pDeviceExtension)
1195 return STATUS_INVALID_PARAMETER;
1196
1197 LowIoContext = &RxContext->LowIoContext;
1198 cbConnectName = LowIoContext->ParamsFor.IoCtl.InputBufferLength;
1199 pwcConnectName = (PWCHAR)LowIoContext->ParamsFor.IoCtl.pInputBuffer;
1200
1201 if (cbConnectName == 0 || !pwcConnectName)
1202 {
1203 Log(("VBOXSF: vbsfCreateConnection: Connection name / length is invalid!\n"));
1204 return STATUS_INVALID_PARAMETER;
1205 }
1206
1207 __try
1208 {
1209 Log(("VBOXSF: vbsfCreateConnection: Name = %.*ls, Len = %d\n",
1210 cbConnectName / sizeof(WCHAR), pwcConnectName, cbConnectName));
1211
1212 FileName.Buffer = pwcConnectName;
1213 FileName.Length = (USHORT)cbConnectName;
1214 FileName.MaximumLength = (USHORT)cbConnectName;
1215
1216 Handle = vbsfOpenConnectionHandle(&FileName);
1217
1218 if (Handle != INVALID_HANDLE_VALUE)
1219 {
1220 PWCHAR pwc;
1221 ULONG i;
1222
1223 ZwClose(Handle);
1224
1225 /* Skip the "\Device\VBoxMiniRdr\;X:" of the string "\Device\VBoxMiniRdr\;X:\vboxsrv\sf" */
1226 pwc = pwcConnectName;
1227 for (i = 0; i < cbConnectName; i += sizeof(WCHAR))
1228 {
1229 if (*pwc == L':')
1230 break;
1231 pwc++;
1232 }
1233
1234 if (i >= sizeof(WCHAR) && i < cbConnectName)
1235 {
1236 pwc--; /* Go back to the drive letter, "X" for example. */
1237
1238 if (*pwc >= L'A' && *pwc <= L'Z') /* Are we in range? */
1239 {
1240 uint32_t idx = *pwc - L'A'; /* Get the index based on the driver letter numbers (26). */
1241
1242 if (idx >= RTL_NUMBER_OF(pDeviceExtension->cLocalConnections))
1243 {
1244 Log(("VBOXSF: vbsfCreateConnection: Index 0x%x is invalid!\n",
1245 idx));
1246 Status = STATUS_BAD_NETWORK_NAME;
1247 }
1248 else
1249 {
1250 ExAcquireFastMutex(&pDeviceExtension->mtxLocalCon);
1251 fMutexAcquired = TRUE;
1252
1253 if (pDeviceExtension->wszLocalConnectionName[idx] != NULL)
1254 {
1255 Log(("VBOXSF: vbsfCreateConnection: LocalConnectionName at index %d is NOT empty!\n",
1256 idx));
1257 }
1258
1259 pDeviceExtension->wszLocalConnectionName[idx] = (PUNICODE_STRING)vbsfAllocNonPagedMem(sizeof(UNICODE_STRING) + cbConnectName);
1260
1261 if (!pDeviceExtension->wszLocalConnectionName[idx])
1262 {
1263 Log(("VBOXSF: vbsfCreateConnection: LocalConnectionName at index %d NOT allocated!\n",
1264 idx));
1265 Status = STATUS_INSUFFICIENT_RESOURCES;
1266 }
1267 else
1268 {
1269 PUNICODE_STRING pRemoteName = pDeviceExtension->wszLocalConnectionName[idx];
1270
1271 pRemoteName->Buffer = (PWSTR)(pRemoteName + 1);
1272 pRemoteName->Length = (USHORT)(cbConnectName - i - sizeof(WCHAR));
1273 pRemoteName->MaximumLength = pRemoteName->Length;
1274 RtlCopyMemory(&pRemoteName->Buffer[0], pwc+2, pRemoteName->Length);
1275
1276 Log(("VBOXSF: vbsfCreateConnection: RemoteName %.*ls, Len = %d\n",
1277 pRemoteName->Length / sizeof(WCHAR), pRemoteName->Buffer, pRemoteName->Length));
1278
1279 pDeviceExtension->cLocalConnections[idx] = TRUE;
1280 }
1281
1282 ExReleaseFastMutex(&pDeviceExtension->mtxLocalCon);
1283 fMutexAcquired = FALSE;
1284 }
1285 }
1286 }
1287 else
1288 {
1289 Log(("VBOXSF: vbsfCreateConnection: bad format\n"));
1290 Status = STATUS_BAD_NETWORK_NAME;
1291 }
1292 }
1293 else
1294 {
1295 Log(("VBOXSF: vbsfCreateConnection: connection was not found\n"));
1296 Status = STATUS_BAD_NETWORK_NAME;
1297 }
1298 }
1299 __except(EXCEPTION_EXECUTE_HANDLER)
1300 {
1301 Status = STATUS_INVALID_PARAMETER;
1302 }
1303
1304 if (fMutexAcquired)
1305 {
1306 ExReleaseFastMutex(&pDeviceExtension->mtxLocalCon);
1307 fMutexAcquired = FALSE;
1308 }
1309
1310 return Status;
1311}
1312
1313NTSTATUS vbsfDeleteConnection(IN PRX_CONTEXT RxContext, OUT PBOOLEAN PostToFsp)
1314{
1315 NTSTATUS Status;
1316 UNICODE_STRING FileName;
1317 HANDLE Handle;
1318 PLOWIO_CONTEXT LowIoContext;
1319 PWCHAR pwcConnectName;
1320 ULONG cbConnectName;
1321 PMRX_VBOX_DEVICE_EXTENSION pDeviceExtension;
1322
1323 BOOLEAN fMutexAcquired = FALSE;
1324
1325 Log(("VBOXSF: vbsfDeleteConnection\n"));
1326
1327 if (!BooleanFlagOn(RxContext->Flags, RX_CONTEXT_FLAG_WAIT))
1328 {
1329 Log(("VBOXSF: vbsfDeleteConnection: post to file system process\n"));
1330 *PostToFsp = TRUE;
1331 return STATUS_PENDING;
1332 }
1333
1334 LowIoContext = &RxContext->LowIoContext;
1335 pwcConnectName = (PWCHAR)LowIoContext->ParamsFor.IoCtl.pInputBuffer;
1336 cbConnectName = LowIoContext->ParamsFor.IoCtl.InputBufferLength;
1337
1338 pDeviceExtension = VBoxMRxGetDeviceExtension(RxContext);
1339 if (!pDeviceExtension)
1340 return STATUS_INVALID_PARAMETER;
1341
1342 __try
1343 {
1344 Log(("VBOXSF: vbsfDeleteConnection: pwcConnectName = %.*ls\n",
1345 cbConnectName / sizeof(WCHAR), pwcConnectName));
1346
1347 FileName.Buffer = pwcConnectName;
1348 FileName.Length = (USHORT)cbConnectName;
1349 FileName.MaximumLength = (USHORT)cbConnectName;
1350
1351 Handle = vbsfOpenConnectionHandle(&FileName);
1352
1353 if (Handle != INVALID_HANDLE_VALUE)
1354 {
1355 PFILE_OBJECT pFileObject;
1356 Status = ObReferenceObjectByHandle(Handle, 0L, NULL, KernelMode, (PVOID *)&pFileObject, NULL);
1357
1358 Log(("VBOXSF: vbsfDeleteConnection: ObReferenceObjectByHandle Status 0x%08X\n",
1359 Status));
1360
1361 if (NT_SUCCESS(Status))
1362 {
1363 PFOBX Fobx = (PFOBX)pFileObject->FsContext2;
1364 Log(("VBOXSF: vbsfDeleteConnection: Fobx %p\n", Fobx));
1365
1366 if (Fobx && NodeType(Fobx) == RDBSS_NTC_V_NETROOT)
1367 {
1368 PV_NET_ROOT VNetRoot = (PV_NET_ROOT)Fobx;
1369
1370 Status = RxFinalizeConnection(VNetRoot->NetRoot, VNetRoot, TRUE);
1371 }
1372 else
1373 {
1374 Log(("VBOXSF: vbsfDeleteConnection: wrong FsContext2\n"));
1375 Status = STATUS_INVALID_DEVICE_REQUEST;
1376 }
1377
1378 ObDereferenceObject(pFileObject);
1379 }
1380
1381 ZwClose(Handle);
1382 }
1383
1384 if (NT_SUCCESS(Status))
1385 {
1386 PWCHAR pwc;
1387 ULONG i;
1388
1389 /* Skip the "\Device\VBoxMiniRdr\;X:" of the string "\Device\VBoxMiniRdr\;X:\vboxsrv\sf" */
1390 pwc = pwcConnectName;
1391 for (i = 0; i < cbConnectName; i += sizeof(WCHAR))
1392 {
1393 if (*pwc == L':')
1394 {
1395 break;
1396 }
1397 pwc++;
1398 }
1399
1400 if (i >= sizeof(WCHAR) && i < cbConnectName)
1401 {
1402 pwc--;
1403
1404 if (*pwc >= L'A' && *pwc <= L'Z')
1405 {
1406 uint32_t idx = *pwc - L'A';
1407
1408 if (idx >= RTL_NUMBER_OF(pDeviceExtension->cLocalConnections))
1409 {
1410 Log(("VBOXSF: vbsfDeleteConnection: Index 0x%x is invalid!\n",
1411 idx));
1412 Status = STATUS_BAD_NETWORK_NAME;
1413 }
1414 else
1415 {
1416 ExAcquireFastMutex(&pDeviceExtension->mtxLocalCon);
1417 fMutexAcquired = TRUE;
1418
1419 pDeviceExtension->cLocalConnections[idx] = FALSE;
1420
1421 /* Free saved name */
1422 if (pDeviceExtension->wszLocalConnectionName[idx])
1423 {
1424 vbsfFreeNonPagedMem(pDeviceExtension->wszLocalConnectionName[idx]);
1425 pDeviceExtension->wszLocalConnectionName[idx] = NULL;
1426 }
1427
1428 ExReleaseFastMutex(&pDeviceExtension->mtxLocalCon);
1429 fMutexAcquired = FALSE;
1430
1431 Log(("VBOXSF: vbsfDeleteConnection: deleted index 0x%x\n",
1432 idx));
1433 }
1434 }
1435 }
1436 else
1437 {
1438 Log(("VBOXSF: vbsfCreateConnection: bad format\n"));
1439 Status = STATUS_BAD_NETWORK_NAME;
1440 }
1441 }
1442 }
1443 __except(EXCEPTION_EXECUTE_HANDLER)
1444 {
1445 Status = STATUS_INVALID_PARAMETER;
1446 }
1447
1448 if (fMutexAcquired)
1449 {
1450 ExReleaseFastMutex(&pDeviceExtension->mtxLocalCon);
1451 fMutexAcquired = FALSE;
1452 }
1453
1454 Log(("VBOXSF: vbsfDeleteConnection: Status 0x%08X\n", Status));
1455 return Status;
1456}
1457
1458NTSTATUS VBoxMRxQueryEaInfo(IN OUT PRX_CONTEXT RxContext)
1459{
1460 Log(("VBOXSF: MRxQueryEaInfo: Ea buffer len remaining is %d\n",
1461 RxContext->Info.LengthRemaining));
1462 return STATUS_SUCCESS;
1463}
1464
1465NTSTATUS VBoxMRxSetEaInfo(IN OUT PRX_CONTEXT RxContext)
1466{
1467 RT_NOREF(RxContext);
1468 Log(("VBOXSF: MRxSetEaInfo\n"));
1469 return STATUS_NOT_IMPLEMENTED;
1470}
1471
1472NTSTATUS VBoxMRxFsCtl (IN OUT PRX_CONTEXT RxContext)
1473{
1474 RT_NOREF(RxContext);
1475 Log(("VBOXSF: MRxFsCtl\n"));
1476 return STATUS_INVALID_DEVICE_REQUEST;
1477}
1478
1479NTSTATUS VBoxMRxNotifyChangeDirectory(IN OUT PRX_CONTEXT RxContext)
1480{
1481 RT_NOREF(RxContext);
1482 Log(("VBOXSF: MRxNotifyChangeDirectory\n"));
1483 return STATUS_NOT_IMPLEMENTED;
1484}
1485
1486NTSTATUS VBoxMRxQuerySdInfo(IN OUT PRX_CONTEXT RxContext)
1487{
1488 RT_NOREF(RxContext);
1489 Log(("VBOXSF: MRxQuerySdInfo\n"));
1490 return STATUS_NOT_IMPLEMENTED;
1491}
1492
1493NTSTATUS VBoxMRxSetSdInfo(IN OUT struct _RX_CONTEXT * RxContext)
1494{
1495 RT_NOREF(RxContext);
1496 Log(("VBOXSF: MRxSetSdInfo\n"));
1497 return STATUS_NOT_IMPLEMENTED;
1498}
1499
1500/*
1501 * WML stubs which are referenced by rdbsslib.
1502 */
1503NTSTATUS WmlTinySystemControl(IN OUT PVOID pWmiLibInfo, IN PVOID pDevObj, IN PVOID pIrp)
1504{
1505 RT_NOREF(pWmiLibInfo, pDevObj, pIrp);
1506 return STATUS_WMI_GUID_NOT_FOUND;
1507}
1508
1509ULONG WmlTrace(IN ULONG ulType, IN PVOID pTraceUuid, IN ULONG64 ullLogger, ...)
1510{
1511 RT_NOREF(ulType, pTraceUuid, ullLogger);
1512 return STATUS_SUCCESS;
1513}
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