Skip to content

Commit

Permalink
Library - Get the latest UserContext during Close
Browse files Browse the repository at this point in the history
Close is called when all events are done and we get  a kernel close request.
The kernel can issue an event (GetFileInfo) but actually do not wait for its completion and directly send a close. We will have a race condition in ReleaseDokanOpenInfo where the DokanFileInfo might have the GetFileInfo UserContext and not the Cleanup UserContext that is expected to happen before Close.

This change enforce to get the latest UserContext we can get from DokanOpenInfo. Yes, it does not prevent the GetFileInfo to be the latest to set UserContext in EventCompletion but that's the best we can do.
  • Loading branch information
Liryna committed Mar 6, 2022
1 parent ed61a3e commit b8ac392
Showing 1 changed file with 15 additions and 15 deletions.
30 changes: 15 additions & 15 deletions dokan/dokan.c
Original file line number Diff line number Diff line change
Expand Up @@ -963,26 +963,26 @@ VOID CreateDispatchCommon(PDOKAN_IO_EVENT IoEvent, ULONG SizeOfEventInfo, BOOL U
}

VOID ReleaseDokanOpenInfo(PDOKAN_IO_EVENT IoEvent) {
LPWSTR fileNameForClose = NULL;

EnterCriticalSection(&IoEvent->DokanOpenInfo->CriticalSection);
IoEvent->DokanOpenInfo->OpenCount--;
if (IoEvent->DokanOpenInfo->OpenCount < 1) {
if (IoEvent->DokanOpenInfo->FileName) {
fileNameForClose = IoEvent->DokanOpenInfo->FileName;
IoEvent->DokanOpenInfo->FileName = NULL;
}
LeaveCriticalSection(&IoEvent->DokanOpenInfo->CriticalSection);
PushFileOpenInfo(IoEvent->DokanOpenInfo);
IoEvent->DokanOpenInfo = NULL;
if (IoEvent->EventResult) {
// Reset the Kernel UserContext if we can. Close events do not have one.
IoEvent->EventResult->Context = 0;
}
} else {
if (IoEvent->DokanOpenInfo->OpenCount > 0) {
LeaveCriticalSection(&IoEvent->DokanOpenInfo->CriticalSection);
return;
}

LPWSTR fileNameForClose = NULL;
if (IoEvent->DokanOpenInfo->FileName) {
fileNameForClose = IoEvent->DokanOpenInfo->FileName;
IoEvent->DokanOpenInfo->FileName = NULL;
}
IoEvent->DokanFileInfo.Context =IoEvent->DokanOpenInfo->UserContext;
LeaveCriticalSection(&IoEvent->DokanOpenInfo->CriticalSection);
PushFileOpenInfo(IoEvent->DokanOpenInfo);
IoEvent->DokanOpenInfo = NULL;
if (IoEvent->EventResult) {
// Reset the Kernel UserContext if we can. Close events do not have one.
IoEvent->EventResult->Context = 0;
}
if (fileNameForClose) {
if (IoEvent->DokanInstance->DokanOperations->CloseFile) {
IoEvent->DokanInstance->DokanOperations->CloseFile(
Expand Down

0 comments on commit b8ac392

Please sign in to comment.