Fungsi RtlQueryRegistryValues (wdm.h)

Rutinitas RtlQueryRegistryValues memungkinkan pemanggil untuk mengkueri beberapa nilai dari subtree registri dengan satu panggilan.

Sintaks

NTSYSAPI NTSTATUS RtlQueryRegistryValues(
  [in]           ULONG                     RelativeTo,
  [in]           PCWSTR                    Path,
  [in, out]      PRTL_QUERY_REGISTRY_TABLE QueryTable,
  [in, optional] PVOID                     Context,
  [in, optional] PVOID                     Environment
);

Parameter

[in] RelativeTo

Menentukan apakah Jalur adalah jalur registri absolut atau relatif terhadap jalur yang telah ditentukan sebelumnya sebagai salah satu dari berikut ini.

Nilai Makna
RTL_REGISTRY_ABSOLUTE Jalur adalah jalur registri absolut.
RTL_REGISTRY_CONTROL Jalur relatif terhadap \Registry\Machine\System\CurrentControlSet\Control.
RTL_REGISTRY_DEVICEMAP Jalur relatif terhadap \Registry\Machine\Hardware\DeviceMap.
RTL_REGISTRY_SERVICES Jalur relatif terhadap \Registry\Machine\System\CurrentControlSet\Services.
RTL_REGISTRY_USER Jalur relatif terhadap \Registry\User\CurrentUser. (Untuk proses sistem, ini adalah \User\. Default.)
RTL_REGISTRY_WINDOWS_NT Jalur relatif terhadap \Registry\Machine\Software\Microsoft\Windows NT\CurrentVersion.

Nilai RelativeTo dapat dimodifikasi oleh bitwise-ORing dengan salah satu bendera berikut.

Bendera Makna
RTL_REGISTRY_OPTIONAL Menentukan bahwa kunci yang dirujuk oleh parameter ini dan parameter Jalur bersifat opsional.
RTL_REGISTRY_HANDLE Menentukan bahwa parameter Path sebenarnya adalah handel registri untuk digunakan.

[in] Path

Penunjuk ke jalur registri absolut atau jalur yang relatif terhadap lokasi yang diketahui yang ditentukan oleh parameter RelativeTo . Perhatikan bahwa nama kunci di jalur seperti itu harus diketahui oleh pemanggil, termasuk kunci terakhir di jalur. Jika bendera RTL_REGISTRY_HANDLE ditentukan, parameter ini adalah handel registri untuk kunci yang sudah dibuka untuk dikueri secara langsung.

[in, out] QueryTable

Penunjuk ke tabel satu atau beberapa nama nilai dan nama subkunci di mana pemanggil tertarik. Setiap entri tabel berisi alamat fungsi QueryRoutine yang disediakan pemanggil yang akan dipanggil untuk setiap nama nilai yang ada di registri. Tabel harus dihentikan dengan entri tabel NULL, yang merupakan entri tabel dengan anggota QueryRoutineNULL dan anggota NamaNULL. Struktur untuk entri tabel kueri didefinisikan sebagai berikut:

typedef struct _RTL_QUERY_REGISTRY_TABLE {
    PRTL_QUERY_REGISTRY_ROUTINE QueryRoutine;
    ULONG Flags;
    PWSTR Name;
    PVOID EntryContext;
    ULONG DefaultType;
    PVOID DefaultData;
    ULONG DefaultLength;
} RTL_QUERY_REGISTRY_TABLE, *PRTL_QUERY_REGISTRY_TABLE;

Jika penelepon mengalokasikan penyimpanan untuk tabel kueri yang diarahkan oleh parameter QueryTable , pemanggil bertanggung jawab untuk merilis penyimpanan ini setelah panggilan RtlQueryRegistryValues kembali.

QueryRoutine

Alamat fungsi QueryRoutine yang disebut dengan nama, jenis, data, dan panjang data dari nilai registri. Jika anggota ini dan anggota Nama keduanya NULL, anggota ini menandai akhir tabel.

Fungsi QueryRoutine dinyatakan sebagai berikut:

NTSTATUS
QueryRoutine (
    IN PWSTR ValueName,
    IN ULONG ValueType,
    IN PVOID ValueData,
    IN ULONG ValueLength,
    IN PVOID Context,
    IN PVOID EntryContext
    );

Untuk informasi selengkapnya, lihat QueryRoutine.

Bendera

Bendera untuk mengontrol bagaimana anggota struktur RTL_QUERY_REGISTRY_TABLE yang tersisa akan ditafsirkan. Bit bendera berikut didefinisikan untuk anggota ini.

Nilai Makna
RTL_QUERY_REGISTRY_SUBKEY Nama entri tabel ini adalah jalur lain ke kunci registri, dan semua entri tabel berikut adalah untuk kunci tersebut daripada kunci yang ditentukan oleh parameter Jalur. Perubahan fokus ini berlangsung hingga akhir tabel atau hingga entri RTL_REGISTRY_SUBKEY atau RTL_QUERY_REGISTRY_TOPKEY lain terlihat. Setiap entri tersebut harus menentukan jalur yang relatif terhadap Jalur yang ditentukan dalam panggilan ke RtlQueryRegistryValues.
RTL_QUERY_REGISTRY_TOPKEY Mengatur ulang handel kunci registri saat ini ke yang asli yang ditentukan oleh parameter RelativeTo dan Path . Ini berguna untuk kembali ke node asli setelah turun ke subkuntang dengan bendera RTL_QUERY_REGISTRY_SUBKEY.
RTL_QUERY_REGISTRY_REQUIRED Menentukan bahwa nilai registri ini harus ada jika DefaultType = REG_NONE; jika tidak, jika tidak ditemukan, RtlQueryRegistryValues segera keluar dengan kode status STATUS_OBJECT_NAME_NOT_FOUND. Keluarnya ini terjadi jika anggota Namaadalah NULL dan kunci saat ini tidak memiliki subkuntus, atau jika Nama menentukan subkunjen yang tidak ada. (Jika bendera ini tidak ditentukan, maka ketika tidak ada kecocokan yang ditemukan untuk Namanon-NULL, rutinitas menggunakan anggota DefaultValue sebagai nilai. Ketika NamaNULL dan kunci saat ini tidak memiliki subkuntang, rutinitas hanya melompati entri tabel tersebut.)
RTL_QUERY_REGISTRY_NOVALUE Menentukan bahwa meskipun tidak ada Nama untuk entri tabel ini, semua pemanggil menginginkan panggilan balik: yaitu, pemanggil tidak ingin menghitung semua nilai di bawah kunci saat ini. QueryRoutine dipanggil dengan NULL untuk ValueData, REG_NONE untuk ValueType, dan nol untuk ValueLength.
RTL_QUERY_REGISTRY_NOEXPAND Untuk nilai registri jenis REG_EXPAND_SZ atau REG_MULTI_SZ, bendera ini mengambil alih perilaku default, yaitu memproses nilai registri sebelum memanggil rutinitas QueryRoutine . Secara default, RtlQueryRegistryValues memperluas referensi variabel lingkungan dalam nilai REG_EXPAND_SZ, dan menghitung setiap string yang dihentikan null dalam nilai REG_MULTI_SZ dalam panggilan QueryRoutine terpisah, sehingga string disajikan sebagai nilai REG_SZ yang memiliki ValueName yang sama. Jika bendera ini diatur, QueryRoutine menerima nilai REG_EXPAND_SZ mentah atau REG_MULTI_SZ dari registri. Untuk informasi selengkapnya tentang format data untuk nilai-nilai ini, lihat KEY_VALUE_BASIC_INFORMATION.
RTL_QUERY_REGISTRY_DIRECT Anggota QueryRoutine tidak digunakan (dan harus NULL), dan EntryContext menunjuk ke buffer untuk menyimpan nilai. Jika penelepon mengatur bendera ini, penelepon juga harus mengatur bendera RTL_QUERY_REGISTRY_TYPECHECK untuk melindungi dari luapan buffer. Untuk informasi lebih lanjut, lihat bagian Keterangan.
RTL_QUERY_REGISTRY_TYPECHECK Gunakan bendera ini dengan bendera RTL_QUERY_REGISTRY_DIRECT untuk memverifikasi bahwa jenis REG_XXX dari nilai registri tersimpan cocok dengan jenis yang diharapkan oleh pemanggil. Jika jenis tidak cocok, panggilan gagal. Untuk informasi lebih lanjut, lihat bagian Keterangan.
RTL_QUERY_REGISTRY_DELETE Bendera ini digunakan untuk menghapus kunci nilai setelah dikueri.

Dimulai dengan Windows 2000, dukungan kotak masuk disediakan untuk semua bit bendera dalam tabel sebelumnya, dengan pengecualian RTL_QUERY_REGISTRY_TYPECHECK. Dukungan kotak masuk untuk RTL_QUERY_REGISTRY_TYPECHECK tersedia dimulai dengan Windows 8. Untuk versi Windows yang lebih lama, dukungan untuk RTL_QUERY_REGISTRY_TYPECHECK disediakan melalui Windows Update. Untuk informasi selengkapnya, lihat Keterangan.

Nama

Ini adalah nama Nilai yang dikueri pemanggil. Jika NamaNULL, fungsi QueryRoutine yang ditentukan untuk entri tabel ini dipanggil untuk semua nilai yang terkait dengan kunci registri saat ini. Jika bendera RTL_QUERY_REGISTRY_DIRECT diatur, nilai non-NULL untuk Nama harus disediakan.

EntryContext

Jika bendera RTL_QUERY_REGISTRY_DIRECT diatur, ini adalah penunjuk ke buffer untuk menyimpan hasil operasi kueri untuk kunci ini. Jika tidak, nilai ini diteruskan sebagai parameter EntryContext dari QueryRoutine.

DefaultType

Byte yang paling tidak signifikan dari anggota ini menentukan jenis data REG_XXX yang akan dikembalikan, jika tidak ada kunci yang cocok yang ditemukan dan bendera RTL_QUERY_REGISTRY_REQUIRED tidak ditentukan. Tentukan REG_NONE tanpa jenis default. Jika bendera RTL_QUERY_REGISTRY_TYPECHECK diatur, byte paling signifikan dari anggota ini menentukan jenis REG_XXX dari nilai registri tersimpan yang diharapkan pemanggil. Bit 8 hingga 23 anggota ini dicadangkan dan harus nol.

DefaultData

Penunjuk ke nilai default yang akan dikembalikan jika tidak ada kunci yang cocok yang ditemukan dan bendera RTL_QUERY_REGISTRY_REQUIRED tidak ditentukan. Anggota ini diabaikan jika DefaultType = REG_NONE. Jika tidak, jenis data yang ditujukkan oleh DefaultData harus sesuai dengan jenis nilai registri yang ditentukan oleh anggota DefaultType . Untuk informasi selengkapnya jenis nilai registri, lihat definisi parameter Jenis di KEY_VALUE_BASIC_INFORMATION.

DefaultLength

Menentukan panjang, dalam byte, dari anggota DefaultData . Jika DefaultType REG_SZ, REG_EXPAND_SZ, atau REG_MULTI_SZ, penelepon dapat secara opsional menentukan nol untuk menunjukkan RtlQueryRegistryValues harus menghitung panjang berdasarkan nilai data default. Jika DefaultType = REG_NONE, anggota ini diabaikan.

[in, optional] Context

Menentukan nilai yang diteruskan sebagai parameter Konteks fungsi QueryRoutine setiap kali dipanggil.

[in, optional] Environment

Penunjuk ke lingkungan yang digunakan saat memperluas nilai variabel dalam nilai registri REG_EXPAND_SZ, atau penunjuk NULL (opsional).

Mengembalikan nilai

RtlQueryRegistryValues mengembalikan kode NTSTATUS. Nilai yang mungkin dikembalikan meliputi:

Menampilkan kode Deskripsi
STATUS_SUCCESS Seluruh tabel kueri berhasil diproses.
STATUS_INVALID_PARAMETER Pemrosesan tabel kueri dihentikan dengan entri tabel yang tidak valid. Entri tabel bisa tidak valid jika bendera yang ditentukan mengharuskan anggota QueryRoutine atau Name menjadi non-NULL, tetapi nilai NULL disediakan.
STATUS_OBJECT_NAME_NOT_FOUND Parameter Jalur tidak cocok dengan kunci yang valid, atau pemrosesan tabel kueri dihentikan dengan entri dengan set bendera RTL_QUERY_REGISTRY_REQUIRED dan tidak ada kunci yang cocok yang ditemukan. Hal ini terjadi jika anggota Nama adalah NULL dan kunci saat ini tidak memiliki subkuntus, atau jika Nama menentukan subkuntus yang tidak ada.
STATUS_BUFFER_TOO_SMALL Bendera RTL_QUERY_REGISTRY_DIRECT diatur, dan buffer yang ditentukan oleh EntryContext terlalu kecil untuk menyimpan data nilai kunci.
STATUS_OBJECT_TYPE_MISMATCH Bendera RTL_QUERY_REGISTRY_TYPECHECK diatur dan jenis nilai registri tersimpan tidak cocok dengan jenis yang diharapkan oleh pemanggil.

RtlQueryRegistryValues juga menghentikan pemrosesan tabel jika fungsi QueryRoutine untuk entri tabel mengembalikan kode kesalahan NTSTATUS, dan mengembalikan kode kesalahan tersebut sebagai hasilnya. (Dengan satu pengecualian: Jika QueryRoutine mengembalikan STATUS_BUFFER_TOO_SMALL, kode kesalahan diabaikan.)

Keterangan

Pemanggil menentukan jalur kunci awal dan tabel. Tabel berisi satu atau beberapa entri yang menjelaskan nilai kunci dan nama subkunci tempat pemanggil tertarik. Tabel dihentikan oleh entri dengan anggota QUERYRoutineNULL dan anggota NamaNULL. Tabel harus dialokasikan dari kumpulan yang tidak disebarkan.

Driver mode kernel harus menentukan bendera RTL_QUERY_REGISTRY_NOEXPAND untuk mencegah pemanggilan rutinitas variabel lingkungan. Rutinitas ini tidak aman, sehingga driver mode kernel tidak boleh menggunakannya.

Perhatian

Jika Anda menggunakan bendera RTL_QUERY_REGISTRY_DIRECT, aplikasi mode pengguna yang tidak tepercaya mungkin dapat menyebabkan luapan buffer. Luapan buffer dapat terjadi jika driver menggunakan bendera ini untuk membaca nilai registri tempat jenis yang salah ditetapkan. Dalam semua kasus, driver yang menggunakan bendera RTL_QUERY_REGISTRY_DIRECT juga harus menggunakan bendera RTL_QUERY_REGISTRY_TYPECHECK untuk mencegah luapan tersebut.

Jika bendera RTL_QUERY_REGISTRY_TYPECHECK diatur dalam entri tabel, pemanggil harus menentukan jenis REG_XXX yang diharapkan dalam 8 bit paling signifikan (MSB) dari anggota DefaultType 32-bit dari entri tabel. Seperti yang ditunjukkan dalam contoh kode berikut, konstanta RTL_QUERY_REGISTRY_TYPECHECK_SHIFT, yang didefinisikan menjadi 24, dapat digunakan sebagai jumlah shift yang diperlukan untuk menempatkan jenis REG_XXX yang diharapkan dalam 8 MSB anggota DefaultType .

RTL_QUERY_REGISTRY_TABLE QueryRegTable[2];    
...
QueryRegTable[0].DefaultType = (REG_SZ << RTL_QUERY_REGISTRY_TYPECHECK_SHIFT) | REG_NONE;
...
QueryRegTable[1].DefaultType = (REG_DWORD << RTL_QUERY_REGISTRY_TYPECHECK_SHIFT) | REG_NONE;
...

Dimulai dengan Windows 8, jika panggilan RtlQueryRegistryValues mengakses sarang yang tidak tepercaya, dan penelepon mengatur bendera RTL_QUERY_REGISTRY_DIRECT untuk panggilan ini, pemanggil juga harus mengatur bendera RTL_QUERY_REGISTRY_TYPECHECK. Pelanggaran aturan ini dengan panggilan dari mode pengguna menyebabkan pengecualian. Pelanggaran aturan ini dengan panggilan dari mode kernel menyebabkan pemeriksaan bug 0x139 (KERNEL_SECURITY_CHECK_FAILURE).

Hanya sarang sistem yang dipercaya. Panggilan RtlQueryRegistryValues yang mengakses sarang sistem tidak menyebabkan pengecualian atau pemeriksaan bug apakah bendera RTL_QUERY_REGISTRY_DIRECT diatur dan bendera RTL_QUERY_REGISTRY_TYPECHECK tidak diatur. Namun, sebagai praktik terbaik, bendera RTL_QUERY_REGISTRY_TYPECHECK harus selalu diatur jika bendera RTL_QUERY_REGISTRY_DIRECT diatur.

Demikian pula, dalam versi Windows sebelum Windows 8, sebagai praktik terbaik, panggilan RtlQueryRegistryValues yang mengatur bendera RTL_QUERY_REGISTRY_DIRECT juga harus mengatur bendera RTL_QUERY_REGISTRY_TYPECHECK. Namun, kegagalan untuk mengikuti rekomendasi ini tidak menyebabkan pengecualian atau pemeriksaan bug.

Berikut ini adalah daftar sarang sistem:

  • \REGISTRY\MACHINE\HARDWARE

  • \REGISTRY\MACHINE\SOFTWARE

  • \REGISTRY\MACHINE\SYSTEM

  • \REGISTRY\MACHINE\SECURITY

  • \REGISTRY\MACHINE\SAM

Dukungan untuk bendera RTL_QUERY_REGISTRY_TYPECHECK tersedia melalui Windows Update untuk Windows 7, Windows Vista, Windows Server 2003, dan Windows XP. Untuk informasi selengkapnya tentang pembaruan ini, lihat Kerentanan di Windows Kernel Dapat Memungkinkan Elevasi (2393802). Dalam versi sistem operasi ini yang tidak memiliki pembaruan ini, pemanggil dapat menggunakan bendera RTL_QUERY_REGISTRY_TYPECHECK. Namun, bendera ini diabaikan oleh rutinitas RtlQueryRegistryValues .

Dimulai dengan Windows Driver Kit (WDK) 8, bendera RTL_QUERY_REGISTRY_TYPECHECK didefinisikan dalam file header Wdm.h sebagai berikut:

#define RTL_QUERY_REGISTRY_TYPECHECK 0x00000100

Jika entri tidak menentukan bendera RTL_QUERY_REGISTRY_DIRECT, RtlQueryRegistryValues menggunakan fungsi QueryRoutine yang ditentukan untuk melaporkan nama nilai, jenis, data, dan panjang data, dalam byte, ke pemanggil. Jika anggota Nama entri adalah NULL, RtlQueryRegistryValues melaporkan setiap subkuntang langsung kunci. Jika jenis kunci REG_MULTI_SZ dan bendera RTL_QUERY_REGISTRY_NOEXPAND tidak ditentukan, rutin memanggil QueryRoutine secara terpisah untuk setiap string individual; jika tidak, rutin melaporkannya sebagai nilai tunggal. Jika entri menentukan bendera RTL_QUERY_REGISTRY_DIRECT, RtlQueryRegistryValues menyimpan nilai kunci dalam buffer yang ditujukkan oleh anggota EntryContext entri. Format data yang dikembalikan adalah sebagai berikut.

Jenis data kunci Bagaimana data dikembalikan
String Unicode yang dihentikan null (seperti REG_SZ, REG_EXPAND_SZ). EntryContext harus menunjuk ke struktur UNICODE_STRING yang diinisialisasi. Jika anggota BufferUNICODE_STRINGNULL, rutin mengalokasikan penyimpanan untuk data string. Jika tidak, ia menyimpan data string di buffer yang dirujuk Buffer .
REG_MULTI_SZ Anda harus menentukan bendera RTL_QUERY_REGISTRY_NOEXPAND untuk tipe data kunci ini. EntryContext menunjuk ke struktur UNICODE_STRING yang diinisialisasi. Rutin menyimpan nilai kunci sebagai nilai string tunggal. Setiap komponen individual dalam string dihentikan oleh nol. Jika anggota BufferUNICODE_STRINGNULL, rutin mengalokasikan penyimpanan untuk data string. Jika tidak, ia menyimpan data string di buffer yang dirujuk Buffer .
Data nonstring dengan ukuran, dalam byte, <= sizeof(ULONG) Nilai disimpan di lokasi memori yang ditentukan oleh EntryContext.
Data nonstring dengan ukuran, dalam byte, >sizeof(ULONG) Buffer yang diacu oleh EntryContext harus dimulai dengan nilai LONG yang ditandatangani. Besarnya nilai harus menentukan ukuran, dalam byte, dari buffer. Jika tanda nilai negatif, RtlQueryRegistryValues hanya akan menyimpan data nilai kunci. Jika tidak, ULONG akan menggunakan ULONG pertama dalam buffer untuk merekam panjang nilai, dalam byte, ULONG kedua untuk merekam jenis nilai, dan sisa buffer untuk menyimpan data nilai.

Jika terjadi kesalahan pada setiap tahap pemrosesan tabel kueri, RtlQueryRegistryValues berhenti memproses tabel dan mengembalikan status kesalahan.

Lihat ZwSetValueKey untuk deskripsi kemungkinan nilai REG_XXX .

Persyaratan

Persyaratan Nilai
Target Platform Universal
Header wdm.h (termasuk Wdm.h, Ntddk.h, Ntifs.h)
Pustaka Ntoskrnl.lib
DLL Ntoskrnl.exe
IRQL PASSIVE_LEVEL

Lihat juga

QueryRoutine

RtlZeroMemory

UNICODE_STRING

ZwEnumerateKey

ZwEnumerateValueKey

ZwSetValueKey