1

I'm interested in how to programatically detect the manufacturer of a hard drive, SSD, etc connected to a Windows PC. If it makes any difference I'll probably use C++ on Windows 10.

Perhaps there's multiple levels, perhaps registry, Windows API, SATA, USB?

I need a method that will work for external drives connected by USB. I think I'm looking for a Windows API that will query the hardware.

Googling I can only see to find ways to see this info from the console or some app, or ways to query other information about the drives but not the manufacturer.

hippietrail
  • 15,848
  • 18
  • 99
  • 158
  • 1
    You can use WMI's Win32_DiskDrive class https://learn.microsoft.com/en-us/windows/win32/cimwin32prov/win32-diskdrive . Otherwise query the disk itself, but its more complicated: https://stackoverflow.com/questions/5070987/sending-ata-commands-directly-to-device-in-windows But as you'll find out the WMI's Manufacturer fields is often populated with "(Standard disk drives)". For other APIs, there will be nothing. If this is the case, it means this information is not available at all. You'll only get the model (which often contains some hint like "WDC" for Western Digital) – Simon Mourier Apr 18 '20 at 14:22
  • 1
    For example, a disk drive listed in Device Manager: `Samsung SSD 850 EVO 500GB`, what you want to get is manufacture name like `Samsung`? – Rita Han Apr 20 '20 at 03:09
  • @RitaHan-MSFT: Yes. I don't know if I'd have to parse a string like that and if the format would be reliable, or if there would be some low-level binary numbers to look up in a table? – hippietrail Apr 20 '20 at 04:46
  • @hippietrail Does the answer work for you? – Rita Han Apr 24 '20 at 08:07

1 Answers1

1

You will find hardware disk manufacture name, for example, at the following Registry key:

HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP\Scsi\Scsi Port 0\Scsi Bus 0\Target Id 0\Logical Unit Id 0

There is a value name "Identifier" seems what you are looking for:

enter image description here

The following is an example for query this value using Registry Functions:

#include <windows.h>
#include <tchar.h>

#define MAX_VALUE_NAME 16383

void QueryKey(HKEY hKey)
{
    DWORD    cValues;   // number of values for key 
    DWORD    retCode;
    TCHAR    pvData[MAX_VALUE_NAME];
    DWORD    cbData = sizeof(TCHAR) * MAX_VALUE_NAME;
    TCHAR    targetValue[] = L"Identifier";

    // Get the value count. 
    retCode = RegQueryInfoKey(
        hKey,           // key handle 
        NULL,           
        NULL,           
        NULL,                    
        NULL,               
        NULL,            
        NULL,            
        &cValues,       // number of values for this key 
        NULL,            
        NULL,         
        NULL,   
        NULL);       

    // Get the key value. 
    if (cValues)
    {
        retCode = RegGetValue(hKey, NULL, targetValue, RRF_RT_REG_SZ, NULL, pvData, &cbData);
        if (retCode != ERROR_SUCCESS)
        {
            _tprintf(TEXT("RegGetValue fails with error: %d\n", retCode));
            return;
        }
        _tprintf(TEXT("%s: %s\n"), targetValue, pvData);
    }
}

void main(void)
{
    HKEY hTestKey;

    if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
        TEXT("HARDWARE\\DEVICEMAP\\\Scsi\\Scsi Port 0\\Scsi Bus 0\\Target Id 0\\Logical Unit Id 0"),
        0,
        KEY_READ,
        &hTestKey) == ERROR_SUCCESS
        )
    {
        QueryKey(hTestKey);
    }

    RegCloseKey(hTestKey);
}
Rita Han
  • 9,574
  • 1
  • 11
  • 24