Aracılığıyla paylaş


Çıkış Arabellekleri Başlatılamadı

Sürücüler, çağırana döndürmeden önce tüm çıkış arabelleklerini sıfırlarla başlatmalıdır. Arabelleğin başlatılmaması, başlatılmamış baytlarda sorunlu veriye neden olabilir.

Aşağıdaki örnekte, bir sürücü kullanılmayan baytlardaki çöp verilerini döndürür.

   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 değeri çıkış arabelleği boyutuna ayarlandığında, bu durum çıkış arabelleğinin tamamının çağırana döndürülmesine neden olur. G/Ç yöneticisi verileri giriş arabelleği boyutunun ötesinde başlatmaz; giriş ve çıkış arabellekleri arabelleğe alınmış bir istek için üst üste biner. Sistem destek yordamı IoGetDeviceProperty tüm arabelleği yazmadığından, bu IOCTL çağırana başlatılmamış verileri döndürür.

Bazı sürücüler, G/Ç istekleri hakkında ek ayrıntılar sağlayan kodları döndürmek için Bilgi alanını kullanır. Sürücülerin, bunu yapmadan önce IRP bayraklarını kontrol ederek IRP_INPUT_OPERATION'ın ayarlı olmadığından emin olması gerekir. Bu bayrak ayarlanmadığında, IOCTL veya FSCTL'de çıkış arabelleği yoktur, bu nedenle Bilgi alanının arabellek boyutu sağlaması gerekmez. Bu durumda. sürücü, kendi kodunu döndürmek için Bilgi alanını güvenli bir şekilde kullanabilir.