Programming - cpueblo.com

WM_DEVICECHANGE 활용 - COM PORT Load / Unload 편


글쓴이 : 유광희 날짜 : 2006-08-31 (목) 15:07 조회 : 13235

WM_DEVICECHANGE 메세지

이번에는 시스템에 새로운 COM 포트가 생성되거나 제거될때, 감지하는 프로그램을 만드려 합니다


모든 COM 포트는 생성 / 제거될때 윈도우에 BROADCAST 방식으로 모든 윈도우에 WM_DEVICECHANGE 이벤트를 발생하게 됩니다
(이는 정확히 말하면 모든 COM 포트를 다루는 드라이버가 자동으로 발생시켜 주는 것이 아니며, 해당하는 드라이버에서 Load / Unload 될때
IoSetDeviceInterfaceState 함수를 통해 발생시켜야 합니다)


Load / Unload 시의 메세지 발생 절차
장치 연결 -> 해당 드라이버 SYS 파일 로드 -> 드라이버내에서 IoSetDeviceInterfaceState 실행
-> 모든 윈도우에 WM_DEVICECHANGE 가 발생 -> COM PORT 감지


WM_DEVICECHANGE 는 모든 윈도우 핸들에 메세지를 전달하기 때문에 특별한 핸들이 필요하지 않습니다.
단지 WM_DEVICECHANGE 를 처리 할 수 있는 함수만 있으면 됩니다.


다만 특정한 GUID 를 가진 드라이버를 검색하기 위해서는 등록 절차가 필요합니다.
이 항목은 PDA 의 ActiveSync 에 사용되는 드라이버를 감지하는 예제를 다루는

페이지를 참고해 주세요


자 이제, WM_DEVICECHANGE 를 활용하여 COM 포트를 감지하는 프로그램을 만들어 봅시다



WindowProc 에 WM_DEVICECHANGE 와 COM PORT 의 Load / Unload 를 체크하는 함수

LRESULT CWMDeviceChangeDlg::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) { CString Str; PDEV_BROADCAST_HDR pdbch = (DEV_BROADCAST_HDR *) lParam; PDEV_BROADCAST_PORT pdbcp = (PDEV_BROADCAST_PORT) lParam; PDEV_BROADCAST_VOLUME pdbcv = (PDEV_BROADCAST_VOLUME) lParam; // // COM 포트는 DBT_DEVTYP_PORT 형태로 들어온다 // // 장치가 올라올때는 DBT_DEVICEARRIVAL, 내려갈때는 DBT_DEVICEREMOVAL // if (message == WM_DEVICECHANGE && wParam == DBT_DEVICEARRIVAL && pdbch->dbch_devicetype == DBT_DEVTYP_PORT) { char *COMPort = pdbcp->dbcp_name; Str.Format("[%s] 포트가 시스템에 생성되었습니다", COMPort); AfxMessageBox(Str); } if (message == WM_DEVICECHANGE && wParam == DBT_DEVICEREMOVECOMPLETE && pdbch->dbch_devicetype == DBT_DEVTYP_PORT) { char *COMPort = pdbcp->dbcp_name; Str.Format("[%s] 포트가 시스템에서 제거되었습니다", COMPort); AfxMessageBox(Str); } return CDialog::WindowProc(message, wParam, lParam); }

사용되는 구조체

DEV_BROADCAST_HDR (c:/ntddk/inc/dbt.h)

typedef struct _DEV_BROADCAST_HDR { DWORD dbch_size; DWORD dbch_devicetype; DWORD dbch_reserved; } DEV_BROADCAST_HDR, *PDEV_BROADCAST_HDR;

DEV_BROADCAST_PORT (c:/ntddk/inc/dbt.h)

typedef struct _DEV_BROADCAST_PORT_A { DWORD dbcp_size; DWORD dbcp_devicetype; DWORD dbcp_reserved; char dbcp_name[1]; } DEV_BROADCAST_PORT_A, *PDEV_BROADCAST_PORT_A;

DEV_BROADCAST_HDR (c:/ntddk/inc/dbt.h)

typedef struct _DEV_BROADCAST_PORT_A { DWORD dbcp_size; DWORD dbcp_devicetype; DWORD dbcp_reserved; char dbcp_name[1]; } DEV_BROADCAST_PORT_A, *PDEV_BROADCAST_PORT_A;

DBT_DEVICEARRIVAL 등의 값

/* * The following messages are for WM_DEVICECHANGE. The immediate list * is for the wParam. ALL THESE MESSAGES PASS A POINTER TO A STRUCT * STARTING WITH A DWORD SIZE AND HAVING NO POINTER IN THE STRUCT. * */ #define DBT_DEVICEARRIVAL 0x8000 // system detected a new device #define DBT_DEVICEQUERYREMOVE 0x8001 // wants to remove, may fail #define DBT_DEVICEQUERYREMOVEFAILED 0x8002 // removal aborted #define DBT_DEVICEREMOVEPENDING 0x8003 // about to remove, still avail. #define DBT_DEVICEREMOVECOMPLETE 0x8004 // device is gone #define DBT_DEVICETYPESPECIFIC 0x8005 // type specific event #if(WINVER >= 0x040A) #define DBT_CUSTOMEVENT 0x8006 // user-defined event #endif #define DBT_DEVTYP_OEM 0x00000000 // oem-defined device type #define DBT_DEVTYP_DEVNODE 0x00000001 // devnode number #define DBT_DEVTYP_VOLUME 0x00000002 // logical volume #define DBT_DEVTYP_PORT 0x00000003 // serial, parallel #define DBT_DEVTYP_NET 0x00000004 // network resource

관련 링크

MSDN - WM_DEVICECHANGE 메세지
MSDN - DEV_BROADCAST_HDR 구조체