Freigeben über


DriverEntry 함수

C 언어를 이용해서 프로그램을 개발해 본 분이 있다면 main() 함수가 entry function의 역할을 한다는 것을 알고 있을 것입니다. 작성한 응용 프로그램이 실행된 후에 처음으로 불려지는 함수가 됩니다. 실제로는 C runtime library가 먼저 초기화 작업을 한 후에 개발자가 작성한 main() 함수를 호출하는 형태입니다. 아무튼 개발자가 작성하는 코드 중에서는 가장 먼저 실행되는 현관문과 같은 역할을 수행합니다.

이와 유사하게 Windows 응용 프로그램을 위해서는 WinMain()이라는 함수를 구현하도록 되어 있고, 다른 프로세스에 의해서 실행 시점에 로딩되어 사용되는 DLL 파일의 경우에는 DllMain()이라는 entry function을 구현하도록 되어 있습니다.

동일한 개념으로 device driver를 개발할 때 entry function이 되는 것이 바로 DriverEntry() 라는 함수입니다. 이 함수는 작성한 driver file이 메모리에 로드 되는 시점에 system thread(I/O manager)에 의해서 불려지는 함수입니다. 따라서 작성된 driver에서 초기화 작업을 진행할 것이 있으면 이 함수 내에서 구현하는 것이 좋습니다. 주의할 것은 DriverEntry() 함수는 driver module이 메모리에 로드 될 때 한 번만 호출 되는 것으로 해당 driver file이 이미 로드 되어 있는 상황에서 device를 새로 추가했다고 해서 다시 호출되는 것이 아닙니다. 이 점을 고려해서 DriverEntry() 함수에 포함되어야 할 코드인지를 주의하셔서 초기화 작업을 진행하시기 바랍니다.

다음은 MSDN 사이트에서 확인한 DriverEntry 함수에 대한 내용입니다. (https://msdn.microsoft.com/en-us/library/ms795702.aspx 참고)

DRIVER_INITIALIZE DriverEntry ; NTSTATUS DriverEntry (     __in struct _DRIVER_OBJECT * DriverObject ,     __in PUNICODE_STRING  RegistryPath     )   {...}

DriverObject           Caller-supplied pointer to a DRIVER_OBJECT structure. This is the driver's driver object.

RegistryPath Pointer to a counted Unicode string specifying the path to the driver's registry key.

DriverEntry가 호출 될 때 전달되는 첫 번째 인자로 I/O manager가 생성한 Driver Object의 주소를 넘겨받는데, driver 실행에 필요한 기본적인 값들에 대해서 이 구조체의 초기값을 설정해야 줘야 합니다. 예를 들면 IRP_MJ_CREATE, IRP_MJ_CLOSE, IRP_MJ_READ 등에 대한 처리를 어느 함수에서 처리할 것인지를 I/O manager에 알려줘야 해당 요청이 있을 때 적절한 dispatch handler routine이 호출됩니다.

예를 들면 다음과 같은 코드 작성이 가능합니다.

pDriverObject->MajorFunction[IRP_MJ_CREATE] = MyCreateFunction;
pDriverObject->MajorFunction[IRP_MJ_CLOSE] = MyCloseFunction;
pDriverObject->MajorFunction[IRP_MJ_READ] = MyReadFunction;
pDriverObject->MajorFunction[IRP_MJ_POWER] = MyPowerFunction;
pDriverObject->DriverExtension->AddDevice = MyAddDeviceFunction;

그리고 driver 내부에서 사용되는 object나 type, resource 등에 대한 초기화 작업을 진행하면 됩니다. 이 과정에서 동적으로 생성한 메모리가 있으면 적절한 해제 작업을 하고 리턴해야 합니다.

초기화 작업에 완료했으면 리턴 값으로 STATUS_SUCCESS를 리턴 합니다. 만약 어떤 이유로 초기화가 제대로 진행되지 못했다면 https://msdn.microsoft.com/en-us/library/aa489610.aspx 문서를 참고하셔서 관련 내용이 이벤트 로그에 남겨질 수 있도록 적절한 NTSTATUS 값을 리턴하시기 바랍니다. NTSTATUS 값은 https://msdn.microsoft.com/en-us/library/aa489585.aspx에서 확인할 수 있습니다.

다음에는 WDM에서 사용되는 주요 함수 중에서 AddDevice 함수에 대해서 간단히 정리해보도록 하겠습니다.