SetupDi 함수 사용하기 #
void GetDeviceRegistryProperty()
{
HDEVINFO devInfo;
SP_DEVINFO_DATA devInfoData;
int devIndex = 0;
TCHAR buffer[MAX_PATH] = {0, };
devInfo = SetupDiGetClassDevs(NULL, _T("USB"), NULL, DIGCF_ALLCLASSES);
ZeroMemory(&devInfoData, sizeof(SP_DEVINFO_DATA));
devInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
while (SetupDiEnumDeviceInfo(devInfo, devIndex, &devInfoData))
{
SetupDiGetDeviceRegistryProperty(
devInfo,
&devInfoData,
SPDRP_HARDWAREID,
NULL,
(BYTE *)buffer,
sizeof(buffer),
NULL);
devIndex++;
}
}
마지막 매개변수는 플래그로써 다음과 같은 효과를 가집니다. OR 연산으로 여러개의 플래그를 지정할 수 있습니다.
SP_DEVINFO_DATA를 구했다면 SetupDiGetDeviceRegistryProperty()를 이용하여 해당 디바이스의 속성과 설정값을 구할 수 있습니다. 대략 많이 쓰는 속성들은 다음과 같습니다.
void SetFilter()
{
HDEVINFO devInfo;
SP_DEVINFO_DATA devInfoData;
... 생략 ...
TCHAR filterString[MAX_PATH] = _T("hello\0world\0\0");
SetupDiSetDeviceRegistryProperty(
devInfo,
&devInfoData,
SPDRP_LOWERFILTERS,
(BYTE *)filterString,
sizeof(filterString));
}
SetupDiSetDeviceRegistryProperty()로 해당 장치의 레지스트리에 필터 값을 설정합니다. SPDRP_LOWERFILTERS를 설정하여 LowerFilters에 설정되도록 합니다. 각각의 필터 문자열 값은 널문자(\0)로 구분해주고 마지막에는 두개의 널문자(\0\0)를 넣어줍니다. REG_MULTI_SZ 타입이기 때문입니다. 마지막 버퍼 크기는 실제 문자열 값의 길이를 넣어줘도 되지만, 필터 문자열 값 중간에 널(\0)이 들어가 있어서 _tcslen() 함수로는 길이를 구해 올 수 없습니다. 따라서 버퍼의 크기만 넣어줘도 마지막 두개의 널문자(\0\0)을 체크하여 기록하기 때문에 큰 상관은 없습니다.
필터 드라이버 로드
void PropertyChange()
{
HDEVINFO devInfo;
SP_DEVINFO_DATA devInfoData;
... 생략 ...
SP_PROPCHANGE_PARAMS propChangeParams;
ZeroMemory(&propChangeParams, sizeof(SP_PROPCHANGE_PARAMS));
propChangeParams.ClassInstallHeader.cbSize = sizeof(SP_CLASSINSTALL_HEADER);
propChangeParams.ClassInstallHeader.InstallFunction = DIF_PROPERTYCHANGE;
propChangeParams.StateChange = DICS_PROPCHANGE;
propChangeParams.Scope = DICS_FLAG_CONFIGSPECIFIC;
propChangeParams.HwProfile = 0;
SetupDiSetClassInstallParams(
devInfo,
devInfoData,
(PSP_CLASSINSTALL_HEADER)&propChangeParams,
sizeof(SP_PROPCHANGE_PARAMS));
SetupDiCallClassInstaller(DIF_PROPERTYCHANGE, devInfo, devInfoData);
}
먼저 SP_PROPCHANGE_PARAMS 구조체에 내용을 설정해줍니다. ClassInstallHeader.cbSize에는 SP_CLASSINSTALL_HEADER의 크기를 넣어줍니다. ClassInstallHeader.InstallFunction에는 호출할 DIF 함수를 지정합니다. DIF_PROPERTYCHANGE를 지정하여 속성을 변경하는 함수를 호출 할 수 있도록 합니다.
StateChange에 DICS_PROPCHANGE를 지정하여 속성을 변경할 수 있도록 합니다. Scope에 DICS_FLAG_CONFIGSPECIFIC를 지정하여 현재 선택된 디바이스의 속성만 변경하도록 합니다. HwProfile에는 0(현재 하드웨어 프로파일)을 지정합니다.
실행가능한 예제 : USB 마우스 장치에 필터 설정, 드라이버 로드하기
#include <windows.h>
#include <setupapi.h>
int _tmain(int argc, _TCHAR* argv[])
{
HDEVINFO devInfo;
SP_DEVINFO_DATA devInfoData;
SP_PROPCHANGE_PARAMS propChangeParams;
int devIndex = 0;
TCHAR buffer[MAX_PATH];
devInfo = SetupDiGetClassDevs(
NULL,
_T("USB"),
NULL,
DIGCF_ALLCLASSES | DIGCF_PRESENT);
ZeroMemory(&devInfoData, sizeof(SP_DEVINFO_DATA));
devInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
ZeroMemory(&propChangeParams, sizeof(SP_PROPCHANGE_PARAMS));
while (SetupDiEnumDeviceInfo(devInfo, devIndex, &devInfoData))
{
SetupDiGetDeviceRegistryProperty(
devInfo,
&devInfoData,
SPDRP_COMPATIBLEIDS,
NULL,
(BYTE *)buffer,
sizeof(buffer),
NULL);
// Protocol 2 마우스
if (_tcsstr(buffer, _T("Prot_02")) != NULL)
{
TCHAR filterString[MAX_PATH] = _T("devlower\0\0");
SetupDiSetDeviceRegistryProperty(
devInfo,
&devInfoData,
SPDRP_LOWERFILTERS,
(BYTE *)filterString,
sizeof(filterString));
propChangeParams.ClassInstallHeader.cbSize =
sizeof(SP_CLASSINSTALL_HEADER);
propChangeParams.ClassInstallHeader.InstallFunction =
DIF_PROPERTYCHANGE;
propChangeParams.StateChange = DICS_PROPCHANGE;
propChangeParams.Scope = DICS_FLAG_CONFIGSPECIFIC;
propChangeParams.HwProfile = 0;
SetupDiSetClassInstallParams(
devInfo,
&devInfoData,
(PSP_CLASSINSTALL_HEADER)&propChangeParams,
sizeof(SP_PROPCHANGE_PARAMS));
SetupDiCallClassInstaller(
DIF_PROPERTYCHANGE,
devInfo,
&devInfoData);
}
devIndex++;
}
}
|
|
|
|
|
|