NTSTATUS DokanFillFileAllInfo(PFILE_ALL_INFORMATION AllInfo, PBY_HANDLE_FILE_INFORMATION FileInfo, PULONG RemainingLength, PEVENT_CONTEXT EventContext) { ULONG allRemainingLength = *RemainingLength; if (*RemainingLength < sizeof(FILE_ALL_INFORMATION)) { return STATUS_BUFFER_OVERFLOW; } // FileBasicInformation DokanFillFileBasicInfo(&AllInfo->BasicInformation, FileInfo, RemainingLength); // FileStandardInformation DokanFillFileStandardInfo(&AllInfo->StandardInformation, FileInfo, RemainingLength); // FilePositionInformation DokanFillFilePositionInfo(&AllInfo->PositionInformation, FileInfo, RemainingLength); // there is not enough space to fill FileNameInformation if (allRemainingLength < sizeof(FILE_ALL_INFORMATION) + EventContext->Operation.File.FileNameLength) { // fill out to the limit // FileNameInformation AllInfo->NameInformation.FileNameLength = EventContext->Operation.File.FileNameLength; AllInfo->NameInformation.FileName[0] = EventContext->Operation.File.FileName[0]; allRemainingLength -= sizeof(FILE_ALL_INFORMATION); *RemainingLength = allRemainingLength; return STATUS_BUFFER_OVERFLOW; } // FileNameInformation AllInfo->NameInformation.FileNameLength = EventContext->Operation.File.FileNameLength; RtlCopyMemory(&(AllInfo->NameInformation.FileName[0]), EventContext->Operation.File.FileName, EventContext->Operation.File.FileNameLength); // the size except of FILE_NAME_INFORMATION allRemainingLength -= (sizeof(FILE_ALL_INFORMATION) - sizeof(FILE_NAME_INFORMATION)); // the size of FILE_NAME_INFORMATION allRemainingLength -= FIELD_OFFSET(FILE_NAME_INFORMATION, FileName[0]); allRemainingLength -= AllInfo->NameInformation.FileNameLength; *RemainingLength = allRemainingLength; return STATUS_SUCCESS; }
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; }