CM 함수는 PnP Configuration Manager 함수를 뜻합니다.

Root DevNode 얻기

void GetRootDevNode()
{
    DEVINST devInst;
    CONFIGRET cr;

    cr = CM_Locate_DevNode(
       &devInst,
       NULL,
       CM_LOCATE_DEVNODE_NORMAL);
}

CM_Locate_DevNode()에서 첫번째 매개변수 DEVINST는 핸들 형태입니다. 함수 실행 후 해당 디바이스 인스턴스의 핸들을 얻어오게 됩니다. 두번째 매개변수에는 디바이스 인스턴스의 문자열 값을 지정합니다(예: USB\VID_0000&PID_0000&REV_0000 형태). NULL을 지정하면 Root 디바이스 인스턴스 핸들을 얻어 옵니다.

세번째 인자는 다음과 같습니다.

  • CM_LOCATE_DEVNODE_NORMAL: 현재 시스템에 장착된 디바이스의 인스턴스를 얻어옵니다.
  • CM_LOCATE_DEVNODE_PHANTOM: 현재 시스템에 장착된 디바이스와 장착되지 않은 디바이스(Phantom Device, 유령 디바이스) 모두 얻어옵니다.

디바이스 트리 탐색하기

void TraversalDeviceTree()
{
    DEVINST devInst;
    DEVINST devInstNext;
    CONFIGRET cr;

    BOOL finish = FALSE;

    cr = CM_Locate_DevNode(
        &devInst,
        NULL,
        CM_LOCATE_DEVNODE_NORMAL);

    while (finish == FALSE)
    {
        // 
        // 이 부분에서 각 디바이스의 정보를 얻어올 수 있음.
        //

        // 자식 디바이스 인스턴스를 구함
        cr = CM_Get_Child(&devInstNext, devInst, 0);
        if (cr == CR_SUCCESS)
        {
            devInst = devInstNext;
            continue;
        }

        while (TRUE)
        {
            // 형제 디바이스 인스턴스를 구함
            cr = CM_Get_Sibling(&devInstNext, devInst, 0);
            if (cr == CR_SUCCESS)
            {
                devInst = devInstNext;
                break;
            }

            // 부모 디바이스 인스턴스를 구함
            cr = CM_Get_Parent(&devInstNext, devInst, 0);
            if (cr == CR_SUCCESS)
            {
                devInst = devInstNext;
            }
            else
            {
                finish = TRUE;
                break;
            }
        }
    }
}

맨 처음 CM_Locate_DevNode()를 이용하여 Root 디바이스 인스턴스의 핸들을 구해옵니다. 이 핸들을 이용해서 CM_Get_Child(), CM_Get_Sibling(), CM_Get_Parent()로 자식, 형제, 부모 디바이스 인스턴스를 구하면서 탐색을 합니다.

디바이스 ID 구하기

void GetDeviceId()
{
    ... 생략 ...

    ULONG bufLen;
    LPTSTR devInstId = NULL;

    cr = CM_Get_Device_ID_Size(&bufLen, devInst, 0);
    if (cr == CR_SUCCESS)
    {
        devInstId = (LPTSTR)LocalAlloc(LMEM_FIXED, (bufLen + 1) * sizeof(TCHAR));
        ZeroMemory(devInstId, (bufLen + 1) * sizeof(TCHAR));

        cr = CM_Get_Device_ID(devInst, devInstId, bufLen, 0);

        LocalFree((HLOCAL)devInstId);
    }
}

CM_Get_Device_ID_Size()를 사용하여 디바이스 ID의 길이를 구해옵니다. 그리고 구해온 길이 만큼 메모리를 할당합니다. 그리고 CM_Get_Device_ID로 할당한 메모리에 디바이스 ID를 구해올 수 있습니다. 디바이스 ID를 구하는 이유는 해당 장치가 PCI, USB, PCMCIA, SCSI 등 어떤 종류인지 알아내기 위해서입니다.

디바이스 속성 구하기

void GetDeviceProperty()
{
    ... 생략 ...

    TCHAR buffer[512] = {0, };
    ULONG length;

    length = sizeof(buffer);
    cr = CM_Get_DevNode_Registry_Property(
        devInst,
        CM_DRP_DRIVER,
        NULL,
        buffer,
        &length,
        0);

}
  • CM_Get_DevNode_Registry_Property()에 디바이스 트리를 순회하면서 구해온 DEVINST를 넣습니다. 두번째 매개변수에는 구해올 속성 이름을 지정합니다. 대략 많이 사용하는 속성은 다음과 같습니다.
  • CM_DRP_DEVICEDESC : 디바이스 설명
  • CM_DRP_HARDWAREID : 하드웨어 ID
  • CM_DRP_COMPATIBLEIDS : Compatible ID, USB에서는 Class, SubClass, Protocol 등의 값
  • CM_DRP_UPPERFILTERS, CM_DRP_LOWERFILTERS : Upper, Lower Filter 값

필터 설정

void SetFilter()
{
    TCHAR filterString[MAX_PATH] = _T("hello\0world\0\0");
    ULONG filterLength = _tcslen(filter) * sizeof(TCHAR);

    cr = CM_Set_DevNode_Registry_Property(
        devInst,
        CM_DRP_LOWERFILTERS,
        filterString,
        filterLength,
        0);
}

CM_Set_DevNode_Registry_Property() 필터를 설정할 수 있습니다. CM_DRP_LOWERFILTERS로 속성을 지정하고 필터 문자열과 문자열의 길이를 넣어줍니다.


저작권 안내

이 웹사이트에 게시된 모든 글의 무단 복제 및 도용을 금지합니다.
  • 블로그, 게시판 등에 퍼가는 것을 금지합니다.
  • 비공개 포스트에 퍼가는 것을 금지합니다.
  • 글 내용, 그림을 발췌 및 요약하는 것을 금지합니다.
  • 링크 및 SNS 공유는 허용합니다.

Published

04 March 2009