#include <pseh/pseh2.h>
#include <limits.h>
#include <dfs.h>
+#include <copysup.h>
#define NDEBUG
#include <debug.h>
FILE_INFORMATION_CLASS FileInfoClass,
PVOID Buffer);
+VOID
+RxPurgeNetFcb(
+ PFCB Fcb,
+ PRX_CONTEXT LocalContext);
+
NTSTATUS
RxQueryAlternateNameInfo(
PRX_CONTEXT RxContext,
return STATUS_SUCCESS;
}
+VOID
+RxCancelNotifyChangeDirectoryRequestsForFobx(
+ PFOBX Fobx)
+{
+ UNIMPLEMENTED;
+}
+
VOID
NTAPI
RxCancelRoutine(
}
/* Validate name is correct */
- for (NextChar = 0; CurChar + 1 < MaxChars; NextChar = CurChar + 1)
+ for (NextChar = 0, CurChar = 0; CurChar + 1 < MaxChars; NextChar = CurChar + 1)
{
USHORT i;
return Status;
}
-NTSTATUS
-NTAPI
-RxChangeBufferingState(
- PSRV_OPEN SrvOpen,
- PVOID Context,
- BOOLEAN ComputeNewState)
-{
- UNIMPLEMENTED;
- return STATUS_NOT_IMPLEMENTED;
-}
-
VOID
NTAPI
RxCheckFcbStructuresForAlignment(
return STATUS_SUCCESS;
}
+/*
+ * @implemented
+ */
NTSTATUS
RxCloseAssociatedSrvOpen(
IN PFOBX Fobx,
IN PRX_CONTEXT RxContext OPTIONAL)
{
- UNIMPLEMENTED;
- return STATUS_NOT_IMPLEMENTED;
+ PFCB Fcb;
+ NTSTATUS Status;
+ PSRV_OPEN SrvOpen;
+ BOOLEAN CloseSrvOpen;
+ PRX_CONTEXT LocalContext;
+
+ PAGED_CODE();
+
+ /* Assume SRV_OPEN is already closed */
+ CloseSrvOpen = FALSE;
+ /* If we have a FOBX, we'll have to close it */
+ if (Fobx != NULL)
+ {
+ /* If the FOBX isn't closed yet */
+ if (!BooleanFlagOn(Fobx->Flags, FOBX_FLAG_SRVOPEN_CLOSED))
+ {
+ SrvOpen = Fobx->SrvOpen;
+ Fcb = (PFCB)SrvOpen->pFcb;
+ /* Check whether we've to close SRV_OPEN first */
+ if (!BooleanFlagOn(SrvOpen->Flags, SRVOPEN_FLAG_CLOSED))
+ {
+ CloseSrvOpen = TRUE;
+ }
+ else
+ {
+ ASSERT(RxIsFcbAcquiredExclusive(Fcb));
+
+ /* Not much to do */
+ SetFlag(Fobx->Flags, FOBX_FLAG_SRVOPEN_CLOSED);
+
+ if (SrvOpen->OpenCount > 0)
+ {
+ --SrvOpen->OpenCount;
+ }
+ }
+ }
+
+ /* No need to close SRV_OPEN, so close FOBX */
+ if (!CloseSrvOpen)
+ {
+ RxMarkFobxOnClose(Fobx);
+
+ return STATUS_SUCCESS;
+ }
+ }
+ else
+ {
+ /* No FOBX? No RX_CONTEXT, ok, job done! */
+ if (RxContext == NULL)
+ {
+ return STATUS_SUCCESS;
+ }
+
+ /* Get the FCB from RX_CONTEXT */
+ Fcb = (PFCB)RxContext->pFcb;
+ SrvOpen == NULL;
+ }
+
+ /* If we don't have RX_CONTEXT, allocte one, we'll need it */
+ if (RxContext == NULL)
+ {
+ ASSERT(Fobx != NULL);
+
+ LocalContext = RxCreateRxContext(NULL, Fcb->RxDeviceObject, RX_CONTEXT_FLAG_MUST_SUCCEED_NONBLOCKING | RX_CONTEXT_FLAG_WAIT);
+ if (LocalContext == NULL)
+ {
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ LocalContext->MajorFunction = 2;
+ LocalContext->pFcb = RX_GET_MRX_FCB(Fcb);
+ LocalContext->pFobx = (PMRX_FOBX)Fobx;
+ LocalContext->pRelevantSrvOpen = (PMRX_SRV_OPEN)Fobx->SrvOpen;
+ }
+ else
+ {
+ LocalContext = RxContext;
+ }
+
+ ASSERT(RxIsFcbAcquiredExclusive(Fcb));
+
+ /* Now, close the FOBX */
+ if (Fobx != NULL)
+ {
+ RxMarkFobxOnClose(Fobx);
+ }
+ else
+ {
+ InterlockedDecrement((volatile long *)&Fcb->OpenCount);
+ }
+
+ /* If not a "standard" file, SRV_OPEN can be null */
+ if (SrvOpen == NULL)
+ {
+ ASSERT((NodeType(Fcb) == RDBSS_NTC_OPENTARGETDIR_FCB) || (NodeType(Fcb) == RDBSS_NTC_IPC_SHARE) || (NodeType(Fcb) == RDBSS_NTC_MAILSLOT));
+ RxDereferenceNetFcb(Fcb);
+
+ if (LocalContext != RxContext)
+ {
+ RxDereferenceAndDeleteRxContext(LocalContext);
+ }
+
+ return STATUS_SUCCESS;
+ }
+
+ /* If SRV_OPEN isn't in a good condition, nothing to close */
+ if (SrvOpen->Condition != Condition_Good)
+ {
+ if (LocalContext != RxContext)
+ {
+ RxDereferenceAndDeleteRxContext(LocalContext);
+ }
+
+ return STATUS_SUCCESS;
+ }
+
+ /* Decrease open count */
+ if (SrvOpen->OpenCount > 0)
+ {
+ --SrvOpen->OpenCount;
+ }
+
+ /* If we're the only one left, is there a FOBX handled by Scavenger? */
+ if (SrvOpen->OpenCount == 1)
+ {
+ if (!IsListEmpty(&SrvOpen->FobxList))
+ {
+ if (!IsListEmpty(&CONTAINING_RECORD(SrvOpen->FobxList.Flink, FOBX, FobxQLinks)->ScavengerFinalizationList))
+ {
+ SetFlag(SrvOpen->Flags, SRVOPEN_FLAG_CLOSE_DELAYED);
+ }
+ }
+ }
+
+ /* Nothing left, purge FCB */
+ if (SrvOpen->OpenCount == 0 && RxContext == NULL)
+ {
+ RxPurgeNetFcb(Fcb, LocalContext);
+ }
+
+ /* Already closed? Job done! */
+ SrvOpen = Fobx->SrvOpen;
+ if (SrvOpen == NULL ||
+ (SrvOpen->OpenCount != 0 && !BooleanFlagOn(SrvOpen->Flags, SRVOPEN_FLAG_BUFFERING_STATE_CHANGE_PENDING)) ||
+ BooleanFlagOn(SrvOpen->Flags, SRVOPEN_FLAG_CLOSED))
+ {
+ SetFlag(Fobx->Flags, FOBX_FLAG_SRVOPEN_CLOSED);
+ if (LocalContext != RxContext)
+ {
+ RxDereferenceAndDeleteRxContext(LocalContext);
+ }
+
+ return STATUS_SUCCESS;
+ }
+
+ ASSERT(RxIsFcbAcquiredExclusive(Fcb));
+
+ /* Inform mini-rdr about closing */
+ MINIRDR_CALL(Status, LocalContext, Fcb->MRxDispatch, MRxCloseSrvOpen, (LocalContext));
+ DPRINT("MRxCloseSrvOpen returned: %lx, called with RX_CONTEXT %p for FOBX %p (FCB %p, SRV_OPEN %p)\n ",
+ Status, RxContext, Fobx, Fcb, SrvOpen);
+
+ /* And mark as such */
+ SetFlag(SrvOpen->Flags, SRVOPEN_FLAG_CLOSED);
+ SrvOpen->Key = (PVOID)-1;
+
+ /* If we were delayed, we're not! */
+ if (BooleanFlagOn(SrvOpen->Flags, SRVOPEN_FLAG_CLOSE_DELAYED))
+ {
+ InterlockedDecrement(&((PSRV_CALL)Fcb->pNetRoot->pSrvCall)->NumberOfCloseDelayedFiles);
+ }
+
+ /* Clear access */
+ RxRemoveShareAccessPerSrvOpens(SrvOpen);
+ RxPurgeChangeBufferingStateRequestsForSrvOpen(SrvOpen);
+
+ /* Dereference */
+ RxDereferenceSrvOpen(SrvOpen, LHS_ExclusiveLockHeld);
+
+ /* Mark the FOBX closed as well */
+ SetFlag(Fobx->Flags, FOBX_FLAG_SRVOPEN_CLOSED);
+
+ if (LocalContext != RxContext)
+ {
+ RxDereferenceAndDeleteRxContext(LocalContext);
+ }
+
+ return Status;
}
/*
#define BugCheckFileId RDBSS_BUG_CHECK_CLEANUP
PFCB Fcb;
PFOBX Fobx;
+ ULONG OpenCount;
NTSTATUS Status;
- BOOLEAN NeedPurge;
+ PNET_ROOT NetRoot;
PFILE_OBJECT FileObject;
+ PLARGE_INTEGER TruncateSize;
+ BOOLEAN NeedPurge, FcbTableAcquired, OneLeft, IsFile, FcbAcquired;
PAGED_CODE();
return Status;
}
+ FcbAcquired = TRUE;
+
Fobx->AssociatedFileObject = NULL;
/* In case SRV_OPEN used is part of FCB */
return STATUS_SUCCESS;
}
- UNIMPLEMENTED;
- return STATUS_NOT_IMPLEMENTED;
+ /* Report the fact that file could be set as delete on close */
+ if (BooleanFlagOn(Fobx->Flags, FOBX_FLAG_DELETE_ON_CLOSE))
+ {
+ SetFlag(Fcb->FcbState, FCB_STATE_DELETE_ON_CLOSE);
+ }
+
+ /* Cancel any pending notification */
+ RxCancelNotifyChangeDirectoryRequestsForFobx(Fobx);
+
+ /* Backup open count before we start playing with it */
+ OpenCount = Fcb->ShareAccess.OpenCount;
+
+ NetRoot = (PNET_ROOT)Fcb->pNetRoot;
+ FcbTableAcquired = FALSE;
+ OneLeft = FALSE;
+
+ _SEH2_TRY
+ {
+ /* Unclean count and delete on close? Verify whether we're the one */
+ if (Fcb->UncleanCount == 1 && BooleanFlagOn(Fcb->FcbState, FCB_STATE_DELETE_ON_CLOSE))
+ {
+ if (RxAcquireFcbTableLockExclusive(&NetRoot->FcbTable, FALSE))
+ {
+ FcbTableAcquired = TRUE;
+ }
+ else
+ {
+ RxReleaseFcb(Context, Fcb);
+
+ RxAcquireFcbTableLockExclusive(&NetRoot->FcbTable, TRUE);
+
+ Status = RxAcquireExclusiveFcb(Context, Fcb);
+ if (Status != STATUS_SUCCESS)
+ {
+ RxReleaseFcbTableLock(&NetRoot->FcbTable);
+ return Status;
+ }
+
+ FcbTableAcquired = TRUE;
+ }
+
+ if (Fcb->UncleanCount == 1)
+ {
+ OneLeft = TRUE;
+ }
+ else
+ {
+ RxReleaseFcbTableLock(&NetRoot->FcbTable);
+ FcbTableAcquired = FALSE;
+ }
+ }
+
+ IsFile = FALSE;
+ TruncateSize = NULL;
+ /* Handle cleanup for pipes and printers */
+ if (NetRoot->Type == NET_ROOT_PIPE || NetRoot->Type == NET_ROOT_PRINT)
+ {
+ UNIMPLEMENTED;
+ }
+ /* Handle cleanup for files */
+ else if (NetRoot->Type == NET_ROOT_DISK || NetRoot->Type == NET_ROOT_WILD)
+ {
+ if (NodeType(Fcb) == RDBSS_NTC_STORAGE_TYPE_FILE)
+ {
+ UNIMPLEMENTED;
+ IsFile = TRUE;
+ }
+ }
+
+ /* We have to still be there! */
+ ASSERT(Fcb->UncleanCount != 0);
+ InterlockedDecrement((volatile long *)&Fcb->UncleanCount);
+
+ if (BooleanFlagOn(FileObject->Flags, FO_NO_INTERMEDIATE_BUFFERING))
+ {
+ --Fcb->UncachedUncleanCount;
+ }
+
+ /* Inform mini-rdr about ongoing cleanup */
+ MINIRDR_CALL(Status, Context, Fcb->MRxDispatch, MRxCleanupFobx, (Context));
+
+ ASSERT(Fobx->SrvOpen->UncleanFobxCount != 0);
+ --Fobx->SrvOpen->UncleanFobxCount;
+
+ /* Flush cache */
+ if (DisableFlushOnCleanup)
+ {
+ /* Only if we're the last standing */
+ if (Fcb->NonPaged->SectionObjectPointers.DataSectionObject != NULL &&
+ Fcb->UncleanCount == Fcb->UncachedUncleanCount)
+ {
+ DPRINT1("Flushing %p due to last cached handle cleanup\n", Context);
+ RxFlushFcbInSystemCache(Fcb, TRUE);
+ }
+ }
+ else
+ {
+ /* Always */
+ if (Fcb->NonPaged->SectionObjectPointers.DataSectionObject != NULL)
+ {
+ DPRINT1("Flushing %p on cleanup\n", Context);
+ RxFlushFcbInSystemCache(Fcb, TRUE);
+ }
+ }
+
+ /* If only remaining uncached & unclean, then flush and purge */
+ if (!BooleanFlagOn(FileObject->Flags, FO_NO_INTERMEDIATE_BUFFERING))
+ {
+ if (Fcb->UncachedUncleanCount != 0)
+ {
+ if (Fcb->UncachedUncleanCount == Fcb->UncleanCount &&
+ Fcb->NonPaged->SectionObjectPointers.DataSectionObject != NULL)
+ {
+ DPRINT1("Flushing FCB in system cache for %p\n", Context);
+ RxPurgeFcbInSystemCache(Fcb, NULL, 0, FALSE, TRUE);
+ }
+ }
+ }
+
+ /* If purge required, flush */
+ if (!OneLeft && NeedPurge)
+ {
+ DPRINT1("Flushing FCB in system cache for %p\n", Context);
+ RxFlushFcbInSystemCache(Fcb, TRUE);
+ }
+
+ /* If it was a file, drop cache */
+ if (IsFile)
+ {
+ DPRINT1("Uninit cache map for file\n");
+ RxUninitializeCacheMap(Context, FileObject, TruncateSize);
+ }
+
+ /* If that's the one left, or if it needs purge, flush */
+ if (OneLeft || NeedPurge)
+ {
+ RxPurgeFcbInSystemCache(Fcb, NULL, 0, FALSE, !OneLeft);
+ /* Also remove from FCB table */
+ if (OneLeft)
+ {
+ RxRemoveNameNetFcb(Fcb);
+ RxReleaseFcbTableLock(&NetRoot->FcbTable);
+ FcbTableAcquired = FALSE;
+ }
+ }
+
+ /* Remove any share access */
+ if (OpenCount != 0 && NetRoot->Type == NET_ROOT_DISK)
+ {
+ RxRemoveShareAccess(FileObject, &Fcb->ShareAccess, "Cleanup the share access", "ClnUpShr");
+ }
+
+ /* In case there's caching, on a file, update file metadata */
+ if (NodeType(Fcb) == RDBSS_NTC_STORAGE_TYPE_FILE && BooleanFlagOn(Fobx->Flags, 0x20000000) &&
+ BooleanFlagOn(Fcb->FcbState, FCB_STATE_WRITECACHING_ENABLED) && !BooleanFlagOn(Fobx->pSrvOpen->Flags, SRVOPEN_FLAG_DONTUSE_WRITE_CACHING))
+ {
+ UNIMPLEMENTED;
+ }
+
+ /* We're clean! */
+ SetFlag(FileObject->Flags, FO_CLEANUP_COMPLETE);
+
+ FcbAcquired = FALSE;
+ RxReleaseFcb(Context, Fcb);
+ }
+ _SEH2_FINALLY
+ {
+ if (FcbAcquired)
+ {
+ RxReleaseFcb(Context, Fcb);
+ }
+
+ if (FcbTableAcquired)
+ {
+ RxReleaseFcbTableLock(&NetRoot->FcbTable);
+ }
+ }
+ _SEH2_END;
+
+ return Status;
#undef BugCheckFileId
}
PIO_STATUS_BLOCK IoStatus,
PDEVICE_OBJECT DeviceObject)
{
+ PFCB Fcb;
+ PSRV_OPEN SrvOpen;
+
+ PAGED_CODE();
+
+ /* Get the FCB to validate it */
+ Fcb = FileObject->FsContext;
+ if (NodeType(Fcb) != RDBSS_NTC_STORAGE_TYPE_FILE)
+ {
+ DPRINT1("Not a file, FastIO not possible!\n");
+ return FALSE;
+ }
+
+ if (FileObject->DeletePending)
+ {
+ DPRINT1("File delete pending\n");
+ return FALSE;
+ }
+
+ /* If there's a pending write operation, deny fast operation */
+ if (Fcb->NonPaged->OutstandingAsyncWrites != 0)
+ {
+ DPRINT1("Write operations to be completed\n");
+ return FALSE;
+ }
+
+ /* Deny read on orphaned node */
+ SrvOpen = (PSRV_OPEN)((PFOBX)FileObject->FsContext2)->pSrvOpen;
+ if (BooleanFlagOn(SrvOpen->Flags, SRVOPEN_FLAG_ORPHANED))
+ {
+ DPRINT1("SRV_OPEN orphaned\n");
+ return FALSE;
+ }
+
+ if (BooleanFlagOn(Fcb->FcbState, FCB_STATE_ORPHANED))
+ {
+ DPRINT1("FCB orphaned\n");
+ return FALSE;
+ }
+
+ /* If there's a buffering state change pending, deny fast operation (it might change
+ * cache status)
+ */
+ if (BooleanFlagOn(SrvOpen->Flags, SRVOPEN_FLAG_BUFFERING_STATE_CHANGE_PENDING))
+ {
+ DPRINT1("Buffering change pending\n");
+ return FALSE;
+ }
+
+ /* File got renamed/deleted, deny operation */
+ if (BooleanFlagOn(SrvOpen->Flags, SRVOPEN_FLAG_FILE_DELETED) ||
+ BooleanFlagOn(SrvOpen->Flags, SRVOPEN_FLAG_FILE_RENAMED))
+ {
+ DPRINT1("File renamed/deleted\n");
+ return FALSE;
+ }
+
+ /* Process pending change buffering state operations */
+ FsRtlEnterFileSystem();
+ RxProcessChangeBufferingStateRequestsForSrvOpen(SrvOpen);
+ FsRtlExitFileSystem();
+
+ /* If operation to come is a read operation */
+ if (CheckForReadOperation)
+ {
+ LARGE_INTEGER LargeLength;
+
+ /* Check that read cache is enabled */
+ if (!BooleanFlagOn(Fcb->FcbState, FCB_STATE_READCACHING_ENABLED))
+ {
+ DPRINT1("Read caching disabled\n");
+ return FALSE;
+ }
+
+ /* Check whether there's a lock conflict */
+ LargeLength.QuadPart = Length;
+ if (!FsRtlFastCheckLockForRead(&Fcb->Specific.Fcb.FileLock,
+ FileOffset,
+ &LargeLength,
+ LockKey,
+ FileObject,
+ PsGetCurrentProcess()))
+ {
+ DPRINT1("FsRtlFastCheckLockForRead failed\n");
+ return FALSE;
+ }
+
+ return TRUE;
+ }
+
UNIMPLEMENTED;
return FALSE;
}
}
}
+/*
+ * @implemented
+ */
BOOLEAN
NTAPI
RxFastIoRead(
PIO_STATUS_BLOCK IoStatus,
PDEVICE_OBJECT DeviceObject)
{
- UNIMPLEMENTED;
- return FALSE;
+ BOOLEAN Ret;
+ RX_TOPLEVELIRP_CONTEXT TopLevelContext;
+
+ PAGED_CODE();
+
+ DPRINT("RxFastIoRead: %p (%p, %p)\n", FileObject, FileObject->FsContext,
+ FileObject->FsContext2);
+ DPRINT("Reading %ld at %I64x\n", Length, FileOffset->QuadPart);
+
+ /* Prepare a TLI context */
+ ASSERT(RxIsThisTheTopLevelIrp(NULL));
+ RxInitializeTopLevelIrpContext(&TopLevelContext, (PIRP)FSRTL_FAST_IO_TOP_LEVEL_IRP,
+ (PRDBSS_DEVICE_OBJECT)DeviceObject);
+
+ Ret = FsRtlCopyRead2(FileObject, FileOffset, Length, Wait, LockKey, Buffer,
+ IoStatus, DeviceObject, &TopLevelContext);
+ if (Ret)
+ {
+ DPRINT("Read OK\n");
+ }
+ else
+ {
+ DPRINT1("Read failed!\n");
+ }
+
+ return Ret;
}
BOOLEAN
return STATUS_SUCCESS;
}
-NTSTATUS
-NTAPI
-RxInitializeRxTimer(
- VOID)
-{
- UNIMPLEMENTED;
- return STATUS_NOT_IMPLEMENTED;
-}
-
/*
* @implemented
*/
Fcb = (PFCB)RxContext->pFcb;
/* Set the RX_CONTEXT */
- RxContext->Info.FsInformationClass = FileInfoClass;
+ RxContext->Info.FileInformationClass = FileInfoClass;
RxContext->Info.Buffer = Buffer;
/* Pass down */
UNIMPLEMENTED;
}
+/*
+ * @implemented
+ */
+VOID
+RxPurgeNetFcb(
+ PFCB Fcb,
+ PRX_CONTEXT LocalContext)
+{
+ NTSTATUS Status;
+
+ PAGED_CODE();
+
+ /* First, flush */
+ MmFlushImageSection(&Fcb->NonPaged->SectionObjectPointers, MmFlushForWrite);
+
+ /* And force close */
+ RxReleaseFcb(NULL, Fcb);
+ MmForceSectionClosed(&Fcb->NonPaged->SectionObjectPointers, TRUE);
+ Status = RxAcquireExclusiveFcb(NULL, Fcb);
+ ASSERT(Status == STATUS_SUCCESS);
+}
+
NTSTATUS
RxQueryAlternateNameInfo(
PRX_CONTEXT RxContext,
Status = ZwQueryValueKey(KeyHandle, &ParamName, KeyValuePartialInformation, PartialInfo, sizeof(Buffer), &ResultLength);
if (NT_SUCCESS(Status) && PartialInfo->Type == REG_DWORD)
{
- DisableByteRangeLockingOnReadOnlyFiles = ((ULONG)PartialInfo->Data != 0);
+ DisableByteRangeLockingOnReadOnlyFiles = (*(PULONG)PartialInfo->Data != 0);
}
RtlInitUnicodeString(&ParamName, L"ReadAheadGranularity");
Status = ZwQueryValueKey(KeyHandle, &ParamName, KeyValuePartialInformation, PartialInfo, sizeof(Buffer), &ResultLength);
if (NT_SUCCESS(Status) && PartialInfo->Type == REG_DWORD)
{
- ULONG Granularity = (ULONG)PartialInfo->Data;
+ ULONG Granularity = *(PULONG)PartialInfo->Data;
if (Granularity > 16)
{
Status = ZwQueryValueKey(KeyHandle, &ParamName, KeyValuePartialInformation, PartialInfo, sizeof(Buffer), &ResultLength);
if (NT_SUCCESS(Status) && PartialInfo->Type == REG_DWORD)
{
- DisableFlushOnCleanup = ((ULONG)PartialInfo->Data != 0);
+ DisableFlushOnCleanup = (*(PULONG)PartialInfo->Data != 0);
}
ZwClose(KeyHandle);
RxInitializePrefixTable(RDBSSDevice->pRxNetNameTable, 0, FALSE);
RDBSSDevice->RxNetNameTableInDeviceObject.IsNetNameTable = TRUE;
ScavengerTimeLimit.QuadPart = MrdrDispatch->ScavengerTimeout * 10000000LL;
- RxInitializeRdbssScavenger(&RDBSSDevice->RdbssScavengerInDeviceObject, ScavengerTimeLimit);
+ RDBSSDevice->pRdbssScavenger = &RDBSSDevice->RdbssScavengerInDeviceObject;
+ RxInitializeRdbssScavenger(RDBSSDevice->pRdbssScavenger, ScavengerTimeLimit);
}
RDBSSDevice->pAsynchronousRequestsCompletionEvent = NULL;
return Context;
}
+/*
+ * @implemented
+ */
VOID
RxRemoveShareAccess(
_Inout_ PFILE_OBJECT FileObject,
_In_ PSZ where,
_In_ PSZ wherelogtag)
{
- UNIMPLEMENTED;
+ PAGED_CODE();
+
+ RxDumpCurrentAccess(where, "before", wherelogtag, ShareAccess);
+ IoRemoveShareAccess(FileObject, ShareAccess);
+ RxDumpCurrentAccess(where, "after", wherelogtag, ShareAccess);
+}
+
+/*
+ * @implemented
+ */
+VOID
+RxRemoveShareAccessPerSrvOpens(
+ IN OUT PSRV_OPEN SrvOpen)
+{
+ ACCESS_MASK DesiredAccess;
+ BOOLEAN ReadAccess;
+ BOOLEAN WriteAccess;
+ BOOLEAN DeleteAccess;
+
+ PAGED_CODE();
+
+ /* Get access that were granted to SRV_OPEN */
+ DesiredAccess = SrvOpen->DesiredAccess;
+ ReadAccess = (DesiredAccess & (FILE_READ_DATA | FILE_EXECUTE)) != 0;
+ WriteAccess = (DesiredAccess & (FILE_WRITE_DATA | FILE_APPEND_DATA)) != 0;
+ DeleteAccess = (DesiredAccess & DELETE) != 0;
+
+ /* If any, drop them */
+ if ((ReadAccess) || (WriteAccess) || (DeleteAccess))
+ {
+ BOOLEAN SharedRead;
+ BOOLEAN SharedWrite;
+ BOOLEAN SharedDelete;
+ ULONG DesiredShareAccess;
+ PSHARE_ACCESS ShareAccess;
+
+ ShareAccess = &((PFCB)SrvOpen->pFcb)->ShareAccessPerSrvOpens;
+ DesiredShareAccess = SrvOpen->ShareAccess;
+
+ ShareAccess->Readers -= ReadAccess;
+ ShareAccess->Writers -= WriteAccess;
+ ShareAccess->Deleters -= DeleteAccess;
+
+ ShareAccess->OpenCount--;
+
+ SharedRead = (DesiredShareAccess & FILE_SHARE_READ) != 0;
+ SharedWrite = (DesiredShareAccess & FILE_SHARE_WRITE) != 0;
+ SharedDelete = (DesiredShareAccess & FILE_SHARE_DELETE) != 0;
+ ShareAccess->SharedRead -= SharedRead;
+ ShareAccess->SharedWrite -= SharedWrite;
+ ShareAccess->SharedDelete -= SharedDelete;
+ }
}
NTSTATUS