Windows System Software -- Consulting, Training, Development -- Unique Expertise, Guaranteed Results

Home NTFSD

Before Posting...

Please check out the Community Guidelines in the Announcements and Administration Category.

More Info on Driver Writing and Debugging


The free OSR Learning Library has more than 50 articles on a wide variety of topics about writing and debugging device drivers and Minifilters. From introductory level to advanced. All the articles have been recently reviewed and updated, and are written using the clear and definitive style you've come to expect from OSR over the years.


Check out The OSR Learning Library at: https://www.osr.com/osr-learning-library/


Can't figure out why my call to IOCTL_STORAGE_MANAGE_DATA_SET_ATTRIBUTES is failing

IOCTLFishIOCTLFish Member Posts: 2

Ok, I am trying to learn how to use IOCTL_STORAGE_MANAGE_DATA_SET_ATTRIBUTES. I have set up a VM and I call it like this:

#include <windows.h>
#include <stdio.h>
#include <string>
#include <iostream>
#include <winnt.h>
#include <winternl.h>
#include <ntddstor.h>

int main(int argc, const char* argv[]) {

    HANDLE hDevice = CreateFile(L"\\\\.\\Physicaldrive0", 
                                GENERIC_READ | GENERIC_WRITE, 
                                FILE_SHARE_READ | FILE_SHARE_WRITE, 
                                NULL, 
                                OPEN_EXISTING, 
                                FILE_FLAG_NO_BUFFERING, 
                                NULL);

    int cf_error = 0; 
    cf_error = GetLastError();

    if (hDevice == INVALID_HANDLE_VALUE) {
        std::cout << "COULDN'T GET HANDLE"; 
        return -1;
    }

    std::cout << "Device Handle error: " << cf_error << "\n";
    std::cout << "Handle value: " << hDevice << "\n"; 

    _DEVICE_MANAGE_DATA_SET_ATTRIBUTES attributes_struct; 

    LPDWORD BytesReturned = 0; 


    int inputbufferlength = 0; 

    inputbufferlength = sizeof(DEVICE_MANAGE_DATA_SET_ATTRIBUTES) + sizeof(_DEVICE_DSM_OFFLOAD_WRITE_PARAMETERS) + sizeof(DEVICE_DATA_SET_RANGE);

    PUCHAR inputbuffer = (PUCHAR)malloc(inputbufferlength);

    PUCHAR outputbuffer = (PUCHAR)malloc(inputbufferlength);

    //RtlZeroMemory(inputbuffer, inputBufferLength);

    PDEVICE_MANAGE_DATA_SET_ATTRIBUTES dsmAttributes = (PDEVICE_MANAGE_DATA_SET_ATTRIBUTES)inputbuffer;

    PDEVICE_DSM_OFFLOAD_WRITE_PARAMETERS offload_write_parameters = NULL; 

    dsmAttributes->Size = sizeof(DEVICE_MANAGE_DATA_SET_ATTRIBUTES);

    dsmAttributes->Action = DeviceDsmAction_OffloadWrite;

    dsmAttributes->Flags = 0; 

    dsmAttributes->ParameterBlockOffset = sizeof(DEVICE_MANAGE_DATA_SET_ATTRIBUTES);

    dsmAttributes->ParameterBlockLength = sizeof(DEVICE_DSM_OFFLOAD_WRITE_PARAMETERS);


    offload_write_parameters = (PDEVICE_DSM_OFFLOAD_WRITE_PARAMETERS)((PUCHAR)dsmAttributes + dsmAttributes->ParameterBlockOffset);

    offload_write_parameters->Flags = 0;
    offload_write_parameters->TokenOffset = 0;

    dsmAttributes->DataSetRangesOffset = dsmAttributes->ParameterBlockOffset + dsmAttributes->ParameterBlockLength;
    dsmAttributes->DataSetRangesLength = sizeof(DEVICE_DATA_SET_RANGE);

    PDEVICE_DATA_SET_RANGE lbaRange = NULL;
    lbaRange = (PDEVICE_DATA_SET_RANGE)((PUCHAR)dsmAttributes + dsmAttributes->DataSetRangesOffset);
    lbaRange->StartingOffset = 0;  // not sure about this one for now 
    lbaRange->LengthInBytes = 256 * 1024 * 1024;


    int status = DeviceIoControl(
        hDevice,                                  // handle to device
        IOCTL_STORAGE_MANAGE_DATA_SET_ATTRIBUTES, // dwIoControlCode
        inputbuffer,                             // input buffer
        inputbufferlength,                      // size of the input buffer
        outputbuffer,                           // output buffer
        inputbufferlength,                      // size of the input buffer - modified to be too small!
        BytesReturned,                          // number of bytes returned
        0 //(LPOVERLAPPED) &overlapped_struct   // OVERLAPPED structure
    );

    DWORD error_num = GetLastError();

    CloseHandle(hDevice);
    std::cout << "STATUS IS: " << status << "\n"; 
    std::cout << "ERROR IS: " << error_num; 
    return 0;
}

And my problem is that it returns STATUS_INVALID_PARAMETER, which would be fine but it seems like this is being returned being something other than the IOCTL I am trying to call. I put a breakpoint on my IOCTL like this:
bp partmgr!PartitionIoctlDsm

and I breakpoint the dispatcher like this:

bp partmgr!PartitionDeviceControl

But neither gets hit by my code, ever. So maybe some other device associated with that physical device doesn't like my parameters and it never makes it to IOCTL_STORAGE_MANAGE_DATA_SET_ATTRIBUTES or the associated dispatch handler. I am a little new to debugging these file system drivers so I wouldn't know where to start figuring out where to look. I cribbed some of this code off an old MS tool I found at https://github.com/microsoft/StorScore/blob/7cbe261a7cad74f3a4f758c2b8a35ca552ba8dde/src/StorageTool/src/_backup.c so I was surprised this code didn't work.

How do I debug this? Do you see anything obviously wrong with my code?

Sign In or Register to comment.

Howdy, Stranger!

It looks like you're new here. Sign in or register to get started.

Upcoming OSR Seminars
OSR has suspended in-person seminars due to the Covid-19 outbreak. But, don't miss your training! Attend via the internet instead!
Kernel Debugging 30 January 2023 Live, Online
Developing Minifilters 20 March 2023 Live, Online
Writing WDF Drivers TBD 2023 Live, Online
Internals & Software Drivers 17 April 2023 Live, Online