Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenreadwrite.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
1.7.6.1
|