본문 바로가기

전체 글418

Io Callback Function EvtIoInternalDeviceControl - 내부 디바이스 I/O control code에 포함되어 있는 I/O request를 처리하는 함수. - 이 함수를 사용할 때는 반드시 EVT_WDF_IO_QUEUE_IO_DEVICE_CONTROL 타입을 사용함으로써 함수를 선언해야 한다. - 드라이버는 WdfIoQueueCreate 가 호출될 때 EvtIoDeviceControl callback 함수를 등록한다. 만약 드라이버가 EvtIoDeviceControl callback 함수를 등록하였다면, callback 함수는 모든 I/O control request(IRP_MJ_DEVICE_CONTROL)를 수신할 것이다. - EvtIoDeviceControl callback 함수는 각각의 수신된 I/O .. 2013. 1. 4.
IRQL에 따른 스레드 선점 주의사항 윈도우즈 커널이나 드라이버에 대한 설명을 나온 책을 보면 항상 IRQL 에 따른 스레드 선점에 대한 얘기가 나오는데 다음과 같은 내용은 오해를 불러일으킬 소지가 있다. "낮은 수준의 IRQL에서 실행하는 코드(스레드)는 높은 수준의 IRQL의 작업이 발생하게 되면 항상 선점된다." "상승 된 IRQL에 코드는 상승 된 IRQL보다 낮은 레벨에 코드가 실행되는 것을 블록시킨다." 그러나 위에 사항들은 예외적일 수 있다. 예를 들어, 스레드 A가 APC_LEVEL로 실행중이고, 스레드 B는 이전에 PASSIVE_LEVEL에서 실행중이었다라고 가정하면 스레드 A가 APC_LEVEL로 실행중이기 때문에 스레드 B보다 IRQL이 높으므로 스레드A가 PASSIVE_LEVEL로 IRQL이 내려가지 않는 이상은 스레드.. 2013. 1. 4.
Object Context란? 오브젝트 context는 드라이버가 오브젝트를 할당하고 배정할 수 있는 extra, nonpageable, memory 공간이다. 각각의 프레임워크 기반의 드라이버는 하나 또는 그 이상의 오브젝트 Context를 생성할 수 있다. 프레임워크 기반의 드라이버는 오브젝트 context 내에 오브젝트와 관련된 모든 데이터를 저장해야 한다. 예를 들어, USB 디바이스 드라이버는 자신의 프레임워크 디바이스 오브젝트를 위한 context를 생성한다. 드라이버는 디바이스의 USB_DEVICE_DESCRIPTOR, USB_CONFIGURATION_DESCRIPTOR 구조체 등과 같은 디바이스 정보들을 context 내에 저장한다.프레임워크는 하나의 드라이버에서 또 다른 드라이버로 프레임워크 오브젝트를 전달하지 않기 .. 2013. 1. 4.
Macro WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE - WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE 매크로는 드라이버의 Wdf Object attributes 구조체를 초기화 하고 구조체 속으로 드라이버의 context 정보를 기입한다. WDF_DECLARE_CONTEXT_TYPE_WITH_NAME - WDF_DECLARE_CONTEXT_TYPE_WITH_NAME 매크로는 드라이버의 오브젝트 context를 위한 특정 이름과 함께 접근자(accessor)를 생성한다. WDF_IO_QUEUE_CONFIG_INIT_DEFAULT_QUEUE - 드라이버의 WDF_IO_QUEUE_CONFIG 구조체를 초기화한다.- 드라이버는 디바이스의 디폴트 큐로써 power-ma.. 2013. 1. 4.
Function WdfFdoInitSetFilter - 프레임워크에게 디바이스 오브젝트가 필터 드라이버임을 알리기 위한 함수.- 필터 드라이버는 전형적으로 몇몇의 I/O Request를 처리하며, 대부분의 Request는 다음 드라이버로 전송하는 역할을 한다.- 그런데 만약 프레임워크가 어떤 Request를 수신하였고 드라이버는 해당하는 Request type과 일치하는 I/O queue를 생성하지 않았을 경우, 프레임워크의 처리 방법은 WdfFdoInitSetFilter를 호출했느냐 아니냐에 따라 달라지게 된다. 만약 드라이버가 WdfFdoInitSetFilter를 호출했다면, 드라이버 프레임 워크는 Request를 다음 드라이버로 보낸다. 만약 드라이버가 WdfFdoInitSetFilter를 호출하지 않았다면, 프레.. 2013. 1. 4.
PAGED_CODE 매크로 PAGED_CODE는 다음과 같이 생긴 매크로이다. #define PAGED_CODE(){\if(KeGetCurrentIrql() > APC_LEVEL) { \kdPrint(""EX: Pageable code called at IRQL %d\n", KeGetCurrentIrql())); \PAGED_ASSERT(FALSE); \} \} 현재의 IRQL을 체크해보고 IRQL이 APC_LEVEL 보다 높다면 시스템을 종료시킨다. 디바이스 드라이버의 세계에서 중요한 규칙 중 하나는 IRQL이 Dispatch 레벨 이상일 때는 페이지 폴트가 일어나서는 안된다는 것이다.IRQL >= DISPATCH_LEVEL 일 때 페이지 폴트가 일어나게 되면 시스템은 크래쉬 된다. 위 규칙을 알고나면 #pragma alloc_.. 2013. 1. 4.
UNREFERENCED_PARAMETER 매크로 프로그램을 작성할 경우 변수나 인자만 선언해 놓고, 참조를 안할 경우 컴파일러는 C4100 오류를 발생시킨다. 만약 이 warning이 눈에 거슬릴 경우, UNREFERENCED_PARAMETER를 해주면 warning이 사라진다. 인자값이나 로컬 변수가 선언되지 않았을 때 컴파일러 경고를 발생시키지 않기 위해 사용하는 매크로이다. UNREFERENCED_PARAMETER는 아직 참조하지 않은 인자에,DBG_UNREFERENCED_LOCAL_VARIABLE은 아직 참조하지 않은 로컬 변수에 사용할 때 사용한다. #pragma warning (disable : 4100) 위 방식과 같은 결과를 나타낸다. 2013. 1. 3.
#pragma alloc_text(PAGE, XXX) 컴파일러에게 코드를 특정한 섹션에 두라고 지시하는 전통적인 방법은 alloc_text라는 pragma를 이용하는 것이다. 모든 컴파일러가 pragma를 다 지원하는 것은 아니기 때문에, DDK 헤더에서는 이 pragma의 지원여부를 알려주기 위해 ALLOC_PRAGMA 상수를 정의할 수도 있고 정의하지 않을 수도 있다.드라이버의 개별 서브루틴에서 아래와 같이 pragma를 호출해서 섹션의 위치를 지정한다[역주 주: pragma 이후에 오는 문장들은 C/C++ 표준 문법이 아니며 각 개별 컴파일러가 하드웨어나 O/S에 의존적인 부분의 차이를 위해 자체적으로 지원하는 기능이다.] #ifdef ALLOC_PRAGMA#pragma alloc_text(INIT, DeviceEntry)#endif 위처럼 INIT .. 2013. 1. 3.
IRQL Dispatching - 실행 중인 한 스레드에서 다른 스레드로 실행을 전환하는 절차 Scheduling - 프로세서에서 실행될 다음 스레드를 결정하는 절차 Quantum - 특정 스레드가 CPU에서 실행하도록 정해진 시간 Pre-emption(선점) - 현재 실행 중인 스레드의 우선 순위보다 더 높은 우선 순위를 가진 스레드가 실행할 준비가 되었을 때 IRQL - 운영체제는 스레드가 실행하고 있는 도중에 인터럽트가 발생하면 이를 처리한다. 우리는 이를 당연하다고 여기지만 사실은 스레드에 의한 코드 실행과 인터럽트 발생으로 인한 코드 실행에는 각각 해당 중요도가 있으며 운영체제는 이들 중요도에 근거하여 우선적인 작업을 먼저 처리한다. - 시스템에 존재하는 각 프로세서(CPU)는 자신만의 IRQL을 가진다.. 2013. 1. 3.