VirtualBox

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

最後變更 在這個檔案從53442是 51254,由 vboxsync 提交於 11 年 前

Additions/SharedFolders: fixed ShflStringInitBuffer(), do really use this function for initializing the SHFLSTRING content; some cosmetcis

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

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