VirtualBox

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

Last change on this file since 48944 was 48944, checked in by vboxsync, 11 years ago

Additions/nt: Whitespace and svn:keyword cleanups by scm.

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