00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
#include "vdmp.h"
00026
#include "vdmprint.h"
00027
#include <i386.h>
00028
#include <v86emul.h>
00029
#include "..\..\..\..\inc\ntddvdm.h"
00030
00031
#ifdef ALLOC_PRAGMA
00032
#pragma alloc_text(PAGE, VdmPrinterStatus)
00033
#pragma alloc_text(PAGE, VdmPrinterWriteData)
00034
#pragma alloc_text(PAGE, VdmFlushPrinterWriteData)
00035
#pragma alloc_text(PAGE, VdmpPrinterDirectIoOpen)
00036
#pragma alloc_text(PAGE, VdmpPrinterDirectIoClose)
00037
#endif
00038
00039
00040
00041 BOOLEAN
00042 VdmPrinterStatus(
00043 ULONG iPort,
00044 ULONG cbInstructionSize,
00045 PKTRAP_FRAME TrapFrame
00046 )
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064 {
00065 UCHAR PrtMode;
00066
USHORT adapter;
00067 ULONG * printer_status;
00068 KIRQL OldIrql;
00069 PIO_STATUS_BLOCK IoStatusBlock;
00070 PVDM_PRINTER_INFO PrtInfo;
00071
PVDM_TIB VdmTib;
00072
NTSTATUS Status = STATUS_SUCCESS;
00073
00074
PAGED_CODE();
00075
00076
00077
00078
00079
00080
00081
Status =
VdmpGetVdmTib(&VdmTib,
VDMTIB_KMODE);
00082
if (!
NT_SUCCESS(
Status)) {
00083
return(
FALSE);
00084 }
00085
00086 PrtInfo = &VdmTib->PrinterInfo;
00087 IoStatusBlock = (PIO_STATUS_BLOCK) &VdmTib->TempArea1;
00088 printer_status = &VdmTib->PrinterInfo.prt_Scratch;
00089
00090 *pNtVDMState |= VDM_IDLEACTIVITY;
00091
try {
00092
00093
00094
00095
00096
if ((
USHORT)iPort == PrtInfo->prt_PortAddr[0] +
STATUS_PORT_OFFSET)
00097 adapter = 0;
00098
else if ((
USHORT)iPort == PrtInfo->prt_PortAddr[1] +
STATUS_PORT_OFFSET)
00099 adapter = 1;
00100
else if ((
USHORT)iPort == PrtInfo->prt_PortAddr[2] +
STATUS_PORT_OFFSET)
00101 adapter = 2;
00102
else {
00103
00104
ASSERT(
FALSE);
00105
return FALSE;
00106 }
00107 PrtMode = PrtInfo->prt_Mode[adapter];
00108
00109
00110
if(PRT_MODE_SIMULATE_STATUS_PORT == PrtMode) {
00111
00112
00113
if (!(
get_status(adapter) &
NOTBUSY) &&
00114 !(
host_lpt_status(adapter) &
HOST_LPT_BUSY)) {
00115
if (
get_control(adapter) &
IRQ)
00116
return FALSE;
00117
set_status(adapter,
get_status(adapter) |
NOTBUSY);
00118 }
00119 *printer_status = (ULONG)(
get_status(adapter) |
STATUS_REG_MASK);
00120 }
00121
else if (PRT_MODE_DIRECT_IO == PrtMode) {
00122
00123
00124
00125
00126
00127
00128
if (PrtInfo->prt_BytesInBuffer[adapter]) {
00129
Status =
VdmFlushPrinterWriteData(adapter);
00130
#ifdef DBG
00131
if (!
NT_SUCCESS(
Status)) {
00132
DbgPrint(
"VdmPrintStatus: failed to flush buffered data, status = %ls\n",
Status);
00133 }
00134
#endif
00135
}
00136 OldIrql = KeGetCurrentIrql();
00137
00138
KeLowerIrql(
PASSIVE_LEVEL);
00139
Status =
NtDeviceIoControlFile(PrtInfo->prt_Handle[adapter],
00140
NULL,
00141
NULL,
00142
NULL,
00143 IoStatusBlock,
00144 IOCTL_VDM_PAR_READ_STATUS_PORT,
00145
NULL,
00146 0,
00147 printer_status,
00148
sizeof(ULONG)
00149 );
00150
00151
if (!
NT_SUCCESS(
Status) || !
NT_SUCCESS(IoStatusBlock->Status)) {
00152
00153
00154 *printer_status = 0x7F;
00155
#ifdef DBG
00156
DbgPrint(
"VdmPrinterStatus: failed to get status from printer, status = %lx\n",
Status);
00157
#endif
00158
00159
Status = STATUS_SUCCESS;
00160 }
00161
KeRaiseIrql(OldIrql, &OldIrql);
00162 }
00163
else
00164
00165
return FALSE;
00166
00167 TrapFrame->Eax &= 0xffffff00;
00168 TrapFrame->Eax |= (UCHAR)*printer_status;
00169 TrapFrame->Eip += cbInstructionSize;
00170
00171 } except(
EXCEPTION_EXECUTE_HANDLER) {
00172
Status = GetExceptionCode();
00173 }
00174
return (
NT_SUCCESS(
Status));
00175 }
00176
00177 BOOLEAN
VdmPrinterWriteData(
00178 ULONG iPort,
00179 ULONG cbInstructionSize,
00180 PKTRAP_FRAME TrapFrame
00181 )
00182 {
00183 UCHAR PrtMode;
00184 PVDM_PRINTER_INFO PrtInfo;
00185
USHORT adapter;
00186
PVDM_TIB VdmTib;
00187
NTSTATUS Status = STATUS_SUCCESS;
00188
00189
PAGED_CODE();
00190
00191
Status =
VdmpGetVdmTib(&VdmTib,
VDMTIB_KMODE);
00192
if (!
NT_SUCCESS(
Status)) {
00193
return(
FALSE);
00194 }
00195
00196 PrtInfo = &VdmTib->PrinterInfo;
00197 *pNtVDMState |= VDM_IDLEACTIVITY;
00198
00199
try {
00200
00201
00202
00203
if ((
USHORT)iPort == PrtInfo->prt_PortAddr[0] +
DATA_PORT_OFFSET)
00204 adapter = 0;
00205
else if ((
USHORT)iPort == PrtInfo->prt_PortAddr[1] +
DATA_PORT_OFFSET)
00206 adapter = 1;
00207
else if ((
USHORT)iPort == PrtInfo->prt_PortAddr[2] +
DATA_PORT_OFFSET)
00208 adapter = 2;
00209
else {
00210
00211
ASSERT(
FALSE);
00212
return FALSE;
00213 }
00214
if (PRT_MODE_DIRECT_IO == PrtInfo->prt_Mode[adapter]){
00215 PrtInfo->prt_Buffer[adapter][PrtInfo->prt_BytesInBuffer[adapter]] = (UCHAR)TrapFrame->Eax;
00216
00217
if (++PrtInfo->prt_BytesInBuffer[adapter] >= PRT_DATA_BUFFER_SIZE){
00218
00219
VdmFlushPrinterWriteData(adapter);
00220 }
00221
00222 TrapFrame->Eip += cbInstructionSize;
00223
00224 }
00225
else
00226
Status = STATUS_ILLEGAL_INSTRUCTION;
00227 } except(
EXCEPTION_EXECUTE_HANDLER) {
00228
Status = GetExceptionCode();
00229 }
00230
return(
NT_SUCCESS(
Status));
00231
00232 }
00233
00234
00235
NTSTATUS
00236 VdmFlushPrinterWriteData(USHORT adapter)
00237 {
00238 KIRQL OldIrql;
00239
PVDM_TIB VdmTib;
00240 PVDM_PRINTER_INFO PrtInfo;
00241 PIO_STATUS_BLOCK IoStatusBlock;
00242
NTSTATUS Status;
00243
00244
00245
PAGED_CODE();
00246
00247
00248
Status =
VdmpGetVdmTib(&VdmTib,
VDMTIB_KMODE);
00249
if (!
NT_SUCCESS(
Status)) {
00250
return(
FALSE);
00251 }
00252
00253 PrtInfo = &VdmTib->PrinterInfo;
00254 IoStatusBlock = (PIO_STATUS_BLOCK)&VdmTib->TempArea1;
00255
try {
00256
if (PrtInfo->prt_Handle[adapter] &&
00257 PrtInfo->prt_BytesInBuffer[adapter] &&
00258 PRT_MODE_DIRECT_IO == PrtInfo->prt_Mode[adapter]) {
00259
00260 OldIrql = KeGetCurrentIrql();
00261
KeLowerIrql(
PASSIVE_LEVEL);
00262
Status =
NtDeviceIoControlFile(PrtInfo->prt_Handle[adapter],
00263
NULL,
00264
NULL,
00265
NULL,
00266 IoStatusBlock,
00267 IOCTL_VDM_PAR_WRITE_DATA_PORT,
00268 &PrtInfo->prt_Buffer[adapter][0],
00269 PrtInfo->prt_BytesInBuffer[adapter],
00270
NULL,
00271 0
00272 );
00273 PrtInfo->prt_BytesInBuffer[adapter] = 0;
00274
KeRaiseIrql(OldIrql, &OldIrql);
00275
if (!
NT_SUCCESS(
Status)) {
00276
#ifdef DBG
00277
DbgPrint(
"IOCTL_VDM_PAR_WRITE_DATA_PORT failed %lx %x\n",
00278
Status, IoStatusBlock->Status);
00279
#endif
00280
Status = IoStatusBlock->Status;
00281
00282 }
00283 }
00284
else
00285
Status = STATUS_INVALID_PARAMETER;
00286 } except (
EXCEPTION_EXECUTE_HANDLER) {
00287
Status = GetExceptionCode();
00288 }
00289
return Status;
00290
00291 }
00292
00293
00294
NTSTATUS
00295 VdmpPrinterInitialize(
00296 PVOID ServiceData
00297 )
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313 {
00314 PUCHAR State, PrtStatus, Control, HostState;
00315
PVDM_TIB VdmTib;
00316 PVDM_PROCESS_OBJECTS VdmObjects;
00317
NTSTATUS Status;
00318
00319
Status = STATUS_SUCCESS;
00320
00321
00322
00323
00324
00325
Status =
VdmpGetVdmTib(&VdmTib,
VDMTIB_KMODE);
00326
if (!
NT_SUCCESS(
Status)) {
00327
return(
FALSE);
00328 }
00329
00330
00331
try {
00332 State = VdmTib->PrinterInfo.prt_State;
00333 PrtStatus = VdmTib->PrinterInfo.prt_Status;
00334 Control = VdmTib->PrinterInfo.prt_Control;
00335 HostState = VdmTib->PrinterInfo.prt_HostState;
00336
00337
00338
00339
00340
ProbeForWrite(
00341 State,
00342 2 *
sizeof(UCHAR),
00343
sizeof(UCHAR)
00344 );
00345
00346
ProbeForWrite(
00347 PrtStatus,
00348 2 *
sizeof(UCHAR),
00349
sizeof(UCHAR)
00350 );
00351
00352
ProbeForWrite(
00353 Control,
00354 2 *
sizeof(UCHAR),
00355
sizeof(UCHAR)
00356 );
00357
00358
ProbeForWrite(
00359 HostState,
00360 2 *
sizeof(UCHAR),
00361
sizeof(UCHAR)
00362 );
00363
00364 } except (
EXCEPTION_EXECUTE_HANDLER) {
00365
Status = GetExceptionCode();
00366 }
00367
00368
if (
NT_SUCCESS(
Status)) {
00369 VdmObjects =
PsGetCurrentProcess()->VdmObjects;
00370 VdmObjects->PrinterState = State;
00371 VdmObjects->PrinterStatus = PrtStatus;
00372 VdmObjects->PrinterControl = Control;
00373 VdmObjects->PrinterHostState = HostState;
00374 }
00375
00376
return Status;
00377 }
00378
00379
NTSTATUS
00380 VdmpPrinterDirectIoOpen(PVOID ServiceData)
00381 {
00382
PAGED_CODE();
00383
00384
return STATUS_SUCCESS;
00385
00386 }
00387
NTSTATUS
00388 VdmpPrinterDirectIoClose(PVOID ServiceData)
00389 {
00390
NTSTATUS Status;
00391 PVDM_PRINTER_INFO PrtInfo;
00392
USHORT Adapter;
00393
PVDM_TIB VdmTib;
00394
00395
PAGED_CODE();
00396
00397
Status = STATUS_SUCCESS;
00398
00399
00400
00401
00402
00403
try {
00404 VdmTib = NtCurrentTeb()->Vdm;
00405
ProbeForWrite(VdmTib,
sizeof(
VDM_TIB),
sizeof(UCHAR));
00406
00407
00408
ProbeForRead(ServiceData,
sizeof(
USHORT),
sizeof(UCHAR));
00409 Adapter = *(
USHORT *)ServiceData;
00410
00411 } except (
ExSystemExceptionFilter()) {
00412
Status = GetExceptionCode();
00413 }
00414
00415
if (
NULL == VdmTib ||
NULL == ServiceData) {
00416
Status = STATUS_ACCESS_VIOLATION;
00417 }
00418
00419
if (!
NT_SUCCESS(
Status)) {
00420
return(
Status);
00421 }
00422
00423 PrtInfo =&VdmTib->PrinterInfo;
00424
00425
try {
00426
if (Adapter < VDM_NUMBER_OF_LPT) {
00427
if (PRT_MODE_DIRECT_IO == PrtInfo->prt_Mode[Adapter] &&
00428 PrtInfo->prt_BytesInBuffer[Adapter]) {
00429
Status =
VdmFlushPrinterWriteData(Adapter);
00430 }
00431 }
00432
else {
00433
Status = STATUS_INVALID_PARAMETER;
00434 }
00435 } except (
EXCEPTION_EXECUTE_HANDLER) {
00436
Status = GetExceptionCode();
00437 }
00438
return Status;
00439 }