(C++) Windows WLAN API를 이용한 WiFi 프로필 검출
현재 연결된 프로필과 저장된 프로필 목록을 대조해 장비 AP인지 판별한다. WlanQueryInterface의 출력 인자 두 개를 같은 변수로 넘겼다가 포인터가 깨진 일과, wcout에 narrow 리터럴을 넣으면 안 되는 이유를 같이 정리했다.
현재 연결된 프로필과 저장된 프로필 목록을 대조해 장비 AP인지 판별한다. WlanQueryInterface의 출력 인자 두 개를 같은 변수로 넘겼다가 포인터가 깨진 일과, wcout에 narrow 리터럴을 넣으면 안 되는 이유를 같이 정리했다.
같은 망의 장비 IP를 찾으려고 arp 출력을 파싱하다 'Too many open files'에 막혔다. system → popen → fork/exec를 거치며 계속 같은 에러가 났고, 결국 프로세스를 안 띄우는 방향으로 돌아선 기록이다.
netsh wlan show profiles와 같은 결과를 WlanGetProfileList로 얻는다. 목록 순서가 곧 연결 우선순위라는 점, 와이드 문자열 변환에서 널 문자가 하나 더 붙는 버그, 저장된 비밀번호를 읽는 방법까지 정리했다.
접속한 AP의 MAC(BSSID)을 뽑는 코드. 이게 내 어댑터 MAC이 아니라는 점, 같은 장비인데 대역마다 BSSID가 다른 점, 로컬 관리 비트로 임의 주소를 구분하는 법까지 정리했다.
WlanQueryInterface로 현재 연결 정보를 직접 받아오는 방법. 연결이 없을 때 나는 에러, 프로필 이름과 실제 SSID의 차이, 신호 품질 값을 dBm으로 되돌리는 식까지 정리했다.
재미로 짠 코드인데 정리하다 보니 rand() 대신
리눅스 명령 출력을 프로그램 변수로 받는 세 가지 방법을 비교했다. popen이 간단한 이유와 그 대가, fork/exec/pipe를 직접 짤 때 빠뜨리기 쉬운 exit·버퍼 경계·strtok 문제까지 정리했다.
검사 결과를 콘솔에 표로 찍으려고 setw를 썼는데, setw가 바이트를 센다는 것과 한글이 섞이면 코드페이지에 따라 정렬이 무너진다는 것을 나중에 알았다. 그 과정과 대안을 정리했다.
WSAGetLastError가 뱉는 숫자를 사람이 읽는 문장으로 바꾸는 FormatMessage 사용법과, 유니코드 빌드에서 메시지가 깨지는 문제·메시지 끝에 붙는 개행·실패 시 LocalFree가 터지는 문제까지 정리했다.
시리얼 번호로 결과 파일명을 만드는 데 CString::Format과 sprintf_s를 써봤다. 유니코드 빌드에서 std::string을 %s로 넘기면 깨지는 문제, sprintf_s가 넘칠 때 자르는 게 아니라 죽는 문제까지 정리했다.