VirtualBox

source: vbox/trunk/src/VBox/Additions/WINNT/SharedFolders/driver/file.cpp@ 78548

Last change on this file since 78548 was 78548, checked in by vboxsync, 6 years ago

winnt/vboxsf: Fixed none-working open+truncate testcase caused by an old misconception in the FileAllocationInformation wrt when the incoming sizes would be updated (before call, as it turns out). bugref:9172

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 21.1 KB
Line 
1/* $Id: file.cpp 78548 2019-05-16 13:53:39Z vboxsync $ */
2/** @file
3 * VirtualBox Windows Guest Shared Folders - File System Driver file routines.
4 */
5
6/*
7 * Copyright (C) 2012-2019 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
19/*********************************************************************************************************************************
20* Header Files *
21*********************************************************************************************************************************/
22#include "vbsf.h"
23#include <iprt/fs.h>
24#include <iprt/mem.h>
25
26
27/*********************************************************************************************************************************
28* Defined Constants And Macros *
29*********************************************************************************************************************************/
30/* How much data to transfer in one HGCM request. */
31#define VBSF_MAX_READ_WRITE_PAGES 256
32
33
34typedef int FNVBSFTRANSFERBUFFER(PVBGLSFCLIENT pClient, PVBGLSFMAP pMap, SHFLHANDLE hFile,
35 uint64_t offset, uint32_t *pcbBuffer,
36 uint8_t *pBuffer, bool fLocked);
37typedef FNVBSFTRANSFERBUFFER *PFNVBSFTRANSFERBUFFER;
38
39typedef int FNVBSFTRANSFERPAGES(PVBGLSFCLIENT pClient, PVBGLSFMAP pMap, SHFLHANDLE hFile,
40 uint64_t offset, uint32_t *pcbBuffer,
41 uint16_t offFirstPage, uint16_t cPages, RTGCPHYS64 *paPages);
42typedef FNVBSFTRANSFERPAGES *PFNVBSFTRANSFERPAGES;
43
44
45static int vbsfTransferBufferRead(PVBGLSFCLIENT pClient, PVBGLSFMAP pMap, SHFLHANDLE hFile,
46 uint64_t offset, uint32_t *pcbBuffer,
47 uint8_t *pBuffer, bool fLocked)
48{
49 return VbglR0SfRead(pClient, pMap, hFile, offset, pcbBuffer, pBuffer, fLocked);
50}
51
52static int vbsfTransferBufferWrite(PVBGLSFCLIENT pClient, PVBGLSFMAP pMap, SHFLHANDLE hFile,
53 uint64_t offset, uint32_t *pcbBuffer,
54 uint8_t *pBuffer, bool fLocked)
55{
56 return VbglR0SfWrite(pClient, pMap, hFile, offset, pcbBuffer, pBuffer, fLocked);
57}
58
59static int vbsfTransferPagesRead(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 VbglR0SfReadPageList(pClient, pMap, hFile, offset, pcbBuffer, offFirstPage, cPages, paPages);
64}
65
66static int vbsfTransferPagesWrite(PVBGLSFCLIENT pClient, PVBGLSFMAP pMap, SHFLHANDLE hFile,
67 uint64_t offset, uint32_t *pcbBuffer,
68 uint16_t offFirstPage, uint16_t cPages, RTGCPHYS64 *paPages)
69{
70 return VbglR0SfWritePageList(pClient, pMap, hFile, offset, pcbBuffer, offFirstPage, cPages, paPages);
71}
72
73
74typedef struct VBSFTRANSFERCTX
75{
76 PVBGLSFCLIENT pClient;
77 PVBGLSFMAP pMap;
78 SHFLHANDLE hFile;
79 uint64_t offset;
80 uint32_t cbData;
81
82 PMDL pMdl;
83 uint8_t *pBuffer;
84 bool fLocked;
85
86 PFNVBSFTRANSFERBUFFER pfnTransferBuffer;
87 PFNVBSFTRANSFERPAGES pfnTransferPages;
88} VBSFTRANSFERCTX;
89
90
91static int vbsfTransferCommon(VBSFTRANSFERCTX *pCtx)
92{
93 int rc = VINF_SUCCESS;
94 BOOLEAN fProcessed = FALSE;
95
96 uint32_t cbTransferred = 0;
97
98 uint32_t cbToTransfer;
99 uint32_t cbIO;
100
101 /** @todo Remove the test and the fall-back path. VbglR0CanUsePhysPageList()
102 * returns true for any host version after 3.0, i.e. further back than
103 * we support. */
104 if (VbglR0CanUsePhysPageList())
105 {
106 ULONG offFirstPage = MmGetMdlByteOffset(pCtx->pMdl);
107 ULONG cPages = ADDRESS_AND_SIZE_TO_SPAN_PAGES(MmGetMdlVirtualAddress(pCtx->pMdl), pCtx->cbData);
108 ULONG cPagesToTransfer = RT_MIN(cPages, VBSF_MAX_READ_WRITE_PAGES);
109 RTGCPHYS64 *paPages = (RTGCPHYS64 *)RTMemTmpAlloc(cPagesToTransfer * sizeof(RTGCPHYS64));
110
111 Log(("VBOXSF: vbsfTransferCommon: using page list: %d pages, offset 0x%03X\n", cPages, offFirstPage));
112
113 if (paPages)
114 {
115 PPFN_NUMBER paPfns = MmGetMdlPfnArray(pCtx->pMdl);
116 ULONG cPagesTransferred = 0;
117 cbTransferred = 0;
118
119 while (cPagesToTransfer != 0)
120 {
121 ULONG iPage;
122 cbToTransfer = cPagesToTransfer * PAGE_SIZE - offFirstPage;
123
124 if (cbToTransfer > pCtx->cbData - cbTransferred)
125 cbToTransfer = pCtx->cbData - cbTransferred;
126
127 if (cbToTransfer == 0)
128 {
129 /* Nothing to transfer. */
130 break;
131 }
132
133 cbIO = cbToTransfer;
134
135 Log(("VBOXSF: vbsfTransferCommon: transferring %d pages at %d; %d bytes at %d\n",
136 cPagesToTransfer, cPagesTransferred, cbToTransfer, cbTransferred));
137
138 for (iPage = 0; iPage < cPagesToTransfer; iPage++)
139 paPages[iPage] = (RTGCPHYS64)paPfns[iPage + cPagesTransferred] << PAGE_SHIFT;
140
141 rc = pCtx->pfnTransferPages(pCtx->pClient, pCtx->pMap, pCtx->hFile,
142 pCtx->offset + cbTransferred, &cbIO,
143 (uint16_t)offFirstPage, (uint16_t)cPagesToTransfer, paPages);
144 if (RT_FAILURE(rc))
145 {
146 Log(("VBOXSF: vbsfTransferCommon: pfnTransferPages %Rrc, cbTransferred %d\n", rc, cbTransferred));
147
148 /* If some data was transferred, then it is no error. */
149 if (cbTransferred > 0)
150 rc = VINF_SUCCESS;
151
152 break;
153 }
154
155 cbTransferred += cbIO;
156
157 if (cbToTransfer < cbIO)
158 {
159 /* Transferred less than requested, do not continue with the possibly remaining data. */
160 break;
161 }
162
163 cPagesTransferred += cPagesToTransfer;
164 offFirstPage = 0;
165
166 cPagesToTransfer = cPages - cPagesTransferred;
167 if (cPagesToTransfer > VBSF_MAX_READ_WRITE_PAGES)
168 cPagesToTransfer = VBSF_MAX_READ_WRITE_PAGES;
169 }
170
171 RTMemTmpFree(paPages);
172
173 fProcessed = TRUE;
174 }
175 }
176
177 if (fProcessed != TRUE)
178 {
179 /* Split large transfers. */
180 cbTransferred = 0;
181 cbToTransfer = RT_MIN(pCtx->cbData, VBSF_MAX_READ_WRITE_PAGES * PAGE_SIZE);
182
183 /* Page list not supported or a fallback. */
184 Log(("VBOXSF: vbsfTransferCommon: using linear address\n"));
185
186 while (cbToTransfer != 0)
187 {
188 cbIO = cbToTransfer;
189
190 Log(("VBOXSF: vbsfTransferCommon: transferring %d bytes at %d\n",
191 cbToTransfer, cbTransferred));
192
193 rc = pCtx->pfnTransferBuffer(pCtx->pClient, pCtx->pMap, pCtx->hFile,
194 pCtx->offset + cbTransferred, &cbIO,
195 pCtx->pBuffer + cbTransferred, true /* locked */);
196
197 if (RT_FAILURE(rc))
198 {
199 Log(("VBOXSF: vbsfTransferCommon: pfnTransferBuffer %Rrc, cbTransferred %d\n", rc, cbTransferred));
200
201 /* If some data was transferred, then it is no error. */
202 if (cbTransferred > 0)
203 rc = VINF_SUCCESS;
204
205 break;
206 }
207
208 cbTransferred += cbIO;
209
210 if (cbToTransfer < cbIO)
211 {
212 /* Transferred less than requested, do not continue with the possibly remaining data. */
213 break;
214 }
215
216 cbToTransfer = pCtx->cbData - cbTransferred;
217 if (cbToTransfer > VBSF_MAX_READ_WRITE_PAGES * PAGE_SIZE)
218 cbToTransfer = VBSF_MAX_READ_WRITE_PAGES * PAGE_SIZE;
219 }
220 }
221
222 pCtx->cbData = cbTransferred;
223
224 return rc;
225}
226
227static NTSTATUS vbsfReadInternal(IN PRX_CONTEXT RxContext)
228{
229 VBSFTRANSFERCTX ctx;
230
231 RxCaptureFcb;
232 RxCaptureFobx;
233
234 PMRX_VBOX_NETROOT_EXTENSION pNetRootExtension = VBoxMRxGetNetRootExtension(capFcb->pNetRoot);
235 PVBSFNTFCBEXT pVBoxFcbx = VBoxMRxGetFcbExtension(capFcb);
236 PMRX_VBOX_FOBX pVBoxFobx = VBoxMRxGetFileObjectExtension(capFobx);
237
238 PLOWIO_CONTEXT LowIoContext = &RxContext->LowIoContext;
239
240 PMDL BufferMdl = LowIoContext->ParamsFor.ReadWrite.Buffer;
241
242 PVOID pbUserBuffer = RxLowIoGetBufferAddress(RxContext);
243
244#ifdef LOG_ENABLED
245 BOOLEAN AsyncIo = BooleanFlagOn(RxContext->Flags, RX_CONTEXT_FLAG_ASYNC_OPERATION);
246 LONGLONG FileSize;
247 RxGetFileSizeWithLock((PFCB)capFcb, &FileSize);
248#endif
249
250 Log(("VBOXSF: vbsfReadInternal: AsyncIo = %d, Fcb->FileSize = 0x%RX64\n",
251 AsyncIo, capFcb->Header.FileSize.QuadPart));
252 Log(("VBOXSF: vbsfReadInternal: UserBuffer %p, BufferMdl %p\n",
253 pbUserBuffer, BufferMdl));
254 Log(("VBOXSF: vbsfReadInternal: ByteCount 0x%X, ByteOffset 0x%RX64, FileSize 0x%RX64\n",
255 LowIoContext->ParamsFor.ReadWrite.ByteCount, LowIoContext->ParamsFor.ReadWrite.ByteOffset, FileSize));
256
257 AssertReturn(BufferMdl, STATUS_INVALID_PARAMETER);
258 Assert(LowIoContext->ParamsFor.ReadWrite.ByteCount > 0); /* ASSUME this is taken care of elsewhere already. */
259
260 ctx.pClient = &g_SfClient;
261 ctx.pMap = &pNetRootExtension->map;
262 ctx.hFile = pVBoxFobx->hFile;
263 ctx.offset = LowIoContext->ParamsFor.ReadWrite.ByteOffset;
264 ctx.cbData = LowIoContext->ParamsFor.ReadWrite.ByteCount;
265 ctx.pMdl = BufferMdl;
266 ctx.pBuffer = (uint8_t *)pbUserBuffer;
267 ctx.fLocked = true;
268 ctx.pfnTransferBuffer = vbsfTransferBufferRead;
269 ctx.pfnTransferPages = vbsfTransferPagesRead;
270
271 int vrc = vbsfTransferCommon(&ctx);
272
273 NTSTATUS Status;
274 if (RT_SUCCESS(vrc))
275 {
276 pVBoxFobx->fTimestampsImplicitlyUpdated |= VBOX_FOBX_F_INFO_LASTACCESS_TIME;
277 if (pVBoxFcbx->pFobxLastAccessTime != pVBoxFobx)
278 pVBoxFcbx->pFobxLastAccessTime = NULL;
279 Status = STATUS_SUCCESS;
280 if (ctx.cbData == 0 && LowIoContext->ParamsFor.ReadWrite.ByteCount > 0)
281 Status = STATUS_END_OF_FILE;
282
283 /*
284 * See if we've reached the EOF early or read beyond what we thought were the EOF.
285 *
286 * Note! We don't dare do this (yet) if we're in paging I/O as we then hold the
287 * PagingIoResource in shared mode and would probably deadlock in the
288 * updating code when taking the lock in exclusive mode.
289 */
290 if (RxContext->LowIoContext.Resource != capFcb->Header.PagingIoResource)
291 {
292 LONGLONG const offEndOfRead = LowIoContext->ParamsFor.ReadWrite.ByteOffset + ctx.cbData;
293 LONGLONG cbFileRdbss;
294 RxGetFileSizeWithLock((PFCB)capFcb, &cbFileRdbss);
295 if ( offEndOfRead < cbFileRdbss
296 && ctx.cbData < LowIoContext->ParamsFor.ReadWrite.ByteCount /* hit EOF */)
297 vbsfNtUpdateFcbSize(RxContext->pFobx->AssociatedFileObject, capFcb, pVBoxFobx, offEndOfRead, cbFileRdbss, -1);
298 else if (offEndOfRead > cbFileRdbss)
299 vbsfNtQueryAndUpdateFcbSize(pNetRootExtension, RxContext->pFobx->AssociatedFileObject, pVBoxFobx, capFcb, pVBoxFcbx);
300 }
301 }
302 else
303 {
304 ctx.cbData = 0; /* Nothing read. */
305 Status = vbsfNtVBoxStatusToNt(vrc);
306 }
307
308 RxContext->InformationToReturn = ctx.cbData;
309
310 Log(("VBOXSF: vbsfReadInternal: Status = 0x%08X, ByteCount = 0x%X\n",
311 Status, ctx.cbData));
312
313 return Status;
314}
315
316
317static VOID vbsfReadWorker(VOID *pv)
318{
319 PRX_CONTEXT RxContext = (PRX_CONTEXT)pv;
320
321 Log(("VBOXSF: vbsfReadWorker: calling the worker\n"));
322
323 RxContext->IoStatusBlock.Status = vbsfReadInternal(RxContext);
324
325 Log(("VBOXSF: vbsfReadWorker: Status 0x%08X\n",
326 RxContext->IoStatusBlock.Status));
327
328 RxLowIoCompletion(RxContext);
329}
330
331/**
332 * Read stuff from a file.
333 *
334 * Prior to calling us, RDBSS will have:
335 * - Called CcFlushCache() for uncached accesses.
336 * - For non-paging access the Fcb.Header.Resource lock in shared mode in one
337 * way or another (ExAcquireResourceSharedLite,
338 * ExAcquireSharedWaitForExclusive).
339 * - For paging the FCB isn't, but the Fcb.Header.PagingResource is taken
340 * in shared mode (ExAcquireResourceSharedLite).
341 *
342 * Upon completion, it will update the file pointer if applicable. There are no
343 * EOF checks and corresponding file size updating like in the write case, so
344 * that's something we have to do ourselves it seems since the library relies on
345 * the size information to be accurate in a few places (set EOF, cached reads).
346 */
347NTSTATUS VBoxMRxRead(IN PRX_CONTEXT RxContext)
348{
349 NTSTATUS Status;
350
351#if 0
352 if ( IoIsOperationSynchronous(RxContext->CurrentIrp)
353 /*&& IoGetRemainingStackSize() >= 1024 - not necessary, checked by RxFsdCommonDispatch already */)
354 {
355 RxContext->IoStatusBlock.Status = Status = vbsfReadInternal(RxContext);
356 Assert(Status != STATUS_PENDING);
357
358 Log(("VBOXSF: MRxRead: vbsfReadInternal: Status %#08X\n", Status));
359 }
360 else
361#endif
362 {
363 Status = RxDispatchToWorkerThread(VBoxMRxDeviceObject, DelayedWorkQueue, vbsfReadWorker, RxContext);
364
365 Log(("VBOXSF: MRxRead: RxDispatchToWorkerThread: Status 0x%08X\n", Status));
366
367 if (Status == STATUS_SUCCESS)
368 Status = STATUS_PENDING;
369 }
370
371 return Status;
372}
373
374static NTSTATUS vbsfWriteInternal(IN PRX_CONTEXT RxContext)
375{
376 NTSTATUS Status = STATUS_SUCCESS;
377 VBSFTRANSFERCTX ctx;
378
379 RxCaptureFcb;
380 RxCaptureFobx;
381
382 PMRX_VBOX_NETROOT_EXTENSION pNetRootExtension = VBoxMRxGetNetRootExtension(capFcb->pNetRoot);
383 PVBSFNTFCBEXT pVBoxFcbx = VBoxMRxGetFcbExtension(capFcb);
384 PMRX_VBOX_FOBX pVBoxFobx = VBoxMRxGetFileObjectExtension(capFobx);
385
386 PLOWIO_CONTEXT LowIoContext = &RxContext->LowIoContext;
387
388 PMDL BufferMdl = LowIoContext->ParamsFor.ReadWrite.Buffer;
389 uint32_t ByteCount = LowIoContext->ParamsFor.ReadWrite.ByteCount;
390 RXVBO ByteOffset = LowIoContext->ParamsFor.ReadWrite.ByteOffset;
391
392 PVOID pbUserBuffer = RxLowIoGetBufferAddress(RxContext);
393
394 int vrc;
395
396#ifdef LOG_ENABLED
397 BOOLEAN AsyncIo = BooleanFlagOn(RxContext->Flags, RX_CONTEXT_FLAG_ASYNC_OPERATION);
398#endif
399 LONGLONG FileSize;
400
401 RxGetFileSizeWithLock((PFCB)capFcb, &FileSize);
402
403 Log(("VBOXSF: vbsfWriteInternal: AsyncIo = %d, Fcb->FileSize = 0x%RX64\n",
404 AsyncIo, capFcb->Header.FileSize.QuadPart));
405 Log(("VBOXSF: vbsfWriteInternal: UserBuffer %p, BufferMdl %p\n",
406 pbUserBuffer, BufferMdl));
407 Log(("VBOXSF: vbsfWriteInternal: ByteCount is 0x%X, ByteOffset is 0x%RX64, FileSize 0x%RX64\n",
408 ByteCount, ByteOffset, FileSize));
409
410 /** @todo allow to write 0 bytes. */
411 if ( !BufferMdl
412 || ByteCount == 0)
413 {
414 AssertFailed();
415 return STATUS_INVALID_PARAMETER;
416 }
417
418 ctx.pClient = &g_SfClient;
419 ctx.pMap = &pNetRootExtension->map;
420 ctx.hFile = pVBoxFobx->hFile;
421 ctx.offset = (uint64_t)ByteOffset;
422 ctx.cbData = ByteCount;
423 ctx.pMdl = BufferMdl;
424 ctx.pBuffer = (uint8_t *)pbUserBuffer;
425 ctx.fLocked = true;
426 ctx.pfnTransferBuffer = vbsfTransferBufferWrite;
427 ctx.pfnTransferPages = vbsfTransferPagesWrite;
428
429 vrc = vbsfTransferCommon(&ctx);
430
431 ByteCount = ctx.cbData;
432
433 Status = vbsfNtVBoxStatusToNt(vrc);
434
435 if (Status == STATUS_SUCCESS)
436 {
437 pVBoxFobx->fTimestampsImplicitlyUpdated |= VBOX_FOBX_F_INFO_LASTWRITE_TIME;
438 if (pVBoxFcbx->pFobxLastWriteTime != pVBoxFobx)
439 pVBoxFcbx->pFobxLastWriteTime = NULL;
440
441 /* Make sure our cached file size value is up to date: */
442 if (ctx.cbData > 0)
443 {
444 RTFOFF offEndOfWrite = LowIoContext->ParamsFor.ReadWrite.ByteOffset + ctx.cbData;
445 if (pVBoxFobx->Info.cbObject < offEndOfWrite)
446 pVBoxFobx->Info.cbObject = offEndOfWrite;
447
448 if (pVBoxFobx->Info.cbAllocated < offEndOfWrite)
449 {
450 pVBoxFobx->Info.cbAllocated = offEndOfWrite;
451 pVBoxFobx->nsUpToDate = 0;
452 }
453 }
454 }
455 else
456 ByteCount = 0; /* Nothing written. */
457
458 RxContext->InformationToReturn = ByteCount;
459
460 Log(("VBOXSF: vbsfWriteInternal: Status = 0x%08X, ByteCount = 0x%X\n",
461 Status, ByteCount));
462
463 return Status;
464}
465
466static VOID vbsfWriteWorker(VOID *pv)
467{
468 PRX_CONTEXT RxContext = (PRX_CONTEXT)pv;
469
470 Log(("VBOXSF: vbsfWriteWorker: calling the worker\n"));
471
472 RxContext->IoStatusBlock.Status = vbsfWriteInternal(RxContext);
473
474 Log(("VBOXSF: vbsfWriteWorker: Status 0x%08X\n",
475 RxContext->IoStatusBlock.Status));
476
477 RxLowIoCompletion(RxContext);
478}
479
480
481NTSTATUS VBoxMRxWrite(IN PRX_CONTEXT RxContext)
482{
483 NTSTATUS Status = RxDispatchToWorkerThread(VBoxMRxDeviceObject, DelayedWorkQueue,
484 vbsfWriteWorker,
485 RxContext);
486
487 Log(("VBOXSF: MRxWrite: RxDispatchToWorkerThread: Status 0x%08X\n",
488 Status));
489
490 if (Status == STATUS_SUCCESS)
491 Status = STATUS_PENDING;
492
493 return Status;
494}
495
496
497NTSTATUS VBoxMRxLocks(IN PRX_CONTEXT RxContext)
498{
499 NTSTATUS Status = STATUS_SUCCESS;
500
501 RxCaptureFcb;
502 RxCaptureFobx;
503
504 PMRX_VBOX_NETROOT_EXTENSION pNetRootExtension = VBoxMRxGetNetRootExtension(capFcb->pNetRoot);
505 PMRX_VBOX_FOBX pVBoxFobx = VBoxMRxGetFileObjectExtension(capFobx);
506
507 PLOWIO_CONTEXT LowIoContext = &RxContext->LowIoContext;
508 uint32_t fu32Lock = 0;
509 int vrc;
510
511 Log(("VBOXSF: MRxLocks: Operation %d\n",
512 LowIoContext->Operation));
513
514 switch (LowIoContext->Operation)
515 {
516 default:
517 AssertMsgFailed(("VBOXSF: MRxLocks: Unsupported lock/unlock type %d detected!\n",
518 LowIoContext->Operation));
519 return STATUS_NOT_IMPLEMENTED;
520
521 case LOWIO_OP_UNLOCK_MULTIPLE:
522 /** @todo Remove multiple locks listed in LowIoContext.ParamsFor.Locks.LockList. */
523 Log(("VBOXSF: MRxLocks: Unsupported LOWIO_OP_UNLOCK_MULTIPLE!\n",
524 LowIoContext->Operation));
525 return STATUS_NOT_IMPLEMENTED;
526
527 case LOWIO_OP_SHAREDLOCK:
528 fu32Lock = SHFL_LOCK_SHARED | SHFL_LOCK_PARTIAL;
529 break;
530
531 case LOWIO_OP_EXCLUSIVELOCK:
532 fu32Lock = SHFL_LOCK_EXCLUSIVE | SHFL_LOCK_PARTIAL;
533 break;
534
535 case LOWIO_OP_UNLOCK:
536 fu32Lock = SHFL_LOCK_CANCEL | SHFL_LOCK_PARTIAL;
537 break;
538 }
539
540 if (LowIoContext->ParamsFor.Locks.Flags & LOWIO_LOCKSFLAG_FAIL_IMMEDIATELY)
541 fu32Lock |= SHFL_LOCK_NOWAIT;
542 else
543 fu32Lock |= SHFL_LOCK_WAIT;
544
545 vrc = VbglR0SfLock(&g_SfClient, &pNetRootExtension->map, pVBoxFobx->hFile,
546 LowIoContext->ParamsFor.Locks.ByteOffset, LowIoContext->ParamsFor.Locks.Length, fu32Lock);
547
548 Status = vbsfNtVBoxStatusToNt(vrc);
549
550 Log(("VBOXSF: MRxLocks: Returned 0x%08X\n", Status));
551 return Status;
552}
553
554NTSTATUS VBoxMRxCompleteBufferingStateChangeRequest(IN OUT PRX_CONTEXT RxContext, IN OUT PMRX_SRV_OPEN SrvOpen,
555 IN PVOID pvContext)
556{
557 RT_NOREF(RxContext, SrvOpen, pvContext);
558 Log(("VBOXSF: MRxCompleteBufferingStateChangeRequest: not implemented\n"));
559 return STATUS_NOT_IMPLEMENTED;
560}
561
562NTSTATUS VBoxMRxFlush (IN PRX_CONTEXT RxContext)
563{
564 NTSTATUS Status = STATUS_SUCCESS;
565
566 RxCaptureFcb;
567 RxCaptureFobx;
568
569 PMRX_VBOX_NETROOT_EXTENSION pNetRootExtension = VBoxMRxGetNetRootExtension(capFcb->pNetRoot);
570 PMRX_VBOX_FOBX pVBoxFobx = VBoxMRxGetFileObjectExtension(capFobx);
571
572 int vrc;
573
574 Log(("VBOXSF: MRxFlush\n"));
575
576 /* Do the actual flushing of file buffers */
577 vrc = VbglR0SfFlush(&g_SfClient, &pNetRootExtension->map, pVBoxFobx->hFile);
578
579 Status = vbsfNtVBoxStatusToNt(vrc);
580
581 Log(("VBOXSF: MRxFlush: Returned 0x%08X\n", Status));
582 return Status;
583}
584
585/** See PMRX_EXTENDFILE_CALLDOWN in ddk/mrx.h
586 *
587 * Documentation says it returns STATUS_SUCCESS on success and an error
588 * status on failure, so the ULONG return type is probably just a typo that
589 * stuck.
590 */
591ULONG NTAPI VBoxMRxExtendStub(IN OUT struct _RX_CONTEXT * RxContext, IN OUT PLARGE_INTEGER pNewFileSize,
592 OUT PLARGE_INTEGER pNewAllocationSize)
593{
594 RT_NOREF(RxContext);
595
596 /* Note: On Windows hosts vbsfNtSetEndOfFile returns ACCESS_DENIED if the file has been
597 * opened in APPEND mode. Writes to a file will extend it anyway, therefore it is
598 * better to not call the host at all and tell the caller that the file was extended.
599 */
600 Log(("VBOXSF: MRxExtendStub: new size = %RX64\n",
601 pNewFileSize->QuadPart));
602
603 pNewAllocationSize->QuadPart = pNewFileSize->QuadPart;
604
605 return STATUS_SUCCESS;
606}
607
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