ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

readwrite.c
Go to the documentation of this file.
00001 /*
00002  * COPYRIGHT:   See COPYING in the top level directory
00003  * PROJECT:     ReactOS NDIS User I/O driver
00004  * FILE:        readwrite.c
00005  * PURPOSE:     Handles IRP_MJ_READ and IRP_MJ_WRITE
00006  * PROGRAMMERS: Cameron Gutman (cameron.gutman@reactos.org)
00007  */
00008 
00009 #include "ndisuio.h"
00010 
00011 #define NDEBUG
00012 #include <debug.h>
00013 
00014 static
00015 VOID
00016 NTAPI
00017 ReadIrpCancel(PDEVICE_OBJECT DeviceObject, PIRP Irp)
00018 {
00019     PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
00020     PNDISUIO_ADAPTER_CONTEXT AdapterContext = IrpSp->FileObject->FsContext;
00021     PNDISUIO_PACKET_ENTRY PacketEntry;
00022     
00023     /* Release the cancel spin lock */
00024     IoReleaseCancelSpinLock(Irp->CancelIrql);
00025 
00026     /* Indicate a 0-byte packet on the queue to cancel the read */
00027     PacketEntry = ExAllocatePool(NonPagedPool, sizeof(NDISUIO_PACKET_ENTRY));
00028     if (PacketEntry)
00029     {
00030         PacketEntry->PacketLength = 0;
00031         
00032         ExInterlockedInsertHeadList(&AdapterContext->PacketList,
00033                                     &PacketEntry->ListEntry,
00034                                     &AdapterContext->Spinlock);
00035         
00036         KeSetEvent(&AdapterContext->PacketReadEvent, IO_NO_INCREMENT, FALSE);
00037     }
00038 }
00039 
00040 NTSTATUS
00041 NTAPI
00042 NduDispatchRead(PDEVICE_OBJECT DeviceObject,
00043                 PIRP Irp)
00044 {
00045     PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
00046     PNDISUIO_ADAPTER_CONTEXT AdapterContext = IrpSp->FileObject->FsContext;
00047     PNDISUIO_OPEN_ENTRY OpenEntry = IrpSp->FileObject->FsContext2;
00048     KIRQL OldIrql, OldCancelIrql;
00049     NTSTATUS Status;
00050     PLIST_ENTRY ListEntry;
00051     PNDISUIO_PACKET_ENTRY PacketEntry = NULL;
00052     ULONG BytesCopied = 0;
00053 
00054     ASSERT(DeviceObject == GlobalDeviceObject);
00055 
00056     if (OpenEntry->WriteOnly)
00057     {
00058         Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
00059         Irp->IoStatus.Information = 0;
00060         IoCompleteRequest(Irp, IO_NO_INCREMENT);
00061         
00062         return STATUS_INVALID_PARAMETER;
00063     }
00064 
00065     /* Make the read cancellable */
00066     IoAcquireCancelSpinLock(&OldCancelIrql);
00067     IoSetCancelRoutine(Irp, ReadIrpCancel);
00068     if (Irp->Cancel)
00069     {
00070         IoReleaseCancelSpinLock(OldCancelIrql);
00071 
00072         /* Indicate a 0 byte read */
00073         Irp->IoStatus.Status = STATUS_SUCCESS;
00074         Irp->IoStatus.Information = 0;
00075         IoCompleteRequest(Irp, IO_NO_INCREMENT);
00076         
00077         return STATUS_SUCCESS;
00078     }
00079     IoReleaseCancelSpinLock(OldCancelIrql);
00080 
00081     while (TRUE)
00082     {
00083         KeAcquireSpinLock(&AdapterContext->Spinlock, &OldIrql);
00084 
00085         /* Check if we have a packet */
00086         if (IsListEmpty(&AdapterContext->PacketList))
00087         {
00088             KeReleaseSpinLock(&AdapterContext->Spinlock, OldIrql);
00089 
00090             /* Wait for a packet (in the context of the calling user thread) */
00091             Status = KeWaitForSingleObject(&AdapterContext->PacketReadEvent,
00092                                            UserRequest,
00093                                            UserMode,
00094                                            TRUE,
00095                                            NULL);
00096             if (Status != STATUS_SUCCESS)
00097             {
00098                 /* Remove the cancel routine */
00099                 IoAcquireCancelSpinLock(&OldCancelIrql);
00100                 IoSetCancelRoutine(Irp, NULL);
00101                 IoReleaseCancelSpinLock(OldCancelIrql);
00102 
00103                 break;
00104             }
00105         }
00106         else
00107         {
00108             /* Remove the cancel routine */
00109             IoAcquireCancelSpinLock(&OldCancelIrql);
00110             IoSetCancelRoutine(Irp, NULL);
00111             IoReleaseCancelSpinLock(OldCancelIrql);
00112             
00113             /* Remove the first packet in the list */
00114             ListEntry = RemoveHeadList(&AdapterContext->PacketList);
00115             PacketEntry = CONTAINING_RECORD(ListEntry, NDISUIO_PACKET_ENTRY, ListEntry);
00116 
00117             /* Release the adapter lock */
00118             KeReleaseSpinLock(&AdapterContext->Spinlock, OldIrql);
00119             
00120             /* And we're done with this loop */
00121             Status = STATUS_SUCCESS;
00122             break;
00123         }
00124     }
00125     
00126     /* Check if we got a packet */
00127     if (PacketEntry != NULL)
00128     {
00129         /* Find the right amount of bytes to copy */
00130         BytesCopied = PacketEntry->PacketLength;
00131         if (BytesCopied > IrpSp->Parameters.Read.Length)
00132             BytesCopied = IrpSp->Parameters.Read.Length;
00133 
00134         /* Copy the packet */
00135         RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer,
00136                       &PacketEntry->PacketData[0],
00137                       BytesCopied);
00138         
00139         /* Free the packet entry */
00140         ExFreePool(PacketEntry);
00141     }
00142     else
00143     {
00144         /* Something failed */
00145         BytesCopied = 0;
00146     }
00147 
00148     /* Complete the IRP */
00149     Irp->IoStatus.Status = Status;
00150     Irp->IoStatus.Information = BytesCopied;
00151     IoCompleteRequest(Irp, IO_NETWORK_INCREMENT);
00152     
00153     return Status;
00154 }
00155 
00156 NTSTATUS
00157 NTAPI
00158 NduDispatchWrite(PDEVICE_OBJECT DeviceObject,
00159                  PIRP Irp)
00160 {
00161     PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
00162     PNDISUIO_ADAPTER_CONTEXT AdapterContext = IrpSp->FileObject->FsContext;
00163     PNDIS_PACKET Packet;
00164     NDIS_STATUS Status;
00165     ULONG BytesCopied = 0;
00166 
00167     ASSERT(DeviceObject == GlobalDeviceObject);
00168     
00169     /* Create a packet and buffer descriptor for this user buffer */
00170     Packet = CreatePacketFromPoolBuffer(AdapterContext,
00171                                         Irp->AssociatedIrp.SystemBuffer,
00172                                         IrpSp->Parameters.Write.Length);
00173     if (Packet)
00174     {
00175         /* Send it via NDIS */
00176         NdisSend(&Status,
00177                  AdapterContext->BindingHandle,
00178                  Packet);
00179 
00180         /* Wait for the send */
00181         if (Status == NDIS_STATUS_PENDING)
00182         {
00183             KeWaitForSingleObject(&AdapterContext->AsyncEvent,
00184                                   Executive,
00185                                   KernelMode,
00186                                   FALSE,
00187                                   NULL);
00188             Status = AdapterContext->AsyncStatus;
00189         }
00190 
00191         /* Check if it succeeded */
00192         if (Status == NDIS_STATUS_SUCCESS)
00193             BytesCopied = IrpSp->Parameters.Write.Length;
00194 
00195         CleanupAndFreePacket(Packet, FALSE);
00196     }
00197     else
00198     {
00199         /* No memory */
00200         Status = STATUS_NO_MEMORY;
00201     }
00202 
00203     /* Complete the IRP */
00204     Irp->IoStatus.Status = Status;
00205     Irp->IoStatus.Information = BytesCopied;
00206     IoCompleteRequest(Irp, IO_NETWORK_INCREMENT);
00207 
00208     return Status;
00209 }

Generated on Fri May 25 2012 04:26:02 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.