mirror of
https://github.com/reactos/reactos.git
synced 2024-12-05 09:23:32 +08:00
[RDBSS]
- Implement RxCloseAssociatedSrvOpen(), RxFastIoRead(), RxPurgeNetFcb(), RxRemoveShareAccess(), RxRemoveShareAccessPerSrvOpens() - Continue implementation of RxCommonCleanup() to handle allocated SRV_OPEN - Halfplement RxFastIoCheckIfPossible() so that it handles read operations - Stub RxCancelNotifyChangeDirectoryRequestsForFobx() [RXCE] - Implement RxChangeBufferingState(), RxFinalizeSrvOpen(), RxFreeFcbObject(), RxGatherRequestsForSrvOpen(), RxGetDeviceObjectOfInstance(), RxInitializeRxTimer(), RxMarkFobxOnCleanup(), RxMarkFobxOnClose(), RxpDiscardChangeBufferingStateRequests(), RxpDispatchChangeBufferingStateRequests(), RxpLookupSrvOpenForRequestLite(), RxpMarkInstanceForScavengedFinalization(), RxPostOneShotTimerRequest(), RxPrepareRequestForReuse(), RxProcessChangeBufferingStateRequestsForSrvOpen(), RxpUndoScavengerFinalizationMarking(), RxPurgeChangeBufferingStateRequestsForSrvOpen(), RxPurgeFobxFromCache(), RxRemoveNameNetFcb(), RxScavengerTimerRoutine(), RxTimerDispatch() - Finish implementation of RxDereference() to handle scavenger - Finish implementation of RxLowIoCompletionTail() to handle blocked operations resume - Fix a bug in RxFinalizeNetFcb() where it was dereferencing its NET_ROOT instead of its V_NET_ROOT - Fix bugs in __RxAcquireFcb() where it improperly handled the lack of RX_CONTEXT - Halfplement RxResumeBlockedOperations_ALL() to extract blocked operations from RX_CONTEXT (and drop them...) - Stub RxDispatchChangeBufferingStateRequests(), RxScavengerFinalizeEntries() [COPYSUP] - Implement FsRtlCopyRead2() This library is basically what you can find in FsRtl with an extended support of Top Level IRP. It is used by RDBSS for FastIO. Next to come in it will be FsRtlCopyWrite2(). This commit brings several improvements to current work on RBDSS/RXCE. First of all, both libraries will leak less (again!). It also brings the scavenger infrastructure (not fully fonctionnal though). Our NFS driver doesn't make use of it though. Finally, this brings support of FastIO (for read operations ;-)) to our NFS driver! Regarding CORE-13484, with copy + FastIO I could copy a file without troubles. But that seems to be still problematic with xcopy without FastIO... CORE-13484 CORE-11327 svn path=/trunk/; revision=75265
This commit is contained in:
parent
92ea310563
commit
0584d49170
@ -11,7 +11,7 @@ add_definitions(-DRDBSS_TRACKER)
|
||||
|
||||
add_library(nfs41_driver SHARED ${SOURCE} nfs.rc)
|
||||
set_module_type(nfs41_driver kernelmodedriver)
|
||||
target_link_libraries(nfs41_driver ntoskrnl_vista rdbsslib rxce memcmp ${PSEH_LIB})
|
||||
target_link_libraries(nfs41_driver ntoskrnl_vista rdbsslib rxce copysup memcmp ${PSEH_LIB})
|
||||
add_importlibs(nfs41_driver ntoskrnl hal)
|
||||
|
||||
if((NOT MSVC) AND (NOT CMAKE_C_COMPILER_ID STREQUAL "Clang"))
|
||||
|
@ -1,6 +1,20 @@
|
||||
#ifndef __BUFFRING_H__
|
||||
#define __BUFFRING_H__
|
||||
|
||||
#define RX_REQUEST_PREPARED_FOR_HANDLING 0x10000000
|
||||
|
||||
typedef struct _CHANGE_BUFFERING_STATE_REQUEST_
|
||||
{
|
||||
LIST_ENTRY ListEntry;
|
||||
ULONG Flags;
|
||||
#if (_WIN32_WINNT < 0x0600)
|
||||
PSRV_CALL pSrvCall;
|
||||
#endif
|
||||
PSRV_OPEN SrvOpen;
|
||||
PVOID SrvOpenKey;
|
||||
PVOID MRxContext;
|
||||
} CHANGE_BUFFERING_STATE_REQUEST, *PCHANGE_BUFFERING_STATE_REQUEST;
|
||||
|
||||
typedef struct _RX_BUFFERING_MANAGER_
|
||||
{
|
||||
BOOLEAN DispatcherActive;
|
||||
@ -49,6 +63,10 @@ VOID
|
||||
RxProcessFcbChangeBufferingStateRequest(
|
||||
_In_ PFCB Fcb);
|
||||
|
||||
VOID
|
||||
RxPurgeChangeBufferingStateRequestsForSrvOpen(
|
||||
_In_ PSRV_OPEN SrvOpen);
|
||||
|
||||
VOID
|
||||
RxCompleteSrvOpenKeyAssociation(
|
||||
_Inout_ PSRV_OPEN SrvOpen);
|
||||
|
@ -211,10 +211,14 @@ typedef struct _FCB
|
||||
#define FCB_STATE_FILE_IS_BUF_COMPRESSED 0x00004000
|
||||
#define FCB_STATE_FILE_IS_DISK_COMPRESSED 0x00008000
|
||||
#define FCB_STATE_FILE_IS_SHADOWED 0x00010000
|
||||
#define FCB_STATE_BUFFERSTATE_CHANGING 0x00002000
|
||||
#define FCB_STATE_SPECIAL_PATH 0x00020000
|
||||
#define FCB_STATE_TIME_AND_SIZE_ALREADY_SET 0x00040000
|
||||
#define FCB_STATE_FILETIMECACHEING_ENABLED 0x00080000
|
||||
#define FCB_STATE_FILESIZECACHEING_ENABLED 0x00100000
|
||||
#define FCB_STATE_LOCK_BUFFERING_ENABLED 0x00200000
|
||||
#define FCB_STATE_COLLAPSING_ENABLED 0x00400000
|
||||
#define FCB_STATE_OPENSHARING_ENABLED 0x00800000
|
||||
#define FCB_STATE_READBUFFERING_ENABLED 0x01000000
|
||||
#define FCB_STATE_READCACHING_ENABLED 0x02000000
|
||||
#define FCB_STATE_WRITEBUFFERING_ENABLED 0x04000000
|
||||
@ -224,6 +228,17 @@ typedef struct _FCB
|
||||
#define FCB_STATE_FOBX_USED 0x40000000
|
||||
#define FCB_STATE_SRVOPEN_USED 0x80000000
|
||||
|
||||
#define FCB_STATE_BUFFERING_STATE_MASK \
|
||||
((FCB_STATE_WRITECACHING_ENABLED \
|
||||
| FCB_STATE_WRITEBUFFERING_ENABLED \
|
||||
| FCB_STATE_READCACHING_ENABLED \
|
||||
| FCB_STATE_READBUFFERING_ENABLED \
|
||||
| FCB_STATE_OPENSHARING_ENABLED \
|
||||
| FCB_STATE_COLLAPSING_ENABLED \
|
||||
| FCB_STATE_LOCK_BUFFERING_ENABLED \
|
||||
| FCB_STATE_FILESIZECACHEING_ENABLED \
|
||||
| FCB_STATE_FILETIMECACHEING_ENABLED))
|
||||
|
||||
typedef struct _FCB_INIT_PACKET
|
||||
{
|
||||
PULONG pAttributes;
|
||||
@ -276,6 +291,7 @@ typedef struct _SRV_OPEN
|
||||
#define FOBX_FLAG_SRVOPEN_CLOSED 0x1000000
|
||||
#define FOBX_FLAG_UNC_NAME 0x2000000
|
||||
#define FOBX_FLAG_ENCLOSED_ALLOCATED 0x4000000
|
||||
#define FOBX_FLAG_MARKED_AS_DORMANT 0x8000000
|
||||
|
||||
typedef struct _FOBX
|
||||
{
|
||||
@ -354,53 +370,57 @@ RxpTrackDereference(
|
||||
DbgPrint("%ld\n", Count); \
|
||||
}
|
||||
|
||||
#define RxReferenceSrvCall(SrvCall) \
|
||||
RxpTrackReference(RDBSS_REF_TRACK_SRVCALL, __FILE__, __LINE__, SrvCall); \
|
||||
RxReference(SrvCall)
|
||||
#define RxReferenceSrvCall(SrvCall) \
|
||||
RxpTrackReference(RDBSS_REF_TRACK_SRVCALL, __FILE__, __LINE__, SrvCall); \
|
||||
RxReference(SrvCall)
|
||||
|
||||
#define RxDereferenceSrvCall(SrvCall, LockHoldingState) \
|
||||
RxpTrackDereference(RDBSS_REF_TRACK_SRVCALL, __FILE__, __LINE__, SrvCall); \
|
||||
RxDereference(SrvCall, LockHoldingState)
|
||||
#define RxDereferenceSrvCall(SrvCall, LockHoldingState) \
|
||||
RxpTrackDereference(RDBSS_REF_TRACK_SRVCALL, __FILE__, __LINE__, SrvCall); \
|
||||
RxDereference(SrvCall, LockHoldingState)
|
||||
|
||||
#define RxReferenceNetRoot(NetRoot) \
|
||||
RxpTrackReference(RDBSS_REF_TRACK_NETROOT, __FILE__, __LINE__, NetRoot); \
|
||||
RxReference(NetRoot)
|
||||
#define RxReferenceNetRoot(NetRoot) \
|
||||
RxpTrackReference(RDBSS_REF_TRACK_NETROOT, __FILE__, __LINE__, NetRoot); \
|
||||
RxReference(NetRoot)
|
||||
|
||||
#define RxDereferenceNetRoot(NetRoot, LockHoldingState) \
|
||||
RxpTrackDereference(RDBSS_REF_TRACK_NETROOT, __FILE__, __LINE__, NetRoot); \
|
||||
RxDereference(NetRoot, LockHoldingState)
|
||||
#define RxDereferenceNetRoot(NetRoot, LockHoldingState) \
|
||||
RxpTrackDereference(RDBSS_REF_TRACK_NETROOT, __FILE__, __LINE__, NetRoot); \
|
||||
RxDereference(NetRoot, LockHoldingState)
|
||||
|
||||
#define RxReferenceVNetRoot(VNetRoot) \
|
||||
RxpTrackReference(RDBSS_REF_TRACK_VNETROOT, __FILE__, __LINE__, VNetRoot); \
|
||||
RxReference(VNetRoot)
|
||||
#define RxReferenceVNetRoot(VNetRoot) \
|
||||
RxpTrackReference(RDBSS_REF_TRACK_VNETROOT, __FILE__, __LINE__, VNetRoot); \
|
||||
RxReference(VNetRoot)
|
||||
|
||||
#define RxDereferenceVNetRoot(VNetRoot, LockHoldingState) \
|
||||
RxpTrackDereference(RDBSS_REF_TRACK_VNETROOT, __FILE__, __LINE__, VNetRoot); \
|
||||
RxDereference(VNetRoot, LockHoldingState)
|
||||
#define RxDereferenceVNetRoot(VNetRoot, LockHoldingState) \
|
||||
RxpTrackDereference(RDBSS_REF_TRACK_VNETROOT, __FILE__, __LINE__, VNetRoot); \
|
||||
RxDereference(VNetRoot, LockHoldingState)
|
||||
|
||||
#define RxDereferenceNetFobx(Fobx, LockHoldingState) \
|
||||
RxpTrackDereference(RDBSS_REF_TRACK_NETFOBX, __FILE__, __LINE__, Fobx); \
|
||||
RxDereference(Fobx, LockHoldingState)
|
||||
#define RxReferenceNetFobx(Fobx) \
|
||||
RxpTrackReference(RDBSS_REF_TRACK_NETFOBX, __FILE__, __LINE__, Fobx); \
|
||||
RxReference(Fobx)
|
||||
|
||||
#define RxReferenceSrvOpen(SrvOpen) \
|
||||
RxpTrackReference(RDBSS_REF_TRACK_SRVOPEN, __FILE__, __LINE__, SrvOpen); \
|
||||
RxReference(SrvOpen)
|
||||
#define RxDereferenceNetFobx(Fobx, LockHoldingState) \
|
||||
RxpTrackDereference(RDBSS_REF_TRACK_NETFOBX, __FILE__, __LINE__, Fobx); \
|
||||
RxDereference(Fobx, LockHoldingState)
|
||||
|
||||
#define RxDereferenceSrvOpen(SrvOpen, LockHoldingState) \
|
||||
RxpTrackDereference(RDBSS_REF_TRACK_SRVOPEN, __FILE__, __LINE__, SrvOpen); \
|
||||
RxDereference(SrvOpen, LockHoldingState)
|
||||
#define RxReferenceSrvOpen(SrvOpen) \
|
||||
RxpTrackReference(RDBSS_REF_TRACK_SRVOPEN, __FILE__, __LINE__, SrvOpen); \
|
||||
RxReference(SrvOpen)
|
||||
|
||||
#define RxReferenceNetFcb(Fcb) \
|
||||
(RxpTrackReference(RDBSS_REF_TRACK_NETFCB, __FILE__, __LINE__, Fcb), \
|
||||
RxpReferenceNetFcb(Fcb))
|
||||
#define RxDereferenceSrvOpen(SrvOpen, LockHoldingState) \
|
||||
RxpTrackDereference(RDBSS_REF_TRACK_SRVOPEN, __FILE__, __LINE__, SrvOpen); \
|
||||
RxDereference(SrvOpen, LockHoldingState)
|
||||
|
||||
#define RxDereferenceNetFcb(Fcb) \
|
||||
((LONG)RxpTrackDereference(RDBSS_REF_TRACK_NETFCB, __FILE__, __LINE__, Fcb), \
|
||||
RxpDereferenceNetFcb(Fcb))
|
||||
#define RxReferenceNetFcb(Fcb) \
|
||||
(RxpTrackReference(RDBSS_REF_TRACK_NETFCB, __FILE__, __LINE__, Fcb), \
|
||||
RxpReferenceNetFcb(Fcb))
|
||||
|
||||
#define RxDereferenceAndFinalizeNetFcb(Fcb, RxContext, RecursiveFinalize, ForceFinalize) \
|
||||
(RxpTrackDereference(RDBSS_REF_TRACK_NETFCB, __FILE__, __LINE__, Fcb), \
|
||||
RxpDereferenceAndFinalizeNetFcb(Fcb, RxContext, RecursiveFinalize, ForceFinalize))
|
||||
#define RxDereferenceNetFcb(Fcb) \
|
||||
((LONG)RxpTrackDereference(RDBSS_REF_TRACK_NETFCB, __FILE__, __LINE__, Fcb), \
|
||||
RxpDereferenceNetFcb(Fcb))
|
||||
|
||||
#define RxDereferenceAndFinalizeNetFcb(Fcb, RxContext, RecursiveFinalize, ForceFinalize) \
|
||||
(RxpTrackDereference(RDBSS_REF_TRACK_NETFCB, __FILE__, __LINE__, Fcb), \
|
||||
RxpDereferenceAndFinalizeNetFcb(Fcb, RxContext, RecursiveFinalize, ForceFinalize))
|
||||
|
||||
PSRV_CALL
|
||||
RxCreateSrvCall(
|
||||
@ -533,6 +553,10 @@ RxFinishFcbInitialization(
|
||||
#define RxWaitForStableSrvOpen(S, R) RxWaitForStableCondition(&(S)->Condition, &(S)->TransitionWaitList, (R), NULL)
|
||||
#define RxTransitionSrvOpen(S, C) RxUpdateCondition((C), &(S)->Condition, &(S)->TransitionWaitList)
|
||||
|
||||
VOID
|
||||
RxRemoveNameNetFcb(
|
||||
_Out_ PFCB ThisFcb);
|
||||
|
||||
LONG
|
||||
RxpReferenceNetFcb(
|
||||
_In_ PFCB Fcb);
|
||||
@ -616,6 +640,16 @@ RxFinalizeNetFobx(
|
||||
#define TRACKER_RELEASE_NON_EXCL_FCB_FOR_THRD_BUFF_PENDING 0x72727430
|
||||
#define TRACKER_RELEASE_EXCL_FCB_FOR_THRD_BUFF_PENDING 0x72727431
|
||||
#define TRACKER_FCB_FREE 0x72724372
|
||||
|
||||
#define FCB_STATE_BUFFERING_STATE_WITH_NO_SHARES \
|
||||
(( FCB_STATE_WRITECACHING_ENABLED \
|
||||
| FCB_STATE_WRITEBUFFERING_ENABLED \
|
||||
| FCB_STATE_READCACHING_ENABLED \
|
||||
| FCB_STATE_READBUFFERING_ENABLED \
|
||||
| FCB_STATE_LOCK_BUFFERING_ENABLED \
|
||||
| FCB_STATE_FILESIZECACHEING_ENABLED \
|
||||
| FCB_STATE_FILETIMECACHEING_ENABLED))
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -132,7 +132,9 @@ typedef struct _MRX_FCB_
|
||||
#define SRVOPEN_FLAG_CLOSE_DELAYED 0x8
|
||||
#define SRVOPEN_FLAG_FILE_RENAMED 0x10
|
||||
#define SRVOPEN_FLAG_FILE_DELETED 0x20
|
||||
#define SRVOPEN_FLAG_BUFFERING_STATE_CHANGE_PENDING 0x40
|
||||
#define SRVOPEN_FLAG_COLLAPSING_DISABLED 0x80
|
||||
#define SRVOPEN_FLAG_BUFFERING_STATE_CHANGE_REQUESTS_PURGED 0x100
|
||||
#define SRVOPEN_FLAG_NO_BUFFERING_STATE_CHANGE 0x200
|
||||
#define SRVOPEN_FLAG_ORPHANED 0x400
|
||||
|
||||
|
@ -42,6 +42,7 @@ typedef enum _RX_FILE_TYPE
|
||||
#define RDBSS_NTC_STORAGE_TYPE_DIRECTORY ((NODE_TYPE_CODE)0xec02)
|
||||
#define RDBSS_NTC_STORAGE_TYPE_FILE ((NODE_TYPE_CODE)0xec03)
|
||||
#define RDBSS_NTC_OPENTARGETDIR_FCB ((NODE_TYPE_CODE)0xecff)
|
||||
#define RDBSS_NTC_IPC_SHARE ((NODE_TYPE_CODE)0xecfe)
|
||||
#define RDBSS_NTC_MAILSLOT ((NODE_TYPE_CODE)0xecfd)
|
||||
#define RDBSS_NTC_SPOOLFILE ((NODE_TYPE_CODE)0xecfc)
|
||||
#define RDBSS_NTC_SRVCALL ((NODE_TYPE_CODE)0xeb10)
|
||||
|
@ -428,6 +428,18 @@ RxRemoveFirstContextFromSerializationQueue(
|
||||
InitializeListHead((Source)); \
|
||||
}
|
||||
|
||||
#define RxTransferListWithMutex(Destination, Source, Mutex) \
|
||||
{ \
|
||||
ExAcquireFastMutex(Mutex); \
|
||||
RxTransferList(Destination, Source); \
|
||||
ExReleaseFastMutex(Mutex); \
|
||||
}
|
||||
|
||||
VOID
|
||||
RxCancelNotifyChangeDirectoryRequestsForFobx(
|
||||
PFOBX Fobx
|
||||
);
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
RxInitializeContext(
|
||||
@ -472,4 +484,8 @@ RxResumeBlockedOperations_Serially(
|
||||
_Inout_ PRX_CONTEXT RxContext,
|
||||
_Inout_ PLIST_ENTRY BlockingIoQ);
|
||||
|
||||
VOID
|
||||
RxResumeBlockedOperations_ALL(
|
||||
_Inout_ PRX_CONTEXT RxContext);
|
||||
|
||||
#endif
|
||||
|
@ -469,6 +469,10 @@ VOID
|
||||
RxUpdateShareAccessPerSrvOpens(
|
||||
_In_ PSRV_OPEN SrvOpen);
|
||||
|
||||
VOID
|
||||
RxRemoveShareAccessPerSrvOpens(
|
||||
_Inout_ PSRV_OPEN SrvOpen);
|
||||
|
||||
#if DBG
|
||||
NTSTATUS
|
||||
RxCheckShareAccess(
|
||||
@ -528,10 +532,33 @@ ULONG
|
||||
RxGetNetworkProviderPriority(
|
||||
_In_ PUNICODE_STRING DeviceName);
|
||||
|
||||
VOID
|
||||
RxPrepareRequestForReuse(
|
||||
PCHANGE_BUFFERING_STATE_REQUEST Request);
|
||||
|
||||
VOID
|
||||
RxpDiscardChangeBufferingStateRequests(
|
||||
_Inout_ PLIST_ENTRY DiscardedRequests);
|
||||
|
||||
VOID
|
||||
RxGatherRequestsForSrvOpen(
|
||||
_Inout_ PSRV_CALL SrvCall,
|
||||
_In_ PSRV_OPEN SrvOpen,
|
||||
_Inout_ PLIST_ENTRY RequestsListHead);
|
||||
|
||||
NTSTATUS
|
||||
RxpLookupSrvOpenForRequestLite(
|
||||
_In_ PSRV_CALL SrvCall,
|
||||
_Inout_ PCHANGE_BUFFERING_STATE_REQUEST Request);
|
||||
|
||||
VOID
|
||||
RxProcessChangeBufferingStateRequestsForSrvOpen(
|
||||
PSRV_OPEN SrvOpen);
|
||||
|
||||
NTSTATUS
|
||||
RxPurgeFobxFromCache(
|
||||
PFOBX FobxToBePurged);
|
||||
|
||||
VOID
|
||||
RxUndoScavengerFinalizationMarking(
|
||||
PVOID Instance);
|
||||
|
@ -8,6 +8,15 @@ typedef struct _RX_WORK_ITEM_
|
||||
ULONG Options;
|
||||
} RX_WORK_ITEM, *PRX_WORK_ITEM;
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
RxPostOneShotTimerRequest(
|
||||
_In_ PRDBSS_DEVICE_OBJECT pDeviceObject,
|
||||
_In_ PRX_WORK_ITEM pWorkItem,
|
||||
_In_ PRX_WORKERTHREAD_ROUTINE Routine,
|
||||
_In_ PVOID pContext,
|
||||
_In_ LARGE_INTEGER TimeInterval);
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
RxInitializeRxTimer(
|
||||
|
@ -116,6 +116,10 @@ BOOLEAN
|
||||
RxScavengeRelatedFobxs(
|
||||
_In_ PFCB Fcb);
|
||||
|
||||
VOID
|
||||
RxpMarkInstanceForScavengedFinalization(
|
||||
PVOID Instance);
|
||||
|
||||
VOID
|
||||
RxpUndoScavengerFinalizationMarking(
|
||||
_In_ PVOID Instance);
|
||||
|
7
reactos/sdk/lib/drivers/copysup/CMakeLists.txt
Normal file
7
reactos/sdk/lib/drivers/copysup/CMakeLists.txt
Normal file
@ -0,0 +1,7 @@
|
||||
add_definitions(-DUNICODE -D_UNICODE)
|
||||
|
||||
list(APPEND SOURCE
|
||||
copysup.c)
|
||||
|
||||
add_library(copysup ${SOURCE})
|
||||
add_dependencies(copysup bugcodes xdk)
|
182
reactos/sdk/lib/drivers/copysup/copysup.c
Normal file
182
reactos/sdk/lib/drivers/copysup/copysup.c
Normal file
@ -0,0 +1,182 @@
|
||||
/*
|
||||
* ReactOS kernel
|
||||
* Copyright (C) 2017 ReactOS Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: sdk/lib/drivers/copysup/copysup.c
|
||||
* PURPOSE: CopySup library
|
||||
* PROGRAMMER: Pierre Schweitzer (pierre@reactos.org)
|
||||
*/
|
||||
|
||||
/* INCLUDES *****************************************************************/
|
||||
|
||||
#include "copysup.h"
|
||||
#include <pseh/pseh2.h>
|
||||
|
||||
/* FUNCTIONS ****************************************************************/
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
BOOLEAN
|
||||
FsRtlCopyRead2(
|
||||
IN PFILE_OBJECT FileObject,
|
||||
IN PLARGE_INTEGER FileOffset,
|
||||
IN ULONG Length,
|
||||
IN BOOLEAN Wait,
|
||||
IN ULONG LockKey,
|
||||
OUT PVOID Buffer,
|
||||
OUT PIO_STATUS_BLOCK IoStatus,
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PVOID TopLevelContext)
|
||||
{
|
||||
BOOLEAN Ret;
|
||||
ULONG PageCount;
|
||||
LARGE_INTEGER FinalOffset;
|
||||
PFSRTL_COMMON_FCB_HEADER Fcb;
|
||||
PFAST_IO_DISPATCH FastIoDispatch;
|
||||
PDEVICE_OBJECT RelatedDeviceObject;
|
||||
|
||||
PAGED_CODE();
|
||||
|
||||
Ret = TRUE;
|
||||
PageCount = ADDRESS_AND_SIZE_TO_SPAN_PAGES(FileOffset, Length);
|
||||
|
||||
/* Null-length read is always OK */
|
||||
if (Length == 0)
|
||||
{
|
||||
IoStatus->Information = 0;
|
||||
IoStatus->Status = STATUS_SUCCESS;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Check we don't overflow */
|
||||
FinalOffset.QuadPart = FileOffset->QuadPart + Length;
|
||||
if (FinalOffset.QuadPart <= 0)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Get the FCB (at least, its header) */
|
||||
Fcb = FileObject->FsContext;
|
||||
|
||||
FsRtlEnterFileSystem();
|
||||
|
||||
/* Acquire its resource (shared) */
|
||||
if (Wait)
|
||||
{
|
||||
ExAcquireResourceSharedLite(Fcb->Resource, TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!ExAcquireResourceSharedLite(Fcb->Resource, FALSE))
|
||||
{
|
||||
Ret = FALSE;
|
||||
goto CriticalSection;
|
||||
}
|
||||
}
|
||||
|
||||
/* If cache wasn't initialized, or FastIO isn't possible, fail */
|
||||
if (FileObject->PrivateCacheMap == NULL || Fcb->IsFastIoPossible == FastIoIsNotPossible)
|
||||
{
|
||||
Ret = FALSE;
|
||||
goto Resource;
|
||||
}
|
||||
|
||||
/* If FastIO is questionable, then, question! */
|
||||
if (Fcb->IsFastIoPossible == FastIoIsQuestionable)
|
||||
{
|
||||
RelatedDeviceObject = IoGetRelatedDeviceObject(FileObject);
|
||||
FastIoDispatch = RelatedDeviceObject->DriverObject->FastIoDispatch;
|
||||
ASSERT(FastIoDispatch != NULL);
|
||||
ASSERT(FastIoDispatch->FastIoCheckIfPossible != NULL);
|
||||
|
||||
/* If it's not possible, then fail */
|
||||
if (!FastIoDispatch->FastIoCheckIfPossible(FileObject, FileOffset, Length,
|
||||
Wait, LockKey, TRUE, IoStatus, RelatedDeviceObject))
|
||||
{
|
||||
Ret = FALSE;
|
||||
goto Resource;
|
||||
}
|
||||
}
|
||||
|
||||
/* If we get beyond file end... */
|
||||
if (FinalOffset.QuadPart > Fcb->FileSize.QuadPart)
|
||||
{
|
||||
/* Fail if the offset was already beyond file end */
|
||||
if (FileOffset->QuadPart >= Fcb->FileSize.QuadPart)
|
||||
{
|
||||
IoStatus->Information = 0;
|
||||
IoStatus->Status = STATUS_END_OF_FILE;
|
||||
goto Resource;
|
||||
}
|
||||
|
||||
/* Otherwise, just fix read length */
|
||||
Length = (ULONG)(Fcb->FileSize.QuadPart - FileOffset->QuadPart);
|
||||
}
|
||||
|
||||
/* Set caller provided context as TLI */
|
||||
IoSetTopLevelIrp(TopLevelContext);
|
||||
|
||||
_SEH2_TRY
|
||||
{
|
||||
/* If we cannot wait, or if file is bigger than 4GB */
|
||||
if (!Wait || (FinalOffset.HighPart | Fcb->FileSize.HighPart) != 0)
|
||||
{
|
||||
/* Forward to Cc */
|
||||
Ret = CcCopyRead(FileObject, FileOffset, Length, Wait, Buffer, IoStatus);
|
||||
SetFlag(FileObject->Flags, FO_FILE_FAST_IO_READ);
|
||||
|
||||
/* Validate output */
|
||||
ASSERT(!Ret || (IoStatus->Status == STATUS_END_OF_FILE) || (((ULONGLONG)FileOffset->QuadPart + IoStatus->Information) <= (ULONGLONG)Fcb->FileSize.QuadPart));
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Forward to Cc */
|
||||
CcFastCopyRead(FileObject, FileOffset->LowPart, Length, PageCount, Buffer, IoStatus);
|
||||
SetFlag(FileObject->Flags, FO_FILE_FAST_IO_READ);
|
||||
|
||||
/* Validate output */
|
||||
ASSERT((IoStatus->Status == STATUS_END_OF_FILE) || ((FileOffset->LowPart + IoStatus->Information) <= Fcb->FileSize.LowPart));
|
||||
}
|
||||
|
||||
/* If read was successful, update the byte offset in the FO */
|
||||
if (Ret)
|
||||
{
|
||||
FileObject->CurrentByteOffset.QuadPart = FileOffset->QuadPart + IoStatus->Information;
|
||||
}
|
||||
}
|
||||
_SEH2_EXCEPT(FsRtlIsNtstatusExpected(_SEH2_GetExceptionCode()) ?
|
||||
EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH)
|
||||
{
|
||||
Ret = FALSE;
|
||||
}
|
||||
_SEH2_END;
|
||||
|
||||
/* Reset TLI */
|
||||
IoSetTopLevelIrp(NULL);
|
||||
|
||||
Resource:
|
||||
ExReleaseResourceLite(Fcb->Resource);
|
||||
CriticalSection:
|
||||
FsRtlExitFileSystem();
|
||||
|
||||
return Ret;
|
||||
}
|
18
reactos/sdk/lib/drivers/copysup/copysup.h
Normal file
18
reactos/sdk/lib/drivers/copysup/copysup.h
Normal file
@ -0,0 +1,18 @@
|
||||
#ifndef _COPYSUP_H_
|
||||
#define _COPYSUP_H_
|
||||
|
||||
#include <ntifs.h>
|
||||
|
||||
BOOLEAN
|
||||
FsRtlCopyRead2(
|
||||
_In_ PFILE_OBJECT FileObject,
|
||||
_In_ PLARGE_INTEGER FileOffset,
|
||||
_In_ ULONG Length,
|
||||
_In_ BOOLEAN Wait,
|
||||
_In_ ULONG LockKey,
|
||||
_Out_ PVOID Buffer,
|
||||
_Out_ PIO_STATUS_BLOCK IoStatus,
|
||||
_In_ PDEVICE_OBJECT DeviceObject,
|
||||
_In_ PVOID TopLevelContext);
|
||||
|
||||
#endif
|
@ -30,6 +30,7 @@
|
||||
#include <pseh/pseh2.h>
|
||||
#include <limits.h>
|
||||
#include <dfs.h>
|
||||
#include <copysup.h>
|
||||
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
@ -357,6 +358,11 @@ RxpQueryInfoMiniRdr(
|
||||
FILE_INFORMATION_CLASS FileInfoClass,
|
||||
PVOID Buffer);
|
||||
|
||||
VOID
|
||||
RxPurgeNetFcb(
|
||||
PFCB Fcb,
|
||||
PRX_CONTEXT LocalContext);
|
||||
|
||||
NTSTATUS
|
||||
RxQueryAlternateNameInfo(
|
||||
PRX_CONTEXT RxContext,
|
||||
@ -779,6 +785,13 @@ RxAllocateCanonicalNameBuffer(
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
VOID
|
||||
RxCancelNotifyChangeDirectoryRequestsForFobx(
|
||||
PFOBX Fobx)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
RxCancelRoutine(
|
||||
@ -971,17 +984,6 @@ RxCanonicalizeNameAndObtainNetRoot(
|
||||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
RxChangeBufferingState(
|
||||
PSRV_OPEN SrvOpen,
|
||||
PVOID Context,
|
||||
BOOLEAN ComputeNewState)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
RxCheckFcbStructuresForAlignment(
|
||||
@ -1058,13 +1060,202 @@ RxCheckShareAccessPerSrvOpens(
|
||||
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;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1258,9 +1449,12 @@ RxCommonCleanup(
|
||||
#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();
|
||||
|
||||
@ -1300,6 +1494,8 @@ RxCommonCleanup(
|
||||
return Status;
|
||||
}
|
||||
|
||||
FcbAcquired = TRUE;
|
||||
|
||||
Fobx->AssociatedFileObject = NULL;
|
||||
|
||||
/* In case SRV_OPEN used is part of FCB */
|
||||
@ -1326,8 +1522,186 @@ RxCommonCleanup(
|
||||
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
|
||||
}
|
||||
|
||||
@ -3234,6 +3608,96 @@ RxFastIoCheckIfPossible(
|
||||
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;
|
||||
}
|
||||
@ -3263,6 +3727,9 @@ RxFastIoDeviceControl(
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
RxFastIoRead(
|
||||
@ -3275,8 +3742,32 @@ 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
|
||||
@ -4399,15 +4890,6 @@ RxInitializeRegistrationStructures(
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
RxInitializeRxTimer(
|
||||
VOID)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
@ -5022,6 +5504,28 @@ RxpUnregisterMinirdr(
|
||||
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,
|
||||
@ -5610,6 +6114,9 @@ RxRemoveOverflowEntry(
|
||||
return Context;
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
VOID
|
||||
RxRemoveShareAccess(
|
||||
_Inout_ PFILE_OBJECT FileObject,
|
||||
@ -5617,7 +6124,58 @@ RxRemoveShareAccess(
|
||||
_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
|
||||
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user