Windows Native Program ZwReadFile return bad parameters

0

I'm trying to create a native application (using Zw* API / Subsystem:native) but i don't find the way to read a file.

This is basic but when i call ZWReadFile the return value is 0xC000000D (bad parameters). I've tried a lot of thing but i don't have more idea :/

Here is my code :

#define _X86_
#include <wdm.h>
#include <stdio.h>

NTSTATUS ZwTerminateProcess(_In_opt_ HANDLE   ProcessHandle,_In_ NTSTATUS ExitStatus);
NTSTATUS NTAPI ZwDelayExecution(IN BOOLEAN Alertable, IN PLARGE_INTEGER Interval);
NTSTATUS NTAPI ZwDisplayString(IN PUNICODE_STRING String);
//NTSTATUS ZwRtlStringCbPrintf( _Out_ LPTSTR  pszDest,  _In_  size_t  cbDest,   _In_  LPCTSTR pszFormat,    ... );



void NtProcessStartup()
{
    UNICODE_STRING us;
    UNICODE_STRING drivePath;
    LARGE_INTEGER liSize;
    LARGE_INTEGER delay;
    OBJECT_ATTRIBUTES driveAttribute;
    IO_STATUS_BLOCK status;

    unsigned int milliseconds = 10000;

    DbgPrint("NATIVE APP STARTED");

    delay.QuadPart = (milliseconds > 1) ? -10000LL * (milliseconds - 1) : -1LL;

    RtlZeroMemory(&driveAttribute, sizeof(OBJECT_ATTRIBUTES));
    RtlInitUnicodeString(&drivePath, L"\\DosDevices\\C:\\test.txt");
    InitializeObjectAttributes(&driveAttribute, &drivePath, OBJ_INHERIT | OBJ_CASE_INSENSITIVE, (HANDLE) NULL, NULL);
    ZwDisplayString(driveAttribute.ObjectName);

    HANDLE drive;
    RtlZeroMemory(&liSize, sizeof(LARGE_INTEGER));
    liSize.LowPart = 1024;
    NTSTATUS open = ZwCreateFile(&drive, FILE_READ_DATA | FILE_WRITE_DATA | SYNCHRONIZE, &driveAttribute, &status, &liSize, FILE_ATTRIBUTE_NORMAL | FILE_SYNCHRONOUS_IO_NONALERT, FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OPEN_IF, FILE_NON_DIRECTORY_FILE, NULL, 0);
    if ( open == STATUS_SUCCESS) {
        RtlInitUnicodeString(&us, L"Device Open \n");
        DbgPrint("Device Open");
        ZwDisplayString(&us);

        char buff[440];

        LARGE_INTEGER byteOffset;
        byteOffset.HighPart = -1;
        byteOffset.LowPart = FILE_USE_FILE_POINTER_POSITION;
        NTSTATUS ret = ZwReadFile(drive, NULL, NULL, NULL, &status, (PVOID)buff, 440, &byteOffset, NULL);
        ZwClose(drive);

        DbgPrint("Return  %02X \t %d \n", ret, ret);

        if (ret == STATUS_SUCCESS) {
            RtlInitUnicodeString(&us, L"READ OK \n");
            ZwDisplayString(&us);
        }
        else {
            RtlInitUnicodeString(&us, L"READ fail \n");
            ZwDisplayString(&us);
        }

    }
    else {
        RtlInitUnicodeString(&us, L"!Open Device \n");
        ZwDisplayString(&us);
        DbgPrint("ZwCreateFile status = 0x%x\n", open);
    }

    ZwDelayExecution(FALSE, &delay);
    ZwTerminateProcess((HANDLE)-1, 0);

}

There is not a lot of parameters to set but i don't understand where is the bug.

Thank you.

c
windows
native
asked on Stack Overflow Dec 27, 2015 by Nicolas Dupoty

1 Answer

0

Since you're using FILE_USE_FILE_POINTER_POSITION you must specify FILE_SYNCHRONOUS_IO_ALERT or FILE_SYNCHRONOUS_IO_NONALERT in the CreateOptions argument to ZwCreateFile. You are incorrectly passing this flag in the FileAttributes argument, where it is invalid. (It happens to have the same value as FILE_ATTRIBUTE_ARCHIVE so that is how it is being interpreted.)

Try

NTSTATUS open = ZwCreateFile(&drive, FILE_READ_DATA | FILE_WRITE_DATA | SYNCHRONIZE, 
   &driveAttribute, &status, &liSize, FILE_ATTRIBUTE_NORMAL, 
   FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OPEN_IF, 
   FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0);
answered on Stack Overflow Dec 28, 2015 by Harry Johnston • edited Dec 28, 2015 by Harry Johnston

User contributions licensed under CC BY-SA 3.0