[C++] WMI를 이용해 Local PC의 고정 IP 변경하기
우리 회사에서 개발 중인 무선 계측기는 검색 기능을 제공하는데, 검색 방법은 UDP 프로토콜을 이용한 브로드캐스팅이다. 짜증스럽게도, UDP 프로토콜로 브로드캐스팅을 하기 위해서는 IP 대역이 맞아야 한다.
우리의 사랑스런(?) 무선계측기들은 IP가 192로 시작하고... 우리 회사의 PC들은 고정 IP를 사용하는데.. 211로 시작한다. 따라서, 무선계측기를 테스트하려고 하면, 항상 IP를 바꿔주는 노가다가 필요하다. 단지, UDP로 브로드캐스팅을 하기 위해서..-_-
일일이 네트워크 환경 - 설정 - TCP/IP 설정..... 으로 이어지는 귀차니즘을 이기지 못하고, 알아본바.. WMI라는 녀석을 알게 되었다.
WMI는 Windows Management Instrumentation인데, Windows 기반 운영체제의 management 데이터를 위한 인프라 구조라고 할 수 있다.
쉽게, 예를 들자면.. 내 운영체제의 버전이 얼마인지? 또는 내 컴퓨터의 IP를 변경하고 싶다던지? 내지는 원격으로 컴퓨터에 프로그램을 설치하고 싶다던지... 이 모든 것이 다 WMI로 가능하다는 것이다.
더 상세한 내용은 MSDN을 참고하기로 하고.. 이미 이전에 WMI를 이용해 C#으로 간단히 IP와 서브넷 마스크, 게이트웨이 등을 설정할 수 있는 프로그램을 만든 바가 있어서 C++로도 간단히 1~2시간이면 할 수 있을거라 여겼다.
하지만, Wrapper Class와 많은 예제가 제공되던 C#과는 달리, C++에서는 WMI가 완전히 COM API 레벨에서 해결해야 하고, 내가 원하는 수준의 예제가 없었다. (내가 못 찾은건지도 모른다-ㅁ-)
그러다보니.. 삽질에 삽질을 거듭하다.. 결국 야근까지 하게되며.. 무려 6시간을 잡고 헤맸다.
잡설이 길었는데.. WMI를 이용해 Local PC의 IP를 바꾸는 내용으로 돌아와서...
구현 환경은 Windows XP Professional, Microsoft Visual Studio 6.0 SP6이다.
내 기억이 맞다면, Microsoft Visual Studio 6.0에서 WMI를 구현하기 위해서는 아마도 Microsoft Platform SDK 또는 WMI SDK를 설치해야 하는 것으로 알고 있다.
그리고 코드의 전체적인 흐름은 다음과 같다.
Step 1. COM 라이브러리를 초기화한다.
Step 2. COM Security Level을 설정한다.
Step 3. WMI에 대한 초기 Locator를 획득한다.
Step 4. WMI에 접근한다.
Step 5. Proxy의 Security Level을 설정한다.
여기까지는 사실, WMI를 프로그래밍 하기 위한 준비 단계라 할 수 있다. 이 다음부터는, IP와 서브넷마스크를 설정하기 위한 단계이다.
Step 6. ExecQuery()를 이용해, Class Object Enum을 가져온다.
hr = pServices->ExecQuery(
bstr_t("WQL"),
bstr_t("SELECT * FROM Win32_NetworkAdapterConfiguration"),
WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
NULL,
&pEnum
);
쉽게 설명하면, Win32_NetworkAdapterConfiguration란 클래스로부터 Network Adpater들의 Enum을 가져온다고 볼 수 있다. WMI의 Win32 Class에 대한 보다 상세한 정보는 http://msdn2.microsoft.com/en-us/library/aa394084.aspx 를 참조하기 바란다.
Step 7. Step 6에서 획득한 Network Adapter들 중에서 IPEnabled(IP 변경 가능 속성)이 TRUE인 녀석의 Index를 찾는다.
Step 8. IP와 서브넷마스크의 값을 설정한다.
Step 9. Object Path를 설정한다.
여기서 Object Path에 대해서 설명하자면.. IP와 서브넷을 변경하기 위해 Win32_NetworkAdapterConfiguration 클래스에서 제공하는 Method가 EnableStatic이다. 이 Method의 타겟이 바로 Object Path라고 할 수 있다. (EnableStatic의 보다 자세한 내용은 http://msdn2.microsoft.com/en-us/library/aa390383.aspx 를 참조하기 바람)
이 부분이 필요한 이유는 비록 내 PC에서 네트워크 환경에서 보이는 로컬 연결 속성이 하나라고 해서, Network Adapter가 1개가 아니고, 로컬 연결 속성으로 사용되지 못하기 때문에, 눈에 보이지 않는 Network Adapter가 다수 존재한다. 따라서, Step 7도 이러한 이유에서 이다.
결국, EnableStatic의 타켓은 Win32_NetWorkAdapterConfiguration.Index이고, Step 7에서는 이 Index를 찾기 위한 단계였다.
Step 10 ~ Step 14는 앞서 설정한 속성들을 Network Adapter에 반영하기 위한 단계들인데, 여기에 등장하는 함수들은 MSDN을 참고하기 바란다.
다음의 코드는 단순히 기능 구현에 중점을 뒀기 때문에, 코드 최적화에 대해서는 전혀 고려하지 않은 막장 코드이므로, 실제 응용을 위해서, 다듬을 필요가 있다.
소스코드 다운로드: http://www.nohungry.net/Data/IPHandler.zip
Trackback
Trackback Address :: http://www.nohungry.net/tt1/trackback/116

Comments
좋은 자료 잘 보았습니다.
다만, 장치의 Index 값을 얻을 때 1을 시작으로 하고 있으나, XP Home Edition 이나 XP Embedded 등의 다른 버전 OS에서는 0부터 시작하는 경우도 있습니다.
따라서 임의적인 증가 수치를 사용하는 것은 문제 발생의 소지가 있구요. 대신 uint32 Index 멤버를 참조하는 것이 정확합니다.
그렇군요!
좋은 지적 감사 드립니다.ㅎ
잘보았습니다 간단한 예제를 찾고 있었는데
가뭄에 단비였네요 일단 더 분석을 해봐야겠지만 감사합니다