2023-06-25 15:56:59 +02:00
|
|
|
//
|
|
|
|
// WinAPI
|
|
|
|
//
|
2023-06-23 02:21:34 +02:00
|
|
|
#define WIN32_LEAN_AND_MEAN
|
|
|
|
#include <Windows.h>
|
2023-06-25 20:36:13 +02:00
|
|
|
#include <WinSock2.h>
|
2023-06-23 02:21:34 +02:00
|
|
|
#include <winioctl.h>
|
|
|
|
#include <ntddscsi.h>
|
2023-06-25 15:56:59 +02:00
|
|
|
#include <devioctl.h>
|
|
|
|
#include <ntdddisk.h>
|
|
|
|
#include <ntddscsi.h>
|
|
|
|
#define _NTSCSI_USER_MODE_
|
|
|
|
#include <scsi.h>
|
|
|
|
#include <stdint.h>
|
|
|
|
#include "ScsiStuff.h"
|
|
|
|
|
2023-06-25 20:36:13 +02:00
|
|
|
#pragma comment(lib, "ws2_32")
|
|
|
|
|
2023-06-25 15:56:59 +02:00
|
|
|
//
|
|
|
|
// STL
|
|
|
|
//
|
|
|
|
#include <algorithm>
|
2023-06-25 16:46:11 +02:00
|
|
|
#include <codecvt>
|
2023-06-25 15:56:59 +02:00
|
|
|
#include <iomanip>
|
2023-06-23 02:21:34 +02:00
|
|
|
#include <iostream>
|
2023-06-25 16:46:11 +02:00
|
|
|
#include <locale>
|
2023-06-23 02:21:34 +02:00
|
|
|
#include <sstream>
|
|
|
|
#include <vector>
|
|
|
|
|
2023-06-25 15:56:59 +02:00
|
|
|
|
2023-06-25 16:46:11 +02:00
|
|
|
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
|
|
|
|
|
2023-06-25 15:56:59 +02:00
|
|
|
//
|
|
|
|
// Sends a sample request, sniffed from the official HP Array Configuration Utility
|
|
|
|
//
|
2023-06-25 18:56:34 +02:00
|
|
|
void SendScsiMiniportRequest(HANDLE handle, PUCHAR Buffer, ULONG BufferLength)
|
2023-06-25 15:56:59 +02:00
|
|
|
{
|
2023-06-25 18:56:34 +02:00
|
|
|
PSRB_IO_CONTROL pIoControl = (PSRB_IO_CONTROL)&Buffer[0];
|
2023-06-25 16:46:11 +02:00
|
|
|
|
|
|
|
std::wcout << L"[I] - HeaderLength: " << std::dec << pIoControl->HeaderLength << std::endl;
|
|
|
|
std::wcout << L"[I] - Signature: " << converter.from_bytes((const char*)pIoControl->Signature) << std::endl;
|
|
|
|
std::wcout << L"[I] - Timeout: " << std::dec << pIoControl->Timeout << std::endl;
|
|
|
|
std::wcout << L"[I] - ControlCode: " << std::hex << pIoControl->ControlCode << std::endl;
|
|
|
|
std::wcout << L"[I] - ReturnCode: " << std::dec << pIoControl->ReturnCode << std::endl;
|
|
|
|
std::wcout << L"[I] - Length: " << std::dec << pIoControl->Length << std::endl;
|
|
|
|
std::wcout << std::endl;
|
|
|
|
|
2023-06-25 15:56:59 +02:00
|
|
|
DWORD bytesReturned = 0;
|
|
|
|
BOOL ret = DeviceIoControl(
|
|
|
|
handle,
|
|
|
|
IOCTL_SCSI_MINIPORT,
|
2023-06-25 18:56:34 +02:00
|
|
|
Buffer,
|
|
|
|
BufferLength,
|
|
|
|
Buffer,
|
|
|
|
BufferLength,
|
2023-06-25 15:56:59 +02:00
|
|
|
&bytesReturned,
|
|
|
|
nullptr
|
|
|
|
);
|
|
|
|
|
|
|
|
if (ret)
|
|
|
|
{
|
|
|
|
std::wcout << L"Request succeeded" << std::endl;
|
2023-06-25 16:46:11 +02:00
|
|
|
std::wcout << std::endl;
|
2023-06-25 15:56:59 +02:00
|
|
|
|
2023-06-25 16:46:11 +02:00
|
|
|
std::wcout << L"[O] - HeaderLength: " << std::dec << pIoControl->HeaderLength << std::endl;
|
|
|
|
std::wcout << L"[O] - Signature: " << converter.from_bytes((const char*)pIoControl->Signature) << std::endl;
|
|
|
|
std::wcout << L"[O] - Timeout: " << std::dec << pIoControl->Timeout << std::endl;
|
|
|
|
std::wcout << L"[O] - ControlCode: " << std::hex << pIoControl->ControlCode << std::endl;
|
|
|
|
std::wcout << L"[O] - ReturnCode: " << std::dec << pIoControl->ReturnCode << std::endl;
|
|
|
|
std::wcout << L"[O] - Length: " << std::dec << pIoControl->Length << std::endl;
|
|
|
|
std::wcout << std::endl;
|
|
|
|
|
|
|
|
//
|
|
|
|
// Skips sizeof(SRB_IO_CONTROL) and only dumps the data buffer afterwards
|
|
|
|
//
|
2023-06-25 18:56:34 +02:00
|
|
|
const std::vector<char> buffer((PUCHAR)Buffer + pIoControl->HeaderLength, (PUCHAR)Buffer + pIoControl->HeaderLength + pIoControl->Length);
|
2023-06-25 15:56:59 +02:00
|
|
|
|
|
|
|
std::wostringstream ss;
|
|
|
|
|
|
|
|
ss << std::hex << std::uppercase << std::setfill(L'0');
|
2023-06-25 16:56:47 +02:00
|
|
|
std::for_each(buffer.cbegin(), buffer.cend(), [&](int c) { ss << std::setw(2) << (unsigned char)c << L" "; });
|
2023-06-25 15:56:59 +02:00
|
|
|
|
|
|
|
const std::wstring hexString = ss.str();
|
|
|
|
|
|
|
|
std::wcout << L"Result buffer: " << hexString << std::endl;
|
2023-06-25 18:56:34 +02:00
|
|
|
std::wcout << std::endl;
|
2023-06-25 15:56:59 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
std::wcerr << L"Failed to send request, error: 0x" << std::hex << GetLastError() << std::endl;
|
|
|
|
}
|
|
|
|
}
|
2023-06-23 02:21:34 +02:00
|
|
|
|
|
|
|
int wmain(int argc, wchar_t* argv[])
|
|
|
|
{
|
|
|
|
if (argc < 2)
|
|
|
|
{
|
|
|
|
std::wcerr << L"Please specify device index" << std::endl;
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
const std::wstring deviceName = std::wstring(L"\\\\.\\Scsi").append(argv[1]).append(L":");
|
|
|
|
|
|
|
|
const HANDLE handle = CreateFile(
|
|
|
|
deviceName.c_str(),
|
|
|
|
GENERIC_READ | GENERIC_WRITE,
|
|
|
|
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
|
|
|
nullptr,
|
|
|
|
OPEN_EXISTING,
|
|
|
|
FILE_ATTRIBUTE_NORMAL,
|
|
|
|
nullptr
|
|
|
|
);
|
|
|
|
|
|
|
|
const DWORD error = GetLastError();
|
|
|
|
|
|
|
|
if (handle == INVALID_HANDLE_VALUE)
|
|
|
|
{
|
|
|
|
std::wcerr << L"Failed to open device " << deviceName << ", error: 0x" << std::hex << error << std::endl;
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::wcout << L"Successfully opened device " << deviceName << std::endl;
|
|
|
|
|
2023-06-25 20:11:31 +02:00
|
|
|
ULONG length = 0, returned = 0;
|
|
|
|
SCSI_PASS_THROUGH_WITH_BUFFERS sptwb;
|
2023-06-26 09:38:44 +02:00
|
|
|
|
2023-06-25 20:11:31 +02:00
|
|
|
ZeroMemory(&sptwb, sizeof(SCSI_PASS_THROUGH_WITH_BUFFERS));
|
|
|
|
sptwb.spt.Length = sizeof(SCSI_PASS_THROUGH);
|
|
|
|
sptwb.spt.PathId = 0;
|
|
|
|
sptwb.spt.TargetId = 0;
|
|
|
|
sptwb.spt.Lun = 0;
|
2023-06-25 20:36:13 +02:00
|
|
|
sptwb.spt.CdbLength = 10;
|
2023-06-25 20:11:31 +02:00
|
|
|
sptwb.spt.SenseInfoLength = SPT_SENSE_LENGTH;
|
|
|
|
sptwb.spt.DataIn = SCSI_IOCTL_DATA_IN;
|
2023-06-26 07:50:45 +02:00
|
|
|
sptwb.spt.DataTransferLength = SPTWB_DATA_LENGTH;
|
2023-06-25 20:36:13 +02:00
|
|
|
sptwb.spt.TimeOutValue = 120;
|
2023-06-25 20:11:31 +02:00
|
|
|
sptwb.spt.DataBufferOffset = offsetof(SCSI_PASS_THROUGH_WITH_BUFFERS, ucDataBuf);
|
|
|
|
sptwb.spt.SenseInfoOffset = offsetof(SCSI_PASS_THROUGH_WITH_BUFFERS, ucSenseBuf);
|
2023-06-26 10:20:57 +02:00
|
|
|
//sptwb.spt.Cdb[0] = 0x26; // SCSIOP_READ
|
|
|
|
//sptwb.spt.Cdb[6] = 0x11;
|
|
|
|
//
|
|
|
|
//const unsigned short reqSize = htons(sizeof(id_ctlr));
|
|
|
|
//memcpy(&sptwb.spt.Cdb[7], &reqSize, 2);
|
2023-06-25 20:11:31 +02:00
|
|
|
|
|
|
|
length = offsetof(SCSI_PASS_THROUGH_WITH_BUFFERS, ucDataBuf) + sptwb.spt.DataTransferLength;
|
|
|
|
|
2023-06-26 10:20:57 +02:00
|
|
|
/*std::wcout << std::dec
|
2023-06-26 10:15:41 +02:00
|
|
|
<< L"Total struct size: " << sizeof(SCSI_PASS_THROUGH_WITH_BUFFERS)
|
|
|
|
<< L", Calculated length: " << length
|
|
|
|
<< L", Header length: " << sptwb.spt.Length
|
2023-06-26 10:20:57 +02:00
|
|
|
<< std::endl;*/
|
2023-06-26 10:15:41 +02:00
|
|
|
|
2023-06-25 20:11:31 +02:00
|
|
|
BOOL ret = DeviceIoControl(
|
|
|
|
handle,
|
|
|
|
IOCTL_SCSI_PASS_THROUGH,
|
|
|
|
&sptwb,
|
2023-06-26 09:38:44 +02:00
|
|
|
sizeof(SCSI_PASS_THROUGH) + sptwb.spt.SenseInfoLength,
|
2023-06-25 20:11:31 +02:00
|
|
|
&sptwb,
|
2023-06-26 10:15:41 +02:00
|
|
|
length,
|
2023-06-25 20:11:31 +02:00
|
|
|
&returned,
|
|
|
|
NULL
|
|
|
|
);
|
|
|
|
|
|
|
|
if (ret)
|
|
|
|
{
|
|
|
|
std::wcout << L"Request succeeded" << std::endl;
|
|
|
|
std::wcout << std::endl;
|
2023-06-26 10:20:57 +02:00
|
|
|
|
|
|
|
const std::vector<char> buffer((PUCHAR)&sptwb + sptwb.spt.DataBufferOffset, (PUCHAR)&sptwb + sptwb.spt.DataBufferOffset + sptwb.spt.DataTransferLength);
|
|
|
|
|
|
|
|
std::wostringstream ss;
|
|
|
|
|
|
|
|
ss << std::hex << std::uppercase << std::setfill(L'0');
|
|
|
|
std::for_each(buffer.cbegin(), buffer.cend(), [&](int c) { ss << std::setw(2) << (unsigned char)c << L" "; });
|
|
|
|
|
|
|
|
const std::wstring hexString = ss.str();
|
|
|
|
|
|
|
|
std::wcout << L"Result buffer: " << hexString << std::endl;
|
|
|
|
std::wcout << std::endl;
|
2023-06-25 20:11:31 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2023-06-26 09:38:44 +02:00
|
|
|
const DWORD error = GetLastError();
|
|
|
|
|
|
|
|
std::wstring errorCode = L"Unknown";
|
|
|
|
|
|
|
|
switch (error)
|
|
|
|
{
|
|
|
|
case ERROR_IO_DEVICE:
|
|
|
|
errorCode = L"ERROR_IO_DEVICE";
|
|
|
|
break;
|
|
|
|
case ERROR_INVALID_PARAMETER:
|
|
|
|
errorCode = L"ERROR_INVALID_PARAMETER";
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::wcerr << L"Failed to send request, error: " << errorCode << std::endl;
|
2023-06-25 20:11:31 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef ACU_REPLAY
|
2023-06-25 18:56:34 +02:00
|
|
|
UCHAR request01[] =
|
|
|
|
{
|
|
|
|
#include "request01.bin"
|
|
|
|
};
|
|
|
|
|
|
|
|
UCHAR request02[] =
|
|
|
|
{
|
|
|
|
#include "request02.bin"
|
|
|
|
};
|
|
|
|
|
|
|
|
UCHAR request03[] =
|
|
|
|
{
|
|
|
|
#include "request03.bin"
|
|
|
|
};
|
|
|
|
|
|
|
|
UCHAR request04[] =
|
|
|
|
{
|
|
|
|
#include "request04.bin"
|
|
|
|
};
|
2023-06-25 20:11:31 +02:00
|
|
|
|
2023-06-25 19:02:49 +02:00
|
|
|
UCHAR request05[] =
|
|
|
|
{
|
|
|
|
#include "request05.bin"
|
|
|
|
};
|
2023-06-25 20:11:31 +02:00
|
|
|
|
2023-06-25 19:02:49 +02:00
|
|
|
UCHAR request06[] =
|
|
|
|
{
|
|
|
|
#include "request06.bin"
|
|
|
|
};
|
2023-06-25 20:11:31 +02:00
|
|
|
|
2023-06-25 19:02:49 +02:00
|
|
|
UCHAR request07[] =
|
|
|
|
{
|
|
|
|
#include "request07.bin"
|
|
|
|
};
|
2023-06-25 20:11:31 +02:00
|
|
|
|
2023-06-25 19:02:49 +02:00
|
|
|
UCHAR request08[] =
|
|
|
|
{
|
|
|
|
#include "request08.bin"
|
|
|
|
};
|
2023-06-25 20:11:31 +02:00
|
|
|
|
2023-06-25 19:02:49 +02:00
|
|
|
UCHAR request09[] =
|
|
|
|
{
|
|
|
|
#include "request09.bin"
|
|
|
|
};
|
2023-06-25 20:11:31 +02:00
|
|
|
|
2023-06-25 19:02:49 +02:00
|
|
|
UCHAR request10[] =
|
|
|
|
{
|
|
|
|
#include "request10.bin"
|
|
|
|
};
|
2023-06-25 20:11:31 +02:00
|
|
|
|
2023-06-25 19:02:49 +02:00
|
|
|
UCHAR request11[] =
|
|
|
|
{
|
|
|
|
#include "request11.bin"
|
|
|
|
};
|
2023-06-25 20:11:31 +02:00
|
|
|
|
2023-06-25 19:02:49 +02:00
|
|
|
UCHAR request12[] =
|
|
|
|
{
|
|
|
|
#include "request12.bin"
|
|
|
|
};
|
2023-06-25 20:11:31 +02:00
|
|
|
|
2023-06-25 19:02:49 +02:00
|
|
|
UCHAR request13[] =
|
|
|
|
{
|
|
|
|
#include "request13.bin"
|
|
|
|
};
|
2023-06-25 18:56:34 +02:00
|
|
|
|
|
|
|
SendScsiMiniportRequest(handle, request01, ARRAYSIZE(request01));
|
|
|
|
SendScsiMiniportRequest(handle, request02, ARRAYSIZE(request02));
|
|
|
|
SendScsiMiniportRequest(handle, request03, ARRAYSIZE(request03));
|
|
|
|
SendScsiMiniportRequest(handle, request04, ARRAYSIZE(request04));
|
2023-06-25 19:02:49 +02:00
|
|
|
SendScsiMiniportRequest(handle, request05, ARRAYSIZE(request05));
|
|
|
|
SendScsiMiniportRequest(handle, request06, ARRAYSIZE(request06));
|
|
|
|
SendScsiMiniportRequest(handle, request07, ARRAYSIZE(request07));
|
|
|
|
SendScsiMiniportRequest(handle, request08, ARRAYSIZE(request08));
|
|
|
|
SendScsiMiniportRequest(handle, request09, ARRAYSIZE(request09));
|
|
|
|
SendScsiMiniportRequest(handle, request10, ARRAYSIZE(request10));
|
|
|
|
SendScsiMiniportRequest(handle, request11, ARRAYSIZE(request11));
|
|
|
|
SendScsiMiniportRequest(handle, request12, ARRAYSIZE(request12));
|
|
|
|
SendScsiMiniportRequest(handle, request13, ARRAYSIZE(request13));
|
2023-06-25 20:11:31 +02:00
|
|
|
#endif
|
2023-06-25 16:46:11 +02:00
|
|
|
|
2023-06-23 02:21:34 +02:00
|
|
|
CloseHandle(handle);
|
2023-06-26 10:20:57 +02:00
|
|
|
}
|