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); CheckFileName(EventContext->Operation.Cleanup.FileName); eventInfo = DispatchCommon(EventContext, sizeOfEventInfo, DokanInstance, &fileInfo, &openInfo); eventInfo->Status = STATUS_SUCCESS; // return success at any case DbgPrint("###Cleanup %04d\n", openInfo != NULL ? openInfo->EventId : -1); if (DokanInstance->DokanOperations->Cleanup) { // ignore return value DokanInstance->DokanOperations->Cleanup( EventContext->Operation.Cleanup.FileName, &fileInfo); } if (openInfo != NULL) openInfo->UserContext = fileInfo.Context; SendEventInformation(Handle, eventInfo, sizeOfEventInfo, DokanInstance); free(eventInfo); }
VOID DispatchQueryVolumeInformation( HANDLE Handle, PEVENT_CONTEXT EventContext, PDOKAN_INSTANCE DokanInstance) { PEVENT_INFORMATION eventInfo; DOKAN_FILE_INFO fileInfo; PDOKAN_OPEN_INFO openInfo; ULONG sizeOfEventInfo = sizeof(EVENT_INFORMATION) - 8 + EventContext->Operation.Volume.BufferLength; eventInfo = (PEVENT_INFORMATION)malloc(sizeOfEventInfo); if (eventInfo == NULL) { return; } RtlZeroMemory(eventInfo, sizeOfEventInfo); RtlZeroMemory(&fileInfo, sizeof(DOKAN_FILE_INFO)); // There is no Context because file is not opened // so DispatchCommon is not used here openInfo = (PDOKAN_OPEN_INFO)(INT_PTR)EventContext->Context; eventInfo->BufferLength = 0; eventInfo->SerialNumber = EventContext->SerialNumber; fileInfo.ProcessId = EventContext->ProcessId; fileInfo.DokanOptions = DokanInstance->DokanOptions; eventInfo->Status = STATUS_NOT_IMPLEMENTED; eventInfo->BufferLength = 0; DbgPrint("###QueryVolumeInfo %04d\n", openInfo ? openInfo->EventId : -1); switch (EventContext->Operation.Volume.FsInformationClass) { case FileFsVolumeInformation: eventInfo->Status = DokanFsVolumeInformation( eventInfo, EventContext, &fileInfo, DokanInstance->DokanOperations); break; case FileFsSizeInformation: eventInfo->Status = DokanFsSizeInformation( eventInfo, EventContext, &fileInfo, DokanInstance->DokanOperations); break; case FileFsAttributeInformation: eventInfo->Status = DokanFsAttributeInformation( eventInfo, EventContext, &fileInfo, DokanInstance->DokanOperations); break; case FileFsFullSizeInformation: eventInfo->Status = DokanFsFullSizeInformation( eventInfo, EventContext, &fileInfo, DokanInstance->DokanOperations); break; default: DbgPrint("error unknown volume info %d\n", EventContext->Operation.Volume.FsInformationClass); } SendEventInformation(Handle, eventInfo, sizeOfEventInfo, NULL); free(eventInfo); return; }
VOID DispatchWrite(HANDLE Handle, PEVENT_CONTEXT EventContext, PDOKAN_INSTANCE DokanInstance) { PEVENT_INFORMATION eventInfo; PDOKAN_OPEN_INFO openInfo; ULONG writtenLength = 0; NTSTATUS status; DOKAN_FILE_INFO fileInfo; BOOL bufferAllocated = FALSE; ULONG sizeOfEventInfo = sizeof(EVENT_INFORMATION); eventInfo = DispatchCommon(EventContext, sizeOfEventInfo, DokanInstance, &fileInfo, &openInfo); // Since driver requested bigger memory, // allocate enough memory and send it to driver if (EventContext->Operation.Write.RequestLength > 0) { ULONG contextLength = EventContext->Operation.Write.RequestLength; PEVENT_CONTEXT contextBuf = (PEVENT_CONTEXT)malloc(contextLength); if (contextBuf == NULL) { free(eventInfo); return; } SendWriteRequest(Handle, eventInfo, sizeOfEventInfo, contextBuf, contextLength); EventContext = contextBuf; bufferAllocated = TRUE; } CheckFileName(EventContext->Operation.Write.FileName); DbgPrint("###WriteFile %04d\n", openInfo != NULL ? openInfo->EventId : -1); if (DokanInstance->DokanOperations->WriteFile) { status = DokanInstance->DokanOperations->WriteFile( EventContext->Operation.Write.FileName, (PCHAR)EventContext + EventContext->Operation.Write.BufferOffset, EventContext->Operation.Write.BufferLength, &writtenLength, EventContext->Operation.Write.ByteOffset.QuadPart, &fileInfo); } else { status = STATUS_NOT_IMPLEMENTED; } if (openInfo != NULL) openInfo->UserContext = fileInfo.Context; eventInfo->Status = status; eventInfo->BufferLength = 0; if (status == STATUS_SUCCESS) { eventInfo->BufferLength = writtenLength; eventInfo->Operation.Write.CurrentByteOffset.QuadPart = EventContext->Operation.Write.ByteOffset.QuadPart + writtenLength; } SendEventInformation(Handle, eventInfo, sizeOfEventInfo, DokanInstance); free(eventInfo); if (bufferAllocated) free(EventContext); }
VOID DispatchRead( HANDLE Handle, PEVENT_CONTEXT EventContext, PDOKAN_INSTANCE DokanInstance) { PEVENT_INFORMATION eventInfo; PDOKAN_OPEN_INFO openInfo; ULONG readLength = 0; int status; DOKAN_FILE_INFO fileInfo; ULONG sizeOfEventInfo; sizeOfEventInfo = sizeof(EVENT_INFORMATION) - 8 + EventContext->Operation.Read.BufferLength; CheckFileName(EventContext->Operation.Read.FileName); eventInfo = DispatchCommon( EventContext, sizeOfEventInfo, DokanInstance, &fileInfo, &openInfo); DbgPrint("###Read %04d\n", openInfo != NULL ? openInfo->EventId : -1); if (DokanInstance->DokanOperations->ReadFile) { status = DokanInstance->DokanOperations->ReadFile( EventContext->Operation.Read.FileName, eventInfo->Buffer, EventContext->Operation.Read.BufferLength, &readLength, EventContext->Operation.Read.ByteOffset.QuadPart, &fileInfo); } else { status = -1; } if (openInfo != NULL) openInfo->UserContext = fileInfo.Context; eventInfo->BufferLength = 0; if (status < 0) { eventInfo->Status = STATUS_INVALID_PARAMETER; } else if(readLength == 0) { eventInfo->Status = STATUS_END_OF_FILE; } else { eventInfo->Status = STATUS_SUCCESS; eventInfo->BufferLength = readLength; eventInfo->Operation.Read.CurrentByteOffset.QuadPart = EventContext->Operation.Read.ByteOffset.QuadPart + readLength; } SendEventInformation(Handle, eventInfo, sizeOfEventInfo, DokanInstance); free(eventInfo); return; }
VOID DispatchQuerySecurity(HANDLE Handle, PEVENT_CONTEXT EventContext, PDOKAN_INSTANCE DokanInstance) { PEVENT_INFORMATION eventInfo; DOKAN_FILE_INFO fileInfo; PDOKAN_OPEN_INFO openInfo; ULONG eventInfoLength; NTSTATUS status = STATUS_NOT_IMPLEMENTED; ULONG lengthNeeded = 0; eventInfoLength = sizeof(EVENT_INFORMATION) - 8 + EventContext->Operation.Security.BufferLength; CheckFileName(EventContext->Operation.Security.FileName); eventInfo = DispatchCommon(EventContext, eventInfoLength, DokanInstance, &fileInfo, &openInfo); if (DokanInstance->DokanOperations->GetFileSecurity) { status = DokanInstance->DokanOperations->GetFileSecurity( EventContext->Operation.Security.FileName, &EventContext->Operation.Security.SecurityInformation, &eventInfo->Buffer, EventContext->Operation.Security.BufferLength, &lengthNeeded, &fileInfo); } eventInfo->Status = status; if (status != STATUS_SUCCESS && status != STATUS_BUFFER_OVERFLOW) { eventInfo->BufferLength = 0; } else { eventInfo->BufferLength = lengthNeeded; if (EventContext->Operation.Security.BufferLength < lengthNeeded) { // Filesystem Application should return STATUS_BUFFER_OVERFLOW in this // case. eventInfo->Status = STATUS_BUFFER_OVERFLOW; } } SendEventInformation(Handle, eventInfo, eventInfoLength, DokanInstance); free(eventInfo); }
VOID DispatchFlush(HANDLE Handle, PEVENT_CONTEXT EventContext, PDOKAN_INSTANCE DokanInstance) { DOKAN_FILE_INFO fileInfo; PEVENT_INFORMATION eventInfo; ULONG sizeOfEventInfo = sizeof(EVENT_INFORMATION); PDOKAN_OPEN_INFO openInfo; NTSTATUS status; CheckFileName(EventContext->Operation.Flush.FileName); eventInfo = DispatchCommon(EventContext, sizeOfEventInfo, DokanInstance, &fileInfo, &openInfo); DbgPrint("###Flush %04d\n", openInfo != NULL ? openInfo->EventId : -1); if (DokanInstance->DokanOperations->FlushFileBuffers) { status = DokanInstance->DokanOperations->FlushFileBuffers( EventContext->Operation.Flush.FileName, &fileInfo); } else { status = STATUS_NOT_IMPLEMENTED; } if (status == STATUS_NOT_IMPLEMENTED) { eventInfo->Status = STATUS_SUCCESS; } else { eventInfo->Status = status != STATUS_SUCCESS ? STATUS_NOT_SUPPORTED : STATUS_SUCCESS; } if (openInfo != NULL) openInfo->UserContext = fileInfo.Context; SendEventInformation(Handle, eventInfo, sizeOfEventInfo, DokanInstance); free(eventInfo); return; }
VOID DispatchFlush( HANDLE Handle, PEVENT_CONTEXT EventContext, PDOKAN_INSTANCE DokanInstance) { DOKAN_FILE_INFO fileInfo; PEVENT_INFORMATION eventInfo; ULONG sizeOfEventInfo = sizeof(EVENT_INFORMATION); PDOKAN_OPEN_INFO openInfo; int status; CheckFileName(EventContext->Flush.FileName); eventInfo = DispatchCommon(EventContext, sizeOfEventInfo, DokanInstance, &fileInfo); openInfo = (PDOKAN_OPEN_INFO)EventContext->Context; DbgPrint("###Flush %04d\n", openInfo->EventId); eventInfo->Status = STATUS_SUCCESS; if (DokanInstance->DokanOperations->FlushFileBuffers) { status = DokanInstance->DokanOperations->FlushFileBuffers( EventContext->Flush.FileName, &fileInfo); eventInfo->Status = status < 0 ? STATUS_NOT_SUPPORTED : STATUS_SUCCESS; } openInfo->UserContext = fileInfo.Context; SendEventInformation(Handle, eventInfo, sizeOfEventInfo); free(eventInfo); return; }
VOID DispatchSetSecurity(HANDLE Handle, PEVENT_CONTEXT EventContext, PDOKAN_INSTANCE DokanInstance) { PEVENT_INFORMATION eventInfo; DOKAN_FILE_INFO fileInfo; PDOKAN_OPEN_INFO openInfo; ULONG eventInfoLength; NTSTATUS status = STATUS_NOT_IMPLEMENTED; PSECURITY_DESCRIPTOR securityDescriptor; eventInfoLength = sizeof(EVENT_INFORMATION); CheckFileName(EventContext->Operation.SetSecurity.FileName); eventInfo = DispatchCommon(EventContext, eventInfoLength, DokanInstance, &fileInfo, &openInfo); securityDescriptor = (PCHAR)EventContext + EventContext->Operation.SetSecurity.BufferOffset; if (DokanInstance->DokanOperations->SetFileSecurity) { status = DokanInstance->DokanOperations->SetFileSecurity( EventContext->Operation.SetSecurity.FileName, &EventContext->Operation.SetSecurity.SecurityInformation, securityDescriptor, EventContext->Operation.SetSecurity.BufferLength, &fileInfo); } if (status > 0) { eventInfo->Status = STATUS_INVALID_PARAMETER; eventInfo->BufferLength = 0; } else { eventInfo->Status = STATUS_SUCCESS; eventInfo->BufferLength = 0; } SendEventInformation(Handle, eventInfo, eventInfoLength, DokanInstance); free(eventInfo); }
VOID DispatchQueryInformation( HANDLE Handle, PEVENT_CONTEXT EventContext, PDOKAN_INSTANCE DokanInstance) { PEVENT_INFORMATION eventInfo; DOKAN_FILE_INFO fileInfo; BY_HANDLE_FILE_INFORMATION byHandleFileInfo; ULONG remainingLength; ULONG status = STATUS_INVALID_PARAMETER; int result; PDOKAN_OPEN_INFO openInfo; ULONG sizeOfEventInfo; sizeOfEventInfo = sizeof(EVENT_INFORMATION) - 8 + EventContext->File.BufferLength; CheckFileName(EventContext->File.FileName); ZeroMemory(&byHandleFileInfo, sizeof(BY_HANDLE_FILE_INFORMATION)); eventInfo = DispatchCommon( EventContext, sizeOfEventInfo, DokanInstance, &fileInfo, &openInfo); eventInfo->BufferLength = EventContext->File.BufferLength; DbgPrint("###GetFileInfo %04d\n", openInfo != NULL ? openInfo->EventId : -1); if (DokanInstance->DokanOperations->GetFileInformation) { result = DokanInstance->DokanOperations->GetFileInformation( EventContext->File.FileName, &byHandleFileInfo, &fileInfo); } else { result = -1; } remainingLength = eventInfo->BufferLength; if (result < 0) { eventInfo->Status = STATUS_INVALID_PARAMETER; eventInfo->BufferLength = 0; } else { switch(EventContext->File.FileInformationClass) { case FileBasicInformation: //DbgPrint("FileBasicInformation\n"); status = DokanFillFileBasicInfo((PFILE_BASIC_INFORMATION)eventInfo->Buffer, &byHandleFileInfo, &remainingLength); break; case FileInternalInformation: status = DokanFillInternalInfo((PFILE_INTERNAL_INFORMATION)eventInfo->Buffer, &byHandleFileInfo, &remainingLength); break; case FileEaInformation: //DbgPrint("FileEaInformation or FileInternalInformation\n"); //status = STATUS_NOT_IMPLEMENTED; status = STATUS_SUCCESS; remainingLength -= sizeof(FILE_EA_INFORMATION); break; case FileStandardInformation: //DbgPrint("FileStandardInformation\n"); status = DokanFillFileStandardInfo((PFILE_STANDARD_INFORMATION)eventInfo->Buffer, &byHandleFileInfo, &remainingLength); break; case FileAllInformation: //DbgPrint("FileAllInformation\n"); status = DokanFillFileAllInfo((PFILE_ALL_INFORMATION)eventInfo->Buffer, &byHandleFileInfo, &remainingLength, EventContext); break; case FileAlternateNameInformation: status = STATUS_NOT_IMPLEMENTED; break; case FileAttributeTagInformation: status = DokanFillFileAttributeTagInfo((PFILE_ATTRIBUTE_TAG_INFORMATION)eventInfo->Buffer, &byHandleFileInfo, &remainingLength); break; case FileCompressionInformation: //DbgPrint("FileAlternateNameInformation or...\n"); status = STATUS_NOT_IMPLEMENTED; break; case FileNameInformation: // this case is not used because driver deal with //DbgPrint("FileNameInformation\n"); status = DokanFillFileNameInfo((PFILE_NAME_INFORMATION)eventInfo->Buffer, &byHandleFileInfo, &remainingLength, EventContext); break; case FileNetworkOpenInformation: //DbgPrint("FileNetworkOpenInformation\n"); status = DokanFillNetworkOpenInfo((PFILE_NETWORK_OPEN_INFORMATION)eventInfo->Buffer, &byHandleFileInfo, &remainingLength); break; case FilePositionInformation: // this case is not used because driver deal with //DbgPrint("FilePositionInformation\n"); status = DokanFillFilePositionInfo((PFILE_POSITION_INFORMATION)eventInfo->Buffer, &byHandleFileInfo, &remainingLength); break; case FileStreamInformation: //DbgPrint("FileStreamInformation\n"); status = STATUS_NOT_IMPLEMENTED; break; default: { DbgPrint(" unknown type:%d\n", EventContext->File.FileInformationClass); } break; } eventInfo->Status = status; eventInfo->BufferLength = EventContext->File.BufferLength - remainingLength; } // information for FileSystem openInfo->UserContext = fileInfo.Context; SendEventInformation(Handle, eventInfo, sizeOfEventInfo, DokanInstance); free(eventInfo); return; }
VOID DispatchSetInformation( HANDLE Handle, PEVENT_CONTEXT EventContext, PDOKAN_INSTANCE DokanInstance) { PEVENT_INFORMATION eventInfo; PDOKAN_OPEN_INFO openInfo; DOKAN_FILE_INFO fileInfo; NTSTATUS status = STATUS_NOT_IMPLEMENTED; ULONG sizeOfEventInfo = sizeof(EVENT_INFORMATION); if (EventContext->Operation.SetFile.FileInformationClass == FileRenameInformation) { PDOKAN_RENAME_INFORMATION renameInfo = (PDOKAN_RENAME_INFORMATION)((PCHAR)EventContext + EventContext->Operation.SetFile.BufferOffset); sizeOfEventInfo += renameInfo->FileNameLength; } CheckFileName(EventContext->Operation.SetFile.FileName); eventInfo = DispatchCommon( EventContext, sizeOfEventInfo, DokanInstance, &fileInfo, &openInfo); DbgPrint("###SetFileInfo %04d %d\n", openInfo != NULL ? openInfo->EventId : -1, EventContext->Operation.SetFile.FileInformationClass); switch (EventContext->Operation.SetFile.FileInformationClass) { case FileAllocationInformation: status = DokanSetAllocationInformation( EventContext, &fileInfo, DokanInstance->DokanOperations); break; case FileBasicInformation: status = DokanSetBasicInformation( EventContext, &fileInfo, DokanInstance->DokanOperations); break; case FileDispositionInformation: status = DokanSetDispositionInformation( EventContext, &fileInfo, DokanInstance->DokanOperations); break; case FileEndOfFileInformation: status = DokanSetEndOfFileInformation( EventContext, &fileInfo, DokanInstance->DokanOperations); break; case FileLinkInformation: status = DokanSetLinkInformation( EventContext, &fileInfo, DokanInstance->DokanOperations); break; case FilePositionInformation: // this case is dealed with by driver status = STATUS_NOT_IMPLEMENTED; break; case FileRenameInformation: status = DokanSetRenameInformation( EventContext, &fileInfo, DokanInstance->DokanOperations); break; case FileValidDataLengthInformation: status = DokanSetValidDataLengthInformation( EventContext, &fileInfo, DokanInstance->DokanOperations); break; } if (openInfo != NULL) openInfo->UserContext = fileInfo.Context; eventInfo->BufferLength = 0; eventInfo->Status = status; if (EventContext->Operation.SetFile.FileInformationClass == FileDispositionInformation) { if (status == STATUS_SUCCESS) { PFILE_DISPOSITION_INFORMATION dispositionInfo = (PFILE_DISPOSITION_INFORMATION)((PCHAR)EventContext + EventContext->Operation.SetFile.BufferOffset); eventInfo->Operation.Delete.DeleteOnClose = dispositionInfo->DeleteFile ? TRUE : FALSE; DbgPrint(" dispositionInfo->DeleteFile = %d\n", dispositionInfo->DeleteFile); } } else { // notice new file name to driver if (status == STATUS_SUCCESS && EventContext->Operation.SetFile.FileInformationClass == FileRenameInformation) { PDOKAN_RENAME_INFORMATION renameInfo = (PDOKAN_RENAME_INFORMATION)((PCHAR)EventContext + EventContext->Operation.SetFile.BufferOffset); eventInfo->BufferLength = renameInfo->FileNameLength; CopyMemory(eventInfo->Buffer, renameInfo->FileName, renameInfo->FileNameLength); } } //DbgPrint("SetInfomation status = %d\n\n", status); SendEventInformation(Handle, eventInfo, sizeOfEventInfo, DokanInstance); free(eventInfo); return; }
VOID DispatchDirectoryInformation(HANDLE Handle, PEVENT_CONTEXT EventContext, PDOKAN_INSTANCE DokanInstance) { PEVENT_INFORMATION eventInfo; DOKAN_FILE_INFO fileInfo; PDOKAN_OPEN_INFO openInfo; NTSTATUS status = STATUS_SUCCESS; ULONG fileInfoClass = EventContext->Operation.Directory.FileInformationClass; ULONG sizeOfEventInfo = sizeof(EVENT_INFORMATION) - 8 + EventContext->Operation.Directory.BufferLength; BOOLEAN patternCheck = TRUE; CheckFileName(EventContext->Operation.Directory.DirectoryName); eventInfo = DispatchCommon(EventContext, sizeOfEventInfo, DokanInstance, &fileInfo, &openInfo); // check whether this is handled FileInfoClass if (fileInfoClass != FileDirectoryInformation && fileInfoClass != FileFullDirectoryInformation && fileInfoClass != FileNamesInformation && fileInfoClass != FileIdBothDirectoryInformation && fileInfoClass != FileBothDirectoryInformation) { DbgPrint("not suported type %d\n", fileInfoClass); // send directory info to driver eventInfo->BufferLength = 0; eventInfo->Status = STATUS_NOT_IMPLEMENTED; SendEventInformation(Handle, eventInfo, sizeOfEventInfo, DokanInstance); free(eventInfo); return; } // IMPORTANT!! // this buffer length is fixed in MatchFiles funciton eventInfo->BufferLength = EventContext->Operation.Directory.BufferLength; if (openInfo->DirListHead == NULL) { openInfo->DirListHead = malloc(sizeof(LIST_ENTRY)); if (openInfo->DirListHead != NULL) { InitializeListHead(openInfo->DirListHead); } else { eventInfo->BufferLength = 0; eventInfo->Status = STATUS_NO_MEMORY; SendEventInformation(Handle, eventInfo, sizeOfEventInfo, DokanInstance); free(eventInfo); return; } } if (EventContext->Operation.Directory.FileIndex == 0) { ClearFindData(openInfo->DirListHead); } if (IsListEmpty(openInfo->DirListHead)) { DbgPrint("###FindFiles %04d\n", openInfo->EventId); // if user defined FindFilesWithPattern if (DokanInstance->DokanOperations->FindFilesWithPattern) { LPCWSTR pattern = L"*"; // if search pattern is specified if (EventContext->Operation.Directory.SearchPatternLength != 0) { pattern = (PWCHAR)( (SIZE_T)&EventContext->Operation.Directory.SearchPatternBase[0] + (SIZE_T)EventContext->Operation.Directory.SearchPatternOffset); } patternCheck = FALSE; // do not recheck pattern later in MatchFiles status = DokanInstance->DokanOperations->FindFilesWithPattern( EventContext->Operation.Directory.DirectoryName, pattern, DokanFillFileData, &fileInfo); } else { status = STATUS_NOT_IMPLEMENTED; } if (status == STATUS_NOT_IMPLEMENTED && DokanInstance->DokanOperations->FindFiles) { patternCheck = TRUE; // do pattern check later in MachFiles // call FileSystem specifeid callback routine status = DokanInstance->DokanOperations->FindFiles( EventContext->Operation.Directory.DirectoryName, DokanFillFileData, &fileInfo); } } if (status != STATUS_SUCCESS) { if (EventContext->Operation.Directory.FileIndex == 0) { DbgPrint(" STATUS_NO_SUCH_FILE\n"); eventInfo->Status = STATUS_NO_SUCH_FILE; } else { DbgPrint(" STATUS_NO_MORE_FILES\n"); eventInfo->Status = STATUS_NO_MORE_FILES; } eventInfo->BufferLength = 0; eventInfo->Operation.Directory.Index = EventContext->Operation.Directory.FileIndex; // free all of list entries ClearFindData(openInfo->DirListHead); } else { LONG index; eventInfo->Status = STATUS_SUCCESS; AddMissingCurrentAndParentFolder(EventContext, openInfo->DirListHead, &fileInfo); DbgPrint("index from %d\n", EventContext->Operation.Directory.FileIndex); // extract entries that match search pattern from FindFiles result index = MatchFiles(EventContext, eventInfo, openInfo->DirListHead, patternCheck, DokanInstance); // there is no matched file if (index < 0) { eventInfo->BufferLength = 0; eventInfo->Operation.Directory.Index = EventContext->Operation.Directory.FileIndex; if (index == -1) { if (EventContext->Operation.Directory.FileIndex == 0) { DbgPrint(" STATUS_NO_SUCH_FILE\n"); eventInfo->Status = STATUS_NO_SUCH_FILE; } else { DbgPrint(" STATUS_NO_MORE_FILES\n"); eventInfo->Status = STATUS_NO_MORE_FILES; } } else { DbgPrint(" STATUS_BUFFER_OVERFLOW\n"); eventInfo->Status = STATUS_BUFFER_OVERFLOW; } ClearFindData(openInfo->DirListHead); } else { DbgPrint("index to %d\n", index); eventInfo->Operation.Directory.Index = index; } } // information for FileSystem openInfo->UserContext = fileInfo.Context; // send directory information to driver SendEventInformation(Handle, eventInfo, sizeOfEventInfo, DokanInstance); free(eventInfo); }
VOID DispatchLock( HANDLE Handle, PEVENT_CONTEXT EventContext, PDOKAN_INSTANCE DokanInstance) { DOKAN_FILE_INFO fileInfo; PEVENT_INFORMATION eventInfo; ULONG sizeOfEventInfo = sizeof(EVENT_INFORMATION); PDOKAN_OPEN_INFO openInfo; int status; CheckFileName(EventContext->Lock.FileName); eventInfo = DispatchCommon( EventContext, sizeOfEventInfo, DokanInstance, &fileInfo, &openInfo); logw(L"###Lock %04d\n", openInfo != NULL ? openInfo->EventId : -1); eventInfo->Status = STATUS_NOT_IMPLEMENTED; switch (EventContext->MinorFunction) { case IRP_MN_LOCK: if (DokanInstance->DokanOperations->LockFile) { status = DokanInstance->DokanOperations->LockFile( EventContext->Lock.FileName, EventContext->Lock.ByteOffset.QuadPart, EventContext->Lock.Length.QuadPart, //EventContext->Lock.Key, &fileInfo); eventInfo->Status = status < 0 ? STATUS_LOCK_NOT_GRANTED : STATUS_SUCCESS; } break; case IRP_MN_UNLOCK_ALL: break; case IRP_MN_UNLOCK_ALL_BY_KEY: break; case IRP_MN_UNLOCK_SINGLE: if (DokanInstance->DokanOperations->UnlockFile) { status = DokanInstance->DokanOperations->UnlockFile( EventContext->Lock.FileName, EventContext->Lock.ByteOffset.QuadPart, EventContext->Lock.Length.QuadPart, //EventContext->Lock.Key, &fileInfo); eventInfo->Status = STATUS_SUCCESS; // at any time return success ? } break; default: logw(L"unkown lock function %d\n", EventContext->MinorFunction); } openInfo->UserContext = fileInfo.Context; SendEventInformation(Handle, eventInfo, sizeOfEventInfo, DokanInstance); free(eventInfo); return; }