Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
Artikel ini menjelaskan cara membuat kode kontrol I/O unik (IOCTL). IOCTL dapat berupa:
- IOCTL publik, yang biasanya ditentukan sistem dan didokumenkan oleh Microsoft.
- IOCTL privat, yang biasanya dimaksudkan untuk digunakan secara eksklusif oleh komponen perangkat lunak vendor untuk berkomunikasi satu sama lain. Mereka biasanya didefinisikan dalam file header vendor dan tidak didokumenkan oleh Microsoft.
Tata letak IOCTL
IOCTL adalah nilai 32-bit yang terdiri dari beberapa bidang. Gambar berikut mengilustrasikan tata letak bit per bit untuk IOCTL.
Setiap bidang di IOCTL memiliki tujuan tertentu, seperti yang dijelaskan dalam tabel berikut:
Bidang | Bit-bit dalam IOCTL | Deskripsi |
---|---|---|
Umum | 31 | Vendor harus mengatur bit ini ketika mereka menggunakan nilai yang ditetapkan vendor untuk DeviceType. |
DeviceType | 16-30 | Mengidentifikasi jenis perangkat. Nilai ini harus cocok dengan nilai yang ditetapkan dalam anggota DeviceType dari struktur DEVICE_OBJECT driver. Vendor harus menggunakan nilai dari 32768 hingga 65535 (0x8000 melalui 0xffff), dan harus mengatur Bit umum . Nilai 0 hingga 32767 (0x0000 hingga 0x7fff) dikhususkan untuk Microsoft. Untuk informasi selengkapnya, lihat Menentukan Jenis Perangkat. |
Akses | 14-15 | Menunjukkan jenis akses yang harus diminta pemanggil saat membuka objek file yang mewakili perangkat (lihat IRP_MJ_CREATE). Manajer I/O akan membuat IRP dan memanggil driver dengan IOCTL tertentu hanya jika pemanggil meminta hak akses tertentu. Bidang ini ditentukan menggunakan konstanta yang ditentukan sistem berikut: FILE_ANY_ACCESS, FILE_READ_DATA, dan FILE_WRITE_DATA. |
Khusus | 13 | Saat diatur, menunjukkan bahwa IOCTL adalah IOCTL yang didefinisikan oleh vendor. |
Fungsi | 2-12 | Kode unik untuk driver yang mengidentifikasi fungsi yang harus dilakukan. Untuk IOCTL yang dibuat vendor, gunakan nilai 2048 hingga 4095 (0x800 hingga 0xfff) dan atur Bit kustom . Nilai yang kurang dari 2048 (0x000 hingga 0x7ff) dicadangkan untuk Microsoft. |
Metode | 0-1 | Menunjukkan bagaimana sistem meneruskan data antara pemanggil DeviceIoControl (atau IoBuildDeviceIoControlRequest) dan driver yang menangani IRP. Untuk informasi selengkapnya, lihat Panduan untuk mengatur bit Metode. |
Makro untuk menentukan kode kontrol I/O
Gunakan makro CTL_CODE yang disediakan sistem untuk menentukan kode kontrol I/O baru. Makro ini didefinisikan dalam devioctl.h sebagai berikut:
#define CTL_CODE( DeviceType, Function, Method, Access ) ( \
((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method) \
)
Lihat bagian sebelumnya untuk deskripsi DeviceType, Function, Method, dan Access.
Ingatlah aturan berikut saat menentukan kode kontrol I/O baru:
Jika IOCTL baru tersedia untuk komponen perangkat lunak mode pengguna, maka IOCTL tersebut harus digunakan bersamaan dengan permintaan IRP_MJ_DEVICE_CONTROL. Komponen mode pengguna memanggil DeviceIoControl untuk mengirim permintaan IRP_MJ_DEVICE_CONTROL .
Jika IOCTL baru hanya akan tersedia untuk komponen driver mode kernel, IOCTL tersebut harus digunakan dengan permintaan IRP_MJ_INTERNAL_DEVICE_CONTROL. Komponen mode kernel dapat membuat permintaan IRP_MJ_INTERNAL_DEVICE_CONTROL dengan memanggil IoBuildDeviceIoControlRequest. Untuk informasi selengkapnya, lihat Membuat Permintaan IOCTL di Driver.
Definisi kode IOCTL baru, baik yang dimaksudkan untuk digunakan dengan permintaan IRP_MJ_DEVICE_CONTROL atau IRP_MJ_INTERNAL_DEVICE_CONTROL, menggunakan format berikut:
#define IOCTL_Device_Function CTL_CODE(DeviceType, Function, Method, Access)
Pilih nama konstanta deskriptif untuk IOCTL, dari formulir IOCTL_Device_Function, di mana Perangkat menunjukkan jenis perangkat dan Fungsi menunjukkan operasi. Misalnya, konstanta IOCTL_VIDEO_ENABLE_CURSOR yang disediakan sistem menggunakan "VIDEO" untuk Perangkat dan "ENABLE_CURSOR" untuk Fungsi.
Panduan untuk mengatur bit Access
Saat menentukan IOCTL baru, Anda harus memilih nilai untuk bidang Bit akses yang menunjukkan jenis akses yang harus diminta pemanggil saat membuka objek file yang mewakili perangkat. Manajer I/O akan membuat IRP dan memanggil driver dengan IOCTL tertentu hanya jika pemanggil meminta hak akses yang ditentukan.
Akses ditentukan dengan menggunakan konstanta yang ditentukan sistem berikut:
Akses_File_Apa_Saja
Manajer I/O mengirimkan IRP untuk setiap pemanggil yang memiliki handle ke objek file yang mewakili objek perangkat target. Sebelum menentukan FILE_ANY_ACCESS untuk kode IOCTL baru, Anda harus benar-benar yakin bahwa memungkinkan akses tidak terbatas ke perangkat Anda tidak membuat jalur yang mungkin bagi pengguna berbahaya untuk membahayakan sistem.
MEMBACA_DATA_FILE
Manajer I/O mengirimkan IRP hanya untuk penelepon dengan hak akses baca, yang memungkinkan driver perangkat yang mendasar mentransfer data dari perangkat ke memori sistem.
TULIS_DATA_BERKAS
Manajer I/O mengirimkan IRP hanya untuk penelepon dengan hak akses tulis, memungkinkan driver perangkat yang mendasar untuk mentransfer data dari memori sistem ke perangkat tersebut.
FILE_READ_DATA dan FILE_WRITE_DATA dapat digabungkan dengan OR apabila pemanggil memerlukan hak akses baca dan tulis.
Beberapa kode kontrol I/O yang ditentukan sistem memiliki nilai Akses FILE_ANY_ACCESS, yang memungkinkan pemanggil untuk mengirim IOCTL tertentu terlepas dari akses yang diberikan ke perangkat. Contohnya termasuk kode kontrol I/O yang dikirim ke driver perangkat eksklusif .
Kode kontrol I/O lain yang ditentukan sistem mengharuskan pemanggil memiliki hak akses baca, hak akses tulis, atau keduanya. Misalnya, definisi publik berikut IOCTL_DISK_SET_PARTITION_INFO IOCTL menunjukkan bahwa permintaan I/O ini dapat dikirim ke driver hanya jika pemanggil memiliki hak akses baca dan tulis:
#define IOCTL_DISK_SET_PARTITION_INFO\
CTL_CODE(IOCTL_DISK_BASE, 0x008, METHOD_BUFFERED,\
FILE_READ_DATA | FILE_WRITE_DATA)
Driver dapat menggunakan IoValidateDeviceIoControlAccess untuk melakukan pemeriksaan akses yang lebih ketat daripada yang disediakan oleh bit Akses IOCTL.
Panduan untuk mengatur bit Metode
Saat menentukan IOCTL baru, Anda harus memilih nilai untuk bidang Bit metode yang menunjukkan bagaimana sistem meneruskan data antara pemanggil DeviceIoControl (atau IoBuildDeviceIoControlRequest) dan driver yang menangani IRP.
Gunakan salah satu konstanta yang ditentukan sistem berikut untuk mengatur bidang Metode .
METODE_BUFFERED
Menentukan metode I/O buffer, yang biasanya digunakan untuk mentransfer sejumlah kecil data per permintaan. Sebagian besar kode kontrol I/O untuk perangkat dan driver perantara menggunakan nilai ini.
Untuk informasi tentang bagaimana sistem menentukan buffer data untuk kode kontrol I/O METHOD_BUFFERED, lihat Deskripsi Buffer untuk Kode Kontrol I/O.
Untuk informasi selengkapnya tentang I/O ter-buffer, lihat Menggunakan I/O ter-buffer.
METHOD_IN_DIRECT atau METHOD_OUT_DIRECT
Menentukan metode I/O langsung , yang biasanya digunakan untuk membaca atau menulis data dalam jumlah besar menggunakan DMA atau PIO yang harus ditransfer dengan cepat.
Tentukan METHOD_IN_DIRECT jika pemanggil DeviceIoControl atau IoBuildDeviceIoControlRequest akan meneruskan data ke driver.
Tentukan METHOD_OUT_DIRECT jika pemanggil DeviceIoControl atau IoBuildDeviceIoControlRequest akan menerima data dari driver.
Untuk informasi tentang bagaimana sistem menentukan buffer data untuk kode kontrol I/O METHOD_IN_DIRECT dan METHOD_OUT_DIRECT, lihat Deskripsi Buffer untuk Kode Kontrol I/O.
Untuk informasi selengkapnya tentang I/O langsung, lihat Menggunakan I/O Langsung.
METODE_TIDAK_SATU_PUN
Menentukan metode I/O tidak di-buffer atau langsung. Manajer I/O tidak menyediakan buffer sistem atau MDL apa pun. IRP menyediakan alamat virtual mode pengguna dari buffer input dan output yang ditentukan untuk DeviceIoControl atau IoBuildDeviceIoControlRequest, tanpa memvalidasi atau memetakannya.
Untuk informasi tentang bagaimana sistem menentukan buffer data untuk kode kontrol I/O METHOD_NEITHER, lihat Deskripsi Buffer untuk Kode Kontrol I/O.
Metode ini hanya dapat digunakan jika driver dijamin berjalan dalam konteks utas yang berasal dari permintaan kontrol I/O. Hanya driver mode kernel tingkat tertinggi yang dijamin untuk memenuhi kondisi ini, jadi METHOD_NEITHER jarang digunakan untuk IOCTL yang diteruskan ke driver perangkat tingkat rendah.
Dengan metode ini, driver tingkat tertinggi:
- Harus menentukan apakah akan menyiapkan akses yang dibuffer atau langsung ke data pengguna pada penerimaan permintaan.
- Mungkin harus mengunci buffer pengguna.
- Harus membungkus aksesnya ke buffer pengguna dalam handler pengecualian terstruktur (lihat Menangani Pengecualian).
Jika tidak, pemanggil mode pengguna yang asli dapat mengubah data buffer sebelum driver dapat menggunakannya, atau pemanggil dapat dipindahkan dari memori tepat saat driver mengakses buffer pengguna.
Untuk informasi selengkapnya, lihat Menggunakan I/O yang Tidak Buffered maupun Langsung.
Makro berguna lainnya
Makro berikut berguna untuk mengekstrak bidang DeviceType 16-bit dan Metode 2-bit dari IOCTL.
#define DEVICE_TYPE_FROM_CTL_CODE(ctrlCode) (((ULONG)(ctrlCode & 0xffff0000)) >> 16)
#define METHOD_FROM_CTL_CODE(ctrlCode) ((ULONG)(ctrlCode & 3))
Makro ini didefinisikan dalam Wdm.h dan Ntddk.h.