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