Esempio n. 1
0
//
// Wrapper for IovAllocateIrp. Use special pool to allocate the IRP.
// This is directly called from IoAllocateIrp.
//
PIRP
IovAllocateIrp(
    IN CCHAR StackSize,
    IN BOOLEAN ChargeQuota
    )
{
    USHORT allocateSize;
    UCHAR fixedSize;
    PIRP irp;
    UCHAR mustSucceed;
    USHORT packetSize;

#ifndef NO_SPECIAL_IRP
    //
    // Should we override normal lookaside caching so that we may catch
    // more bugs?
    //
    SPECIALIRP_IO_ALLOCATE_IRP_1(StackSize, ChargeQuota, &irp) ;

    if (irp) {
       return irp ;
    }
#endif

    //
    // If special pool is not turned on lets just call the standard
    // irp allocator.
    //

    if (!(IovpVerifierFlags & DRIVER_VERIFIER_SPECIAL_POOLING )) {
        irp = IopAllocateIrpPrivate(StackSize, ChargeQuota);
        return irp;
    }


    irp = NULL;
    fixedSize = 0;
    mustSucceed = 0;
    packetSize = IoSizeOfIrp(StackSize);
    allocateSize = packetSize;

    //
    // There are no free packets on the lookaside list, or the packet is
    // too large to be allocated from one of the lists, so it must be
    // allocated from nonpaged pool. If quota is to be charged, charge it
    // against the current process. Otherwise, allocate the pool normally.
    //

    if (ChargeQuota) {
        try {
            irp = ExAllocatePoolWithTagPriority(
                    NonPagedPool,
                    allocateSize,
                    ' prI',
                    HighPoolPrioritySpecialPoolOverrun);
        } except(EXCEPTION_EXECUTE_HANDLER) {
            NOTHING;
        }

    } else {
Esempio n. 2
0
PIRP
FASTCALL
IovpProtectedIrpAllocate(
    IN CCHAR    StackSize,
    IN BOOLEAN  ChargeQuota,
    IN PETHREAD QuotaThread OPTIONAL
    )
/*++

  Description:

    This routine allocates an IRP from the special pool using the
    "replacement IRP" tag.

  Arguments:

     StackSize   - Number of stack locations to give the new IRP

     ChargeQuota - TRUE iff quota should be charged against QuotaThread

     QuotaThread - See above

  Return Value:

     Pointer to the memory allocated.

--*/
{
    PIRP pSurrogateIrp;
    ULONG_PTR irpPtr;
    SIZE_T sizeOfAllocation;

    //
    // We are allocating an IRP from the special pool. Since IRPs may come from
    // lookaside lists they may be ULONG aligned. The memory manager on the
    // other hand gaurentees quad-aligned allocations. So to catch all special
    // pool overrun bugs we "skew" the IRP right up to the edge.
    //
    sizeOfAllocation = IoSizeOfIrp(StackSize);

    ASSERT((sizeOfAllocation % (sizeof(ULONG))) == 0);

    //
    // ADRIAO BUGBUG 08/16/98 - Use a quota'd alloc function if one is available
    // later...
    //
    irpPtr = (ULONG_PTR) ExAllocatePoolWithTagPriority(
        NonPagedPool,
        sizeOfAllocation,
        POOL_TAG_PROTECTED_IRP,
        HighPoolPrioritySpecialPoolOverrun
        );

    pSurrogateIrp = (PIRP) (irpPtr);

    return pSurrogateIrp;
}
Esempio n. 3
0
NTSTATUS
SerialWrite( IN PDEVICE_OBJECT DeviceObject,
             IN PIRP Irp )
/*++

Routine Description:

    This is the dispatch routine for write.  It validates the parameters
    for the write request and if all is ok and there are no outstanding
    write requests, it then checks to see if there is enough room for the
    data in the controllers Tx buffer.  It places the request on the work
    queue if it can't place all the data in the controllers buffer, or there
    is an outstanding write request.

Arguments:

    DeviceObject - Pointer to the device object for this device

    Irp - Pointer to the IRP for the current request

Return Value:

    If the io is zero length then it will return STATUS_SUCCESS,
    otherwise this routine will return STATUS_PENDING, or the result
    of trying to write the data to the waiting controller.

--*/
{
   PDIGI_DEVICE_EXTENSION DeviceExt = DeviceObject->DeviceExtension;
   PDIGI_CONTROLLER_EXTENSION ControllerExt = DeviceExt->ParentControllerExt;
   NTSTATUS Status;
#if DBG
   LARGE_INTEGER CurrentSystemTime;
#endif

   ASSERT( IoGetCurrentIrpStackLocation(Irp)->MajorFunction == IRP_MJ_WRITE );

   if (DeviceObject==ControllerExt->ControllerDeviceObject)
   {
      /*
      ** No writes allowed to controller.
      */
      Irp->IoStatus.Status = STATUS_ACCESS_VIOLATION;
      Irp->IoStatus.Information = 0;
      DigiIoCompleteRequest( Irp, IO_NO_INCREMENT );
      return STATUS_ACCESS_VIOLATION;
   }

   if( DeviceExt->DeviceState != DIGI_DEVICE_STATE_OPEN )
   {
      Irp->IoStatus.Status = STATUS_CANCELLED;
      Irp->IoStatus.Information = 0;
      DigiIoCompleteRequest( Irp, IO_NO_INCREMENT );
      return STATUS_CANCELLED;
   }

   InterlockedIncrement(&ControllerExt->PerfData.WriteRequests);
   InterlockedIncrement(&DeviceExt->PerfData.WriteRequests);

#if DBG
   KeQuerySystemTime( &CurrentSystemTime );
#endif
   DigiDump( (DIGIIRP|DIGIFLOW|DIGIWRITE), ("Entering SerialWrite: port = %s\tIRP = 0x%x\t%u:%u\n",
                                            DeviceExt->DeviceDbgString, Irp, CurrentSystemTime.HighPart, CurrentSystemTime.LowPart) );

   //
   // Check first for a write length of 0, then for a NULL buffer!
   //
   if( IoGetCurrentIrpStackLocation( Irp )->Parameters.Write.Length == 0 )
   {
      //
      // We assume a write of 0 length is valid.  Just complete the request
      // and return.
      //
      Irp->IoStatus.Information = 0L;
      Irp->IoStatus.Status = STATUS_SUCCESS;
      DigiIoCompleteRequest( Irp, IO_NO_INCREMENT );

      DigiDump( DIGITXTRACE, ("port %s requested a zero length write\n",
                              DeviceExt->DeviceDbgString) );
#if DBG
      KeQuerySystemTime( &CurrentSystemTime );
#endif
      DigiDump( (DIGIFLOW|DIGIWRITE), ("Exiting SerialWrite: port = %s\t%u:%u\n",
                                       DeviceExt->DeviceDbgString, CurrentSystemTime.HighPart, CurrentSystemTime.LowPart) );
      return( STATUS_SUCCESS );
   }

   if( Irp->AssociatedIrp.SystemBuffer == NULL )
   {
      //
      // This is most definitely a No No!
      //
      DigiDump( DIGIERRORS, ("SerialWrite - Invalid Irp->AssociatedIrp.SystemBuffer!\n") );

      Irp->IoStatus.Information = 0L;
      Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
      DigiIoCompleteRequest( Irp, IO_NO_INCREMENT );

#if DBG
      KeQuerySystemTime( &CurrentSystemTime );
#endif
      DigiDump( DIGIFLOW, ("Exiting SerialWrite: port = %s ret = %d\t%u:%u\n",
                           DeviceExt->DeviceDbgString, STATUS_INVALID_PARAMETER, CurrentSystemTime.HighPart, CurrentSystemTime.LowPart) );
      return( STATUS_INVALID_PARAMETER );
   }

   //
   // Mark the IRP as being "not started."
   // StartWriteRequest will set this field to zero.
   // WriteTxBuffer updates the field to the number of bytes written.
   //
   Irp->IoStatus.Information = MAXULONG;

   DigiDump( DIGIWRITE, ("  #bytes to write: %d\n",
            IoGetCurrentIrpStackLocation(Irp)->Parameters.Write.Length) );

#if DBG
   if( DigiDebugLevel & DIGITXTRACE )
   {
      PUCHAR Temp = Irp->AssociatedIrp.SystemBuffer;
      ULONG i;

      DigiDump( DIGITXTRACE, ("TXTRACE: %s: TxLength = %d (0x%x)",
                              DeviceExt->DeviceDbgString,
                              IoGetCurrentIrpStackLocation( Irp )->Parameters.Write.Length,
                              IoGetCurrentIrpStackLocation( Irp )->Parameters.Write.Length) );
      for( i = 0;
           i < IoGetCurrentIrpStackLocation( Irp )->Parameters.Write.Length;
           i++ )
      {
         if( (i & 15) == 0 )
            DigiDump( DIGITXTRACE, ( "\n\t") );

         DigiDump( DIGITXTRACE, ( "-%02x", Temp[i]) );
      }
      DigiDump( DIGITXTRACE, ("\n") );
   }
#endif

   //
   // If we are doing RAS, then we wait for any data in
   // the transmit queue to be put on the wire.
   //
   if( DeviceExt->SpecialFlags & DIGI_SPECIAL_FLAG_FAST_RAS )
   {
      PIRP NewIrp;

//#undef IO_ALLOC_IRP_WORKS, at least under 3.5 (807) checked build (IoFreeIrp reports corrupted memory)

#ifdef IO_ALLOC_IRP_WORKS
      NewIrp = IoAllocateIrp( 2, FALSE );
#else
      NewIrp = DigiAllocMem( NonPagedPool, IoSizeOfIrp( 2 ) );
#endif

      if( NewIrp )
      {
         PIO_STACK_LOCATION NewIrpSp;

         IoInitializeIrp( NewIrp, IoSizeOfIrp( 2 ), 2 );
         IoSetCompletionRoutine( NewIrp, FreeDigiIrp, NULL, TRUE, TRUE, TRUE );
         IoSetNextIrpStackLocation( NewIrp );
         NewIrpSp = IoGetCurrentIrpStackLocation( NewIrp );
         NewIrpSp->MajorFunction = IRP_MJ_FLUSH_BUFFERS;
         NewIrpSp->DeviceObject = DeviceObject;

         DigiDump( 0, ("Inserting flush irp 0x%x on %s\n", NewIrp, DeviceExt->DeviceDbgString) );
         (VOID) DigiStartIrpRequest( ControllerExt, DeviceExt,
                                       &DeviceExt->WriteQueue, NewIrp,
                                       StartWriteRequest );
      }
   }

   Status = DigiStartIrpRequest( ControllerExt, DeviceExt,
                                 &DeviceExt->WriteQueue, Irp,
                                 StartWriteRequest );

#if DBG
   KeQuerySystemTime( &CurrentSystemTime );
#endif
   DigiDump( (DIGIFLOW|DIGIWRITE), ("Exiting SerialWrite: port = %s\t%u:%u\n",
                                    DeviceExt->DeviceDbgString, CurrentSystemTime.HighPart, CurrentSystemTime.LowPart) );

   return( Status );
}  // end SerialWrite
Esempio n. 4
0
/*
 * @implemented
 */
VOID
IssueUniqueIdChangeNotifyWorker(IN PUNIQUE_ID_WORK_ITEM WorkItem,
                                IN PMOUNTDEV_UNIQUE_ID UniqueId)
{
    PIRP Irp;
    NTSTATUS Status;
    PFILE_OBJECT FileObject;
    PIO_STACK_LOCATION Stack;
    PDEVICE_OBJECT DeviceObject;

    /* Get the device object */
    Status = IoGetDeviceObjectPointer(&(WorkItem->DeviceName),
                                      FILE_READ_ATTRIBUTES,
                                      &FileObject,
                                      &DeviceObject);
    if (!NT_SUCCESS(Status))
    {
        RemoveWorkItem(WorkItem);
        return;
    }

    /* And then, the attached device */
    DeviceObject = IoGetAttachedDeviceReference(FileObject->DeviceObject);

    /* Initialize the IRP */
    Irp = WorkItem->Irp;
    IoInitializeIrp(Irp, IoSizeOfIrp(WorkItem->StackSize), (CCHAR)WorkItem->StackSize);

    if (InterlockedExchange((PLONG)&(WorkItem->Event), 0) != 0)
    {
        ObDereferenceObject(FileObject);
        ObDereferenceObject(DeviceObject);
        RemoveWorkItem(WorkItem);
        return;
    }

    Irp->AssociatedIrp.SystemBuffer = WorkItem->IrpBuffer;
    Irp->Tail.Overlay.Thread = PsGetCurrentThread();
    RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer, UniqueId, UniqueId->UniqueIdLength + sizeof(USHORT));

    Stack = IoGetNextIrpStackLocation(Irp);

    Stack->Parameters.DeviceIoControl.InputBufferLength = UniqueId->UniqueIdLength + sizeof(USHORT);
    Stack->Parameters.DeviceIoControl.OutputBufferLength = WorkItem->IrpBufferLength;
    Stack->Parameters.DeviceIoControl.Type3InputBuffer = 0;
    Stack->Parameters.DeviceIoControl.IoControlCode = IOCTL_MOUNTDEV_UNIQUE_ID_CHANGE_NOTIFY;
    Stack->MajorFunction = IRP_MJ_DEVICE_CONTROL;

    Status = IoSetCompletionRoutineEx(WorkItem->DeviceExtension->DeviceObject,
                                      Irp,
                                      UniqueIdChangeNotifyCompletion,
                                      WorkItem,
                                      TRUE, TRUE, TRUE);
    if (!NT_SUCCESS(Status))
    {
        ObDereferenceObject(FileObject);
        ObDereferenceObject(DeviceObject);
        RemoveWorkItem(WorkItem);
        return;
    }

    /* Call the driver */
    IoCallDriver(DeviceObject, Irp);
    ObDereferenceObject(FileObject);
    ObDereferenceObject(DeviceObject);
}