00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00020 #include <wdm.h>
00021 #include "cbm_driver.h"
00022 #include "iec.h"
00023
00035 static NTSTATUS
00036 cbm_checkbuffer(IN PIO_STACK_LOCATION IrpSp)
00037 {
00038 NTSTATUS ntStatus;
00039
00040 FUNC_ENTER();
00041
00042
00043
00044
00045
00046 DBG_ASSERT(&IrpSp->Parameters.Read.ByteOffset == &IrpSp->Parameters.Write.ByteOffset);
00047
00048 if ((IrpSp->Parameters.Write.ByteOffset.HighPart != 0) ||
00049 (IrpSp->Parameters.Write.ByteOffset.LowPart != 0))
00050 {
00051 ntStatus = STATUS_INVALID_PARAMETER;
00052 }
00053 else
00054 {
00055 ntStatus = STATUS_SUCCESS;
00056 }
00057 FUNC_LEAVE_NTSTATUS(ntStatus);
00058 }
00059
00060
00084 NTSTATUS
00085 cbm_readwrite(IN PDEVICE_OBJECT Fdo, IN PIRP Irp)
00086 {
00087 PIO_STACK_LOCATION irpSp;
00088 PDEVICE_EXTENSION pdx;
00089 NTSTATUS ntStatus;
00090 ULONG readWriteBytesProcessed;
00091 ULONG readWriteLength;
00092 PUCHAR readWriteBuffer;
00093
00094 FUNC_ENTER();
00095
00096
00097
00098 pdx = Fdo->DeviceExtension;
00099
00100
00101
00102 irpSp = IoGetCurrentIrpStackLocation(Irp);
00103
00104
00105
00106 ntStatus = cbm_checkbuffer(irpSp);
00107
00108 DBG_IRPPATH_PROCESS("read/write");
00109
00110
00111
00112
00113 readWriteLength = 0;
00114
00115
00116 if (NT_SUCCESS(ntStatus))
00117 {
00118
00119
00120
00121
00122 DBG_ASSERT(&irpSp->Parameters.Read.Length == &irpSp->Parameters.Write.Length);
00123
00124
00125
00126 readWriteLength = irpSp->Parameters.Read.Length;
00127
00128
00129
00130 if (irpSp->MajorFunction == IRP_MJ_READ)
00131 {
00132 PERF_EVENT_READ_QUEUE(irpSp->Parameters.Read.Length);
00133 }
00134 else
00135 {
00136 PERF_EVENT_WRITE_QUEUE(irpSp->Parameters.Write.Length);
00137 }
00138
00139
00140
00141
00142 if (readWriteLength != 0)
00143 {
00144
00145
00146 ntStatus = QueueStartPacket(&pdx->IrpQueue, Irp, FALSE, Fdo);
00147 }
00148 }
00149
00150 if (!NT_SUCCESS(ntStatus) || readWriteLength == 0)
00151 {
00152
00153
00154
00155 QueueCompleteIrp(NULL, Irp, ntStatus, 0);
00156 }
00157
00158 FUNC_LEAVE_NTSTATUS(ntStatus);
00159 }
00160
00178 NTSTATUS
00179 cbm_execute_readwrite(IN PDEVICE_EXTENSION Pdx, IN PIRP Irp)
00180 {
00181 PIO_STACK_LOCATION irpSp;
00182 NTSTATUS ntStatus;
00183 ULONG readWriteBytesProcessed;
00184 ULONG readWriteLength;
00185 PUCHAR readWriteBuffer;
00186
00187 FUNC_ENTER();
00188
00189
00190
00191 irpSp = IoGetCurrentIrpStackLocation(Irp);
00192
00193
00194
00195
00196
00197 DBG_ASSERT(&irpSp->Parameters.Read.Length == &irpSp->Parameters.Write.Length);
00198
00199
00200
00201 readWriteLength = irpSp->Parameters.Read.Length;
00202
00203
00204
00205
00206 readWriteBuffer = Irp->AssociatedIrp.SystemBuffer;
00207
00208
00209
00210 if (irpSp->MajorFunction == IRP_MJ_READ)
00211 {
00212 PERF_EVENT_READ_EXECUTE(irpSp->Parameters.Read.Length);
00213 }
00214 else
00215 {
00216 PERF_EVENT_WRITE_EXECUTE(irpSp->Parameters.Write.Length);
00217 }
00218
00219 DBG_IRPPATH_EXECUTE("read/write");
00220
00221
00222
00223
00224
00225 DBG_ASSERT(readWriteLength != 0);
00226
00227 if (readWriteLength != 0)
00228 {
00229
00230
00231 switch (irpSp->MajorFunction)
00232 {
00233 case IRP_MJ_READ:
00234 ntStatus = cbmiec_raw_read(Pdx, readWriteBuffer, readWriteLength,
00235 &readWriteBytesProcessed);
00236 break;
00237
00238 case IRP_MJ_WRITE:
00239 ntStatus = cbmiec_raw_write(Pdx, readWriteBuffer, readWriteLength,
00240 &readWriteBytesProcessed);
00241 break;
00242
00243 default:
00244 DBG_ERROR((DBG_PREFIX "UNKNOWN IRP_MJ code in cbm_readwrite!"));
00245 ntStatus = STATUS_INTERNAL_ERROR;
00246 readWriteBytesProcessed = 0;
00247 break;
00248 }
00249 }
00250
00251
00252
00253
00254 DBG_ASSERT(ntStatus != STATUS_PENDING);
00255
00256
00257
00259
00260 if (ntStatus != STATUS_PENDING)
00261 {
00262 QueueCompleteIrp(&Pdx->IrpQueue, Irp, ntStatus, readWriteBytesProcessed);
00263 }
00264
00265 FUNC_LEAVE_NTSTATUS(ntStatus);
00266 }