ZwQueryDirectoryFile usage

I am having some difficulty using ZwQueryDirectoryFile(). I get an error c…8 indicating a bad file handle. I successfully open the root directory, and pass in that handle. Here is my code:

// Build WCHAR string to point to root directory.
WCHAR root_str[MAX_UNICODE_STACK_BUFFER_LENGTH] = { 0 };
wcsncpy(root_str, FilterExt->DeviceName,
(sizeof(root_str) - sizeof(WCHAR)) / sizeof(WCHAR));
wcscat(root_str, L"\");
// Initialize unicode string to root directory.
UNICODE_STRING root_name;
RtlInitUnicodeString(&root_name, root_str);

KdPrint((“%s: %s(%d) [%S] Root directory name: %wZ\n”,
FILE, FUNCTION, LINE,
FilterExt->DeviceName, root_name));

OBJECT_ATTRIBUTES obj_attrib;
InitializeObjectAttributes(&obj_attrib, &root_name,
OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL);
HANDLE r_handle = NULL;
IO_STATUS_BLOCK io_status;
// Open a file handle to the root directory.
NTSTATUS status = IoCreateFile(&r_handle,
GENERIC_READ | GENERIC_WRITE | FILE_LIST_DIRECTORY, &obj_attrib,
&io_status, NULL, FILE_ATTRIBUTE_DIRECTORY, FILE_SHARE_READ | FILE_SHARE_WRITE,
FILE_OPEN_IF, FILE_DIRECTORY_FILE, NULL, 0, CreateFileTypeNone, NULL,
IO_NO_PARAMETER_CHECKING);
if (NT_ERROR(status)) {
KdPrint((“%s: %s(%d) [%S] Error %lx opening root directory %wZ\n”,
FILE, FUNCTION, LINE,
FilterExt->DeviceName, status, root_name));
return status;
}

ULONG info_len = sizeof(FILE_DIRECTORY_INFORMATION) +
((MAXIMUM_FILENAME_LENGTH * sizeof(WCHAR)) + sizeof(WCHAR));
PFILE_DIRECTORY_INFORMATION file_info = ExAllocatePool(NonPagedPool, info_len);

// Search pattern.
UNICODE_STRING fn;
RtlInitUnicodeString(&fn, L"<.TXT");
// Scan one file at a time.
for (BOOLEAN first_time = TRUE;; first_time = FALSE) {
KEVENT event;
KeInitializeEvent(&event, SynchronizationEvent, FALSE);
status = ZwQueryDirectoryFile(r_handle, &event, NULL, 0, &io_status,
file_info, info_len, FileDirectoryInformation, TRUE, &fn, first_time);
KdPrint((“%s: %s(%d) [%S] ZwQueryDirectoryFile() %lx\n”,
FILE, FUNCTION, LINE,
FilterExt->DeviceName, status));

Since I am using the event parameter, I am assuming that I do not need to set synchronization when creating the handle to the root. I get no error when opening the root.

– Jamey

On Oct 18, 2017, at 8:55 PM, xxxxx@gmail.com wrote:
>
> I am having some difficulty using ZwQueryDirectoryFile(). I get an error c…8 indicating a bad file handle. I successfully open the root directory, and pass in that handle. Here is my code:
>
> // Build WCHAR string to point to root directory.
> WCHAR root_str[MAX_UNICODE_STACK_BUFFER_LENGTH] = { 0 };
> wcsncpy(root_str, FilterExt->DeviceName,
> (sizeof(root_str) - sizeof(WCHAR)) / sizeof(WCHAR));
> wcscat(root_str, L"\");

There’s a subtle problem in this code, although it is EXTREMELY unlikely to occur in real life. If the string being copied happens to be exactly MAX_UNICODE_STACK_BUFFER_LENGTH-1 characters long, wcsncpy copies the string but not the zero terminator. That’s perfectly fine, because you still have one element left in the array, and it was initialized to zero.

However, the wcscat will put the \ in that final element, and then store a zero one past the end.

This is why we need std::string in the kernel…

Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

The second parameter should be a handle for an event object not an event object itself.

In your case the event object is allocated on the stack and doesn’t have a header required for a full fledged object so you can’t create a handle for such event object.

You should use IoCreateSynchronizationEvent or ZwCreateEvent instead.

Well dang. I give that a try. Thanks.

On Thu, Oct 19, 2017, 3:49 AM xxxxx@hotmail.com
wrote:

>


>
> The second parameter should be a handle for an event object not an event
> object itself.
>
> In your case the event object is allocated on the stack and doesn’t have
> a header required for a full fledged object so you can’t create a handle
> for such event object.
>
> You should use IoCreateSynchronizationEvent or ZwCreateEvent instead.
>
> —
> NTDEV is sponsored by OSR
>
> Visit the list online at: <
> http://www.osronline.com/showlists.cfm?list=ntdev&gt;
>
> MONTHLY seminars on crash dump analysis, WDF, Windows internals and
> software drivers!
> Details at http:
>
> To unsubscribe, visit the List Server section of OSR Online at <
> http://www.osronline.com/page.cfm?name=ListServer&gt;
></http:>

After some tinkering, I decided I do not like having to create a named
event for this, so I just open with synchronization, and wait on the file
object. Works fine. Can’t believe I missed the HANDLE as parameter two.
Dugh.

On Thu, Oct 19, 2017 at 11:39 AM Jamey Kirby wrote:

> Well dang. I give that a try. Thanks.
>
> On Thu, Oct 19, 2017, 3:49 AM xxxxx@hotmail.com
> wrote:
>
>>


>>
>> The second parameter should be a handle for an event object not an event
>> object itself.
>>
>> In your case the event object is allocated on the stack and doesn’t have
>> a header required for a full fledged object so you can’t create a handle
>> for such event object.
>>
>> You should use IoCreateSynchronizationEvent or ZwCreateEvent instead.
>>
>> —
>> NTDEV is sponsored by OSR
>>
>> Visit the list online at: <
>> http://www.osronline.com/showlists.cfm?list=ntdev&gt;
>>
>> MONTHLY seminars on crash dump analysis, WDF, Windows internals and
>> software drivers!
>> Details at http:
>>
>> To unsubscribe, visit the List Server section of OSR Online at <
>> http://www.osronline.com/page.cfm?name=ListServer&gt;
>>
></http:>