Esempio n. 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);
}
Esempio n. 2
0
NTSTATUS
DokanFindStreams(PFILE_STREAM_INFORMATION StreamInfo, PDOKAN_FILE_INFO FileInfo,
                 PEVENT_CONTEXT EventContext, PDOKAN_INSTANCE DokanInstance,
                 PULONG RemainingLength) {
  PDOKAN_OPEN_INFO openInfo =
      (PDOKAN_OPEN_INFO)(UINT_PTR)FileInfo->DokanContext;
  NTSTATUS status = STATUS_SUCCESS;

  if (!DokanInstance->DokanOperations->FindStreams) {
    return STATUS_NOT_IMPLEMENTED;
  }

  if (openInfo->StreamListHead == NULL) {
    openInfo->StreamListHead = malloc(sizeof(LIST_ENTRY));
    if (openInfo->StreamListHead != NULL) {
      InitializeListHead(openInfo->StreamListHead);
    } else {
      status = STATUS_NO_MEMORY;
    }
  }

  if (status == STATUS_SUCCESS && IsListEmpty(openInfo->StreamListHead)) {
    status = DokanInstance->DokanOperations->FindStreams(
        EventContext->Operation.File.FileName, DokanFillFindStreamData,
        FileInfo);
  }

  if (status == STATUS_SUCCESS) {
    PLIST_ENTRY listHead, entry;
    ULONG entrySize;

    listHead = openInfo->StreamListHead;
    entrySize = 0;

    for (entry = listHead->Flink; entry != listHead; entry = entry->Flink) {
      PDOKAN_FIND_STREAM_DATA find =
          CONTAINING_RECORD(entry, DOKAN_FIND_STREAM_DATA, ListEntry);

      ULONG nextEntryOffset = entrySize;

      ULONG streamNameLength =
          (ULONG)wcslen(find->FindStreamData.cStreamName) * sizeof(WCHAR);
      entrySize = sizeof(FILE_STREAM_INFORMATION) + streamNameLength;
      // Must be align on a 8-byte boundary.
      entrySize = QuadAlign(entrySize);
      if (*RemainingLength < entrySize) {
        status = STATUS_BUFFER_OVERFLOW;
        break;
      }

      // Not the first entry, set the offset before filling the new entry
      if (nextEntryOffset > 0) {
        StreamInfo->NextEntryOffset = nextEntryOffset;
        StreamInfo = (PFILE_STREAM_INFORMATION)((LPBYTE)StreamInfo +
                                                StreamInfo->NextEntryOffset);
      }

      // Fill the new entry
      StreamInfo->StreamNameLength = streamNameLength;
      memcpy(StreamInfo->StreamName, find->FindStreamData.cStreamName,
             streamNameLength);
      StreamInfo->StreamSize = find->FindStreamData.StreamSize;
      StreamInfo->StreamAllocationSize = find->FindStreamData.StreamSize;
      StreamInfo->NextEntryOffset = 0;
      ALIGN_ALLOCATION_SIZE(&StreamInfo->StreamAllocationSize);

      *RemainingLength -= entrySize;
    }

    if (status != STATUS_BUFFER_OVERFLOW) {
      ClearFindStreamData(openInfo->StreamListHead);
    }

  } else {
    ClearFindStreamData(openInfo->StreamListHead);
  }

  return status;
}