windows-nt/Source/XPSP1/NT/net/rras/ndis/asyncmac/io.c
2020-09-26 16:20:57 +08:00

153 lines
3.6 KiB
C

/*++
Copyright (c) 1992 Microsoft Corporation
Module Name:
io.c
Abstract:
Author:
Thomas J. Dimitri (TommyD) 08-May-1992
Environment:
Kernel Mode - Or whatever is the equivalent on OS/2 and DOS.
Revision History:
--*/
#include "asyncall.h"
// asyncmac.c will define the global parameters.
#include "globals.h"
NTSTATUS
AsyncSetupIrp(
IN PASYNC_FRAME Frame,
IN PIRP irp
)
/*++
This is the routine which intializes the Irp
--*/
{
// PMDL mdl;
PDEVICE_OBJECT deviceObject=Frame->Info->DeviceObject;
PFILE_OBJECT fileObject=Frame->Info->FileObject;
irp->Tail.Overlay.OriginalFileObject = fileObject;
irp->RequestorMode = KernelMode;
irp->PendingReturned = FALSE;
//
// Fill in the service independent parameters in the IRP.
//
irp->UserEvent = NULL;
irp->Overlay.AsynchronousParameters.UserApcRoutine = NULL;
irp->Overlay.AsynchronousParameters.UserApcContext = NULL;
//
// Now determine whether this device expects to have data buffered to it
// or whether it performs direct I/O. This is based on the DO_BUFFERED_IO
// flag in the device object. If the flag is set, then a system buffer is
// allocated and the caller's data is copied into it. Otherwise, a Memory
// Descriptor List (MDL) is allocated and the caller's buffer is locked
// down using it.
//
if (deviceObject->Flags & DO_BUFFERED_IO) {
//
// The device does not support direct I/O. Allocate a system buffer,
// and copy the caller's data into it. This is done using an
// exception handler that will perform cleanup if the operation
// fails. Note that this is only done if the operation has a non-zero
// length.
//
irp->AssociatedIrp.SystemBuffer = Frame->Frame;
//
// Set the IRP_BUFFERED_IO flag in the IRP so that I/O completion
// will know that this is not a direct I/O operation.
//
irp->Flags = IRP_BUFFERED_IO;
} else if (deviceObject->Flags & DO_DIRECT_IO) {
//
// This is a direct I/O operation. Allocate an MDL and invoke the
// memory management routine to lock the buffer into memory. This
// is done using an exception handler that will perform cleanup if
// the operation fails. Note that no MDL is allocated, nor is any
// memory probed or locked if the length of the request was zero.
//
#if DBG
DbgPrintf(("The DeviceObject is NOT BUFFERED_IO!! IRP FAILURE!!\n"));
DbgBreakPoint();
#endif
} else {
//
// Pass the address of the caller's buffer to the device driver. It
// is now up to the driver to do everything.
//
irp->UserBuffer = Frame->Frame;
}
// For now, if we get this far, it means success!
return(STATUS_SUCCESS);
}
PASYNC_IO_CTX
AsyncAllocateIoCtx(
BOOLEAN AllocateSync,
PVOID Context
)
{
PASYNC_IO_CTX AsyncIoCtx;
AsyncIoCtx = ExAllocateFromNPagedLookasideList(&AsyncIoCtxList);
if (AsyncIoCtx == NULL) {
return (NULL);
}
RtlZeroMemory(AsyncIoCtx, sizeof(ASYNC_IO_CTX));
AsyncIoCtx->Context = Context;
AsyncIoCtx->Sync = AllocateSync;
if (AllocateSync) {
ASSERT(KeGetCurrentIrql() < DISPATCH_LEVEL);
KeInitializeEvent(&AsyncIoCtx->Event,
SynchronizationEvent,
(BOOLEAN)FALSE);
}
return (AsyncIoCtx);
}
VOID
AsyncFreeIoCtx(
PASYNC_IO_CTX AsyncIoCtx
)
{
ExFreeToNPagedLookasideList(&AsyncIoCtxList,
AsyncIoCtx);
}