Поделиться через


Сбой инициализации буферов вывода

Драйверы должны инициализировать все выходные буферы нулями, прежде чем возвращать их вызывающему объекту. Если не инициализировать буфер, данные мусора будут содержаться в неинициализированных байтах.

В следующем примере драйвер возвращает мусор в неиспользуемых байтах.

   case IOCTL_GET_NAME: {
      ...
      ...
      outputBufferLength = 
         ioStack->Parameters.DeviceIoControl.OutputBufferLength;
      outputBuffer = (PGET_NAME) Irp->AssociatedIrp.SystemBuffer;
 
      if (outputBufferLength >= sizeof(GET_NAME)) {
         length = outputBufferLength - sizeof(GET_NAME);
 
         ntStatus = IoGetDeviceProperty(
                        DeviceExtension->PhysicalDeviceObject,
                        DevicePropertyDriverKeyName,
                        length,
                        outputBuffer->DriverKeyName,
                        &length);

         outputBuffer->ActualLength =
                        length + sizeof(GET_NAME);

         Irp->IoStatus.Information = outputBufferLength;
 
      } else {
         ntStatus = STATUS_BUFFER_TOO_SMALL;
      }

Если в IoStatus.Information задан размер выходного буфера, вызывающий объект возвращает весь выходной буфер. Диспетчер ввода-вывода не инициализирует данные сверх размера входного буфера— входной и выходной буферы перекрываются для буферизованного запроса. Так как система, поддерживающая подпрограмму IoGetDeviceProperty , не записывает весь буфер, этот IOCTL возвращает неинициализированные данные вызывающей объекту.

Некоторые драйверы используют поле Сведения для возврата кодов, которые предоставляют дополнительные сведения о запросах ввода-вывода. Перед этим такие драйверы должны проверка флаги IRP, чтобы убедиться, что IRP_INPUT_OPERATION не задан. Если этот флаг не задан, IOCTL или FSCTL не имеют выходного буфера, поэтому в поле Сведения не требуется указывать размер буфера. В этом случае. драйвер может безопасно использовать поле Сведения для возврата собственного кода.