Bagikan melalui


Menulis driver untuk versi Windows yang berbeda

Ketika Anda membuat proyek driver, Anda menentukan sistem operasi target minimum, yang merupakan versi minimum Windows yang akan dijalankan driver Anda. Misalnya, Anda dapat menentukan bahwa Windows 7 adalah sistem operasi target minimum. Dalam hal ini, driver Anda akan berjalan pada Windows 7 dan versi Windows yang lebih baru.

Nota

Jika Anda mengembangkan driver untuk versi minimum Windows tertentu dan Anda ingin driver Anda bekerja pada versi Windows yang lebih baru, Anda tidak boleh menggunakan fungsi yang tidak terdokumentasi, dan Anda tidak boleh menggunakan fungsi terdokumentasi dengan cara apa pun selain cara yang dijelaskan dalam dokumentasi. Jika tidak, driver Anda mungkin gagal dijalankan pada versi Windows yang lebih baru. Bahkan jika Anda telah berhati-hati untuk hanya menggunakan fungsi yang didokumentasikan, Anda harus menguji driver Anda pada versi baru Windows setiap kali satu dirilis.

Menulis driver multi-versi hanya menggunakan fitur umum

Ketika Anda merancang driver yang akan berjalan pada beberapa versi Windows, pendekatan paling sederhana adalah memungkinkan driver hanya menggunakan fungsi dan struktur DDI yang umum untuk semua versi Windows yang akan dijalankan driver. Dalam situasi ini, Anda menetapkan sistem operasi target minimum ke versi Windows paling awal yang akan didukung driver.

Misalnya, untuk mendukung semua versi Windows, dimulai dengan Windows 7, Anda harus:

  1. Desain dan terapkan driver sehingga hanya menggunakan fitur-fitur yang ada di Windows 7.

  2. Saat Anda membangun driver, tentukan Windows 7 sebagai sistem operasi target minimum.

Meskipun proses ini sederhana, mungkin membatasi driver untuk hanya menggunakan subset fungsionalitas yang tersedia pada versi Windows yang lebih baru. Dalam banyak kasus, Anda ingin menggunakan fungsionalitas sistem operasi yang lebih baru ketika tersedia untuk meningkatkan keamanan, meningkatkan keandalan, atau mengaktifkan fitur yang lebih baru.

Menulis driver multi-versi yang menggunakan fitur yang bergantung pada versi

Driver kernel mode dapat menentukan secara dinamis apakah API yang disediakan oleh sistem operasi tersedia, atau versi Windows mana yang dijalankan oleh driver, dan kemudian memilih untuk menggunakan fitur yang tersedia di lingkungan run time tersebut. Misalnya, driver yang harus mendukung semua versi Windows, dimulai dengan Windows 7, dapat menentukan, pada waktu proses, versi Windows yang dijalankannya. Jika driver berjalan pada Windows 7, driver hanya harus menggunakan fungsi DDI yang didukung Windows 7. Namun, driver yang sama dapat menggunakan fungsi DDI tambahan yang unik untuk Windows 8, misalnya, ketika pemeriksaan run-time menentukan bahwa API tersebut saat ini ada atau menentukan bahwa API tersebut berjalan pada Windows 8.

Nota

Disarankan agar Anda memeriksa ketersediaan fitur atau API jika memungkinkan alih-alih mencoba memeriksa apakah driver Anda berjalan pada versi sistem operasi tertentu atau yang lebih baru.

Memanggil fungsi dependen versi Windows secara kondisional

Driver mode kernel dapat menggunakan fungsi MmGetSystemRoutineAddress atau mmGetSystemRoutineAddressEx fungsi untuk secara dinamis memeriksa apakah API tertentu yang ingin digunakan tersedia di lingkungan run time saat ini dan untuk mendapatkan penunjuk fungsi yang akan digunakan untuk memanggil API tersebut.

Nota

Untuk membantu mempertahankan pemeriksaan jenis dan mencegah kesalahan yang tidak disengaja, Anda harus membuat typedef yang mencerminkan jenis fungsi asli.

Contoh: Menentukan ketersediaan API dan API panggilan kondisional

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
}

Menentukan versi Windows

Driver modus kernel dapat menggunakan fungsi RtlVerifyVersionInfo untuk memeriksa versi Windows mana yang sedang berjalan.

Nota

Disarankan agar Anda memeriksa ketersediaan fitur atau API jika memungkinkan alih-alih mencoba memeriksa apakah driver Anda berjalan pada versi sistem operasi tertentu atau yang lebih baru.

Contoh: Menentukan versi Windows

Contoh berikut mendeteksi apakah versi sistem operasi yang sedang berjalan lebih besar dari atau sama dengan versi 10.0 dan mendeteksi apakah nomor build lebih besar dari atau sama dengan build 22000 (Windows 11, versi 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.
    //

}
...