INIT section and literal strings

Discussion in 'Windows Vista Drivers' started by Pavel A., Aug 13, 2006.

  1. Pavel A.

    Pavel A. Guest

    Alex, if you don't mind I'm forwarding this to the drivers newsgroup;
    the WDK discussions are mostly occuring there.

    Regards,
    --PA

    ~~~

    :

    Hello,

    I've found an interesting behavior when using the WDK build environment
    which was quite surprising and which I don't see documented anywhere.

    I have the following code:

    --- cut ---

    NTSTATUS DriverEntry(
    __in PDRIVER_OBJECT DriverObject,
    __in PUNICODE_STRING RegistryPath
    );

    #pragma alloc_text("INIT", DriverEntry)

    NTSTATUS DriverEntry(
    __in PDRIVER_OBJECT DriverObject,
    __in PUNICODE_STRING RegistryPath
    )
    {
    NTSTATUS Status = STATUS_SUCCESS;
    UNICODE_STRING DeviceName;

    // initialize device name string
    RtlInitUnicodeString(&DeviceName, L"\\Device\\mydevice");

    // register with the RDBSS and create device object
    Status = RxRegisterMinirdr(
    &DeviceObject,
    DriverObject,
    &MyMiniRdrDispatch,
    RX_REGISTERMINI_FLAG_DONT_PROVIDE_MAILSLOTS,
    &DeviceName,
    sizeof(MY_DEVICE_EXT),
    FILE_DEVICE_NETWORK_FILE_SYSTEM,
    FILE_REMOTE_DEVICE);

    ...

    return Status;
    }

    --- cut ---

    It turns out, when compiling with the WDK build environment, that not only
    the DriverEntry code is put into the INIT section, but the string literal
    referenced in the call RtlInitUnicodeString as well (I can clearly see this
    in the assembly listing generated by the compiler). This causes a crash
    later, because RxRegisterMinirdr saves this pointer in the
    RDBSS_DEVICE_OBJECT structure.

    The fact that putting a function into a different code segment also affects
    literal strings referenced in this function was totally surprising and
    counterintuitive to me. It appears this is caused by the undocumented
    /cbstring cl option, which is added when using the WDK build environment
    (adding /cbstring- to USER_C_FLAGS moves the string to the CONST segment,
    as expected).

    Reworking the code so that the string is defined separately helps:

    // outside of DriverEntry
    const PCWSTR MyDeviceName = L"\\Device\\mydevice";

    .....

    RtlInitUnicodeString(&DeviceName, MyDeviceName);


    What is also surprising is that I cannot find any mentioning of this
    problem. Is it only me who does this? Am I doing anything wrong? The NulMRx
    sample has similar code, but it does not bother allocating DriverEntry in
    the INIT segment.

    This behavior affects PAGExxxx sections as well, e.g.

    --- cut ---

    PCWSTR PagedFunction();
    NTSTATUS NonPagedFunction(PCWSTR Param);

    #pragma alloc_text("PAGE", PagedFunction)

    PCWSTR PagedFunction()
    {
    return L"String";
    }

    NTSTATUS NonPagedFunction(PCWSTR Param)
    {
    // acquire spinlock
    // walk throuhg a list for a matching string
    // release spinlock
    }

    .....

    // this causes IRQL_NOT_LESS_OR_EQUAL since the parameter
    // is in paged memory
    NonPagedFunction(PagedFunction());

    --- cut ---

    It would be great if the /cbstring option and the above behavior were
    documented somewhere.


    This is WDK 5483, cl version 14.00.50727.161.

    -- Alex Fedotov
     
    Pavel A., Aug 13, 2006
    #1
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.