![]()
「C:」などのドライブ名からSetup APIを利用して「汎用ボリューム」といったデバイス名などを取得する。「こんな処理何に使うの?」と聞かれると答えに窮するが...
ドライブ名とHDEVINFO系を関連付けるためにQueryDosDeviceを利用している。
#include <winioctl.h>
#include <setupapi.h>
#pragma comment(lib,"setupapi.lib")
#include "atlstr.h"
//
// 使用中のドライブレター取得
//
//ドライブ名が文字列として列挙されて返る。例:AとC、Dドライブが使われているなら"ACD"
//
bool GetUsedDriveLetter(TCHAR* pszLetter,int nSize)
{
int i;
int nIndex;
TCHAR cbDrive;
DWORD dwDrives;
if(pszLetter == NULL || nSize <= 0)
return false;
dwDrives = ::GetLogicalDrives();
ZeroMemory(pszLetter,sizeof(TCHAR) * nSize);
nIndex = 0;
cbDrive = _T('A');
for(i = 0; i <= 'Z' - 'A'; i++)
{
if(! ((1 << i) & dwDrives))
continue;
pszLetter[nIndex++] = cbDrive + i;
if(nIndex < nSize)
continue;
return (dwDrives << (i+1)) ? false : true;
}
return true;
}
//
// HDEVINFO(SP_DEVINFO_DATA)のプロパティ文字列取得
//
//SetupDiGetDeviceRegistryPropertyにより文字列データを取得する
//
bool GetDeviceRegistryPropertyString(HDEVINFO hDeviceInfoSet,PSP_DEVINFO_DATA pDeviceInfoData,DWORD dwProperty,CAtlString* pstrText)
{
BOOL ret;
DWORD dwDataType;
DWORD dwDataSize;
BYTE* pData;
if(pstrText == NULL)
return false;
*pstrText = _T("");
pData = NULL;
dwDataSize = 0;
while(1)
{
ret = ::SetupDiGetDeviceRegistryProperty(hDeviceInfoSet,pDeviceInfoData,dwProperty,&dwDataType,pData,dwDataSize,&dwDataSize);
if(ret || ::GetLastError() != ERROR_INSUFFICIENT_BUFFER)
break;
if(pData)
delete pData;
pData = new BYTE[dwDataSize];
}
if(ret && pData)
{
//TODO:REG_MULTI_SZも1つの文字列として扱っている!
if(dwDataType == REG_EXPAND_SZ || dwDataType == REG_MULTI_SZ || dwDataType == REG_SZ)
*pstrText = (TCHAR*)pData;
}
if(pData)
delete pData;
return (ret && pData) ? true : false;
}
//
// HDEVINFOデバイス検索例
//
//「C:」などのドライブレターからQueryDosDeviceで取得できる文字列と同じ場所を示すHDEVINFOを探す
//
bool SearchHDEVINFODevice(LPCTSTR pszPhysicalDeviceName)
{
bool bRet;
BOOL ret;
DWORD i;
HDEVINFO hDevInfo;
CAtlString strProperty;
SP_DEVINFO_DATA sDeviceInfoData;
hDevInfo = ::SetupDiGetClassDevs(NULL,0,0,DIGCF_PRESENT | DIGCF_ALLCLASSES);
if(hDevInfo == INVALID_HANDLE_VALUE)
return false;
i = 0;
sDeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
while(1)
{
ret = ::SetupDiEnumDeviceInfo(hDevInfo,i,&sDeviceInfoData);
if(ret == FALSE)
break;
i++;
bRet = GetDeviceRegistryPropertyString(hDevInfo,&sDeviceInfoData,SPDRP_PHYSICAL_DEVICE_OBJECT_NAME,&strProperty);
if(bRet == false)
continue;
//一致するデバイスかどうかチェック
if(strProperty != pszPhysicalDeviceName)
continue;
//デバイスが見つかった!
//ここではいくつかのプロパティをメッセージボックスで表示
{
CAtlString strBuff;
CAtlString strMessage;
bRet = GetDeviceRegistryPropertyString(hDevInfo,&sDeviceInfoData,SPDRP_DEVICEDESC,&strProperty);
if(bRet)
{
strBuff.Format(_T("SPDRP_DEVICEDESC:%s\n"),strProperty);
strMessage += strBuff;
}
bRet = GetDeviceRegistryPropertyString(hDevInfo,&sDeviceInfoData,SPDRP_HARDWAREID,&strProperty);
if(bRet)
{
strBuff.Format(_T("SPDRP_HARDWAREID:%s\n"),strProperty);
strMessage += strBuff;
}
bRet = GetDeviceRegistryPropertyString(hDevInfo,&sDeviceInfoData,SPDRP_CLASS,&strProperty);
if(bRet)
{
strBuff.Format(_T("SPDRP_CLASS:%s\n"),strProperty);
strMessage += strBuff;
}
bRet = GetDeviceRegistryPropertyString(hDevInfo,&sDeviceInfoData,SPDRP_DRIVER,&strProperty);
if(bRet)
{
strBuff.Format(_T("SPDRP_DRIVER:%s\n"),strProperty);
strMessage += strBuff;
}
bRet = GetDeviceRegistryPropertyString(hDevInfo,&sDeviceInfoData,SPDRP_PHYSICAL_DEVICE_OBJECT_NAME,&strProperty);
if(bRet)
{
strBuff.Format(_T("SPDRP_PHYSICAL_DEVICE_OBJECT_NAME:%s\n"),strProperty);
strMessage += strBuff;
}
bRet = GetDeviceRegistryPropertyString(hDevInfo,&sDeviceInfoData,SPDRP_DEVTYPE,&strProperty);
if(bRet)
{
strBuff.Format(_T("SPDRP_DEVTYPE:%s\n"),strProperty);
strMessage += strBuff;
}
::MessageBox(NULL,strMessage,_T(""),MB_OK);
}
}
::SetupDiDestroyDeviceInfoList(hDevInfo);
return true;;
}
bool Test()
{
bool ret;
size_t i;
size_t nSize;
TCHAR pszDrives[256];
//使われている全ドライブを取得
ret = GetUsedDriveLetter(pszDrives,256);
if(ret == false)
return false;
//ドライブごとに処理
nSize = ::_tcslen(pszDrives);
for(i = 0; i < nSize; i++)
{
DWORD dwRet;
TCHAR pszTargetPath[MAX_PATH];
CAtlString strDrive;
strDrive.Format(_T("%c:"),pszDrives[i]);
dwRet = ::QueryDosDevice(strDrive,pszTargetPath,MAX_PATH);
if(dwRet == 0)
continue;
ret = SearchHDEVINFODevice(pszTargetPath);
}
return true;
}
