예제 #1
0
파일: fileinfo.c 프로젝트: Driim/dokany
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;
}
예제 #2
0
파일: fileinfo.c 프로젝트: liuk9662/dokany
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;

}