Пример #1
0
VOID
ReleaseDokanOpenInfo(
	PEVENT_INFORMATION	EventInformation,
	PDOKAN_INSTANCE		DokanInstance)
{
	PDOKAN_OPEN_INFO openInfo;
	EnterCriticalSection(&DokanInstance->CriticalSection);

    openInfo = (PDOKAN_OPEN_INFO)(UINT_PTR)EventInformation->Context;
	if (openInfo != NULL) {
		openInfo->OpenCount--;
		if (openInfo->OpenCount < 1) {
			if (openInfo->DirListHead != NULL) {
				ClearFindData(openInfo->DirListHead);
				free(openInfo->DirListHead);
				openInfo->DirListHead = NULL;
			}
			if (openInfo->StreamListHead != NULL) {
				ClearFindStreamData(openInfo->StreamListHead);
				free(openInfo->StreamListHead);
				openInfo->StreamListHead = NULL;
			}
			free(openInfo);
			EventInformation->Context = 0;
		}
	}
	LeaveCriticalSection(&DokanInstance->CriticalSection);
}
Пример #2
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);
}