Esempio n. 1
0
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);
}
Esempio n. 2
0
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;
}
Esempio n. 3
0
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);
}
Esempio n. 4
0
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;
}
Esempio n. 5
0
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);
}
Esempio n. 6
0
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;
}
Esempio n. 7
0
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;
}
Esempio n. 8
0
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);
}
Esempio n. 9
0
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;

}
Esempio n. 10
0
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;
}
Esempio n. 11
0
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);
}
Esempio n. 12
0
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;
}