Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

vdmprint.c File Reference

#include "vdmp.h"
#include "vdmprint.h"
#include <i386.h>
#include <v86emul.h>
#include "..\..\..\..\inc\ntddvdm.h"

Go to the source code of this file.

Functions

BOOLEAN VdmPrinterStatus (ULONG iPort, ULONG cbInstructionSize, PKTRAP_FRAME TrapFrame)
BOOLEAN VdmPrinterWriteData (ULONG iPort, ULONG cbInstructionSize, PKTRAP_FRAME TrapFrame)
NTSTATUS VdmFlushPrinterWriteData (USHORT adapter)
NTSTATUS VdmpPrinterInitialize (PVOID ServiceData)
NTSTATUS VdmpPrinterDirectIoOpen (PVOID ServiceData)
NTSTATUS VdmpPrinterDirectIoClose (PVOID ServiceData)


Function Documentation

NTSTATUS VdmFlushPrinterWriteData USHORT  adapter  ) 
 

Definition at line 236 of file vdmprint.c.

References DbgPrint, EXCEPTION_EXECUTE_HANDLER, FALSE, KeLowerIrql(), KeRaiseIrql(), NT_SUCCESS, NtDeviceIoControlFile(), NTSTATUS(), NULL, PAGED_CODE, PASSIVE_LEVEL, Status, VdmpGetVdmTib(), and VDMTIB_KMODE.

Referenced by VdmpPrinterDirectIoClose(), VdmPrinterStatus(), and VdmPrinterWriteData().

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, // notification event 00264 NULL, // APC routine 00265 NULL, // APC context 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 }

NTSTATUS VdmpPrinterDirectIoClose PVOID  ServiceData  ) 
 

Definition at line 388 of file vdmprint.c.

References EXCEPTION_EXECUTE_HANDLER, ExSystemExceptionFilter(), NT_SUCCESS, NTSTATUS(), NULL, PAGED_CODE, ProbeForRead, ProbeForWrite(), Status, USHORT, and VdmFlushPrinterWriteData().

Referenced by NtVdmControl().

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 // first we fetch vdm tib and do some damage control in case 00400 // this is bad user-mode memory 00401 // PrtInfo points to a stricture 00402 00403 try { 00404 VdmTib = NtCurrentTeb()->Vdm; 00405 ProbeForWrite(VdmTib, sizeof(VDM_TIB), sizeof(UCHAR)); 00406 00407 // now verify that servicedata ptr is valid 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 }

NTSTATUS VdmpPrinterDirectIoOpen PVOID  ServiceData  ) 
 

Definition at line 380 of file vdmprint.c.

References PAGED_CODE.

Referenced by NtVdmControl().

00381 { 00382 PAGED_CODE(); 00383 00384 return STATUS_SUCCESS; 00385 00386 }

NTSTATUS VdmpPrinterInitialize PVOID  ServiceData  ) 
 

Definition at line 295 of file vdmprint.c.

References EXCEPTION_EXECUTE_HANDLER, FALSE, NT_SUCCESS, NTSTATUS(), ProbeForWrite(), PsGetCurrentProcess, Status, VdmpGetVdmTib(), and VDMTIB_KMODE.

Referenced by NtVdmControl().

00300 : 00301 00302 This routine probes and caches the data associated with kernel 00303 mode printer emulation. 00304 00305 Arguments: 00306 00307 ServiceData - Not used. 00308 00309 Return Value: 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 // Note: We only support two printers in the kernel. 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 // Probe the locations for two printers 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 }

BOOLEAN VdmPrinterStatus ULONG  iPort,
ULONG  cbInstructionSize,
PKTRAP_FRAME  TrapFrame
 

Definition at line 42 of file vdmprint.c.

References ASSERT, DbgPrint, EXCEPTION_EXECUTE_HANDLER, FALSE, get_control, get_status, HOST_LPT_BUSY, host_lpt_status, IRQ, KeLowerIrql(), KeRaiseIrql(), NOTBUSY, NT_SUCCESS, NtDeviceIoControlFile(), NTSTATUS(), NULL, PAGED_CODE, PASSIVE_LEVEL, set_status, Status, STATUS_PORT_OFFSET, STATUS_REG_MASK, USHORT, VdmFlushPrinterWriteData(), VdmpGetVdmTib(), and VDMTIB_KMODE.

00050 : 00051 00052 This routine handles the read operation on the printer status port 00053 00054 Arguments: 00055 iPort - port on which the io was trapped 00056 cbInstructionSize - Instruction size to update TsEip 00057 TrapFrame - Trap Frame 00058 00059 Return Value: 00060 00061 True if successfull, False otherwise 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 // why we have printer stuff in TIB? It would be more appropriate 00077 // if we have them in the process object. The main reason(I think) 00078 // is that we can get rid of synchronization. 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 // first, figure out which PRT we are dealing with. The 00093 // port addresses in the PrinterInfo are base address of each 00094 // PRT sorted in the adapter order. 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 // something must be wrong in our code, better check it out 00104 ASSERT(FALSE); 00105 return FALSE; 00106 } 00107 PrtMode = PrtInfo->prt_Mode[adapter]; 00108 00109 00110 if(PRT_MODE_SIMULATE_STATUS_PORT == PrtMode) { 00111 // we are simulating printer status read. 00112 // get the current status from softpc. 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 // we have to read the i/o directly(of course, through file system 00123 // which in turn goes to the driver). 00124 // Before performing read, flush out all pending output data in our 00125 // buffer. This is done because the status we are about to read 00126 // may depend on those pending output data. 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 // lower irql to passive before doing any IO 00138 KeLowerIrql(PASSIVE_LEVEL); 00139 Status = NtDeviceIoControlFile(PrtInfo->prt_Handle[adapter], 00140 NULL, // notification event 00141 NULL, // APC routine 00142 NULL, // Apc Context 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 // fake a status to make it looks like the port is not connected 00153 // to a printer. 00154 *printer_status = 0x7F; 00155 #ifdef DBG 00156 DbgPrint("VdmPrinterStatus: failed to get status from printer, status = %lx\n", Status); 00157 #endif 00158 // always tell the caller that we have simulated the operation. 00159 Status = STATUS_SUCCESS; 00160 } 00161 KeRaiseIrql(OldIrql, &OldIrql); 00162 } 00163 else 00164 // we don't simulate it here 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 }

BOOLEAN VdmPrinterWriteData ULONG  iPort,
ULONG  cbInstructionSize,
PKTRAP_FRAME  TrapFrame
 

Definition at line 177 of file vdmprint.c.

References ASSERT, DATA_PORT_OFFSET, EXCEPTION_EXECUTE_HANDLER, FALSE, NT_SUCCESS, NTSTATUS(), PAGED_CODE, Status, USHORT, VdmFlushPrinterWriteData(), VdmpGetVdmTib(), and VDMTIB_KMODE.

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 // first, figure out which PRT we are dealing with. The 00201 // port addresses in the PrinterInfo are base address of each 00202 // PRT sorted in the adapter order 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 // something must be wrong in our code, better check it out 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 // buffer full, then flush it out 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 }


Generated on Sat May 15 19:46:07 2004 for test by doxygen 1.3.7