1735 lines
48 KiB
C
1735 lines
48 KiB
C
/*++
|
||
|
||
Copyright (C) Microsoft Corporation, 1993 - 1999
|
||
|
||
Module Name :
|
||
|
||
parclass.h
|
||
|
||
Abstract:
|
||
|
||
Type definitions and data for the ParClass (parallel.sys) driver.
|
||
|
||
Author:
|
||
|
||
|
||
Revision History:
|
||
|
||
--*/
|
||
|
||
|
||
#include "ntddk.h" // Windows NT DDK header
|
||
#include "parallel.h" // Public (driver) interface to ParPort
|
||
#include "queue.h" // dvrh's Queue
|
||
#include "test.h"
|
||
// #include "log.h" - structure moved to ntddpar.h
|
||
#include <wmilib.h>
|
||
|
||
#define ASSERT_EVENT(E) { \
|
||
ASSERT((E)->Header.Type == NotificationEvent || \
|
||
(E)->Header.Type == SynchronizationEvent); \
|
||
}
|
||
|
||
#define REQUEST_DEVICE_ID TRUE
|
||
#define HAVE_PORT_KEEP_PORT TRUE
|
||
|
||
// enable scans for Legacy Zip?
|
||
extern ULONG ParEnableLegacyZip;
|
||
|
||
#define PAR_LGZIP_PSEUDO_1284_ID_STRING "MFG:IMG;CMD:;MDL:VP0;CLS:SCSIADAPTER;DES:IOMEGA PARALLEL PORT"
|
||
extern PCHAR ParLegacyZipPseudoId;
|
||
|
||
#define USE_PAR3QUERYDEVICEID 1
|
||
|
||
// Disable IRQL Raising in Parclass
|
||
// 0 - Run at passive
|
||
// 1 - Run everything at dispatch
|
||
// NOTE: SPP.c will still raise IRQL to dispatch regardless of this setting.
|
||
// This has not changed since NT 3.51. Any takers?
|
||
#define DVRH_RAISE_IRQL 0
|
||
|
||
extern LARGE_INTEGER AcquirePortTimeout; // timeout for IOCTL_INTERNAL_PARALLEL_PORT_ALLOCATE
|
||
extern ULONG g_NumPorts; // used to generate N in \Device\ParallelN ClassName
|
||
extern UNICODE_STRING RegistryPath; // copy of the registry path passed to DriverEntry()
|
||
|
||
extern ULONG DumpDevExtTable;
|
||
|
||
// Driver Globals
|
||
extern ULONG SppNoRaiseIrql; // 0 == original raise IRQL behavior in SPP
|
||
// !0 == new behavior - disable raise IRQL
|
||
// and insert some KeDelayExecutionThread
|
||
// calls while waiting for peripheral response
|
||
|
||
extern ULONG DefaultModes; // Upper USHORT is Reverse Default Mode, Lower is Forward Default Mode
|
||
// if == 0, or invalid, then use default of Nibble/Centronics
|
||
|
||
// used to slow down Spp writes to reduce CPU util caused by printing
|
||
extern ULONG gSppLoopDelay; // how long to sleep each time we decide to do so (100ns units)
|
||
extern ULONG gSppLoopBytesPerDelay; // how many bytes to write between sleeps
|
||
|
||
//
|
||
// Temporary Development Globals - used as switches in debug code
|
||
//
|
||
extern ULONG tdev1;
|
||
extern ULONG tdev2;
|
||
|
||
//
|
||
// remove this after PnP stops calling us back multiple
|
||
// times for the same interface arrival
|
||
//
|
||
#define USE_TEMP_FIX_FOR_MULTIPLE_INTERFACE_ARRIVAL 1
|
||
|
||
#define PAR_USE_BUFFER_READ_WRITE 1 // Used to select between WRITE_PORT_BUFFER_UCHAR/READ_PORT_BUFFER_UCHAR vs WRITE_PORT_UCHAR/READ_PORT_UCHAR in hwecp.c
|
||
#define DVRH_USE_CORRECT_PTRS 1
|
||
|
||
#define PAR_NO_FAST_CALLS 1
|
||
#if PAR_NO_FAST_CALLS
|
||
VOID
|
||
ParCompleteRequest(
|
||
IN PIRP Irp,
|
||
IN CCHAR PriorityBoost
|
||
);
|
||
|
||
NTSTATUS
|
||
ParCallDriver(
|
||
IN PDEVICE_OBJECT DeviceObject,
|
||
IN OUT PIRP Irp
|
||
);
|
||
#else
|
||
#define ParCompleteRequest(a,b) IoCompleteRequest(a,b)
|
||
#define ParCallDriver(a,b) IoCallDriver(a,b)
|
||
#endif
|
||
|
||
#ifdef POOL_TAGGING
|
||
#ifdef ExAllocatePool
|
||
#undef ExAllocatePool
|
||
#endif
|
||
#define ExAllocatePool(a,b) ExAllocatePoolWithTag(a,b,'CraP')
|
||
#endif
|
||
|
||
#define PARCLASS_POOL_TAG (ULONG) 'CraP'
|
||
|
||
// used as a check that this is a ParClass Device Extension
|
||
// - used for debugging and by a ParClass debugger extension
|
||
// - the value is arbitrary but must be consistent between the driver and the debugger extension
|
||
#define PARCLASS_EXTENSION_SIGNATURE 0xA55AC33C
|
||
|
||
// the following two variables are not currently used
|
||
extern ULONG OpenCloseReferenceCount;// Keep track of Creates vs Closes
|
||
extern PFAST_MUTEX OpenCloseMutex; // protect access to OpenCloseReferenceCount
|
||
#if 0
|
||
#define ParClaimDriver() \
|
||
ExAcquireFastMutex(OpenCloseMutex); \
|
||
if(++OpenCloseReferenceCount == 1) { \
|
||
MmResetDriverPaging(DriverEntry); \
|
||
} \
|
||
ExReleaseFastMutex(OpenCloseMutex);
|
||
#define ParReleaseDriver() \
|
||
ExAcquireFastMutex(OpenCloseMutex); \
|
||
if(--OpenCloseReferenceCount == 0) { \
|
||
MmPageEntireDriver(DriverEntry); \
|
||
} \
|
||
ExReleaseFastMutex(OpenCloseMutex);
|
||
#else
|
||
#define ParClaimDriver()
|
||
#define ParReleaseDriver()
|
||
#endif
|
||
|
||
extern const PHYSICAL_ADDRESS PhysicalZero;
|
||
|
||
//
|
||
// For the above directory, the serial port will
|
||
// use the following name as the suffix of the serial
|
||
// ports for that directory. It will also append
|
||
// a number onto the end of the name. That number
|
||
// will start at 1.
|
||
//
|
||
#define DEFAULT_PARALLEL_NAME L"LPT"
|
||
|
||
//
|
||
// This is the parallel class name.
|
||
//
|
||
#define DEFAULT_NT_SUFFIX L"Parallel"
|
||
|
||
|
||
#define PARALLEL_DATA_OFFSET 0
|
||
#define PARALLEL_STATUS_OFFSET 1
|
||
#define PARALLEL_CONTROL_OFFSET 2
|
||
#define PARALLEL_REGISTER_SPAN 3
|
||
|
||
//
|
||
// Ieee 1284 constants (Protocol Families)
|
||
//
|
||
#define FAMILY_NONE 0x0
|
||
#define FAMILY_REVERSE_NIBBLE 0x1
|
||
#define FAMILY_REVERSE_BYTE 0x2
|
||
#define FAMILY_ECP 0x3
|
||
#define FAMILY_EPP 0x4
|
||
#define FAMILY_BECP 0x5
|
||
#define FAMILY_MAX FAMILY_BECP
|
||
|
||
//
|
||
// For pnp id strings
|
||
//
|
||
#define MAX_ID_SIZE 256
|
||
|
||
// used to construct IEEE 1284.3 "Dot" name suffixes
|
||
// table lookup for integer to WCHAR conversion
|
||
#define PAR_UNICODE_PERIOD L'.'
|
||
#define PAR_UNICODE_COLON L':'
|
||
|
||
|
||
//
|
||
// DeviceStateFlags
|
||
//
|
||
#define PAR_DEVICE_STARTED ((ULONG)0x00000001)
|
||
#define PAR_DEVICE_DELETED ((ULONG)0x00000002) // IoDeleteDevice has been called
|
||
#define PAR_DEVICE_REMOVE_PENDING ((ULONG)0x00000004) // received QUERY_REMOVE, waiting for REMOVE or CANCEL
|
||
#define PAR_DEVICE_REMOVED ((ULONG)0x00000008) // received REMOVE
|
||
#define PAR_DEVICE_PAUSED ((ULONG)0x00000010) // stop-pending, stopped, or remove-pending states
|
||
#define PAR_DEVICE_STOP_PENDING ((ULONG)0x00000020) // received QUERY_STOP
|
||
#define PAR_DEVICE_DELETE_PENDING ((ULONG)0x00000040) // we have started the process of deleting device object
|
||
#define PAR_DEVICE_HARDWARE_GONE ((ULONG)0x00000080) // our hardware is gone
|
||
#define PAR_DEVICE_SURPRISE_REMOVAL ((ULONG)0x00000100) // we received a SURPRISE_REMOVAL
|
||
#define PAR_DEVICE_PORT_REMOVE_PENDING ((ULONG)0x00000200) // our ParPort is in a Remove Pending State
|
||
|
||
//#define PAR_REV_MODE_SKIP_MASK (CHANNEL_NIBBLE | BYTE_BIDIR | EPP_ANY)
|
||
#define PAR_REV_MODE_SKIP_MASK (CHANNEL_NIBBLE | BYTE_BIDIR | EPP_ANY | ECP_ANY)
|
||
#define PAR_FWD_MODE_SKIP_MASK (EPP_ANY | BOUNDED_ECP | ECP_HW_NOIRQ | ECP_HW_IRQ)
|
||
//#define PAR_FWD_MODE_SKIP_MASK (EPP_ANY)
|
||
#define PAR_MAX_CHANNEL 127
|
||
#define PAR_COMPATIBILITY_RESET 300
|
||
|
||
typedef struct _DOT3DL_PCTL {
|
||
PVOID fnRead;
|
||
PVOID fnWrite;
|
||
PVOID fnReset;
|
||
P12843_DL_MODES DataLinkMode;
|
||
USHORT CurrentPID;
|
||
USHORT FwdSkipMask;
|
||
USHORT RevSkipMask;
|
||
UCHAR DataChannel;
|
||
UCHAR ResetChannel;
|
||
UCHAR ResetByteCount;
|
||
UCHAR ResetByte;
|
||
PKEVENT Event;
|
||
BOOLEAN bEventActive;
|
||
} DOT3DL_PCTL, *PDOT3DL_PCTL;
|
||
|
||
#if PAR_TEST_HARNESS
|
||
typedef struct _PAR_HARNS_PCTL {
|
||
PVOID fnRead;
|
||
PVOID fnRevSetInterfaceAddress;
|
||
PVOID fnEnterReverse;
|
||
PVOID fnExitReverse;
|
||
PVOID fnReadShadow;
|
||
PVOID fnHaveReadData;
|
||
|
||
PVOID fnWrite;
|
||
PVOID fnFwdSetInterfaceAddress;
|
||
PVOID fnEnterForward;
|
||
PVOID fnExitForward;
|
||
|
||
UNICODE_STRING deviceName;
|
||
PDEVICE_OBJECT device;
|
||
PFILE_OBJECT file;
|
||
|
||
} PAR_HARNS_PCTL, *PPAR_HARNS_PCTL;
|
||
#endif
|
||
|
||
|
||
//
|
||
// ParClass DeviceObject structure
|
||
//
|
||
// - Lists the ParClass created PODO and all PDOs associated with a specific ParPort device
|
||
//
|
||
typedef struct _PAR_DEVOBJ_STRUCT {
|
||
PUCHAR Controller; // host controller address for devices in this structure
|
||
PDEVICE_OBJECT LegacyPodo; // legacy or "raw" port device
|
||
PDEVICE_OBJECT EndOfChainPdo; // End-Of-Chain PnP device
|
||
PDEVICE_OBJECT Dot3Id0Pdo; // 1284.3 daisy chain device, 1284.3 deviceID == 0
|
||
PDEVICE_OBJECT Dot3Id1Pdo;
|
||
PDEVICE_OBJECT Dot3Id2Pdo;
|
||
PDEVICE_OBJECT Dot3Id3Pdo; // 1284.3 daisy chain device, 1284.3 deviceID == 3
|
||
PDEVICE_OBJECT LegacyZipPdo; // Legacy Zip Drive
|
||
PFILE_OBJECT pFileObject; // Need an open handle to ParPort device to prevent it
|
||
// from being removed out from under us
|
||
struct _PAR_DEVOBJ_STRUCT *Next;
|
||
} PAR_DEVOBJ_STRUCT, *PPAR_DEVOBJ_STRUCT;
|
||
|
||
//
|
||
// Used in device extension for DeviceType field
|
||
//
|
||
#define PAR_DEVTYPE_FDO 0x00000001
|
||
#define PAR_DEVTYPE_PODO 0x00000002
|
||
#define PAR_DEVTYPE_PDO 0x00000004
|
||
|
||
|
||
//
|
||
// ParClass Device Extension:
|
||
// - This is a common structure for ParClass (parallel.sys) FDO, PDOs, and PODOs.
|
||
// - Fields that are not used by a particular type of device object are 0, NULL, or FALSE.
|
||
// - FDO == field used by Function Device Object
|
||
// - PDO == field used by Physical Device Objects
|
||
// - PODO == field used by Plain Old Device Objects - similar to a PDOs but no
|
||
// device ID and is not reported to or known by PnP
|
||
// - P[O]DO == field used by PDOs and PODOs
|
||
// - no mark == field used by all three types of ParClass device objects
|
||
//
|
||
typedef struct _DEVICE_EXTENSION {
|
||
|
||
ULONG ExtensionSignature; // Used to increase our confidence that this is a ParClass extension
|
||
|
||
ULONG DeviceType; // PAR_DEVTYPE_FDO=0x1, PODO=0x2, or PDO=0x4
|
||
|
||
ULONG DeviceStateFlags; // Device State - See Device State Flags above
|
||
|
||
UCHAR Ieee1284_3DeviceId; // PDO - 0..3 is 1284.3 Daisy Chain device, 4 is End-Of-Chain Device, 5 is Legacy Zip
|
||
BOOLEAN IsPdo; // TRUE == this is either a PODO or a PDO - use DeviceIdString[0] to distinguish
|
||
BOOLEAN EndOfChain; // PODO - TRUE==NOT a 1284.3 daisy chain device - deprecated, use Ieee1284_3DeviceId==4 instead
|
||
BOOLEAN PodoRegForWMI; // has this PODO registered for WMI callbacks?
|
||
|
||
// 0x10 on x86
|
||
|
||
PDEVICE_OBJECT ParClassFdo; // P[O]DO - points to the ParClass FDO
|
||
|
||
PDEVICE_OBJECT ParClassPdo; // FDO - points to first P[O]DO in list of ParClass created PODOs and PDOs
|
||
|
||
PDEVICE_OBJECT Next; // P[O]DO - points to the next DO in the list of ParClass ejected P[O]DOs
|
||
|
||
PDEVICE_OBJECT DeviceObject;// back pointer to our device object
|
||
|
||
// 0x20 on x86
|
||
|
||
PDEVICE_OBJECT PortDeviceObject; // P[O]DO - points to the associated ParPort device object
|
||
|
||
PFILE_OBJECT PortDeviceFileObject;// P[O]DO - referenced pointer to a FILE created against PortDeviceObject
|
||
|
||
UNICODE_STRING PortSymbolicLinkName;// P[O]DO - Symbolic link name of the associated ParPort device - used to open a FILE
|
||
|
||
// 0x30 on x86
|
||
|
||
PDEVICE_OBJECT PhysicalDeviceObject;// FDO - The PDO passed to ParPnPAddDevice
|
||
|
||
PDEVICE_OBJECT ParentDeviceObject; // FDO - parent DO returned by IoAttachDeviceToDeviceStack
|
||
|
||
PIRP CurrentOpIrp; // IRP that our thread is currently processing
|
||
|
||
PVOID NotificationHandle; // PlugPlay Notification Handle
|
||
|
||
// 0x40 on x86
|
||
|
||
UNICODE_STRING ClassName; // P[O]DO - ClassName passed to IoCreateDevice() as DeviceName
|
||
|
||
UNICODE_STRING SymbolicLinkName; // P[O]DO - SymbolicLinkName linked to ClassName using IoCreateUnprotectedSymbolicLink()
|
||
|
||
// 0x50 on x86
|
||
|
||
ULONG TimerStart; // initial value used for countdown when starting an operation
|
||
|
||
BOOLEAN CreatedSymbolicLink; // P[O]DO - did we create a Symbolic Link for this device?
|
||
|
||
BOOLEAN UsePIWriteLoop; // P[O]DO - do we want to use processor independant write loop?
|
||
|
||
BOOLEAN Initialized; // FALSE == we think that the device needs to be initialized
|
||
|
||
//
|
||
// Set to true before the deferred initialization routine is run
|
||
// and false once it has completed. Used to synchronize the deferred
|
||
// initialization worker thread and the parallel port thread
|
||
//
|
||
BOOLEAN Initializing;
|
||
|
||
LONG OpenCloseRefCount; // count of Creates vs Closes - number of open FILEs against us,
|
||
// used for QUERY_REMOVE decision: SUCCEED if count == 0, otherwise FAIL
|
||
|
||
BOOLEAN ParPortDeviceGone; // Is our ParPort device object gone, possibly surprise removed?
|
||
|
||
BOOLEAN RegForPptRemovalRelations; // Are we registered for ParPort removal relations?
|
||
|
||
UCHAR Ieee1284Flags; // is device Stl older 1284.3 spec device?
|
||
|
||
UCHAR spare1; // return to dword alignment
|
||
|
||
// 0x60 on x86
|
||
USHORT IdxForwardProtocol; // see afpForward[] in ieee1284.c
|
||
USHORT IdxReverseProtocol; // see arpReverse[] in ieee1284.c
|
||
ULONG CurrentEvent; // IEEE 1284 event - see IEEE 1284-1994 spec
|
||
P1284_PHASE CurrentPhase; // see parallel.h for enum def - PHASE_UNKNOWN, ..., PHASE_INTERRUPT_HOST
|
||
P1284_HW_MODE PortHWMode; // see parallel.h for enum def - HW_MODE_COMPATIBILITY, ..., HW_MODE_CONFIGURATION
|
||
|
||
// 0x70 on x86
|
||
FAST_MUTEX OpenCloseMutex; // protect manipulation of OpenCloseRefCount
|
||
|
||
// 0x90 on x86
|
||
FAST_MUTEX DevObjListMutex; // protect manipulation of list of ParClass ejected DOs
|
||
|
||
// 0xb0 on x86
|
||
LIST_ENTRY WorkQueue; // Queue of irps waiting to be processed.
|
||
|
||
PVOID ThreadObjectPointer; // pointer to a worker thread for this Device
|
||
|
||
KSEMAPHORE RequestSemaphore;// dispatch routines use this to tell device worker thread that there is work to do
|
||
|
||
//
|
||
// PARALLEL_PORT_INFORMATION returned by IOCTL_INTERNAL_GET_PARALLEL_PORT_INFO
|
||
//
|
||
PHYSICAL_ADDRESS OriginalController;
|
||
PUCHAR Controller;
|
||
PUCHAR EcrController;
|
||
ULONG SpanOfController;
|
||
PPARALLEL_TRY_ALLOCATE_ROUTINE TryAllocatePort; // nonblocking callback to allocate ParPort device
|
||
PPARALLEL_FREE_ROUTINE FreePort; // callback to free ParPort device
|
||
PPARALLEL_QUERY_WAITERS_ROUTINE QueryNumWaiters; // callback to query number of waiters in port allocation queue
|
||
PVOID PortContext; // context for callbacks to ParPort
|
||
|
||
//
|
||
// subset of PARALLEL_PNP_INFORMATION returned by IOCTL_INTERNAL_GET_PARALLEL_PNP_INFO
|
||
//
|
||
ULONG HardwareCapabilities;
|
||
PPARALLEL_SET_CHIP_MODE TrySetChipMode;
|
||
PPARALLEL_CLEAR_CHIP_MODE ClearChipMode;
|
||
PPARALLEL_TRY_SELECT_ROUTINE TrySelectDevice;
|
||
PPARALLEL_DESELECT_ROUTINE DeselectDevice;
|
||
ULONG FifoDepth;
|
||
ULONG FifoWidth;
|
||
|
||
BOOLEAN bAllocated; // have we allocated associated ParPort device?
|
||
// Note: during some PnP processing we may have the port
|
||
// for a short duration without setting this value to TRUE
|
||
|
||
ULONG BusyDelay; // number of microseconds to wait after strobing a byte before checking the BUSY line.
|
||
|
||
BOOLEAN BusyDelayDetermined;// Indicates if the BusyDelay parameter has been computed yet.
|
||
|
||
PWORK_QUEUE_ITEM DeferredWorkItem; // Holds the work item used to defer printer initialization
|
||
|
||
BOOLEAN TimeToTerminateThread; // TRUE == Thread should kill itself via PsTerminateSystemThread()
|
||
|
||
// If the registry entry by the same name is set, run the parallel
|
||
// thread at the priority we used for NT 3.5 - this solves some
|
||
// cases where a dos app spinning for input in the foreground is
|
||
// starving the parallel thread
|
||
BOOLEAN UseNT35Priority;
|
||
|
||
ULONG InitializationTimeout;// timeout in seconds to wait for device to respond to an initialization request
|
||
// - default == 15 seconds
|
||
// - value overridden by registry entry of same name
|
||
// - we will spin for max amount if no device attached
|
||
|
||
LARGE_INTEGER AbsoluteOneSecond;// constants that are cheaper to put here rather
|
||
LARGE_INTEGER OneSecond; // than in bss
|
||
|
||
//
|
||
// IEEE 1284 Mode support
|
||
//
|
||
BOOLEAN Connected; // are we currently negotiated into a 1284 mode?
|
||
BOOLEAN AllocatedByLockPort; // are we currently allocated via IOCTL_INTERNAL_LOCK_PORT?
|
||
USHORT spare4[2];
|
||
#if (1 == DVRH_USE_CORRECT_PTRS)
|
||
PVOID fnRead; // Current pointer to a valid read funtion
|
||
PVOID fnWrite; // Current pointer to a valid write Funtion
|
||
#endif
|
||
LARGE_INTEGER IdleTimeout; // how long do we hold the port on the caller's behalf following an operation?
|
||
USHORT ProtocolData[FAMILY_MAX];
|
||
UCHAR ForwardInterfaceAddress;
|
||
UCHAR ReverseInterfaceAddress;
|
||
BOOLEAN SetForwardAddress;
|
||
BOOLEAN SetReverseAddress;
|
||
FAST_MUTEX LockPortMutex;
|
||
|
||
DEVICE_POWER_STATE DeviceState;// Current Device Power State
|
||
SYSTEM_POWER_STATE SystemState;// Current System Power State
|
||
|
||
ULONG spare2;
|
||
BOOLEAN bShadowBuffer;
|
||
Queue ShadowBuffer;
|
||
ULONG spare3;
|
||
BOOLEAN bSynchWrites; // TRUE if ECP HW writes should be synchronous
|
||
BOOLEAN bFirstByteTimeout; // TRUE if bus just reversed, means give the
|
||
// device some time to respond with some data
|
||
BOOLEAN bIsHostRecoverSupported; // Set via IOCTL_PAR_ECP_HOST_RECOVERY.
|
||
// HostRecovery will not be utilized unless this bit is set
|
||
KEVENT PauseEvent; // PnP dispatch routine uses this to pause worker thread during
|
||
// during QUERY_STOP, STOP, and QUERY_REMOVE states
|
||
|
||
USHORT ProtocolModesSupported;
|
||
USHORT BadProtocolModes;
|
||
|
||
PARALLEL_SAFETY ModeSafety;
|
||
BOOLEAN IsIeeeTerminateOk;
|
||
BOOLEAN IsCritical;
|
||
DOT3DL_PCTL P12843DL;
|
||
|
||
// WMI
|
||
PARALLEL_WMI_LOG_INFO log;
|
||
WMILIB_CONTEXT WmiLibContext;
|
||
LONG WmiRegistrationCount; // number of times this device has registered with WMI
|
||
|
||
// PnP Query ID results
|
||
UCHAR DeviceIdString[MAX_ID_SIZE]; // IEEE 1284 DeviceID string massaged/checksum'd to match INF form
|
||
UCHAR DeviceDescription[MAX_ID_SIZE]; // "Manufacturer<SPACE>Model" from IEEE 1284 DeviceID string
|
||
|
||
#if PAR_TEST_HARNESS
|
||
PAR_HARNS_PCTL ParTestHarness;
|
||
#endif
|
||
ULONG dummy; // dummy word to force RemoveLock to QuadWord alignment
|
||
IO_REMOVE_LOCK RemoveLock; // FDO - insure that other IRPs drain before FDO processes REMOVE_DEVICE
|
||
PVOID HwProfileChangeNotificationHandle;
|
||
ULONG ExtensionSignatureEnd; // keep this the last member in extension
|
||
} DEVICE_EXTENSION, *PDEVICE_EXTENSION;
|
||
|
||
|
||
//
|
||
// Protocol structure definitions
|
||
//
|
||
|
||
typedef
|
||
BOOLEAN
|
||
(*PPROTOCOL_IS_MODE_SUPPORTED_ROUTINE) (
|
||
IN PDEVICE_EXTENSION Extension
|
||
);
|
||
|
||
typedef
|
||
NTSTATUS
|
||
(*PPROTOCOL_CONNECT_ROUTINE) (
|
||
IN PDEVICE_EXTENSION Extension,
|
||
IN BOOLEAN DeviceIdRequest
|
||
);
|
||
|
||
typedef
|
||
VOID
|
||
(*PPROTOCOL_DISCONNECT_ROUTINE) (
|
||
IN PDEVICE_EXTENSION Extension
|
||
);
|
||
|
||
typedef
|
||
NTSTATUS
|
||
(*PPROTOCOL_ENTER_FORWARD_ROUTINE) (
|
||
IN PDEVICE_EXTENSION Extension
|
||
);
|
||
|
||
typedef
|
||
NTSTATUS
|
||
(*PPROTOCOL_EXIT_FORWARD_ROUTINE) (
|
||
IN PDEVICE_EXTENSION Extension
|
||
);
|
||
|
||
typedef
|
||
NTSTATUS
|
||
(*PPROTOCOL_ENTER_REVERSE_ROUTINE) (
|
||
IN PDEVICE_EXTENSION Extension
|
||
);
|
||
|
||
typedef
|
||
NTSTATUS
|
||
(*PPROTOCOL_EXIT_REVERSE_ROUTINE) (
|
||
IN PDEVICE_EXTENSION Extension
|
||
);
|
||
|
||
typedef
|
||
NTSTATUS
|
||
(*PPROTOCOL_READ_ROUTINE) (
|
||
IN PDEVICE_EXTENSION Extension,
|
||
IN PVOID Buffer,
|
||
IN ULONG BufferSize,
|
||
OUT PULONG BytesTransferred
|
||
);
|
||
|
||
typedef
|
||
VOID
|
||
(*PPROTOCOL_READSHADOW_ROUTINE) (
|
||
IN Queue *pShadowBuffer,
|
||
IN PUCHAR lpsBufPtr,
|
||
IN ULONG dCount,
|
||
OUT ULONG *fifoCount
|
||
);
|
||
|
||
typedef
|
||
BOOLEAN
|
||
(*PPROTOCOL_HAVEREADDATA_ROUTINE) (
|
||
IN PDEVICE_EXTENSION Extension
|
||
);
|
||
|
||
typedef
|
||
NTSTATUS
|
||
(*PPROTOCOL_WRITE_ROUTINE) (
|
||
IN PDEVICE_EXTENSION Extension,
|
||
IN PVOID Buffer,
|
||
IN ULONG BufferSize,
|
||
OUT PULONG BytesTransferred
|
||
);
|
||
|
||
typedef
|
||
NTSTATUS
|
||
(*PPROTOCOL_SET_INTERFACE_ADDRESS_ROUTINE) (
|
||
IN PDEVICE_EXTENSION Extension,
|
||
IN UCHAR Address
|
||
);
|
||
|
||
typedef struct _FORWARD_PTCL {
|
||
PPROTOCOL_IS_MODE_SUPPORTED_ROUTINE fnIsModeSupported;
|
||
PPROTOCOL_CONNECT_ROUTINE fnConnect;
|
||
PPROTOCOL_DISCONNECT_ROUTINE fnDisconnect;
|
||
PPROTOCOL_SET_INTERFACE_ADDRESS_ROUTINE fnSetInterfaceAddress;
|
||
PPROTOCOL_ENTER_FORWARD_ROUTINE fnEnterForward;
|
||
PPROTOCOL_EXIT_FORWARD_ROUTINE fnExitForward;
|
||
PPROTOCOL_WRITE_ROUTINE fnWrite;
|
||
USHORT Protocol;
|
||
USHORT ProtocolFamily;
|
||
} FORWARD_PTCL, *PFORWARD_PTCL;
|
||
|
||
typedef struct _REVERSE_PTCL {
|
||
PPROTOCOL_IS_MODE_SUPPORTED_ROUTINE fnIsModeSupported;
|
||
PPROTOCOL_CONNECT_ROUTINE fnConnect;
|
||
PPROTOCOL_DISCONNECT_ROUTINE fnDisconnect;
|
||
PPROTOCOL_SET_INTERFACE_ADDRESS_ROUTINE fnSetInterfaceAddress;
|
||
PPROTOCOL_ENTER_REVERSE_ROUTINE fnEnterReverse;
|
||
PPROTOCOL_EXIT_REVERSE_ROUTINE fnExitReverse;
|
||
PPROTOCOL_READSHADOW_ROUTINE fnReadShadow;
|
||
PPROTOCOL_HAVEREADDATA_ROUTINE fnHaveReadData;
|
||
PPROTOCOL_READ_ROUTINE fnRead;
|
||
USHORT Protocol;
|
||
USHORT ProtocolFamily;
|
||
} REVERSE_PTCL, *PREVERSE_PTCL;
|
||
|
||
extern FORWARD_PTCL afpForward[];
|
||
extern REVERSE_PTCL arpReverse[];
|
||
|
||
//
|
||
// WARNING...Make sure that enumeration matches the protocol array...
|
||
//
|
||
typedef enum _FORWARD_MODE {
|
||
|
||
FORWARD_FASTEST = 0,
|
||
BOUNDED_ECP_FORWARD = FORWARD_FASTEST,
|
||
ECP_HW_FORWARD_NOIRQ,
|
||
EPP_HW_FORWARD,
|
||
EPP_SW_FORWARD,
|
||
ECP_SW_FORWARD,
|
||
IEEE_COMPAT_MODE,
|
||
CENTRONICS_MODE,
|
||
FORWARD_NONE
|
||
|
||
} FORWARD_MODE;
|
||
|
||
typedef enum _REVERSE_MODE {
|
||
|
||
REVERSE_FASTEST = 0,
|
||
BOUNDED_ECP_REVERSE = REVERSE_FASTEST,
|
||
ECP_HW_REVERSE_NOIRQ,
|
||
EPP_HW_REVERSE,
|
||
EPP_SW_REVERSE,
|
||
ECP_SW_REVERSE,
|
||
BYTE_MODE,
|
||
NIBBLE_MODE,
|
||
CHANNELIZED_NIBBLE_MODE,
|
||
REVERSE_NONE
|
||
|
||
} REVERSE_MODE;
|
||
|
||
//
|
||
// Ieee Extensibility constants
|
||
//
|
||
|
||
#define NIBBLE_EXTENSIBILITY 0x00
|
||
#define BYTE_EXTENSIBILITY 0x01
|
||
#define CHANNELIZED_EXTENSIBILITY 0x08
|
||
#define ECP_EXTENSIBILITY 0x10
|
||
#define BECP_EXTENSIBILITY 0x18
|
||
#define EPP_EXTENSIBILITY 0x40
|
||
#define DEVICE_ID_REQ 0x04
|
||
|
||
//
|
||
// Bit Definitions in the status register.
|
||
//
|
||
|
||
#define PAR_STATUS_NOT_ERROR 0x08 //not error on device
|
||
#define PAR_STATUS_SLCT 0x10 //device is selected (on-line)
|
||
#define PAR_STATUS_PE 0x20 //paper empty
|
||
#define PAR_STATUS_NOT_ACK 0x40 //not acknowledge (data transfer was not ok)
|
||
#define PAR_STATUS_NOT_BUSY 0x80 //operation in progress
|
||
|
||
//
|
||
// Bit Definitions in the control register.
|
||
//
|
||
|
||
#define PAR_CONTROL_STROBE 0x01 //to read or write data
|
||
#define PAR_CONTROL_AUTOFD 0x02 //to autofeed continuous form paper
|
||
#define PAR_CONTROL_NOT_INIT 0x04 //begin an initialization routine
|
||
#define PAR_CONTROL_SLIN 0x08 //to select the device
|
||
#define PAR_CONTROL_IRQ_ENB 0x10 //to enable interrupts
|
||
#define PAR_CONTROL_DIR 0x20 //direction = read
|
||
#define PAR_CONTROL_WR_CONTROL 0xc0 //the 2 highest bits of the control
|
||
// register must be 1
|
||
//
|
||
// More bit definitions.
|
||
//
|
||
|
||
#define DATA_OFFSET 0
|
||
#define DSR_OFFSET 1
|
||
#define DCR_OFFSET 2
|
||
|
||
#define OFFSET_DATA DATA_OFFSET // Put in for compatibility with legacy code
|
||
#define OFFSET_DSR DSR_OFFSET // Put in for compatibility with legacy code
|
||
#define OFFSET_DCR DCR_OFFSET // Put in for compatibility with legacy code
|
||
|
||
//
|
||
// Bit definitions for the DSR.
|
||
//
|
||
|
||
#define DSR_NOT_BUSY 0x80
|
||
#define DSR_NOT_ACK 0x40
|
||
#define DSR_PERROR 0x20
|
||
#define DSR_SELECT 0x10
|
||
#define DSR_NOT_FAULT 0x08
|
||
|
||
//
|
||
// More bit definitions for the DSR.
|
||
//
|
||
|
||
#define DSR_NOT_PTR_BUSY 0x80
|
||
#define DSR_NOT_PERIPH_ACK 0x80
|
||
#define DSR_WAIT 0x80
|
||
#define DSR_PTR_CLK 0x40
|
||
#define DSR_PERIPH_CLK 0x40
|
||
#define DSR_INTR 0x40
|
||
#define DSR_ACK_DATA_REQ 0x20
|
||
#define DSR_NOT_ACK_REVERSE 0x20
|
||
#define DSR_XFLAG 0x10
|
||
#define DSR_NOT_DATA_AVAIL 0x08
|
||
#define DSR_NOT_PERIPH_REQUEST 0x08
|
||
|
||
//
|
||
// Bit definitions for the DCR.
|
||
//
|
||
|
||
#define DCR_RESERVED 0xC0
|
||
#define DCR_DIRECTION 0x20
|
||
#define DCR_ACKINT_ENABLED 0x10
|
||
#define DCR_SELECT_IN 0x08
|
||
#define DCR_NOT_INIT 0x04
|
||
#define DCR_AUTOFEED 0x02
|
||
#define DCR_STROBE 0x01
|
||
|
||
//
|
||
// More bit definitions for the DCR.
|
||
//
|
||
|
||
#define DCR_NOT_1284_ACTIVE 0x08
|
||
#define DCR_ASTRB 0x08
|
||
#define DCR_NOT_REVERSE_REQUEST 0x04
|
||
#define DCR_NOT_HOST_BUSY 0x02
|
||
#define DCR_NOT_HOST_ACK 0x02
|
||
#define DCR_DSTRB 0x02
|
||
#define DCR_NOT_HOST_CLK 0x01
|
||
#define DCR_WRITE 0x01
|
||
|
||
#define DCR_NEUTRAL (DCR_RESERVED | DCR_SELECT_IN | DCR_NOT_INIT)
|
||
|
||
//
|
||
// Give a timeout of 300 seconds. Some postscript printers will
|
||
// buffer up a lot of commands then proceed to render what they
|
||
// have. The printer will then refuse to accept any characters
|
||
// until it's done with the rendering. This render process can
|
||
// take a while. We'll give it 300 seconds.
|
||
//
|
||
// Note that an application can change this value.
|
||
//
|
||
#define PAR_WRITE_TIMEOUT_VALUE 300
|
||
|
||
|
||
#ifdef JAPAN // IBM-J printers
|
||
|
||
//
|
||
// Support for IBM-J printers.
|
||
//
|
||
// When the printer operates in Japanese (PS55) mode, it redefines
|
||
// the meaning of parallel lines so that extended error status can
|
||
// be reported. It is roughly compatible with PC/AT, but we have to
|
||
// take care of a few cases where the status looks like PC/AT error
|
||
// condition.
|
||
//
|
||
// Status Busy /AutoFdXT Paper Empty Select /Fault
|
||
// ------ ---- --------- ----------- ------ ------
|
||
// Not RMR 1 1 1 1 1
|
||
// Head Alarm 1 1 1 1 0
|
||
// ASF Jam 1 1 1 0 0
|
||
// Paper Empty 1 0 1 0 0
|
||
// No Error 0 0 0 1 1
|
||
// Can Req 1 0 0 0 1
|
||
// Deselect 1 0 0 0 0
|
||
//
|
||
// The printer keeps "Not RMR" during the parallel port
|
||
// initialization, then it takes "Paper Empty", "No Error"
|
||
// or "Deselect". Other status can be thought as an
|
||
// H/W error condition.
|
||
//
|
||
// Namely, "Not RMR" conflicts with PAR_NO_CABLE and "Deselect"
|
||
// should also be regarded as another PAR_OFF_LINE. When the
|
||
// status is PAR_PAPER_EMPTY, the initialization is finished
|
||
// (we should not send init purlse again.)
|
||
//
|
||
// See ParInitializeDevice() for more information.
|
||
//
|
||
// [takashim]
|
||
|
||
#define PAR_OFF_LINE_COMMON( Status ) ( \
|
||
(IsNotNEC_98) ? \
|
||
(Status & PAR_STATUS_NOT_ERROR) && \
|
||
((Status & PAR_STATUS_NOT_BUSY) ^ PAR_STATUS_NOT_BUSY) && \
|
||
!(Status & PAR_STATUS_SLCT) : \
|
||
\
|
||
((Status & PAR_STATUS_NOT_ERROR) ^ PAR_STATUS_NOT_ERROR) && \
|
||
((Status & PAR_STATUS_NOT_BUSY) ^ PAR_STATUS_NOT_BUSY) && \
|
||
((Status & PAR_STATUS_PE) ^ PAR_STATUS_PE) && \
|
||
!(Status & PAR_STATUS_SLCT) \
|
||
)
|
||
|
||
#define PAR_OFF_LINE_IBM55( Status ) ( \
|
||
((Status & PAR_STATUS_NOT_BUSY) ^ PAR_STATUS_NOT_BUSY) && \
|
||
((Status & PAR_STATUS_PE) ^ PAR_STATUS_PE) && \
|
||
((Status & PAR_STATUS_SLCT) ^ PAR_STATUS_SLCT) && \
|
||
((Status & PAR_STATUS_NOT_ERROR) ^ PAR_STATUS_NOT_ERROR))
|
||
|
||
#define PAR_PAPER_EMPTY2( Status ) ( \
|
||
((Status & PAR_STATUS_NOT_BUSY) ^ PAR_STATUS_NOT_BUSY) && \
|
||
(Status & PAR_STATUS_PE) && \
|
||
((Status & PAR_STATUS_SLCT) ^ PAR_STATUS_SLCT) && \
|
||
((Status & PAR_STATUS_NOT_ERROR) ^ PAR_STATUS_NOT_ERROR))
|
||
|
||
//
|
||
// Redefine this for Japan.
|
||
//
|
||
|
||
#define PAR_OFF_LINE( Status ) ( \
|
||
PAR_OFF_LINE_COMMON( Status ) || \
|
||
PAR_OFF_LINE_IBM55( Status ))
|
||
|
||
#else // JAPAN
|
||
//
|
||
// Busy, not select, not error
|
||
//
|
||
// !JAPAN
|
||
|
||
#define PAR_OFF_LINE( Status ) ( \
|
||
(IsNotNEC_98) ? \
|
||
(Status & PAR_STATUS_NOT_ERROR) && \
|
||
((Status & PAR_STATUS_NOT_BUSY) ^ PAR_STATUS_NOT_BUSY) && \
|
||
!(Status & PAR_STATUS_SLCT) : \
|
||
\
|
||
((Status & PAR_STATUS_NOT_ERROR) ^ PAR_STATUS_NOT_ERROR) && \
|
||
((Status & PAR_STATUS_NOT_BUSY) ^ PAR_STATUS_NOT_BUSY) && \
|
||
((Status & PAR_STATUS_PE) ^ PAR_STATUS_PE) && \
|
||
!(Status & PAR_STATUS_SLCT) \
|
||
)
|
||
|
||
#endif // JAPAN
|
||
|
||
//
|
||
// Busy, PE
|
||
//
|
||
|
||
#define PAR_PAPER_EMPTY( Status ) ( \
|
||
(Status & PAR_STATUS_PE) )
|
||
|
||
//
|
||
// error, ack, not busy
|
||
//
|
||
|
||
#define PAR_POWERED_OFF( Status ) ( \
|
||
(IsNotNEC_98) ? \
|
||
((Status & PAR_STATUS_NOT_ERROR) ^ PAR_STATUS_NOT_ERROR) && \
|
||
((Status & PAR_STATUS_NOT_ACK) ^ PAR_STATUS_NOT_ACK) && \
|
||
(Status & PAR_STATUS_NOT_BUSY) : \
|
||
\
|
||
((Status & PAR_STATUS_NOT_ERROR) ^ PAR_STATUS_NOT_ERROR) && \
|
||
(Status & PAR_STATUS_NOT_ACK) && \
|
||
(Status & PAR_STATUS_NOT_BUSY) \
|
||
)
|
||
|
||
//
|
||
// not error, not busy, not select
|
||
//
|
||
|
||
#define PAR_NOT_CONNECTED( Status ) ( \
|
||
(Status & PAR_STATUS_NOT_ERROR) && \
|
||
(Status & PAR_STATUS_NOT_BUSY) &&\
|
||
!(Status & PAR_STATUS_SLCT) )
|
||
|
||
//
|
||
// not error, not busy
|
||
//
|
||
|
||
#define PAR_OK(Status) ( \
|
||
(Status & PAR_STATUS_NOT_ERROR) && \
|
||
((Status & PAR_STATUS_PE) ^ PAR_STATUS_PE) && \
|
||
(Status & PAR_STATUS_NOT_BUSY) )
|
||
|
||
//
|
||
// busy, select, not error
|
||
//
|
||
|
||
#define PAR_POWERED_ON(Status) ( \
|
||
((Status & PAR_STATUS_NOT_BUSY) ^ PAR_STATUS_NOT_BUSY) && \
|
||
(Status & PAR_STATUS_SLCT) && \
|
||
(Status & PAR_STATUS_NOT_ERROR))
|
||
|
||
//
|
||
// busy, not error
|
||
//
|
||
|
||
#define PAR_BUSY(Status) (\
|
||
(( Status & PAR_STATUS_NOT_BUSY) ^ PAR_STATUS_NOT_BUSY) && \
|
||
( Status & PAR_STATUS_NOT_ERROR ) )
|
||
|
||
//
|
||
// selected
|
||
//
|
||
|
||
#define PAR_SELECTED(Status) ( \
|
||
( Status & PAR_STATUS_SLCT ) )
|
||
|
||
//
|
||
// No cable attached.
|
||
//
|
||
|
||
#define PAR_NO_CABLE(Status) ( \
|
||
(IsNotNEC_98) ? \
|
||
((Status & PAR_STATUS_NOT_BUSY) ^ PAR_STATUS_NOT_BUSY) && \
|
||
(Status & PAR_STATUS_NOT_ACK) && \
|
||
(Status & PAR_STATUS_PE) && \
|
||
(Status & PAR_STATUS_SLCT) && \
|
||
(Status & PAR_STATUS_NOT_ERROR) : \
|
||
\
|
||
(Status & PAR_STATUS_NOT_BUSY) && \
|
||
(Status & PAR_STATUS_NOT_ACK) && \
|
||
(Status & PAR_STATUS_PE) && \
|
||
(Status & PAR_STATUS_SLCT) && \
|
||
(Status & PAR_STATUS_NOT_ERROR) \
|
||
)
|
||
|
||
//
|
||
// not error, not busy, selected.
|
||
//
|
||
|
||
#define PAR_ONLINE(Status) ( \
|
||
(Status & PAR_STATUS_NOT_ERROR) && \
|
||
(Status & PAR_STATUS_NOT_BUSY) && \
|
||
((Status & PAR_STATUS_PE) ^ PAR_STATUS_PE) && \
|
||
(Status & PAR_STATUS_SLCT) )
|
||
|
||
|
||
//BOOLEAN
|
||
//ParCompareGuid(
|
||
// IN LPGUID guid1,
|
||
// IN LPGUID guid2
|
||
// )
|
||
//
|
||
#define ParCompareGuid(g1, g2) ( \
|
||
( (g1) == (g2) ) ? \
|
||
TRUE : \
|
||
RtlCompareMemory( (g1), (g2), sizeof(GUID) ) == sizeof(GUID) \
|
||
)
|
||
|
||
|
||
//VOID StoreData(
|
||
// IN PUCHAR RegisterBase,
|
||
// IN UCHAR DataByte
|
||
// )
|
||
// Data must be on line before Strobe = 1;
|
||
// Strobe = 1, DIR = 0
|
||
// Strobe = 0
|
||
//
|
||
// We change the port direction to output (and make sure stobe is low).
|
||
//
|
||
// Note that the data must be available at the port for at least
|
||
// .5 microseconds before and after you strobe, and that the strobe
|
||
// must be active for at least 500 nano seconds. We are going
|
||
// to end up stalling for twice as much time as we need to, but, there
|
||
// isn't much we can do about that.
|
||
//
|
||
// We put the data into the port and wait for 1 micro.
|
||
// We strobe the line for at least 1 micro
|
||
// We lower the strobe and again delay for 1 micro
|
||
// We then revert to the original port direction.
|
||
//
|
||
// Thanks to Olivetti for advice.
|
||
//
|
||
|
||
#define StoreData(RegisterBase,DataByte) \
|
||
{ \
|
||
PUCHAR _Address = RegisterBase; \
|
||
UCHAR _Control; \
|
||
_Control = GetControl(_Address); \
|
||
ASSERT(!(_Control & PAR_CONTROL_STROBE)); \
|
||
StoreControl( \
|
||
_Address, \
|
||
(UCHAR)(_Control & ~(PAR_CONTROL_STROBE | PAR_CONTROL_DIR)) \
|
||
); \
|
||
WRITE_PORT_UCHAR( \
|
||
_Address+PARALLEL_DATA_OFFSET, \
|
||
(UCHAR)DataByte \
|
||
); \
|
||
KeStallExecutionProcessor((ULONG)1); \
|
||
StoreControl( \
|
||
_Address, \
|
||
(UCHAR)((_Control | PAR_CONTROL_STROBE) & ~PAR_CONTROL_DIR) \
|
||
); \
|
||
KeStallExecutionProcessor((ULONG)1); \
|
||
StoreControl( \
|
||
_Address, \
|
||
(UCHAR)(_Control & ~(PAR_CONTROL_STROBE | PAR_CONTROL_DIR)) \
|
||
); \
|
||
KeStallExecutionProcessor((ULONG)1); \
|
||
StoreControl( \
|
||
_Address, \
|
||
(UCHAR)_Control \
|
||
); \
|
||
}
|
||
|
||
//UCHAR
|
||
//GetControl(
|
||
// IN PUCHAR RegisterBase
|
||
// )
|
||
#define GetControl(RegisterBase) \
|
||
(READ_PORT_UCHAR((RegisterBase)+PARALLEL_CONTROL_OFFSET))
|
||
|
||
|
||
//VOID
|
||
//StoreControl(
|
||
// IN PUCHAR RegisterBase,
|
||
// IN UCHAR ControlByte
|
||
// )
|
||
#define StoreControl(RegisterBase,ControlByte) \
|
||
{ \
|
||
WRITE_PORT_UCHAR( \
|
||
(RegisterBase)+PARALLEL_CONTROL_OFFSET, \
|
||
(UCHAR)ControlByte \
|
||
); \
|
||
}
|
||
|
||
|
||
//UCHAR
|
||
//GetStatus(
|
||
// IN PUCHAR RegisterBase
|
||
// )
|
||
|
||
#define GetStatus(RegisterBase) \
|
||
(READ_PORT_UCHAR((RegisterBase)+PARALLEL_STATUS_OFFSET))
|
||
|
||
|
||
//
|
||
// Function prototypes
|
||
//
|
||
|
||
//
|
||
// ieee1284.c
|
||
//
|
||
|
||
VOID
|
||
IeeeTerminate1284Mode(
|
||
IN PDEVICE_EXTENSION Extension
|
||
);
|
||
|
||
NTSTATUS
|
||
IeeeEnter1284Mode(
|
||
IN PDEVICE_EXTENSION Extension,
|
||
IN UCHAR Extensibility
|
||
);
|
||
|
||
VOID
|
||
IeeeDetermineSupportedProtocols(
|
||
IN PDEVICE_EXTENSION Extension
|
||
);
|
||
|
||
NTSTATUS
|
||
IeeeNegotiateBestMode(
|
||
IN PDEVICE_EXTENSION Extension,
|
||
IN USHORT usReadMask,
|
||
IN USHORT usWriteMask
|
||
);
|
||
|
||
NTSTATUS
|
||
IeeeNegotiateMode(
|
||
IN PDEVICE_EXTENSION Extension,
|
||
IN USHORT usReadMask,
|
||
IN USHORT usWriteMask
|
||
);
|
||
|
||
//
|
||
// port.c
|
||
//
|
||
|
||
NTSTATUS
|
||
ParGetPortInfoFromPortDevice(
|
||
IN OUT PDEVICE_EXTENSION Extension
|
||
);
|
||
|
||
VOID
|
||
ParReleasePortInfoToPortDevice(
|
||
IN PDEVICE_EXTENSION Extension
|
||
);
|
||
|
||
VOID
|
||
ParFreePort(
|
||
IN PDEVICE_EXTENSION Extension
|
||
);
|
||
|
||
NTSTATUS
|
||
ParAllocPortCompletionRoutine(
|
||
IN PDEVICE_OBJECT DeviceObject,
|
||
IN PIRP Irp,
|
||
IN PVOID Context
|
||
);
|
||
|
||
BOOLEAN
|
||
ParAllocPort(
|
||
IN PDEVICE_EXTENSION Extension
|
||
);
|
||
|
||
PDEVICE_OBJECT
|
||
ParGetPortObjectFromLinkName(
|
||
IN PUNICODE_STRING SymbolicLinkName,
|
||
IN PDEVICE_EXTENSION Extension
|
||
);
|
||
|
||
//
|
||
// parpnp.c
|
||
//
|
||
#ifndef STATIC_LOAD
|
||
|
||
NTSTATUS
|
||
ParPnpAddDevice(
|
||
IN PDRIVER_OBJECT pDriverObject,
|
||
IN PDEVICE_OBJECT pPhysicalDeviceObject
|
||
);
|
||
|
||
NTSTATUS
|
||
ParParallelPnp (
|
||
IN PDEVICE_OBJECT pDeviceObject,
|
||
IN PIRP pIrp
|
||
);
|
||
|
||
NTSTATUS
|
||
ParSynchCompletionRoutine(
|
||
IN PDEVICE_OBJECT DeviceObject,
|
||
IN PIRP Irp,
|
||
IN PKEVENT Event
|
||
);
|
||
|
||
BOOLEAN
|
||
ParMakeNames(
|
||
IN ULONG ParallelPortNumber,
|
||
OUT PUNICODE_STRING ClassName,
|
||
OUT PUNICODE_STRING LinkName
|
||
);
|
||
|
||
VOID
|
||
ParCheckParameters(
|
||
IN OUT PDEVICE_EXTENSION Extension
|
||
);
|
||
|
||
#endif
|
||
|
||
//
|
||
// oldinit.c
|
||
//
|
||
|
||
#ifdef STATIC_LOAD
|
||
|
||
NTSTATUS
|
||
DriverEntry(
|
||
IN PDRIVER_OBJECT DriverObject,
|
||
IN PUNICODE_STRING RegistryPath
|
||
);
|
||
|
||
BOOLEAN
|
||
ParMakeNames(
|
||
IN ULONG ParallelPortNumber,
|
||
OUT PUNICODE_STRING PortName,
|
||
OUT PUNICODE_STRING ClassName,
|
||
OUT PUNICODE_STRING LinkName
|
||
);
|
||
|
||
VOID
|
||
ParInitializeClassDevice(
|
||
IN PDRIVER_OBJECT DriverObject,
|
||
IN PUNICODE_STRING RegistryPath,
|
||
IN ULONG ParallelPortNumber
|
||
);
|
||
|
||
VOID
|
||
ParCheckParameters(
|
||
IN PUNICODE_STRING RegistryPath,
|
||
IN OUT PDEVICE_EXTENSION Extension
|
||
);
|
||
|
||
#endif
|
||
|
||
//
|
||
// parloop.c
|
||
//
|
||
|
||
ULONG
|
||
SppWriteLoop(
|
||
IN PUCHAR Controller,
|
||
IN PUCHAR WriteBuffer,
|
||
IN ULONG NumBytesToWrite
|
||
);
|
||
|
||
//
|
||
// parclass.c
|
||
//
|
||
|
||
VOID
|
||
ParLogError(
|
||
IN PDRIVER_OBJECT DriverObject,
|
||
IN PDEVICE_OBJECT DeviceObject OPTIONAL,
|
||
IN PHYSICAL_ADDRESS P1,
|
||
IN PHYSICAL_ADDRESS P2,
|
||
IN ULONG SequenceNumber,
|
||
IN UCHAR MajorFunctionCode,
|
||
IN UCHAR RetryCount,
|
||
IN ULONG UniqueErrorValue,
|
||
IN NTSTATUS FinalStatus,
|
||
IN NTSTATUS SpecificIOStatus
|
||
);
|
||
|
||
NTSTATUS
|
||
ParCreateOpen(
|
||
IN PDEVICE_OBJECT DeviceObject,
|
||
IN PIRP Irp
|
||
);
|
||
|
||
NTSTATUS
|
||
ParClose(
|
||
IN PDEVICE_OBJECT DeviceObject,
|
||
IN PIRP Irp
|
||
);
|
||
|
||
NTSTATUS
|
||
ParCleanup(
|
||
IN PDEVICE_OBJECT DeviceObject,
|
||
IN PIRP Irp
|
||
);
|
||
|
||
NTSTATUS
|
||
ParReadWrite(
|
||
IN PDEVICE_OBJECT DeviceObject,
|
||
IN PIRP Irp
|
||
);
|
||
|
||
NTSTATUS
|
||
ParDeviceControl(
|
||
IN PDEVICE_OBJECT DeviceObject,
|
||
IN PIRP Irp
|
||
);
|
||
|
||
NTSTATUS
|
||
ParInternalDeviceControl(
|
||
IN PDEVICE_OBJECT DeviceObject,
|
||
IN PIRP Irp
|
||
);
|
||
|
||
NTSTATUS
|
||
ParQueryInformationFile(
|
||
IN PDEVICE_OBJECT DeviceObject,
|
||
IN PIRP Irp
|
||
);
|
||
|
||
NTSTATUS
|
||
ParSetInformationFile(
|
||
IN PDEVICE_OBJECT DeviceObject,
|
||
IN PIRP Irp
|
||
);
|
||
|
||
NTSTATUS
|
||
ParExportedNegotiateIeeeMode(
|
||
IN PDEVICE_EXTENSION Extension,
|
||
IN USHORT ModeMaskFwd,
|
||
IN USHORT ModeMaskRev,
|
||
IN PARALLEL_SAFETY ModeSafety,
|
||
IN BOOLEAN IsForward
|
||
);
|
||
|
||
NTSTATUS
|
||
ParExportedTerminateIeeeMode(
|
||
IN PDEVICE_EXTENSION Extension
|
||
);
|
||
|
||
//////////////////////////////////////////////////////////////////
|
||
// Modes of operation
|
||
//////////////////////////////////////////////////////////////////
|
||
|
||
//
|
||
// spp.c
|
||
//
|
||
|
||
NTSTATUS
|
||
ParEnterSppMode(
|
||
IN PDEVICE_EXTENSION Extension,
|
||
IN BOOLEAN DeviceIdRequest
|
||
);
|
||
|
||
ULONG
|
||
SppWriteLoopPI(
|
||
IN PUCHAR Controller,
|
||
IN PUCHAR WriteBuffer,
|
||
IN ULONG NumBytesToWrite,
|
||
IN ULONG BusyDelay
|
||
);
|
||
|
||
ULONG
|
||
SppCheckBusyDelay(
|
||
IN PDEVICE_EXTENSION Extension,
|
||
IN PUCHAR WriteBuffer,
|
||
IN ULONG NumBytesToWrite
|
||
);
|
||
|
||
NTSTATUS
|
||
SppWrite(
|
||
IN PDEVICE_EXTENSION Extension,
|
||
IN PVOID Buffer,
|
||
IN ULONG BytesToWrite,
|
||
OUT PULONG BytesTransferred
|
||
);
|
||
|
||
VOID
|
||
ParTerminateSppMode(
|
||
IN PDEVICE_EXTENSION Extension
|
||
);
|
||
|
||
NTSTATUS
|
||
SppQueryDeviceId(
|
||
IN PDEVICE_EXTENSION Extension,
|
||
OUT PUCHAR DeviceIdBuffer,
|
||
IN ULONG BufferSize,
|
||
OUT PULONG DeviceIdSize,
|
||
IN BOOLEAN bReturnRawString
|
||
);
|
||
|
||
//
|
||
// sppieee.c
|
||
//
|
||
NTSTATUS
|
||
SppIeeeWrite(
|
||
IN PDEVICE_EXTENSION Extension,
|
||
IN PVOID Buffer,
|
||
IN ULONG BytesToWrite,
|
||
OUT PULONG BytesTransferred
|
||
);
|
||
|
||
//
|
||
// nibble.c
|
||
//
|
||
|
||
BOOLEAN
|
||
ParIsChannelizedNibbleSupported(
|
||
IN PDEVICE_EXTENSION Extension
|
||
);
|
||
|
||
BOOLEAN
|
||
ParIsNibbleSupported(
|
||
IN PDEVICE_EXTENSION Extension
|
||
);
|
||
|
||
NTSTATUS
|
||
ParEnterNibbleMode(
|
||
IN PDEVICE_EXTENSION Extension,
|
||
IN BOOLEAN DeviceIdRequest
|
||
);
|
||
|
||
NTSTATUS
|
||
ParEnterChannelizedNibbleMode(
|
||
IN PDEVICE_EXTENSION Extension,
|
||
IN BOOLEAN DeviceIdRequest
|
||
);
|
||
|
||
VOID
|
||
ParTerminateNibbleMode(
|
||
IN PDEVICE_EXTENSION Extension
|
||
);
|
||
|
||
NTSTATUS
|
||
ParNibbleModeRead(
|
||
IN PDEVICE_EXTENSION Extension,
|
||
IN PVOID Buffer,
|
||
IN ULONG BufferSize,
|
||
OUT PULONG BytesTransferred
|
||
);
|
||
|
||
//
|
||
// Byte.c
|
||
//
|
||
|
||
BOOLEAN
|
||
ParIsByteSupported(
|
||
IN PDEVICE_EXTENSION Extension
|
||
);
|
||
|
||
NTSTATUS
|
||
ParEnterByteMode(
|
||
IN PDEVICE_EXTENSION Extension,
|
||
IN BOOLEAN DeviceIdRequest
|
||
);
|
||
|
||
VOID
|
||
ParTerminateByteMode(
|
||
IN PDEVICE_EXTENSION Extension
|
||
);
|
||
|
||
NTSTATUS
|
||
ParByteModeRead(
|
||
IN PDEVICE_EXTENSION Extension,
|
||
IN PVOID Buffer,
|
||
IN ULONG BufferSize,
|
||
OUT PULONG BytesTransferred
|
||
);
|
||
|
||
//
|
||
// epp.c
|
||
//
|
||
|
||
NTSTATUS
|
||
ParEppSetAddress(
|
||
IN PDEVICE_EXTENSION Extension,
|
||
IN UCHAR Address
|
||
);
|
||
|
||
//
|
||
// hwepp.c
|
||
//
|
||
|
||
BOOLEAN
|
||
ParIsEppHwSupported(
|
||
IN PDEVICE_EXTENSION Extension
|
||
);
|
||
|
||
NTSTATUS
|
||
ParEnterEppHwMode(
|
||
IN PDEVICE_EXTENSION Extension,
|
||
IN BOOLEAN DeviceIdRequest
|
||
);
|
||
|
||
VOID
|
||
ParTerminateEppHwMode(
|
||
IN PDEVICE_EXTENSION Extension
|
||
);
|
||
|
||
NTSTATUS
|
||
ParEppHwWrite(
|
||
IN PDEVICE_EXTENSION Extension,
|
||
IN PVOID Buffer,
|
||
IN ULONG BufferSize,
|
||
OUT PULONG BytesTransferred
|
||
);
|
||
|
||
NTSTATUS
|
||
ParEppHwRead(
|
||
IN PDEVICE_EXTENSION Extension,
|
||
IN PVOID Buffer,
|
||
IN ULONG BufferSize,
|
||
OUT PULONG BytesTransferred
|
||
);
|
||
|
||
//
|
||
// swepp.c
|
||
//
|
||
|
||
BOOLEAN
|
||
ParIsEppSwWriteSupported(
|
||
IN PDEVICE_EXTENSION Extension
|
||
);
|
||
|
||
BOOLEAN
|
||
ParIsEppSwReadSupported(
|
||
IN PDEVICE_EXTENSION Extension
|
||
);
|
||
|
||
NTSTATUS
|
||
ParEnterEppSwMode(
|
||
IN PDEVICE_EXTENSION Extension,
|
||
IN BOOLEAN DeviceIdRequest
|
||
);
|
||
|
||
VOID
|
||
ParTerminateEppSwMode(
|
||
IN PDEVICE_EXTENSION Extension
|
||
);
|
||
|
||
NTSTATUS
|
||
ParEppSwWrite(
|
||
IN PDEVICE_EXTENSION Extension,
|
||
IN PVOID Buffer,
|
||
IN ULONG BufferSize,
|
||
OUT PULONG BytesTransferred
|
||
);
|
||
|
||
NTSTATUS
|
||
ParEppSwRead(
|
||
IN PDEVICE_EXTENSION Extension,
|
||
IN PVOID Buffer,
|
||
IN ULONG BufferSize,
|
||
OUT PULONG BytesTransferred
|
||
);
|
||
|
||
//
|
||
// ecp.c and swecp.c
|
||
//
|
||
|
||
NTSTATUS
|
||
ParEcpEnterForwardPhase (
|
||
IN PDEVICE_EXTENSION Extension
|
||
);
|
||
|
||
BOOLEAN
|
||
ParEcpHaveReadData (
|
||
IN PDEVICE_EXTENSION Extension
|
||
);
|
||
|
||
BOOLEAN
|
||
ParIsEcpSwWriteSupported(
|
||
IN PDEVICE_EXTENSION Extension
|
||
);
|
||
|
||
BOOLEAN
|
||
ParIsEcpSwReadSupported(
|
||
IN PDEVICE_EXTENSION Extension
|
||
);
|
||
|
||
NTSTATUS
|
||
ParEnterEcpSwMode(
|
||
IN PDEVICE_EXTENSION Extension,
|
||
IN BOOLEAN DeviceIdRequest
|
||
);
|
||
|
||
VOID
|
||
ParCleanupSwEcpPort(
|
||
IN PDEVICE_EXTENSION Extension
|
||
);
|
||
|
||
VOID
|
||
ParTerminateEcpMode(
|
||
IN PDEVICE_EXTENSION Extension
|
||
);
|
||
|
||
NTSTATUS
|
||
ParEcpSetAddress(
|
||
IN PDEVICE_EXTENSION Extension,
|
||
IN UCHAR Address
|
||
);
|
||
|
||
NTSTATUS
|
||
ParEcpSwWrite(
|
||
IN PDEVICE_EXTENSION Extension,
|
||
IN PVOID Buffer,
|
||
IN ULONG BufferSize,
|
||
OUT PULONG BytesTransferred
|
||
);
|
||
|
||
NTSTATUS
|
||
ParEcpSwRead(
|
||
IN PDEVICE_EXTENSION Extension,
|
||
IN PVOID Buffer,
|
||
IN ULONG BufferSize,
|
||
OUT PULONG BytesTransferred
|
||
);
|
||
|
||
NTSTATUS
|
||
ParEcpForwardToReverse(
|
||
IN PDEVICE_EXTENSION Extension
|
||
);
|
||
|
||
NTSTATUS
|
||
ParEcpReverseToForward(
|
||
IN PDEVICE_EXTENSION Extension
|
||
);
|
||
|
||
//
|
||
// hwecp.c
|
||
//
|
||
|
||
BOOLEAN
|
||
ParEcpHwHaveReadData (
|
||
IN PDEVICE_EXTENSION Extension
|
||
);
|
||
|
||
NTSTATUS
|
||
ParEcpHwExitForwardPhase (
|
||
IN PDEVICE_EXTENSION Extension
|
||
);
|
||
|
||
NTSTATUS
|
||
ParEcpHwEnterReversePhase (
|
||
IN PDEVICE_EXTENSION Extension
|
||
);
|
||
|
||
NTSTATUS
|
||
ParEcpHwExitReversePhase (
|
||
IN PDEVICE_EXTENSION Extension
|
||
);
|
||
|
||
VOID
|
||
ParEcpHwDrainShadowBuffer(IN Queue *pShadowBuffer,
|
||
IN PUCHAR lpsBufPtr,
|
||
IN ULONG dCount,
|
||
OUT ULONG *fifoCount);
|
||
|
||
NTSTATUS
|
||
ParEcpHwRead(
|
||
IN PDEVICE_EXTENSION Extension,
|
||
IN PVOID Buffer,
|
||
IN ULONG BufferSize,
|
||
OUT PULONG BytesTransferred
|
||
);
|
||
|
||
NTSTATUS
|
||
ParEcpHwWrite(
|
||
IN PDEVICE_EXTENSION Extension,
|
||
IN PVOID Buffer,
|
||
IN ULONG BufferSize,
|
||
OUT PULONG BytesTransferred
|
||
);
|
||
|
||
NTSTATUS
|
||
ParEcpHwSetAddress(
|
||
IN PDEVICE_EXTENSION Extension,
|
||
IN UCHAR Address
|
||
);
|
||
|
||
NTSTATUS
|
||
ParEnterEcpHwMode(
|
||
IN PDEVICE_EXTENSION Extension,
|
||
IN BOOLEAN DeviceIdRequest
|
||
);
|
||
|
||
BOOLEAN
|
||
ParIsEcpHwSupported(
|
||
IN PDEVICE_EXTENSION Extension
|
||
);
|
||
|
||
NTSTATUS
|
||
ParEcpHwSetupPhase(
|
||
IN PDEVICE_EXTENSION Extension
|
||
);
|
||
|
||
VOID
|
||
ParTerminateHwEcpMode(
|
||
IN PDEVICE_EXTENSION Extension
|
||
);
|
||
|
||
//
|
||
// becp.c
|
||
//
|
||
|
||
NTSTATUS
|
||
ParBecpExitReversePhase(
|
||
IN PDEVICE_EXTENSION Extension
|
||
);
|
||
|
||
NTSTATUS
|
||
ParBecpRead(
|
||
IN PDEVICE_EXTENSION Extension,
|
||
IN PVOID Buffer,
|
||
IN ULONG BufferSize,
|
||
OUT PULONG BytesTransferred
|
||
);
|
||
|
||
NTSTATUS
|
||
ParEnterBecpMode(
|
||
IN PDEVICE_EXTENSION Extension,
|
||
IN BOOLEAN DeviceIdRequest
|
||
);
|
||
|
||
BOOLEAN
|
||
ParIsBecpSupported(
|
||
IN PDEVICE_EXTENSION Extension
|
||
);
|
||
VOID
|
||
ParTerminateBecpMode(
|
||
IN PDEVICE_EXTENSION Extension
|
||
);
|
||
|
||
//
|
||
// p12843dl.c
|
||
//
|
||
NTSTATUS
|
||
ParDot3Connect(
|
||
IN PDEVICE_EXTENSION Extension
|
||
);
|
||
|
||
VOID
|
||
ParDot3CreateObject(
|
||
IN PDEVICE_EXTENSION Extension,
|
||
IN PUCHAR DOT3DL,
|
||
IN PUCHAR DOT3C
|
||
);
|
||
|
||
VOID
|
||
ParDot4CreateObject(
|
||
IN PDEVICE_EXTENSION Extension,
|
||
IN PUCHAR DOT4DL
|
||
);
|
||
|
||
VOID
|
||
ParDot3ParseModes(
|
||
IN PDEVICE_EXTENSION Extension,
|
||
IN PUCHAR DOT3M
|
||
);
|
||
|
||
VOID
|
||
ParMLCCreateObject(
|
||
IN PDEVICE_EXTENSION Extension,
|
||
IN PUCHAR CMDField
|
||
);
|
||
|
||
VOID
|
||
ParDot3DestroyObject(
|
||
IN PDEVICE_EXTENSION Extension
|
||
);
|
||
|
||
NTSTATUS
|
||
ParDot3Disconnect(
|
||
IN PDEVICE_EXTENSION Extension
|
||
);
|
||
|
||
NTSTATUS
|
||
ParDot3Read(
|
||
IN PDEVICE_EXTENSION Extension,
|
||
IN PVOID Buffer,
|
||
IN ULONG BufferSize,
|
||
OUT PULONG BytesTransferred
|
||
);
|
||
|
||
NTSTATUS
|
||
ParDot3Write(
|
||
IN PDEVICE_EXTENSION Extension,
|
||
IN PVOID Buffer,
|
||
IN ULONG BufferSize,
|
||
OUT PULONG BytesTransferred
|
||
);
|
||
|
||
typedef
|
||
NTSTATUS
|
||
(*PDOT3_RESET_ROUTINE) (
|
||
IN PDEVICE_EXTENSION Extension
|
||
);
|
||
|
||
NTSTATUS
|
||
ParMLCCompatReset(
|
||
IN PDEVICE_EXTENSION Extension
|
||
);
|
||
|
||
NTSTATUS
|
||
ParMLCECPReset(
|
||
IN PDEVICE_EXTENSION Extension
|
||
);
|
||
|
||
#if DBG
|
||
VOID
|
||
ParInitDebugLevel (
|
||
IN PUNICODE_STRING RegistryPath
|
||
);
|
||
#endif
|