장치를 활성화/비활성화하기 위해 상위 필터 드라이버(kbfiltr/moufiltr)에 IOCTL을 보내는 원시 PDO

StackOverflow https://stackoverflow.com/questions/1430798

문제

저는 드라이버 개발이 처음이고 키보드나 마우스 장치를 활성화하거나 비활성화하는 간단한 필터 드라이버를 작성하려고 합니다.작동하게 할 수 있다면 마우스가 연결되어 있을 때 노트북의 터치패드를 비활성화하는 데 사용하고 싶습니다.이미 이 작업을 수행하는 소프트웨어가 있다는 것을 알고 있지만 장치 드라이버에 정말 관심이 있고 직접 수행하는 방법을 배우고 싶습니다.

나는 kbfiltr 그리고 무필터 상위 필터 드라이버로 설치되는 WDK와 함께 제공되는 예입니다.kbfiltr 예제는 사용자 모드 프로그램에 의해 열거되고 연결될 수 있는 pdo를 생성합니다.이를 통해 내가 처리하는 PDO에 IOCTL을 보낼 수 있습니다. KbFilter_EvtIoDeviceControlForRawPdo.그러나 필터 드라이버와 관련된 모든 작업을 시도할 때 KbFilter_EvtIoInternalDeviceControl 그래서 나는 다음과 같은 것을 할 수 있습니다

VOID
KbFilter_EvtIoInternalDeviceControl(
    IN WDFQUEUE      Queue,
    IN WDFREQUEST    Request,
    IN size_t        OutputBufferLength,
    IN size_t        InputBufferLength,
    IN ULONG         IoControlCode
    )
    ...
    hDevice = WdfIoQueueGetDevice(Queue);
    devExt = FilterGetData(hDevice);

    switch (IoControlCode) {      
    ...
      case IOCTL_INTERNAL_KEYBOARD_DISCONNECT:
       //
       // Clear the connection parameters in the device extension.
       //
       devExt->UpperConnectData.ClassService = NULL;
       break;
    ...
    }

BSOD가 발생합니다.위의 코드가 아닙니다. 바닐라 예제에서는 null로 설정된 것이 주석 처리되어 있으며 Kbfilter를 호출하면 BSOD가 발생합니다.PDO에서 직접 장치 확장을 설정하려고 시도했지만 이로 인해 BSOD가 발생합니다. 아마도 kbfiltr이 아닌 PDO devExt이기 때문일 것입니다.

(관련된:BSOD에서 스택 추적을 얻는 좋은 방법은 무엇입니까?테스트 환경으로 Virtual PC를 사용하고 있으며 확인되지 않은 XPSP3 빌드를 사용하고 있습니다.)

IOCTL_INTERNAL_KEYBOARD_DISCONNECT를 드라이버 스택에 직접 보낼 수 없습니다(입력 장치가 한 번에 하나의 연결만 허용한다는 것을 알고 있습니까?). 따라서 원시 PDO가 필요합니다.실제로 두 개의 IOCTL(활성화 및 비활성화)만 보내면 되며 키보드 분리 및 연결이 이미 정의되어 있기 때문에 키보드 연결 끊기 및 연결을 사용할 것이라고 생각했습니다.

이러한 가정 중 하나라도 틀렸다면 알려주시기 바랍니다. 저는 이 분야에 대해 정말 멍청하다는 것을 알고 있지만 PDO를 통한 이러한 종류의 통신에 대한 문서를 많이 찾지 못했습니다.

도움이 되었습니까?

해결책

좋아, 드디어 이 문제를 해결했고 드라이버가 작동 중입니다.

KMDF 필터 드라이버 구현:

COM 포트 접근 방식을 제안한 Sergius에게 감사드립니다. 이것이 제가 설정하는 데 도움이 되었기 때문입니다. WinDbg. 이 멋진 블로그 게시물 빠르게 설정하는 방법을 설명합니다. 기본적으로 VPC가 com 포트를 명명된 파이프로 설정하고, 가상화된 OS에서 커널 디버그 모드를 활성화하고, 부팅하는 동안 연결하도록 합니다.그러면 드라이버가 로드될 때 모든 DbgPrint 메시지를 얻을 수 있고 더 많은 작업을 수행할 수 있지만 시작 프로세스 중 추적 메시지만으로도 큰 도움이 되었습니다.

내 주요 문제는 KbFiltr에서 내부 IOCTL을 재사용하려는 것이었습니다.내부 IOCTL과 다른 IOCTL의 차이점을 이해하지 못했기 때문에 이는 잘못된 설계 아이디어였습니다. IOCTL_INTERNAL_KEYBOARD_DISCONNECT와 같은 내부 IOCTLS는 제한된 액세스 조건을 가지며 다른 드라이버나 커널에 의해서만 전송되어야 합니다.또한 이 KB 문서 "IOCTL을 필터 드라이버로 보내는 방법" 는 동일한 제어 장치 구조를 사용한 예이지만 WDM입니다.

어쨌든, 주말 내내 KbFiltr 예제와 싸운 끝에 마침내 포기하고 다음을 사용하여 다시 시작했습니다. WDF 토스터/필터 예.이것은 보다 기본적인 KMDF 필터 드라이버이며 KbFiltr 및 MouFiltr을 사용하여 많은 공백을 채워야 했습니다.토스터 필터 드라이버 작업은 KbFiltr과 유사하지만 PDO 대신 제어 장치를 생성합니다.또한 해당 단계를 수행하기 위해 Pinvoke를 하지 않고도 사용자 모드에서 통신할 수 있도록 제어 장치에 대한 DOS 장치 이름을 설정합니다.제어 장치를 사용하면 컬렉션을 반복하여 필터 드라이버가 로드된 모든 장치를 제어할 수 있습니다.대기 잠금은 컬렉션에 대한 액세스를 동기화하는 데 사용됩니다.

또한 INF 파일을 수정하고(Toaster 클래스 대신 Mouse 클래스를 사용하기 위해) 드라이버 코드를 수정하지 않고 테스트 컴퓨터에서 바로 적용할 수 있었습니다. 효과가 있는 것부터 시작하는 것이 훨씬 쉽습니다. 이 페이지 샘플을 적용하기 위해 변경해야 하는 항목의 포괄적인 목록을 제공합니다.

다른 팁

우선, 사용자 모드에서 원하는 작업 (마우스를 연결하면 내 노트북의 터치 패드를 비활성화)을 수행 할 수 있습니다. 훨씬 간단하고 안전합니다. 보다 장치 설치 기능 사용 그리고 WM_DEVICECHANGE

코드의 문제를 디버깅하려면 : BSOD에서 메모리 덤프를 가져 오거나 커널 디버거 연결 (파이프로 리디렉션 된 가상 PC의 COM 포트 사용)을 설정하십시오. 보다 Windows 용 도구 디버깅 도구

재미있게 보내세요!

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top