| 351 | return status; |
| 352 | } |
| 353 | static NTSTATUS NTAPI HookedNtQueryDirectoryFileEx(HANDLE fileHandle, HANDLE event, PIO_APC_ROUTINE apcRoutine, LPVOID apcContext, PIO_STATUS_BLOCK ioStatusBlock, LPVOID fileInformation, ULONG length, FILE_INFORMATION_CLASS fileInformationClass, ULONG queryFlags, PUNICODE_STRING fileName) |
| 354 | { |
| 355 | NTSTATUS status = OriginalNtQueryDirectoryFileEx(fileHandle, event, apcRoutine, apcContext, ioStatusBlock, fileInformation, length, fileInformationClass, queryFlags, fileName); |
| 356 | |
| 357 | // Hide files, directories and named pipes |
| 358 | // Some applications (e.g. cmd.exe) use NtQueryDirectoryFileEx instead of NtQueryDirectoryFile. |
| 359 | if (NT_SUCCESS(status) && (fileInformationClass == FileDirectoryInformation || fileInformationClass == FileFullDirectoryInformation || fileInformationClass == FileIdFullDirectoryInformation || fileInformationClass == FileBothDirectoryInformation || fileInformationClass == FileIdBothDirectoryInformation || fileInformationClass == FileNamesInformation)) |
| 360 | { |
| 361 | WCHAR fileDirectoryPath[MAX_PATH + 1] = { 0 }; |
| 362 | WCHAR fileFileName[MAX_PATH + 1] = { 0 }; |
| 363 | WCHAR fileFullPath[MAX_PATH + 1] = { 0 }; |
| 364 | |
| 365 | if (GetFileType(fileHandle) == FILE_TYPE_PIPE) StrCpyW(fileDirectoryPath, L"\\\\.\\pipe\\"); |
| 366 | else GetPathFromHandle(fileHandle, fileDirectoryPath, MAX_PATH); |
| 367 | |
| 368 | if (queryFlags & SL_RETURN_SINGLE_ENTRY) |
| 369 | { |
| 370 | // When returning a single entry, skip until the first item is found that is not hidden. |
| 371 | for (BOOL skip = HasPrefix(FileInformationGetName(fileInformation, fileInformationClass, fileFileName)) || IsPathHidden(CreatePath(fileFullPath, fileDirectoryPath, FileInformationGetName(fileInformation, fileInformationClass, fileFileName))); skip; skip = HasPrefix(FileInformationGetName(fileInformation, fileInformationClass, fileFileName)) || IsPathHidden(CreatePath(fileFullPath, fileDirectoryPath, FileInformationGetName(fileInformation, fileInformationClass, fileFileName)))) |
| 372 | { |
| 373 | status = OriginalNtQueryDirectoryFileEx(fileHandle, event, apcRoutine, apcContext, ioStatusBlock, fileInformation, length, fileInformationClass, queryFlags, fileName); |
| 374 | if (status) break; |
| 375 | } |
| 376 | } |
| 377 | else |
| 378 | { |
| 379 | LPVOID current = fileInformation; |
| 380 | LPVOID previous = NULL; |
| 381 | ULONG nextEntryOffset; |
| 382 | |
| 383 | do |
| 384 | { |
| 385 | nextEntryOffset = FileInformationGetNextEntryOffset(current, fileInformationClass); |
| 386 | |
| 387 | if (HasPrefix(FileInformationGetName(current, fileInformationClass, fileFileName)) || IsPathHidden(CreatePath(fileFullPath, fileDirectoryPath, FileInformationGetName(current, fileInformationClass, fileFileName)))) |
| 388 | { |
| 389 | if (nextEntryOffset) |
| 390 | { |
| 391 | i_memcpy( |
| 392 | current, |
| 393 | (LPBYTE)current + nextEntryOffset, |
| 394 | (ULONG)(length - ((ULONGLONG)current - (ULONGLONG)fileInformation) - nextEntryOffset) |
| 395 | ); |
| 396 | continue; |
| 397 | } |
| 398 | else |
| 399 | { |
| 400 | if (current == fileInformation) status = STATUS_NO_MORE_FILES; |
| 401 | else FileInformationSetNextEntryOffset(previous, fileInformationClass, 0); |
| 402 | break; |
| 403 | } |
| 404 | } |
| 405 | |
| 406 | previous = current; |
| 407 | current = (LPBYTE)current + nextEntryOffset; |
| 408 | } |
| 409 | while (nextEntryOffset); |
| 410 | } |
nothing calls this directly
no test coverage detected