Windows 2000 디바이스 드라이버 샘플 코드 오류

@codemaru · December 02, 2007 · 2 min read

제가 가진 몇 안되는 디바이스 드라이버 책 중에 하나가 "Windows 2000 디바이스 드라이버"입니다. 질럿님께서 번역하셔서 더 애착이 가는 책이기도 합니다. ㅋ 물론 설명이 다른 책에 비해서 훨씬 쉬운 것도 한 가지 장점이 아닌가 생각해 봅니다.

각설하고 그 Windows 2000 디바이스 드라이버의 400 페이지를 보면 시스템 스레드를 종료하기 위해서 시스템 스레드를 대기하는 코드가 나옵니다. 코드를 발췌하면 아래와 같습니다.

KeWaitForSingleObject(  
    &pDE->pThreadObj,  
    Executive,  
    KernelMode,  
    FALSE,  
    NULL);  
  
ObDereferenceObject(&pDE->pThreadObj);

pDE->pThreadObj는 PETHREAD로 선언된 변수입니다. 별 생각없이 이 코드를 그대로 DriverUnload에 붙였더니 공포의 블루스크린이 마구 뜨더군요. 그런데도 첨에는 왜 뜨는지를 이해하질 못했습니다. 디버그 로그를 보니 단지 스레드가 종료되지 않았다는 것은 알 수 있었습니다. 더 훼이크 스러운건 KeSetEvent나 KeWaitForSingleObjects로 넘어가는 대부분의 인자가 &variable 형태라는 것 입니다. 그래서 더욱 헤맸습니다.

제가 내린 결론는 위 코드가 *아마도* 잘못된 것이 아닐까하는 것입니다. KeWaitForSingleObject의 인자로는 PVOID가 들어갑니다. 커널 오브젝트의 포인터죠. KEVENT라는 커널 이벤트 객체가 있다면 PKEVENT가 인자로 넘어가는 겁니다. 따라서 pDE->pThreadObj는 ETHREAD의 포인터인 PETHREAD로 선언된 변수이기 때문에 굳이 다시 주소 연산자를 사용해서 주소를 넘길 필요가 없습니다. 위 코드에서 &부분을 뺀 다음 테스트를 해보니 정상적으로 동작을 하더군요. ObDereferenceObject 함수도 마찬가지입니다.

@codemaru
돌아보니 좋은 날도 있었고, 나쁜 날도 있었다. 그런 나의 모든 소소한 일상과 배움을 기록한다. 여기에 기록된 모든 내용은 한 개인의 관점이고 의견이다. 내가 속한 조직과는 1도 상관이 없다.
(C) 2001 YoungJin Shin, 0일째 운영 중