解決策が見つからない、かなり興味深い問題があります。Setup API を使用して、システム内のドライブを一覧表示しています。列挙子を「IDE」に設定する場合、以下にリストされているコードを使用しても問題はありません。列挙子の値が「SCSI」に設定されていると、私の不安が生じます。この問題を再現するコードは次のとおりです。
#include <iostream>
#include <Windows.h>
#include <SetupAPI.h>
#include <cfgmgr32.h>
#include <devguid.h>
int main() {
std::cout << "Looking for only SCSI disks" << std::endl;
HDEVINFO hDevs(SetupDiGetClassDevs(&GUID_DEVCLASS_DISKDRIVE, "SCSI", NULL, DIGCF_PRESENT));
if(INVALID_HANDLE_VALUE == hDevs) {
DWORD error(GetLastError());
std::cout << "Handle returned is invalid. Error code: " << error << std::endl;
return 1;
}
SP_DEVINFO_DATA sp = {sizeof(SP_DEVINFO_DATA)};
char buff[256];
memset(buff, 0, 256);
DWORD index(0);
std::cout << "The handle is valid, listing drives now" << std::endl;
while(SetupDiEnumDeviceInfo(hDevs, index++, &sp)) {
CM_Get_Device_ID(sp.DevInst, buff, 256, 0);
std::cout << buff << std::endl;
memset(buff, 0, 256);
}
SetupDiDestroyDeviceInfoList(hDevs);
return 0;
}
ご覧のとおり、このコードには特筆すべき点はありません。問題は、特定のラップトップでは、このコードが SetupDiGetClassDevs() でエラーになることです。GetLastError() を確認すると、ERROR_INVALID_DATA (0xd) で失敗したことがわかります。私が理解していないのは、その理由です。これとまったく同じプログラムを、自分のユーザー (管理者権限を持つ) と非特権ユーザーの両方として開発ボックスで実行すると、SCSI ドライブが存在するかどうかに関係なく正常に動作します。
使用中の GUID が正しいことはわかっています。これは devguid.h で定義されています。「SCSI」は有効な PnP 列挙子であり、このMSDN ページで参照されているほか、デバイス マネージャーの「列挙子」プロパティを調べることからも参照できます。3 番目の引数は NULL の場合があり、4 番目の引数はこの関数に対して有効な定義済みフラグです。私がこれを知っているのは、これらのラップトップを除いて、これまでに試したすべてのシステムで動作するからです (私の組織ではかなりの数です)。ここの誰かが、これらの条件でこのエラーで SetupDiGetClassDevs() が失敗する原因を知っているか、少なくとも正しい方向に向けてくれることを願っています。私は Windows の専門家ではないので、システム構成またはアクセス許可に何か不足している可能性があります (ただし、エラーから暗示されているわけではありません)。
明らかなように、管理者権限を持つユーザーと管理者ユーザーの両方としてテストできる 1 台のラップトップでこのコードを実行しましたが、どちらも同じ結果になりました。このラップトップは、Windows 7 64 ビット Service Pack 1 を実行する HP EliteBook 8460p です。このコードを 32 ビットまたは 64 ビットでコンパイルしても違いはありません。