Skip to content

Commit

Permalink
Initial commit for async IO support dokan-dev#210
Browse files Browse the repository at this point in the history
More or less rewrote all of dokan.dll to support async IO.
Rewrote the Mirror example to support the new Dokan API. Still need to add async IO support.
User-mode drivers can reeturn STATUS_PENDING to indicate they are performing an async operation at which point they are responsible for calling EndDispatch*() to notify the driver that the operation has completed.
Still some known issues that need to be fixed.
  • Loading branch information
Keith Newton committed Aug 1, 2016
1 parent ac20f52 commit 1766d8c
Show file tree
Hide file tree
Showing 29 changed files with 4,589 additions and 2,675 deletions.
28 changes: 12 additions & 16 deletions dokan/access.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,55 +22,51 @@ with this program. If not, see <http://www.gnu.org/licenses/>.
#include "dokani.h"
#include "fileinfo.h"

HANDLE DOKANAPI DokanOpenRequestorToken(PDOKAN_FILE_INFO FileInfo) {
HANDLE DOKANAPI DokanOpenRequestorToken(PDOKAN_CREATE_FILE_EVENT FileInfo) {

PDOKAN_IO_EVENT ioEvent = (PDOKAN_IO_EVENT)FileInfo;
BOOL status;
ULONG returnedLength;
PDOKAN_INSTANCE instance;
PDOKAN_OPEN_INFO openInfo;
PEVENT_CONTEXT eventContext;
PEVENT_INFORMATION eventInfo;
HANDLE handle = INVALID_HANDLE_VALUE;
ULONG eventInfoSize;
WCHAR rawDeviceName[MAX_PATH];

openInfo = (PDOKAN_OPEN_INFO)(UINT_PTR)FileInfo->DokanContext;
if (openInfo == NULL) {
if (ioEvent->DokanOpenInfo == NULL) {
return INVALID_HANDLE_VALUE;
}

eventContext = openInfo->EventContext;
if (eventContext == NULL) {
if (ioEvent->DokanInstance == NULL) {
return INVALID_HANDLE_VALUE;
}

instance = openInfo->DokanInstance;
if (instance == NULL) {
return INVALID_HANDLE_VALUE;
}

if (eventContext->MajorFunction != IRP_MJ_CREATE) {
if (ioEvent->KernelInfo.EventContext.MajorFunction != IRP_MJ_CREATE) {
return INVALID_HANDLE_VALUE;
}

eventInfoSize = sizeof(EVENT_INFORMATION);
eventInfo = (PEVENT_INFORMATION)malloc(eventInfoSize);

if (eventInfo == NULL) {
return INVALID_HANDLE_VALUE;
}

RtlZeroMemory(eventInfo, eventInfoSize);

eventInfo->SerialNumber = eventContext->SerialNumber;
eventInfo->SerialNumber = ioEvent->KernelInfo.EventContext.SerialNumber;

status = SendToDevice(
GetRawDeviceName(instance->DeviceName, rawDeviceName, MAX_PATH),
GetRawDeviceName(ioEvent->DokanInstance->DeviceName, rawDeviceName, MAX_PATH),
IOCTL_GET_ACCESS_TOKEN, eventInfo, eventInfoSize, eventInfo,
eventInfoSize, &returnedLength);

if (status) {
handle = eventInfo->Operation.AccessToken.Handle;
} else {
DbgPrintW(L"IOCTL_GET_ACCESS_TOKEN failed\n");
}

free(eventInfo);

return handle;
}
37 changes: 16 additions & 21 deletions dokan/cleanup.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,33 +22,28 @@ with this program. If not, see <http://www.gnu.org/licenses/>.
#include "dokani.h"
#include "fileinfo.h"

VOID DispatchCleanup(HANDLE Handle, PEVENT_CONTEXT EventContext,
PDOKAN_INSTANCE DokanInstance) {
PEVENT_INFORMATION eventInfo;
DOKAN_FILE_INFO fileInfo;
PDOKAN_OPEN_INFO openInfo;
ULONG sizeOfEventInfo = sizeof(EVENT_INFORMATION);
void DispatchCleanup(DOKAN_IO_EVENT *EventInfo) {

CheckFileName(EventContext->Operation.Cleanup.FileName);
PDOKAN_INSTANCE dokan = EventInfo->DokanInstance;
DOKAN_CLEANUP_EVENT *cleanupFileEvent = &EventInfo->EventInfo.Cleanup;

eventInfo = DispatchCommon(EventContext, sizeOfEventInfo, DokanInstance,
&fileInfo, &openInfo);
CheckFileName(EventInfo->KernelInfo.EventContext.Operation.Cleanup.FileName);

eventInfo->Status = STATUS_SUCCESS; // return success at any case
CreateDispatchCommon(EventInfo, 0);

DbgPrint("###Cleanup %04d\n", openInfo != NULL ? openInfo->EventId : -1);
EventInfo->EventResult->Status = STATUS_SUCCESS; // return success at any case

if (DokanInstance->DokanOperations->Cleanup) {
// ignore return value
DokanInstance->DokanOperations->Cleanup(
EventContext->Operation.Cleanup.FileName, &fileInfo);
}
DbgPrint("###Cleanup file handle = 0x%p, eventID = %04d\n",
EventInfo->DokanOpenInfo,
EventInfo->DokanOpenInfo != NULL ? EventInfo->DokanOpenInfo->EventId : -1);

if (openInfo != NULL)
openInfo->UserContext = fileInfo.Context;
if (dokan->DokanOperations->Cleanup) {

cleanupFileEvent->DokanFileInfo = &EventInfo->DokanFileInfo;
cleanupFileEvent->FileName = EventInfo->KernelInfo.EventContext.Operation.Close.FileName;

SendEventInformation(Handle, eventInfo, sizeOfEventInfo, DokanInstance);
dokan->DokanOperations->Cleanup(cleanupFileEvent);
}

free(eventInfo);
return;
SendIoEventResult(EventInfo);
}
44 changes: 19 additions & 25 deletions dokan/close.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,40 +22,34 @@ with this program. If not, see <http://www.gnu.org/licenses/>.
#include "dokani.h"
#include "fileinfo.h"

VOID DispatchClose(HANDLE Handle, PEVENT_CONTEXT EventContext,
PDOKAN_INSTANCE DokanInstance) {
PEVENT_INFORMATION eventInfo;
DOKAN_FILE_INFO fileInfo;
PDOKAN_OPEN_INFO openInfo;
ULONG sizeOfEventInfo = sizeof(EVENT_INFORMATION);
void DispatchClose(DOKAN_IO_EVENT *EventInfo) {

UNREFERENCED_PARAMETER(Handle);
PDOKAN_INSTANCE dokan = EventInfo->DokanInstance;
DOKAN_CLOSE_FILE_EVENT *closeFileEvent = &EventInfo->EventInfo.CloseFile;

CheckFileName(EventContext->Operation.Close.FileName);
CheckFileName(EventInfo->KernelInfo.EventContext.Operation.Close.FileName);

eventInfo = DispatchCommon(EventContext, sizeOfEventInfo, DokanInstance,
&fileInfo, &openInfo);
CreateDispatchCommon(EventInfo, 0);

eventInfo->Status = STATUS_SUCCESS; // return success at any case
EventInfo->EventResult->Status = STATUS_SUCCESS; // return success at any case

DbgPrint("###Close file handle = 0x%p, eventID = %04d\n",
EventInfo->DokanOpenInfo,
EventInfo->DokanOpenInfo != NULL ? EventInfo->DokanOpenInfo->EventId : -1);

DbgPrint("###Close %04d\n", openInfo != NULL ? openInfo->EventId : -1);
if (dokan->DokanOperations->CloseFile) {

if (DokanInstance->DokanOperations->CloseFile) {
// ignore return value
DokanInstance->DokanOperations->CloseFile(
EventContext->Operation.Close.FileName, &fileInfo);
closeFileEvent->DokanFileInfo = &EventInfo->DokanFileInfo;
closeFileEvent->FileName = EventInfo->KernelInfo.EventContext.Operation.Close.FileName;

dokan->DokanOperations->CloseFile(closeFileEvent);
}

// do not send it to the driver
// SendEventInformation(Handle, eventInfo, length);
if(EventInfo->DokanOpenInfo) {

if (openInfo != NULL) {
EnterCriticalSection(&DokanInstance->CriticalSection);
openInfo->OpenCount--;
LeaveCriticalSection(&DokanInstance->CriticalSection);
PushFileOpenInfo(EventInfo->DokanOpenInfo);
EventInfo->DokanOpenInfo = NULL;
}
ReleaseDokanOpenInfo(eventInfo, DokanInstance);
free(eventInfo);

return;
// do not send it to the driver
}
Loading

0 comments on commit 1766d8c

Please sign in to comment.