「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; }