VirtualBox

source: vbox/trunk/src/VBox/Additions/WINNT/SharedFolders/driver/file.c@ 58196

Last change on this file since 58196 was 58196, checked in by vboxsync, 9 years ago

VBoxGuestR0LibSharedFolders: VBSFMAP -> VBGLSFMAP; VBSFCLIENT -> VBGLSFCLIENT

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 19.4 KB
Line 
1/* $Id: file.c 58196 2015-10-12 15:18:51Z vboxsync $ */
2/** @file
3 *
4 * VirtualBox Windows Guest Shared Folders
5 *
6 * File System Driver file routines
7 */
8
9/*
10 * Copyright (C) 2012-2013 Oracle Corporation
11 *
12 * This file is part of VirtualBox Open Source Edition (OSE), as
13 * available from http://www.virtualbox.org. This file is free software;
14 * you can redistribute it and/or modify it under the terms of the GNU
15 * General Public License (GPL) as published by the Free Software
16 * Foundation, in version 2 as it comes in the "COPYING" file of the
17 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
18 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
19 */
20
21#include "vbsf.h"
22#include <iprt/fs.h>
23#include <iprt/mem.h>
24
25
26/* How much data to transfer in one HGCM request. */
27#define VBSF_MAX_READ_WRITE_PAGES 256
28
29
30typedef int FNVBSFTRANSFERBUFFER(PVBGLSFCLIENT pClient, PVBGLSFMAP pMap, SHFLHANDLE hFile,
31 uint64_t offset, uint32_t *pcbBuffer,
32 uint8_t *pBuffer, bool fLocked);
33typedef FNVBSFTRANSFERBUFFER *PFNVBSFTRANSFERBUFFER;
34
35typedef int FNVBSFTRANSFERPAGES(PVBGLSFCLIENT pClient, PVBGLSFMAP pMap, SHFLHANDLE hFile,
36 uint64_t offset, uint32_t *pcbBuffer,
37 uint16_t offFirstPage, uint16_t cPages, RTGCPHYS64 *paPages);
38typedef FNVBSFTRANSFERPAGES *PFNVBSFTRANSFERPAGES;
39
40
41static int vbsfTransferBufferRead(PVBGLSFCLIENT pClient, PVBGLSFMAP pMap, SHFLHANDLE hFile,
42 uint64_t offset, uint32_t *pcbBuffer,
43 uint8_t *pBuffer, bool fLocked)
44{
45 return VbglR0SfRead(pClient, pMap, hFile, offset, pcbBuffer, pBuffer, fLocked);
46}
47
48static int vbsfTransferBufferWrite(PVBGLSFCLIENT pClient, PVBGLSFMAP pMap, SHFLHANDLE hFile,
49 uint64_t offset, uint32_t *pcbBuffer,
50 uint8_t *pBuffer, bool fLocked)
51{
52 return VbglR0SfWrite(pClient, pMap, hFile, offset, pcbBuffer, pBuffer, fLocked);
53}
54
55static int vbsfTransferPagesRead(PVBGLSFCLIENT pClient, PVBGLSFMAP pMap, SHFLHANDLE hFile,
56 uint64_t offset, uint32_t *pcbBuffer,
57 uint16_t offFirstPage, uint16_t cPages, RTGCPHYS64 *paPages)
58{
59 return VbglR0SfReadPageList(pClient, pMap, hFile, offset, pcbBuffer, offFirstPage, cPages, paPages);
60}
61
62static int vbsfTransferPagesWrite(PVBGLSFCLIENT pClient, PVBGLSFMAP pMap, SHFLHANDLE hFile,
63 uint64_t offset, uint32_t *pcbBuffer,
64 uint16_t offFirstPage, uint16_t cPages, RTGCPHYS64 *paPages)
65{
66 return VbglR0SfWritePageList(pClient, pMap, hFile, offset, pcbBuffer, offFirstPage, cPages, paPages);
67}
68
69
70typedef struct VBSFTRANSFERCTX
71{
72 PVBGLSFCLIENT pClient;
73 PVBGLSFMAP pMap;
74 SHFLHANDLE hFile;
75 uint64_t offset;
76 uint32_t cbData;
77
78 PMDL pMdl;
79 uint8_t *pBuffer;
80 bool fLocked;
81
82 PFNVBSFTRANSFERBUFFER pfnTransferBuffer;
83 PFNVBSFTRANSFERPAGES pfnTransferPages;
84} VBSFTRANSFERCTX;
85
86
87static int vbsfTransferCommon(VBSFTRANSFERCTX *pCtx)
88{
89 int rc = VINF_SUCCESS;
90 BOOLEAN fProcessed = FALSE;
91
92 uint32_t cbTransferred = 0;
93
94 uint32_t cbToTransfer;
95 uint32_t cbIO;
96
97 if (VbglR0CanUsePhysPageList())
98 {
99 ULONG offFirstPage = MmGetMdlByteOffset(pCtx->pMdl);
100 ULONG cPages = ADDRESS_AND_SIZE_TO_SPAN_PAGES(MmGetMdlVirtualAddress(pCtx->pMdl), pCtx->cbData);
101 ULONG cPagesToTransfer = RT_MIN(cPages, VBSF_MAX_READ_WRITE_PAGES);
102 RTGCPHYS64 *paPages = (RTGCPHYS64 *)RTMemTmpAlloc(cPagesToTransfer * sizeof(RTGCPHYS64));
103
104 Log(("VBOXSF: vbsfTransferCommon: using page list: %d pages, offset 0x%03X\n", cPages, offFirstPage));
105
106 if (paPages)
107 {
108 PPFN_NUMBER paPfns = MmGetMdlPfnArray(pCtx->pMdl);
109 ULONG cPagesTransferred = 0;
110 cbTransferred = 0;
111
112 while (cPagesToTransfer != 0)
113 {
114 ULONG iPage;
115 cbToTransfer = cPagesToTransfer * PAGE_SIZE - offFirstPage;
116
117 if (cbToTransfer > pCtx->cbData - cbTransferred)
118 cbToTransfer = pCtx->cbData - cbTransferred;
119
120 if (cbToTransfer == 0)
121 {
122 /* Nothing to transfer. */
123 break;
124 }
125
126 cbIO = cbToTransfer;
127
128 Log(("VBOXSF: vbsfTransferCommon: transferring %d pages at %d; %d bytes at %d\n",
129 cPagesToTransfer, cPagesTransferred, cbToTransfer, cbTransferred));
130
131 for (iPage = 0; iPage < cPagesToTransfer; iPage++)
132 paPages[iPage] = (RTGCPHYS64)paPfns[iPage + cPagesTransferred] << PAGE_SHIFT;
133
134 rc = pCtx->pfnTransferPages(pCtx->pClient, pCtx->pMap, pCtx->hFile,
135 pCtx->offset + cbTransferred, &cbIO,
136 (uint16_t)offFirstPage, (uint16_t)cPagesToTransfer, paPages);
137 if (RT_FAILURE(rc))
138 {
139 Log(("VBOXSF: vbsfTransferCommon: pfnTransferPages %Rrc, cbTransferred %d\n", rc, cbTransferred));
140
141 /* If some data was transferred, then it is no error. */
142 if (cbTransferred > 0)
143 rc = VINF_SUCCESS;
144
145 break;
146 }
147
148 cbTransferred += cbIO;
149
150 if (cbToTransfer < cbIO)
151 {
152 /* Transferred less than requested, do not continue with the possibly remaining data. */
153 break;
154 }
155
156 cPagesTransferred += cPagesToTransfer;
157 offFirstPage = 0;
158
159 cPagesToTransfer = cPages - cPagesTransferred;
160 if (cPagesToTransfer > VBSF_MAX_READ_WRITE_PAGES)
161 cPagesToTransfer = VBSF_MAX_READ_WRITE_PAGES;
162 }
163
164 RTMemTmpFree(paPages);
165
166 fProcessed = TRUE;
167 }
168 }
169
170 if (fProcessed != TRUE)
171 {
172 /* Split large transfers. */
173 cbTransferred = 0;
174 cbToTransfer = RT_MIN(pCtx->cbData, VBSF_MAX_READ_WRITE_PAGES * PAGE_SIZE);
175
176 /* Page list not supported or a fallback. */
177 Log(("VBOXSF: vbsfTransferCommon: using linear address\n"));
178
179 while (cbToTransfer != 0)
180 {
181 cbIO = cbToTransfer;
182
183 Log(("VBOXSF: vbsfTransferCommon: transferring %d bytes at %d\n",
184 cbToTransfer, cbTransferred));
185
186 rc = pCtx->pfnTransferBuffer(pCtx->pClient, pCtx->pMap, pCtx->hFile,
187 pCtx->offset + cbTransferred, &cbIO,
188 pCtx->pBuffer + cbTransferred, true /* locked */);
189
190 if (RT_FAILURE(rc))
191 {
192 Log(("VBOXSF: vbsfTransferCommon: pfnTransferBuffer %Rrc, cbTransferred %d\n", rc, cbTransferred));
193
194 /* If some data was transferred, then it is no error. */
195 if (cbTransferred > 0)
196 rc = VINF_SUCCESS;
197
198 break;
199 }
200
201 cbTransferred += cbIO;
202
203 if (cbToTransfer < cbIO)
204 {
205 /* Transferred less than requested, do not continue with the possibly remaining data. */
206 break;
207 }
208
209 cbToTransfer = pCtx->cbData - cbTransferred;
210 if (cbToTransfer > VBSF_MAX_READ_WRITE_PAGES * PAGE_SIZE)
211 cbToTransfer = VBSF_MAX_READ_WRITE_PAGES * PAGE_SIZE;
212 }
213 }
214
215 pCtx->cbData = cbTransferred;
216
217 return rc;
218}
219
220static NTSTATUS vbsfReadInternal(IN PRX_CONTEXT RxContext)
221{
222 NTSTATUS Status = STATUS_SUCCESS;
223 VBSFTRANSFERCTX ctx;
224
225 RxCaptureFcb;
226 RxCaptureFobx;
227
228 PMRX_VBOX_DEVICE_EXTENSION pDeviceExtension = VBoxMRxGetDeviceExtension(RxContext);
229 PMRX_VBOX_NETROOT_EXTENSION pNetRootExtension = VBoxMRxGetNetRootExtension(capFcb->pNetRoot);
230 PMRX_VBOX_FOBX pVBoxFobx = VBoxMRxGetFileObjectExtension(capFobx);
231
232 PLOWIO_CONTEXT LowIoContext = &RxContext->LowIoContext;
233
234 PMDL BufferMdl = LowIoContext->ParamsFor.ReadWrite.Buffer;
235 uint32_t ByteCount = LowIoContext->ParamsFor.ReadWrite.ByteCount;
236 RXVBO ByteOffset = LowIoContext->ParamsFor.ReadWrite.ByteOffset;
237
238 PVOID pbUserBuffer = RxLowIoGetBufferAddress(RxContext);
239
240 int vboxRC;
241
242 BOOLEAN AsyncIo = BooleanFlagOn(RxContext->Flags, RX_CONTEXT_FLAG_ASYNC_OPERATION);
243 LONGLONG FileSize;
244
245 RxGetFileSizeWithLock((PFCB)capFcb, &FileSize);
246
247 Log(("VBOXSF: vbsfReadInternal: AsyncIo = %d, Fcb->FileSize = 0x%RX64\n",
248 AsyncIo, capFcb->Header.FileSize.QuadPart));
249 Log(("VBOXSF: vbsfReadInternal: UserBuffer %p, BufferMdl %p\n",
250 pbUserBuffer, BufferMdl));
251 Log(("VBOXSF: vbsfReadInternal: ByteCount 0x%X, ByteOffset 0x%RX64, FileSize 0x%RX64\n",
252 ByteCount, ByteOffset, FileSize));
253
254 /* @todo check if this is necessary. */
255#ifdef FCB_STATE_READCACHING_ENABLED /* Correct spelling for Vista 6001 SDK. */
256 if (!FlagOn(capFcb->FcbState, FCB_STATE_READCACHING_ENABLED))
257#else
258 if (!FlagOn(capFcb->FcbState, FCB_STATE_READCACHEING_ENABLED))
259#endif
260 {
261 if (ByteOffset >= FileSize)
262 {
263 Log(("VBOXSF: vbsfReadInternal: EOF\n"));
264 return STATUS_END_OF_FILE;
265 }
266
267 if (ByteCount > FileSize - ByteOffset)
268 ByteCount = (ULONG)(FileSize - ByteOffset);
269 }
270
271 /* @todo read 0 bytes == always success? */
272 if ( !BufferMdl
273 || ByteCount == 0)
274 {
275 AssertFailed();
276 return STATUS_INVALID_PARAMETER;
277 }
278
279 ctx.pClient = &pDeviceExtension->hgcmClient;
280 ctx.pMap = &pNetRootExtension->map;
281 ctx.hFile = pVBoxFobx->hFile;
282 ctx.offset = (uint64_t)ByteOffset;
283 ctx.cbData = ByteCount;
284 ctx.pMdl = BufferMdl;
285 ctx.pBuffer = (uint8_t *)pbUserBuffer;
286 ctx.fLocked = true;
287 ctx.pfnTransferBuffer = vbsfTransferBufferRead;
288 ctx.pfnTransferPages = vbsfTransferPagesRead;
289
290 vboxRC = vbsfTransferCommon(&ctx);
291
292 ByteCount = ctx.cbData;
293
294 Status = VBoxErrorToNTStatus(vboxRC);
295
296 if (Status != STATUS_SUCCESS)
297 {
298 /* Nothing read. */
299 ByteCount = 0;
300 }
301
302 RxContext->InformationToReturn = ByteCount;
303
304 Log(("VBOXSF: vbsfReadInternal: Status = 0x%08X, ByteCount = 0x%X\n",
305 Status, ByteCount));
306
307 return Status;
308}
309
310
311static VOID vbsfReadWorker(VOID *pv)
312{
313 PRX_CONTEXT RxContext = (PRX_CONTEXT)pv;
314
315 Log(("VBOXSF: vbsfReadWorker: calling the worker\n"));
316
317 RxContext->IoStatusBlock.Status = vbsfReadInternal(RxContext);
318
319 Log(("VBOXSF: vbsfReadWorker: Status 0x%08X\n",
320 RxContext->IoStatusBlock.Status));
321
322 RxLowIoCompletion(RxContext);
323}
324
325
326NTSTATUS VBoxMRxRead(IN PRX_CONTEXT RxContext)
327{
328 NTSTATUS Status = RxDispatchToWorkerThread(VBoxMRxDeviceObject, DelayedWorkQueue,
329 vbsfReadWorker,
330 RxContext);
331
332 Log(("VBOXSF: MRxRead: RxDispatchToWorkerThread: Status 0x%08X\n", Status));
333
334 if (Status == STATUS_SUCCESS)
335 Status = STATUS_PENDING;
336
337 return Status;
338}
339
340static NTSTATUS vbsfWriteInternal(IN PRX_CONTEXT RxContext)
341{
342 NTSTATUS Status = STATUS_SUCCESS;
343 VBSFTRANSFERCTX ctx;
344
345 RxCaptureFcb;
346 RxCaptureFobx;
347
348 PMRX_VBOX_DEVICE_EXTENSION pDeviceExtension = VBoxMRxGetDeviceExtension(RxContext);
349 PMRX_VBOX_NETROOT_EXTENSION pNetRootExtension = VBoxMRxGetNetRootExtension(capFcb->pNetRoot);
350 PMRX_VBOX_FOBX pVBoxFobx = VBoxMRxGetFileObjectExtension(capFobx);
351
352 PLOWIO_CONTEXT LowIoContext = &RxContext->LowIoContext;
353
354 PMDL BufferMdl = LowIoContext->ParamsFor.ReadWrite.Buffer;
355 uint32_t ByteCount = LowIoContext->ParamsFor.ReadWrite.ByteCount;
356 RXVBO ByteOffset = LowIoContext->ParamsFor.ReadWrite.ByteOffset;
357
358 PVOID pbUserBuffer = RxLowIoGetBufferAddress(RxContext);
359
360 int vboxRC;
361
362 BOOLEAN AsyncIo = BooleanFlagOn(RxContext->Flags, RX_CONTEXT_FLAG_ASYNC_OPERATION);
363 LONGLONG FileSize;
364
365 RxGetFileSizeWithLock((PFCB)capFcb, &FileSize);
366
367 Log(("VBOXSF: vbsfWriteInternal: AsyncIo = %d, Fcb->FileSize = 0x%RX64\n",
368 AsyncIo, capFcb->Header.FileSize.QuadPart));
369 Log(("VBOXSF: vbsfWriteInternal: UserBuffer %p, BufferMdl %p\n",
370 pbUserBuffer, BufferMdl));
371 Log(("VBOXSF: vbsfWriteInternal: ByteCount is 0x%X, ByteOffset is 0x%RX64, FileSize 0x%RX64\n",
372 ByteCount, ByteOffset, FileSize));
373
374 /* @todo allow to write 0 bytes. */
375 if ( !BufferMdl
376 || ByteCount == 0)
377 {
378 AssertFailed();
379 return STATUS_INVALID_PARAMETER;
380 }
381
382 ctx.pClient = &pDeviceExtension->hgcmClient;
383 ctx.pMap = &pNetRootExtension->map;
384 ctx.hFile = pVBoxFobx->hFile;
385 ctx.offset = (uint64_t)ByteOffset;
386 ctx.cbData = ByteCount;
387 ctx.pMdl = BufferMdl;
388 ctx.pBuffer = (uint8_t *)pbUserBuffer;
389 ctx.fLocked = true;
390 ctx.pfnTransferBuffer = vbsfTransferBufferWrite;
391 ctx.pfnTransferPages = vbsfTransferPagesWrite;
392
393 vboxRC = vbsfTransferCommon(&ctx);
394
395 ByteCount = ctx.cbData;
396
397 Status = VBoxErrorToNTStatus(vboxRC);
398
399 if (Status != STATUS_SUCCESS)
400 {
401 /* Nothing written. */
402 ByteCount = 0;
403 }
404
405 RxContext->InformationToReturn = ByteCount;
406
407 Log(("VBOXSF: vbsfWriteInternal: Status = 0x%08X, ByteCount = 0x%X\n",
408 Status, ByteCount));
409
410 return Status;
411}
412
413static VOID vbsfWriteWorker(VOID *pv)
414{
415 PRX_CONTEXT RxContext = (PRX_CONTEXT)pv;
416
417 Log(("VBOXSF: vbsfWriteWorker: calling the worker\n"));
418
419 RxContext->IoStatusBlock.Status = vbsfWriteInternal(RxContext);
420
421 Log(("VBOXSF: vbsfWriteWorker: Status 0x%08X\n",
422 RxContext->IoStatusBlock.Status));
423
424 RxLowIoCompletion(RxContext);
425}
426
427
428NTSTATUS VBoxMRxWrite(IN PRX_CONTEXT RxContext)
429{
430 NTSTATUS Status = RxDispatchToWorkerThread(VBoxMRxDeviceObject, DelayedWorkQueue,
431 vbsfWriteWorker,
432 RxContext);
433
434 Log(("VBOXSF: MRxWrite: RxDispatchToWorkerThread: Status 0x%08X\n",
435 Status));
436
437 if (Status == STATUS_SUCCESS)
438 Status = STATUS_PENDING;
439
440 return Status;
441}
442
443
444NTSTATUS VBoxMRxLocks(IN PRX_CONTEXT RxContext)
445{
446 NTSTATUS Status = STATUS_SUCCESS;
447
448 RxCaptureFcb;
449 RxCaptureFobx;
450
451 PMRX_VBOX_DEVICE_EXTENSION pDeviceExtension = VBoxMRxGetDeviceExtension(RxContext);
452 PMRX_VBOX_NETROOT_EXTENSION pNetRootExtension = VBoxMRxGetNetRootExtension(capFcb->pNetRoot);
453 PMRX_VBOX_FOBX pVBoxFobx = VBoxMRxGetFileObjectExtension(capFobx);
454
455 PLOWIO_CONTEXT LowIoContext = &RxContext->LowIoContext;
456 uint32_t fu32Lock = 0;
457 int vboxRC;
458
459 Log(("VBOXSF: MRxLocks: Operation %d\n",
460 LowIoContext->Operation));
461
462 switch (LowIoContext->Operation)
463 {
464 default:
465 AssertMsgFailed(("VBOXSF: MRxLocks: Unsupported lock/unlock type %d detected!\n",
466 LowIoContext->Operation));
467 return STATUS_NOT_IMPLEMENTED;
468
469 case LOWIO_OP_UNLOCK_MULTIPLE:
470 /* @todo Remove multiple locks listed in LowIoContext.ParamsFor.Locks.LockList. */
471 Log(("VBOXSF: MRxLocks: Unsupported LOWIO_OP_UNLOCK_MULTIPLE!\n",
472 LowIoContext->Operation));
473 return STATUS_NOT_IMPLEMENTED;
474
475 case LOWIO_OP_SHAREDLOCK:
476 fu32Lock = SHFL_LOCK_SHARED | SHFL_LOCK_PARTIAL;
477 break;
478
479 case LOWIO_OP_EXCLUSIVELOCK:
480 fu32Lock = SHFL_LOCK_EXCLUSIVE | SHFL_LOCK_PARTIAL;
481 break;
482
483 case LOWIO_OP_UNLOCK:
484 fu32Lock = SHFL_LOCK_CANCEL | SHFL_LOCK_PARTIAL;
485 break;
486 }
487
488 if (LowIoContext->ParamsFor.Locks.Flags & LOWIO_LOCKSFLAG_FAIL_IMMEDIATELY)
489 fu32Lock |= SHFL_LOCK_NOWAIT;
490 else
491 fu32Lock |= SHFL_LOCK_WAIT;
492
493 vboxRC = VbglR0SfLock(&pDeviceExtension->hgcmClient, &pNetRootExtension->map, pVBoxFobx->hFile,
494 LowIoContext->ParamsFor.Locks.ByteOffset, LowIoContext->ParamsFor.Locks.Length, fu32Lock);
495
496 Status = VBoxErrorToNTStatus(vboxRC);
497
498 Log(("VBOXSF: MRxLocks: Returned 0x%08X\n", Status));
499 return Status;
500}
501
502NTSTATUS VBoxMRxCompleteBufferingStateChangeRequest(IN OUT PRX_CONTEXT RxContext,
503 IN OUT PMRX_SRV_OPEN SrvOpen,
504 IN PVOID pContext)
505{
506 Log(("VBOXSF: MRxCompleteBufferingStateChangeRequest: not implemented\n"));
507 return STATUS_NOT_IMPLEMENTED;
508}
509
510NTSTATUS VBoxMRxFlush (IN PRX_CONTEXT RxContext)
511{
512 NTSTATUS Status = STATUS_SUCCESS;
513
514 RxCaptureFcb;
515 RxCaptureFobx;
516
517 PMRX_VBOX_DEVICE_EXTENSION pDeviceExtension = VBoxMRxGetDeviceExtension(RxContext);
518 PMRX_VBOX_NETROOT_EXTENSION pNetRootExtension = VBoxMRxGetNetRootExtension(capFcb->pNetRoot);
519 PMRX_VBOX_FOBX pVBoxFobx = VBoxMRxGetFileObjectExtension(capFobx);
520
521 int vboxRC;
522
523 Log(("VBOXSF: MRxFlush\n"));
524
525 /* Do the actual flushing of file buffers */
526 vboxRC = VbglR0SfFlush(&pDeviceExtension->hgcmClient, &pNetRootExtension->map, pVBoxFobx->hFile);
527
528 Status = VBoxErrorToNTStatus(vboxRC);
529
530 Log(("VBOXSF: MRxFlush: Returned 0x%08X\n", Status));
531 return Status;
532}
533
534NTSTATUS vbsfSetEndOfFile(IN OUT struct _RX_CONTEXT * RxContext,
535 IN OUT PLARGE_INTEGER pNewFileSize,
536 OUT PLARGE_INTEGER pNewAllocationSize)
537{
538 NTSTATUS Status = STATUS_SUCCESS;
539
540 RxCaptureFcb;
541 RxCaptureFobx;
542
543 PMRX_VBOX_DEVICE_EXTENSION pDeviceExtension = VBoxMRxGetDeviceExtension(RxContext);
544 PMRX_VBOX_NETROOT_EXTENSION pNetRootExtension = VBoxMRxGetNetRootExtension(capFcb->pNetRoot);
545 PMRX_VBOX_FOBX pVBoxFobx = VBoxMRxGetFileObjectExtension(capFobx);
546
547 PSHFLFSOBJINFO pObjInfo;
548 uint32_t cbBuffer;
549 int vboxRC;
550
551 Log(("VBOXSF: vbsfSetEndOfFile: New size = %RX64 (%p), pNewAllocationSize = %p\n",
552 pNewFileSize->QuadPart, pNewFileSize, pNewAllocationSize));
553
554 Assert(pVBoxFobx && pNetRootExtension && pDeviceExtension);
555
556 cbBuffer = sizeof(SHFLFSOBJINFO);
557 pObjInfo = (SHFLFSOBJINFO *)vbsfAllocNonPagedMem(cbBuffer);
558 if (!pObjInfo)
559 {
560 AssertFailed();
561 return STATUS_INSUFFICIENT_RESOURCES;
562 }
563
564 RtlZeroMemory(pObjInfo, cbBuffer);
565 pObjInfo->cbObject = pNewFileSize->QuadPart;
566
567 vboxRC = VbglR0SfFsInfo(&pDeviceExtension->hgcmClient, &pNetRootExtension->map, pVBoxFobx->hFile,
568 SHFL_INFO_SET | SHFL_INFO_SIZE, &cbBuffer, (PSHFLDIRINFO)pObjInfo);
569
570 Log(("VBOXSF: vbsfSetEndOfFile: VbglR0SfFsInfo returned %Rrc\n", vboxRC));
571
572 Status = VBoxErrorToNTStatus(vboxRC);
573 if (Status == STATUS_SUCCESS)
574 {
575 Log(("VBOXSF: vbsfSetEndOfFile: VbglR0SfFsInfo new allocation size = %RX64\n",
576 pObjInfo->cbAllocated));
577
578 /* Return new allocation size */
579 pNewAllocationSize->QuadPart = pObjInfo->cbAllocated;
580 }
581
582 if (pObjInfo)
583 vbsfFreeNonPagedMem(pObjInfo);
584
585 Log(("VBOXSF: vbsfSetEndOfFile: Returned 0x%08X\n", Status));
586 return Status;
587}
588
589NTSTATUS VBoxMRxExtendStub(IN OUT struct _RX_CONTEXT * RxContext,
590 IN OUT PLARGE_INTEGER pNewFileSize,
591 OUT PLARGE_INTEGER pNewAllocationSize)
592{
593 /* Note: On Windows hosts vbsfSetEndOfFile returns ACCESS_DENIED if the file has been
594 * opened in APPEND mode. Writes to a file will extend it anyway, therefore it is
595 * better to not call the host at all and tell the caller that the file was extended.
596 */
597 Log(("VBOXSF: MRxExtendStub: new size = %RX64\n",
598 pNewFileSize->QuadPart));
599
600 pNewAllocationSize->QuadPart = pNewFileSize->QuadPart;
601
602 return STATUS_SUCCESS;
603}
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