Using `FltCreateNamedPipeFile` to create a NamedPipe in minifilter

I am using a relatively new API called FltCreateNamedPipeFile (https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/fltkernel/nf-fltkernel-fltcreatenamedpipefile) to create a named pipe in my DfLoad routine of mini filter.

I am feeling a bit lazy to create MWE. The function InitializeNamedPipe creates a named pipe.

// globals.
UNICODE_STRING gServerNamedPipe = RTL_CONSTANT_STRING(L"\\\\.\\pipe\\SubComPipe");
HANDLE gServerNamedPipeHandle;

// ... 
NTSTATUS
InitializeNamedPipe(IN PUNICODE_STRING PipeName, IN PFLT_FILTER Filter)
{
    PAGED_CODE();
    OBJECT_ATTRIBUTES objAttr;
    IO_STATUS_BLOCK ioStatusBlock;

    NTSTATUS status;
    InitializeObjectAttributes(&objAttr, &gServerNamedPipe, OBJ_KERNEL_HANDLE, NULL, NULL);

    status = FltCreateNamedPipeFile(Filter, /* Filter */
        NULL,                               /* Instance */
        &gServerNamedPipeHandle,            /* FileHandle */
        NULL,                               /* *FileObject */
        FILE_WRITE_DATA,                    /* DesiredAccess */
        &objAttr,                           /* ObjectAttributes */
        &ioStatusBlock,                     /* IoStatusBlock */
        FILE_SHARE_READ,                    /* ShareAccess */
        FILE_OPEN_IF,                       /* CreateDisposition */
        FILE_WRITE_THROUGH,                 /* CreateOptions */
        FILE_PIPE_BYTE_STREAM_TYPE,         /* NamedPipeType */
        FILE_PIPE_BYTE_STREAM_MODE,         /* ReadMode */
        FILE_PIPE_COMPLETE_OPERATION,       /* CompletionMode */
        NULL,                               /* MaximumInstnaces */
        1024,                               /* InboundQuota */
        4096,                               /* OutboundQuota */
        NULL,                               /* DefaultTimeOut */
        NULL                                /* DriverContext */
    );
    DFLOG(INFO, __FUNCTION__ ": IoStatusBlock status %X", ioStatusBlock.Status);
    return status;
}

This routine returns (status in functions above) code C0000033 which – according to the NTSTATUS reference page – means that The object name is invalid. From a brief search, I am getting the hint that maybe there is something wrong with the gServerNamedPipe?! On the other hand, windivert.c (https://github.com/basil00/Divert/blob/master/dll/windivert.c#L531) is using a similar naming scheme for named pipes (but without \\pipe\\).

InitializeNamedPipe: IoStatusBlock status 0
Shield>DriverEntry: NamePipeCreation code - C0000033

I am pretty sure I am doing something wrong but can’t figure out how to go about debugging it.

You need a kernel name. Try “\??\pipe\SubComPipe”

If you’re creating a new pipe you’ll also need to specify a max instance count and a default timeout.