WMI 이벤트 추적

이 섹션에서는 커널 모드 드라이버가 정보 공급자로서 정보 소비자에게 정보를 제공하는 데 사용할 수 있는 WDM(Windows 2000 이상에서 지원)에 대한 WMI 확장에 대해 설명합니다. 드라이버는 일반적으로 소비자가 드라이버의 구성 및 리소스 사용량을 결정하는 데 사용하는 정보를 제공합니다. WDM에 대한 WMI 확장 외에도 사용자 모드 API는 WMI 이벤트 정보의 공급자 또는 소비자를 지원합니다. 자세한 내용은 Windows SDK를 참조하세요.

이벤트 추적 로거는 최대 32개의 인스턴스를 지원합니다. 인스턴스 중 하나는 커널 추적을 위해 예약되어 있습니다. 로거는 높은 이벤트 속도 추적을 지원합니다.

추적 이벤트는 다른 WMI 이벤트와 동일한 방식으로 정의됩니다. WMI 이벤트는 MOF 파일에 설명되어 있습니다. WMI 이벤트 설명에 대한 자세한 내용은 WMI 데이터 및 이벤트 블록에 대한 MOF 구문을 참조하세요.

커널 모드 드라이버 로그 정보가 기존 WMI 인프라에 통합되는 프로세스입니다. 추적 이벤트를 기록하기 위해 드라이버는 다음을 수행합니다.

  1. IoWMIRegistrationControl을 호출하여 WMI 공급자로 등록합니다.

  2. 드라이버가 WMI에 이벤트를 등록할 때 전달되는 WMIREGGUID 구조체의 Flags 멤버에서 WMIREG_FLAG_TRACED_GUID 설정하여 이벤트를 추적 가능한 것으로 표시합니다.

  3. 드라이버가 WMI에 이벤트를 등록할 때 전달되는 WMIREGGUID 구조체의 Flags 멤버에서 WMIREG_FLAG_TRACE_CONTROL_GUID 설정하여 추적 이벤트 집합을 전체적으로 사용/사용하지 않도록 설정하기 위한 컨트롤 이벤트로 하나의 이벤트를 지정합니다.

  4. GUID가 추적 컨트롤 GUID와 일치하는 이벤트를 사용하도록 WMI에서 요청을 받으면 드라이버는 로거에 핸들을 저장해야 합니다. 이벤트를 작성할 때 값이 필요합니다. 이 핸들을 사용하는 방법에 대한 자세한 내용은 6단계를 참조하세요. 로거 핸들 값은 이벤트 사용 요청에서 매개 변수의 일부인 WMI 버퍼의 WNODE_HEADER 부분의 HistoricalContext 멤버에 포함됩니다.

  5. 추적 이벤트를 WMI 이벤트 소비자에게 보낼지 아니면 WMI 이벤트 로거만 대상으로 하는지 여부를 결정합니다. 이렇게 하면 EVENT_TRACE_HEADER 구조체의 메모리가 어디에서 나올지 결정됩니다. 이 메모리는 결국 IoWMIWriteEvent에 전달됩니다.

    이벤트가 로그 이벤트인 경우에만 WMI에서 메모리를 삭제하지 않습니다. 이 경우 드라이버는 스택의 버퍼를 전달해야 하거나 이 목적을 위해 할당된 버퍼를 다시 사용해야 합니다. 성능상의 이유로 드라이버는 메모리를 할당하거나 사용 가능한 불필요한 호출을 최소화해야 합니다. 이 권장 사항을 준수하지 않으면 로그 파일에 포함된 타이밍 정보의 무결성이 손상됩니다.

    이벤트를 로거와 WMI 이벤트 소비자 모두에게 보내려면 비페이지 풀에서 메모리를 할당해야 합니다. 이 경우 이벤트는 로거로 전송된 다음 WMI로 전달되어 이벤트 알림을 요청한 WMI 이벤트 소비자에게 전송됩니다. 그런 다음 IoWMIWriteEvent의 동작에 따라 WMI에서 이벤트에 대한 메모리를 해제합니다.

  6. EVENT_TRACE_HEADER 및 드라이버 이벤트 데이터에 대한 메모리(있는 경우)가 보호된 후 다음 정보를 설정해야 합니다.

    Size 멤버를 sizeof(EVENT_TRACE_HEADER)와 EVENT_TRACE_HEADER 끝에 추가할 추가 드라이버 이벤트 데이터의 크기로 설정합니다.

    이벤트를 로거로 보내도록 Flags 멤버를 WNODE_FLAG_TRACED_GUID 설정합니다. WMI 이벤트 소비자에게도 이벤트를 보내려면 WNODE_FLAG_LOG_WNODE 설정합니다. WNODE_FLAG_LOG_WNODE 설정하면 WNODE_FLAG_TRACED_GUID 설정할 필요가 없습니다. 둘 다 설정되면 WNODE_FLAG_TRACED_GUID 우선적으로 적용되며 이벤트가 WMI 이벤트 소비자에게 전송되지 않습니다.

    Guid 또는 GuidPtr 멤버를 설정합니다. GuidPtr을 사용하는 경우 Flags 멤버에서 WNODE_FLAG_USE_GUID_PTR 설정합니다.

    필요에 따라 TimeStamp의 값을 지정합니다. 드라이버가 TimeStamp 값을 지정하지 않으면 로거가 이 값을 채웁니다. 드라이버가 로거가 타임스탬프를 설정하지 않도록 하려면 Flags 멤버에서 WNODE_FLAG_USE_TIMESTAMP 설정해야 합니다.

    드라이버에 의미가 있는 다음 EVENT_TRACE_HEADER 멤버를 설정합니다. Class.Type, Class.LevelClass.Version.

    마지막으로 EVENT_TRACE_HEADER WNODE_HEADER 캐스팅하고 WnodeHistoricalContext 값을 위의 4단계에서 저장한 로거 핸들로 설정합니다.

  7. EVENT_TRACE_HEADER 구조체에 대한 포인터를 사용하여 IoWMIWriteEvent를 호출합니다.

드라이버는 드라이버가 IRP_MN_DISABLE_EVENTS 요청을 통해 이벤트 로깅을 사용하지 않도록 설정하는 알림을 받을 때까지 컨트롤 GUID와 연결된 추적 이벤트를 계속 로깅해야 합니다.