다음을 통해 공유


다양한 버전의 Windows용 드라이버 작성

드라이버 프로젝트를 만들 때 드라이버가 실행될 Windows의 최소 버전인 최소 대상 운영 체제를 지정합니다. 예를 들어 Windows 7이 최소 대상 운영 체제임을 지정할 수 있습니다. 이 경우 드라이버는 Windows 7 이상 버전의 Windows에서 실행됩니다.

참고 항목

특정 최소 버전의 Windows용 드라이버를 개발하고 드라이버가 이후 버전의 Windows에서 작동하도록 하려면 문서화되지 않은 함수를 사용하지 않아야 하며 설명서에 설명된 방법 이외의 방법으로 문서화된 함수를 사용하면 안 됩니다. 그렇지 않으면 드라이버가 이후 버전의 Windows에서 실행되지 않을 수 있습니다. 문서화된 함수만 사용해야 하는 경우에도 릴리스될 때마다 새 버전의 Windows에서 드라이버를 테스트해야 합니다.

일반적인 기능만 사용하여 다중 버전 드라이버 작성

여러 버전의 Windows에서 실행되는 드라이버를 디자인할 때 가장 간단한 방법은 드라이버가 실행되는 모든 Windows 버전에 공통적인 DDI 함수 및 구조만 사용할 수 있도록 하는 것입니다. 이 경우 최소 대상 운영 체제를 드라이버가 지원할 Windows의 초기 버전으로 설정합니다.

예를 들어 Windows 7부터 모든 버전의 Windows를 지원하려면 다음을 수행해야 합니다.

  1. Windows 7에 있는 기능만 사용할 수 있도록 드라이버를 디자인하고 구현합니다.

  2. 드라이버를 빌드할 때 Windows 7을 최소 대상 운영 체제로 지정합니다.

이 프로세스는 간단하지만 이후 버전의 Windows에서 사용할 수 있는 기능의 하위 집합만 사용하도록 드라이버를 제한할 수 있습니다. 대부분의 경우 보안을 향상시키거나 안정성을 향상시키거나 최신 기능을 사용하도록 설정하기 위해 사용 가능한 경우 최신 운영 체제 기능을 사용하려고 합니다.

버전 종속 기능을 사용하는 다중 버전 드라이버 작성

커널 모드 드라이버는 운영 체제 제공 API를 사용할 수 있는지 또는 드라이버가 실행 중인 Windows 버전을 동적으로 확인하고 해당 런타임 환경에서 사용할 수 있는 기능을 사용하도록 선택할 수 있습니다. 예를 들어 Windows 7부터 모든 버전의 Windows를 지원해야 하는 드라이버는 런타임에 실행 중인 Windows 버전을 확인할 수 있습니다. 드라이버가 Windows 7에서 실행되는 경우 Windows 7에서 지원하는 DDI 함수만 사용해야 합니다. 그러나 동일한 드라이버는 Windows 8에 고유한 추가 DDI 함수를 사용할 수 있습니다. 예를 들어 런타임 검사 해당 API가 현재 있는지 확인하거나 Windows 8에서 실행 중임을 확인할 때 사용할 수 있습니다.

참고 항목

드라이버가 특정 운영 체제 버전 이상에서 실행되는 경우 검사 대신 가능하면 기능 또는 API 가용성을 검사 것이 좋습니다.

조건부로 Windows 버전 종속 함수 호출

커널 모드 드라이버는 MmGetSystemRoutineAddress 또는 MmGetSystemRoutineAddressEx 함수를 사용하여 현재 런타임 환경에서 사용하려는 특정 API를 사용할 수 있는지 여부를 동적으로 검사 해당 API를 호출하기 위해 사용할 함수 포인터를 가져올 수 있습니다.

참고 항목

형식 검사 유지 및 의도하지 않은 오류를 방지하려면 원래 함수 형식을 미러 typedef를 만들어야 합니다.

예: API 가용성 확인 및 조건부 API 호출

typedef
NTSTATUS
(*PFN_IoOpenDriverRegistryKey)(
    PDRIVER_OBJECT     DriverObject,
    DRIVER_REGKEY_TYPE RegKeyType,
    ACCESS_MASK        DesiredAccess,
    ULONG              Flags,
    PHANDLE            DriverRegKey
    );

VOID ExampleFunction(VOID) {
    NTSTATUS status = STATUS_UNSUCCESSFUL;
    HANDLE persistentStateKey = NULL;
    PFN_IoOpenDriverRegistryKey pfnIoOpenDriverRegistryKey = NULL;
    UNICODE_STRING functionName = {0};

    RtlInitUnicodeString(&functionName, L"IoOpenDriverRegistryKey");
    pfnIoOpenDriverRegistryKey = (PFN_IoOpenDriverRegistryKey)MmGetSystemRoutineAddress(&functionName);

    if (pfnIoOpenDriverRegistryKey != NULL) {
        // Open a key to where state can be stored under the driver service
        status = pfnIoOpenDriverRegistryKey(g_GlobalStructure.DriverObject,
                                            DriverRegKeyPersistentState,
                                            KEY_WRITE,
                                            0,
                                            &persistentStateKey);
    } else {
        // Fall back to opening up a different location to store state in
    }

    // Use the opened registry key
}

Windows 버전 확인

커널 모드 드라이버는 RtlVerifyVersionInfo 함수를 사용하여 현재 실행 중인 Windows 버전을 동적으로 검사 수 있습니다.

참고 항목

드라이버가 특정 운영 체제 버전 이상에서 실행되는 경우 검사 대신 가능하면 기능 또는 API 가용성을 검사 것이 좋습니다.

예: Windows 버전 확인

다음 예제에서는 현재 실행 중인 운영 체제 버전이 버전 10.0보다 크거나 같은지 감지하고 빌드 번호가 빌드 22000(Windows 11, 버전 21H2)보다 크거나 같은지 검색합니다.

...

NTSTATUS Status = STATUS_SUCCESS;
RTL_OSVERSIONINFOEXW VersionInfo = {0};
ULONG TypeMask = 0;
ULONGLONG ConditionMask = 0;

VersionInfo.dwOSVersionInfoSize = sizeof(VersionInfo);
VersionInfo.dwMajorVersion = 10;
VersionInfo.dwMinorVersion = 0;
VersionInfo.dwBuildNumber = 22000;

TypeMask = VER_MAJORVERSION | VER_MINORVERSION | VER_BUILDNUMBER;
VER_SET_CONDITION(ConditionMask, VER_MAJORVERSION, VER_GREATER_EQUAL);
VER_SET_CONDITION(ConditionMask, VER_MINORVERSION, VER_GREATER_EQUAL);
VER_SET_CONDITION(ConditionMask, VER_BUILDNUMBER, VER_GREATER_EQUAL);

Status = RtlVerifyVersionInfo(&VersionInfo,
                              TypeMask,
                              ConditionMask);

if (NT_SUCCESS(Status)) {

    //
    // The call to RtlVerifyVersionInfo succeeded, so the running OS
    // version and build number is greater than or equal to the value
    // specified. Do appropriate action for newer OS versions.
    //

} else if (Status == STATUS_REVISION_MISMATCH) {

    //
    // The running OS version is less than the value specified. Do
    // appropriate action for older OS versions.
    //

} else {

    //
    // There was an error comparing to the running OS version. Do
    // appropriate action for when the OS version is not known.
    //

}
...