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); }
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; }