I have this code, that should make changes to the PhysicalDrive0, so I try to read from it, change the buffer and write it back.
Read:
HANDLE device = CreateFileW(L"\\\\.\\PhysicalDrive0", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, nullptr);
if (device == INVALID_HANDLE_VALUE) {
std::cerr << "Failed to open the drive. Error code: " << GetLastError() << std::endl;
return 1;
}
STORAGE_PROPERTY_QUERY storage_query;
storage_query.PropertyId = StorageDeviceProperty;
storage_query.QueryType = PropertyStandardQuery;
STORAGE_DESCRIPTOR_HEADER storage_descriptor;
DWORD bytes_returned = 0;
if (!DeviceIoControl(device, IOCTL_STORAGE_QUERY_PROPERTY, &storage_query, sizeof(STORAGE_PROPERTY_QUERY),
&storage_descriptor, sizeof(STORAGE_DESCRIPTOR_HEADER), &bytes_returned, nullptr)) {
std::cerr << "Failed to query storage property. Error code: " << GetLastError() << std::endl;
CloseHandle(device);
return 2;
}
DWORD buffer_size = storage_descriptor.Size;
BYTE* buffer = new BYTE[buffer_size];
if (!DeviceIoControl(device, IOCTL_STORAGE_QUERY_PROPERTY, &storage_query, sizeof(STORAGE_PROPERTY_QUERY),
buffer, buffer_size, &bytes_returned, nullptr)) {
std::cerr << "Failed to query storage property again. Error code: " << GetLastError() << std::endl;
CloseHandle(device);
delete[] buffer;
return 3;
}
Then I want to change some things on the buffer. And then write it back:
if (!DeviceIoControl(device, IOCTL_STORAGE_SET_PROPERTY, buffer, buffer_size, nullptr, 0, nullptr, nullptr)) {
unsigned long code = GetLastError();
std::cerr << "Failed to write to the drive. Error code: " << code << std::endl;
CloseHandle(device);
delete[] buffer;
return 5;
}
std::cout << "Write successful." << std::endl;
CloseHandle(device);
delete[] buffer;
EDIT 1: Also tried this:
ULONG new_buffer_size = sizeof(STORAGE_PROPERTY_SET) + buffer_size;
BYTE* new_buffer = new BYTE[new_buffer_size];
STORAGE_PROPERTY_SET set;
set.SetType = PropertyStandardSet;
set.PropertyId = StorageDeviceProperty;
memcpy(new_buffer, &set, sizeof(STORAGE_PROPERTY_SET));
memcpy(new_buffer + sizeof(STORAGE_PROPERTY_SET), buffer, buffer_size);
// Write the buffer combined with STORAGE_PROPERTY_SET and STORAGE_DEVICE_DESCRIPTOR (buffer), I also tried with no output buffer, but same issue
if (!DeviceIoControl(device, IOCTL_STORAGE_SET_PROPERTY, new_buffer, new_buffer_size, new_buffer, new_buffer_size, &bytes_returned, nullptr)) {
DWORD code = GetLastError();
std::cerr << "Failed to write to the drive. Error code: " << code << std::endl;
CloseHandle(device);
delete[] buffer;
delete[] new_buffer;
return 5;
}
std::cout << "Write successful." << std::endl;
CloseHandle(device);
delete[] buffer;
delete[] new_buffer;
EDIT 2: Also tried this:
ULONG new_buffer_size = sizeof(STORAGE_PROPERTY_SET) + buffer_size;
BYTE* new_buffer = new BYTE[new_buffer_size];
STORAGE_PROPERTY_SET set;
set.SetType = PropertyStandardSet;
set.PropertyId = StorageDeviceProperty;
memcpy(new_buffer, &set, sizeof(STORAGE_PROPERTY_SET));
memcpy(&((STORAGE_PROPERTY_SET*)new_buffer)->AdditionalParameters[0], buffer, buffer_size);
// Write the buffer combined with STORAGE_PROPERTY_SET and STORAGE_DEVICE_DESCRIPTOR (buffer), I also tried with no output buffer, but same issue
if (!DeviceIoControl(device, IOCTL_STORAGE_SET_PROPERTY, new_buffer, new_buffer_size, new_buffer, new_buffer_size, &bytes_returned, nullptr)) {
DWORD code = GetLastError();
std::cerr << "Failed to write to the drive. Error code: " << code << std::endl;
CloseHandle(device);
delete[] buffer;
delete[] new_buffer;
return 5;
}
std::cout << "Write successful." << std::endl;
CloseHandle(device);
delete[] buffer;
delete[] new_buffer;
But the IOCTL_STORAGE_SET_PROPERTY device io control operation fails with code 1. Why are the function parameters invalid?