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.
Anda dapat memberikan Pemverifikasi Driver Statis (SDV) dengan informasi tambahan tentang kode sumber driver Anda sehingga selama verifikasi Anda dapat menekan laporan cacat palsu. Cacat palsu terjadi ketika SDV melaporkan pelanggaran aturan yang tampak, tetapi dalam situasi di mana pengemudi bertindak dengan benar.
Untuk memberikan informasi tambahan ini kepada SDV, gunakan fungsi __analysis_assume . Fungsi ini memiliki sintaks berikut:
__analysis_assume( expression )
Di mana ekspresi dapat berupa ekspresi apa pun yang diasumsikan untuk dievaluasi ke true.
Saat Anda menggunakan fungsi ini, SDV mengasumsikan bahwa kondisi yang diwakili oleh ekspresi adalah true pada titik di mana fungsi __analysis_assume muncul. Fungsi __analysis_assume hanya digunakan oleh alat analisis statis. Fungsi diabaikan oleh pengkompilasi.
Jika Anda menggunakan __analysis_assume, sangat penting bahwa Anda yakin dengan validitas asumsi yang Anda buat. Jika ternyata asumsi Anda salah, baik sekarang maupun di masa depan, Anda mungkin mengabaikan cacat yang sebenarnya. Kami menyarankan agar Anda selalu menambahkan komentar ke kode Anda yang menjelaskan mengapa Anda menggunakan fungsi __analysis_assume . Jika Anda tidak dapat memberikan alasan untuk asumsi tersebut, jangan menyembunyikan cacatnya.
Anda harus menambahkan fungsi __analysis_assume sesuai kebutuhan, setiap kali Anda menemukan cacat palsu yang dapat Anda hilangkan dengan aman.
Contoh
Dalam contoh kode berikut, aturan KMDF RequestCompletedLocal melaporkan cacat. Ini adalah kesalahan palsu karena SDV tidak dapat menginterpretasikan pernyataan pengalihan dengan benar dan akibatnya tidak memasuki cabang tempat permintaan diselesaikan.
Dalam pernyataan switch ini, ada enam kemungkinan kasus. Driver telah mendefinisikan enam kode IOCTL, sehingga driver pasti akan mengambil salah satu cabang. Jika salah satu cabang diambil, permintaan berhasil diselesaikan.
VOID
PortIOEvtIoDeviceControl(
__in WDFQUEUE Queue,
__in WDFREQUEST Request,
__in size_t OutputBufferLength,
__in size_t InputBufferLength,
__in ULONG IoControlCode
)
PDEVICE_CONTEXT devContext = NULL;
WDFDEVICE device;
PAGED_CODE();
device = WdfIoQueueGetDevice(Queue);
devContext = PortIOGetDeviceContext(device);
switch(IoControlCode)
case IOCTL_GPD_READ_PORT_UCHAR:
case IOCTL_GPD_READ_PORT_USHORT:
case IOCTL_GPD_READ_PORT_ULONG:
PortIOIoctlReadPort(devContext,
Request,
OutputBufferLength,
InputBufferLength,
IoControlCode);
break;
case IOCTL_GPD_WRITE_PORT_UCHAR:
case IOCTL_GPD_WRITE_PORT_USHORT:
case IOCTL_GPD_WRITE_PORT_ULONG:
PortIOIoctlWritePort(devContext,
Request,
OutputBufferLength,
InputBufferLength,
IoControlCode);
break;
}
}
Untuk menekan defek palsu dengan aman, gunakan fungsi __analysis_assume untuk menentukan bahwa IoControlCode dijamin sebagai salah satu IOCTL yang telah didefinisikan oleh driver.
VOID
PortIOEvtIoDeviceControl(
__in WDFQUEUE Queue,
__in WDFREQUEST Request,
__in size_t OutputBufferLength,
__in size_t InputBufferLength,
__in ULONG IoControlCode
)
PDEVICE_CONTEXT devContext = NULL;
WDFDEVICE device;
PAGED_CODE();
device = WdfIoQueueGetDevice(Queue);
devContext = PortIOGetDeviceContext(device);
/* Use __analysis_assume to suppress a false defect for the SDV RequestCompletedLocal rule.
There are only 6 possible IOCTLs for IoControlCode; each case is covered in the switch statement.
*/
__analysis_assume( IoControlCode == IOCTL_GPD_READ_PORT_UCHAR || \
IoControlCode == IOCTL_GPD_READ_PORT_USHORT|| \
IoControlCode == IOCTL_GPD_READ_PORT_ULONG || \
IoControlCode == IOCTL_GPD_WRITE_PORT_UCHAR|| \
IoControlCode == IOCTL_GPD_WRITE_PORT_USHORT|| \
IoControlCode == IOCTL_GPD_WRITE_PORT_ULONG);
switch(IoControlCode)
case IOCTL_GPD_READ_PORT_UCHAR:
case IOCTL_GPD_READ_PORT_USHORT:
case IOCTL_GPD_READ_PORT_ULONG:
PortIOIoctlReadPort(devContext,
Request,
OutputBufferLength,
InputBufferLength,
IoControlCode);
break;
case IOCTL_GPD_WRITE_PORT_UCHAR:
case IOCTL_GPD_WRITE_PORT_USHORT:
case IOCTL_GPD_WRITE_PORT_ULONG:
PortIOIoctlWritePort(devContext,
Request,
OutputBufferLength,
InputBufferLength,
IoControlCode);
break;
}
}
Untuk contoh lain tentang bagaimana Anda dapat menggunakan __analysis_assume, lihat contoh kode yang digunakan dalam Menggunakan __sdv_save_request dan __sdv_retrieve_request untuk Panggilan Prosedur Yang Ditangguhkan. Contoh menunjukkan cara menggunakan __sdv_save_request dan __sdv_retrieve_request untuk DPC (workitem, Timer, dan sebagainya). Fungsi __analysis_assume digunakan untuk menekan cacat palsu yang mungkin dihasilkan.