Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Вы можете предоставить средство проверки статических драйверов (SDV) с дополнительными сведениями о исходном коде драйвера, чтобы во время проверки можно подавлять отчеты о ложных дефектах. Ложные дефекты возникают, когда SDV сообщает о явном нарушении правил, но в ситуации, когда драйвер действует правильно.
Чтобы предоставить SDV дополнительную информацию, используйте функцию __analysis_assume. Функция имеет следующий синтаксис:
__analysis_assume( expression )
Где выражение может быть любое выражение, которое должно оцениваться как true.
При использовании этой функции SDV предполагает, что условие, представленное выражением , верно в точке, где отображается функция __analysis_assume . Функция __analysis_assume используется только статическими средствами анализа. Функция игнорируется компилятором.
Если вы используете __analysis_assume, крайне важно, что вы уверены в действительности допущения, которое вы делаете. Если оказывается, что ваше предположение является ложным, либо сейчас, либо в будущем, вы можете подавлять истинный дефект. Мы рекомендуем всегда добавлять комментарий в код, который объясняет, почему вы используете функцию __analysis_assume . Если вы не можете написать причину предположения, не подавляйте дефект.
По мере необходимости добавляйте функцию __analysis_assume, когда обнаруживаете ложные дефекты, которые можно безопасно отключить.
Примеры
В следующем примере кода правило KMDF RequestCompletedLocal сообщает о дефекте. Это ложный дефект, так как SDV не может правильно интерпретировать инструкцию switch и, следовательно, не вводит ветвь, в которой выполняется запрос.
В этом операторе switch существует шесть возможных вариантов. Драйвер определил шесть кодов IOCTL, поэтому драйвер определенно займет одну из ветвей. Если взята какая-либо из ветвей, запрос выполняется успешно.
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;
}
}
Чтобы безопасно отключить ложный дефект, используйте функцию __analysis_assume, чтобы указать, что IoControlCode гарантированно является одним из IOCTL, определённых драйвером.
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;
}
}
Другой пример использования __analysis_assume см. в примере кода, используемого в использовании __sdv_save_request и __sdv_retrieve_request для отложенных вызовов процедур. В примере показано, как использовать __sdv_save_request и __sdv_retrieve_request для ДПК (рабочих элементов, таймеров и т. д.). Функция __analysis_assume используется для подавления ложных дефектов, которые могут возникнуть в противном случае.