@@ -274,9 +274,8 @@ VOID SetupIOEventForProcessing(PDOKAN_IO_EVENT IoEvent) {
274
274
if (IoEvent -> DokanOpenInfo ) {
275
275
EnterCriticalSection (& IoEvent -> DokanOpenInfo -> CriticalSection );
276
276
IoEvent -> DokanOpenInfo -> OpenCount ++ ;
277
+ IoEvent -> DokanFileInfo .Context = IoEvent -> DokanOpenInfo -> UserContext ;
277
278
LeaveCriticalSection (& IoEvent -> DokanOpenInfo -> CriticalSection );
278
- IoEvent -> DokanFileInfo .Context =
279
- InterlockedAdd64 (& IoEvent -> DokanOpenInfo -> UserContext , 0 );
280
279
IoEvent -> DokanFileInfo .IsDirectory =
281
280
(UCHAR )IoEvent -> DokanOpenInfo -> IsDirectory ;
282
281
@@ -879,11 +878,7 @@ VOID ALIGN_ALLOCATION_SIZE(PLARGE_INTEGER size, PDOKAN_OPTIONS DokanOptions) {
879
878
880
879
VOID EventCompletion (PDOKAN_IO_EVENT IoEvent ) {
881
880
assert (IoEvent -> EventResult );
882
- if (IoEvent -> DokanOpenInfo ) {
883
- InterlockedExchange64 (& IoEvent -> DokanOpenInfo -> UserContext ,
884
- IoEvent -> DokanFileInfo .Context );
885
- ReleaseDokanOpenInfo (IoEvent );
886
- }
881
+ ReleaseDokanOpenInfo (IoEvent );
887
882
}
888
883
889
884
VOID CheckFileName (LPWSTR FileName ) {
@@ -963,26 +958,38 @@ VOID CreateDispatchCommon(PDOKAN_IO_EVENT IoEvent, ULONG SizeOfEventInfo, BOOL U
963
958
}
964
959
965
960
VOID ReleaseDokanOpenInfo (PDOKAN_IO_EVENT IoEvent ) {
966
- LPWSTR fileNameForClose = NULL ;
967
-
961
+ if (!IoEvent -> DokanOpenInfo ) {
962
+ return ;
963
+ }
968
964
EnterCriticalSection (& IoEvent -> DokanOpenInfo -> CriticalSection );
965
+ IoEvent -> DokanOpenInfo -> UserContext = IoEvent -> DokanFileInfo .Context ;
969
966
IoEvent -> DokanOpenInfo -> OpenCount -- ;
970
- if (IoEvent -> DokanOpenInfo -> OpenCount < 1 ) {
971
- if (IoEvent -> DokanOpenInfo -> FileName ) {
972
- fileNameForClose = IoEvent -> DokanOpenInfo -> FileName ;
973
- IoEvent -> DokanOpenInfo -> FileName = NULL ;
974
- }
975
- LeaveCriticalSection (& IoEvent -> DokanOpenInfo -> CriticalSection );
976
- PushFileOpenInfo (IoEvent -> DokanOpenInfo );
977
- IoEvent -> DokanOpenInfo = NULL ;
978
- if (IoEvent -> EventResult ) {
979
- // Reset the Kernel UserContext if we can. Close events do not have one.
980
- IoEvent -> EventResult -> Context = 0 ;
981
- }
982
- } else {
967
+ if (IoEvent -> EventContext -> MajorFunction == IRP_MJ_CLOSE ) {
968
+ IoEvent -> DokanOpenInfo -> CloseFileName =
969
+ _wcsdup (IoEvent -> EventContext -> Operation .Close .FileName );
970
+ IoEvent -> DokanOpenInfo -> CloseUserContext = IoEvent -> DokanFileInfo .Context ;
971
+ IoEvent -> DokanOpenInfo -> OpenCount -- ;
972
+ }
973
+ if (IoEvent -> DokanOpenInfo -> OpenCount > 0 ) {
974
+ // We are still waiting for the Close event or there is another event running. We delay the Close event.
983
975
LeaveCriticalSection (& IoEvent -> DokanOpenInfo -> CriticalSection );
976
+ return ;
984
977
}
985
978
979
+ // Process close event as OpenCount is now 0
980
+ LPWSTR fileNameForClose = NULL ;
981
+ if (IoEvent -> DokanOpenInfo -> CloseFileName ) {
982
+ fileNameForClose = IoEvent -> DokanOpenInfo -> CloseFileName ;
983
+ IoEvent -> DokanOpenInfo -> CloseFileName = NULL ;
984
+ }
985
+ IoEvent -> DokanFileInfo .Context = IoEvent -> DokanOpenInfo -> CloseUserContext ;
986
+ LeaveCriticalSection (& IoEvent -> DokanOpenInfo -> CriticalSection );
987
+ PushFileOpenInfo (IoEvent -> DokanOpenInfo );
988
+ IoEvent -> DokanOpenInfo = NULL ;
989
+ if (IoEvent -> EventResult ) {
990
+ // Reset the Kernel UserContext if we can. Close events do not have one.
991
+ IoEvent -> EventResult -> Context = 0 ;
992
+ }
986
993
if (fileNameForClose ) {
987
994
if (IoEvent -> DokanInstance -> DokanOperations -> CloseFile ) {
988
995
IoEvent -> DokanInstance -> DokanOperations -> CloseFile (
0 commit comments