VirtualBox

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

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

GA/NT/SharedFolders: warnings

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

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette