diff --git a/SmartArrayControllerTool.sln b/SmartArrayControllerTool.sln new file mode 100644 index 0000000..acf11dd --- /dev/null +++ b/SmartArrayControllerTool.sln @@ -0,0 +1,31 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.6.33723.286 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SmartArrayControllerTool", "SmartArrayControllerTool\SmartArrayControllerTool.vcxproj", "{21404AC8-39DC-4E18-8B23-C922EEBD160C}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {21404AC8-39DC-4E18-8B23-C922EEBD160C}.Debug|x64.ActiveCfg = Debug|x64 + {21404AC8-39DC-4E18-8B23-C922EEBD160C}.Debug|x64.Build.0 = Debug|x64 + {21404AC8-39DC-4E18-8B23-C922EEBD160C}.Debug|x86.ActiveCfg = Debug|Win32 + {21404AC8-39DC-4E18-8B23-C922EEBD160C}.Debug|x86.Build.0 = Debug|Win32 + {21404AC8-39DC-4E18-8B23-C922EEBD160C}.Release|x64.ActiveCfg = Release|x64 + {21404AC8-39DC-4E18-8B23-C922EEBD160C}.Release|x64.Build.0 = Release|x64 + {21404AC8-39DC-4E18-8B23-C922EEBD160C}.Release|x86.ActiveCfg = Release|Win32 + {21404AC8-39DC-4E18-8B23-C922EEBD160C}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {AEA5CED4-6264-4AEC-AD59-18EC53C2C573} + EndGlobalSection +EndGlobal diff --git a/SmartArrayControllerTool/SmartArrayControllerTool.cpp b/SmartArrayControllerTool/SmartArrayControllerTool.cpp new file mode 100644 index 0000000..f09e9cb --- /dev/null +++ b/SmartArrayControllerTool/SmartArrayControllerTool.cpp @@ -0,0 +1,249 @@ +#define WIN32_LEAN_AND_MEAN +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +typedef struct { + unsigned char num_logical_drives; + uint32_t signature; + uint32_t running_firm_rev; + unsigned char rom_firm_rev[4]; + unsigned char hardware_rev; + unsigned char reserved[4]; + uint32_t drive_present_bit_map; + uint32_t external_drive_bit_map; + uint32_t board_id; + unsigned char reserved2; + uint32_t non_disk_map; + unsigned char reserved3[5]; + unsigned char marketing_revision; + unsigned char controller_flags; + // unsigned char reserved4[2]; + unsigned char host_flags; + unsigned char expand_disable_code; + unsigned char scsi_chip_count; + uint32_t reserved5; + uint32_t ctlr_clock; + unsigned char drives_per_scsi_bus; + uint16_t big_drive_present_map[8]; + uint16_t big_ext_drive_map[8]; + uint16_t big_non_disk_map[8]; + + /* Beyond this point is previously undisclosed stuff which + my higher-ups at HP have nonetheless allowed me to put in here. + Was told most of this stuff is exposed to some degree by + the Array Diagnostics Utility already anyhow, so no big deal. + */ + + unsigned short task_flags; /* used for FW debugging */ + unsigned char ICL_bus_map; /* Bitmap used for ICL between controllers */ + unsigned char redund_ctlr_modes_support; /* See REDUNDANT MODE VALUES */ +#define SUPPORT_ACTIVE_STANDBY 0x01 +#define SUPPORT_PRIMARY_SECONDARY 0x02 + unsigned char curr_redund_ctlr_mode; /* See REDUNDANT MODE VALUES */ +#define ACTIVE_STANDBY_MODE 0x01 +#define PRIMARY_SECONDARY_MODE 0x02 + unsigned char redund_ctlr_status; /* See REDUNDANT STATUS FLAG */ +#define PREFERRED_REDUNDANT_CTLR (0x04) + unsigned char redund_op_failure_code; /* See REDUNDANT FAILURE VALUES */ + unsigned char unsupported_nile_bus; + unsigned char host_i2c_autorev; + unsigned char cpld_revision; + unsigned char fibre_chip_count; + unsigned char daughterboard_type; + unsigned char reserved6[2]; + + unsigned char access_module_status; + unsigned char features_supported[12]; + unsigned char bRecRomInactiveRev[4]; /* Recovery ROM inactive f/w revision */ + unsigned char bRecRomFlags; /* Recovery ROM flags */ + unsigned char bPciToPciBridgeStatus; /* PCI to PCI bridge status */ + unsigned int ulReserved; /* Reserved for future use */ + unsigned char bPercentWriteCache; /* Percent of memory allocated to write cache */ + unsigned short usDaughterboardCacheSize;/* Total cache board size */ + unsigned char bCacheBatteryCount; /* Number of cache batteries */ + unsigned short usTotalMemorySize; /* Total size (MB) of atttached memory */ + unsigned char bMoreControllerFlags; /* Additional controller flags byte */ + unsigned char bXboardHostI2cAutorev; /* 2nd byte of 3 byte autorev field */ + unsigned char bBatteryPicRev; /* BBWC PIC revision */ + unsigned char bDdffVersion[4]; /* DDFF update engine version */ + unsigned short usMaxLogicalUnits; /* Maximum logical units supported */ + unsigned short usExtLogicalUnitCount; /* Big num configured logical units */ + unsigned short usMaxPhysicalDevices; /* Maximum physical devices supported */ + unsigned short usMaxPhyDrvPerLogicalUnit; /* Max physical drive per logical unit */ + unsigned char bEnclosureCount; /* Number of attached enclosures */ + unsigned char bExpanderCount; /* Number of expanders detected */ + unsigned short usOffsetToEDPbitmap; /* Offset to extended drive present map*/ + unsigned short usOffsetToEEDPbitmap; /* Offset to extended external drive present map */ + unsigned short usOffsetToENDbitmap; /* Offset to extended non-disk map */ + unsigned char bInternalPortStatus[8]; /* Internal port status bytes */ + unsigned char bExternalPortStatus[8]; /* External port status bytes */ + unsigned int uiYetMoreControllerFlags; /* Yet More Controller flags */ + unsigned char bLastLockup; /* Last lockup code */ + unsigned char bSlot; /* PCI slot according to option ROM*/ + unsigned short usBuildNum; /* Build number */ + unsigned int uiMaxSafeFullStripeSize; /* Maximum safe full stripe size */ + unsigned int uiTotalLength; /* Total structure length */ + unsigned char bVendorID[8]; /* Vendor ID */ + unsigned char bProductID[16]; /* Product ID */ + unsigned char reserved7[288]; + + /* End of previously unexposed stuff */ + +} id_ctlr; + +typedef struct alarm_struct_t { + uint8_t alarm_status; + uint8_t temp_status; + uint8_t valid_alarm_bits; + uint16_t alarm_count; + uint16_t specific_alarm_counts[8]; +} alarm_struct; + +typedef struct inquiry_data_t { + uint8_t peripheral_type; + uint8_t rmb; + uint8_t versions; + uint8_t misc; + uint8_t additional_length; + uint8_t reserved[2]; + uint8_t support_bits; + uint8_t vendor_id[8]; + uint8_t product_id[16]; + uint8_t product_revision[4]; +} inquiry_data; + +typedef struct sense_bus_param_t { + inquiry_data inquiry; + uint8_t inquiry_valid; + uint32_t installed_drive_map; + uint16_t hot_plug_count[32]; + uint8_t reserved1; /* physical box number? */ + uint8_t reserved2; + alarm_struct alarm_data; + uint16_t connection_info; /* 0x01: External Connector is Used? */ + uint8_t scsi_device_revision; + uint8_t fan_status; + uint8_t more_inquiry_data[64]; + uint32_t scsi_device_type; + uint32_t bus_bit_map; + uint8_t reserved3[8]; + uint8_t scsi_initiator_id; + uint8_t scsi_target_id; + uint8_t physical_port[2]; + uint16_t big_installed_drive_map[8]; + uint16_t big_bus_bit_map[8]; + uint16_t big_box_bit_map[8]; + uint8_t installed_box_map; + uint8_t more_connection_info; + uint8_t reserved4[2]; + char chassis_sn[40]; +} sense_bus_param; +#include + +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; + + + + SCSI_PASS_THROUGH_DIRECT scsiPassThrough = { 0 }; + scsiPassThrough.Length = sizeof(SCSI_PASS_THROUGH_DIRECT); + scsiPassThrough.PathId = 0; + scsiPassThrough.TargetId = 2; // Target ID of the RAID controller + scsiPassThrough.Lun = 0; + scsiPassThrough.DataIn = SCSI_IOCTL_DATA_IN; + //scsiPassThrough.DataTransferLength = bufferSize; // Size of the status buffer + scsiPassThrough.TimeOutValue = 2; // Timeout in seconds + //scsiPassThrough.DataBuffer = statusBuffer; // Buffer to store the status information + scsiPassThrough.CdbLength = 10; // SCSI command length + + + + + auto signature = "CPQCISS"; + + const UCHAR payload[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87, 0x5B, 0x94, 0x04, 0x00, 0x00, 0x00, 0x00, 0x90, 0x4A, + 0x4F, 0x0D, 0x00, 0x01, 0x00, 0x00, 0xA0, 0x62, 0x4F, 0x0D, 0x00, 0x00, 0x00, 0x00, 0xB0, 0xA9, 0xDA, 0x03, + 0x00, 0x00, 0x00, 0x00, 0xB0, 0xA9, 0xDA, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x84, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x4A, 0x4F, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x50, 0x8A, 0xC4, 0x03 + }; + + const size_t requestSize = sizeof(SRB_IO_CONTROL) + ARRAYSIZE(payload); + const PSRB_IO_CONTROL request = (PSRB_IO_CONTROL)malloc(requestSize); + ZeroMemory(request, sizeof(SRB_IO_CONTROL)); + + request->HeaderLength = sizeof(SRB_IO_CONTROL); + CopyMemory(request->Signature, signature, sizeof(request->Signature)); + request->ControlCode = 4; + request->Timeout = 180; + request->Length = ARRAYSIZE(payload); + + DWORD bytesReturned = 0; + BOOL ret = DeviceIoControl( + handle, + IOCTL_SCSI_MINIPORT, + request, + requestSize, + request, + requestSize, + &bytesReturned, + NULL + ); + + if (ret) + { + std::wcout << L"Request succeeded" << std::endl; + + const std::vector buffer((PUCHAR)request, (PUCHAR)request + requestSize); + + 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) << c << L" "; }); + + const std::wstring hexString = ss.str(); + + std::wcout << L"Result buffer: " << hexString << std::endl; + } + + free(request); + CloseHandle(handle); +} diff --git a/SmartArrayControllerTool/SmartArrayControllerTool.vcxproj b/SmartArrayControllerTool/SmartArrayControllerTool.vcxproj new file mode 100644 index 0000000..3028728 --- /dev/null +++ b/SmartArrayControllerTool/SmartArrayControllerTool.vcxproj @@ -0,0 +1,139 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 16.0 + Win32Proj + {21404ac8-39dc-4e18-8b23-c922eebd160c} + SmartArrayControllerTool + 10.0 + + + + Application + true + v143 + Unicode + + + Application + false + v143 + true + Unicode + + + Application + true + v143 + Unicode + + + Application + false + v143 + true + Unicode + + + + + + + + + + + + + + + + + + + + + + Level3 + true + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + MultiThreadedDebug + + + Console + true + + + + + Level3 + true + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + MultiThreaded + + + Console + true + true + true + + + + + Level3 + true + _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + MultiThreadedDebug + + + Console + true + + + + + Level3 + true + true + true + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + MultiThreaded + + + Console + true + true + true + + + + + + + + + \ No newline at end of file diff --git a/SmartArrayControllerTool/SmartArrayControllerTool.vcxproj.filters b/SmartArrayControllerTool/SmartArrayControllerTool.vcxproj.filters new file mode 100644 index 0000000..021ae52 --- /dev/null +++ b/SmartArrayControllerTool/SmartArrayControllerTool.vcxproj.filters @@ -0,0 +1,22 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Source Files + + + \ No newline at end of file