📄 dbgport.c
字号:
/*
* Twidle - send an intermittent pulse over a line to let the person
* at the other end know you're there
*/
static bool Twidle(
PDEVICE_EXTENSION ext,
bool check )
{
unsigned i;
unsigned long time;
for( i = 20; i != 0; i-- ) {
WriteData( TWIDLE_ON );
time = Ticks() + TWIDLE_TIME;
while( time > Ticks() ){
if( check ) {
if( CountTwidle(ext) ) {
return( TRUE );
}
} else {
if( Synch(ext) ) {
return( TRUE );
}
}
}
WriteData( TWIDLE_OFF );
time = Ticks() + TWIDLE_TIME;
while( time > Ticks() ){
if( check ) {
if( CountTwidle(ext) ) {
return( TRUE );
}
} else {
if( Synch(ext) ) {
return( TRUE );
}
}
}
}
return( FALSE );
}
/*
* LineTest - make sure that all lines are working
*/
static bool LineTestServer(
PDEVICE_EXTENSION ext)
{
unsigned send;
unsigned long time;
unsigned ret;
for( send = 1; send != 256; send *= 2 ) {
time = Ticks() + LINE_TEST_WAIT;
if( time == RELINQUISH ) time ++;
if( time == KEEP ) time ++;
ret = DataPut( ext, send, time );
if( ret == TIMEOUT ) return( FALSE );
time = Ticks() + LINE_TEST_WAIT;
if( time == RELINQUISH ) time ++;
if( time == KEEP ) time ++;
ret = DataGet( ext, time );
if( ret == TIMEOUT ) return( FALSE );
if( ret != send ) {
return( FALSE );
}
}
time = Ticks() + LINE_TEST_WAIT;
if( time == RELINQUISH ) time ++;
if( time == KEEP ) time ++;
ret = DataPut( ext, DONE_LINE_TEST, time );
if( ret == TIMEOUT ) return( FALSE );
return( TRUE );
}
/*
* LineTest - make sure that all lines are working
*/
static bool LineTestClient(
PDEVICE_EXTENSION ext)
{
unsigned send;
unsigned long time;
send = 0;
for( ;; ) {
time = Ticks() + LINE_TEST_WAIT;
if( time == RELINQUISH ) time ++;
if( time == KEEP ) time ++;
send = DataGet( ext, time );
if( send == TIMEOUT ) return( FALSE );
if( send == DONE_LINE_TEST ) break;
time = Ticks() + LINE_TEST_WAIT;
if( time == RELINQUISH ) time ++;
if( time == KEEP ) time ++;
DataPut( ext, send, time );
if( send == TIMEOUT ) return( FALSE );
}
return( TRUE );
}
int RemoteConnectServer(
PDEVICE_EXTENSION ext)
{
unsigned long time;
bool got_twidles;
if( !CountTwidle(ext) ) return( 0 );
got_twidles = Twidle( ext, FALSE );
switch( ext->CableType ) {
case WATCOM_VAL:
LowerCtl1();
LowerCtl2();
case FMR_VAL:
LowerCtl1();
LowerCtl2();
case LAPLINK_VAL:
LL_LowerCtl1();
break;
case DUTCHMAN_VAL:
FD_LowerCtl1();
break;
}
if( !got_twidles ) {
time = Ticks() + SYNCH_WAIT;
for( ;; ) {
if( Synch(ext) ) {
break;
} else if( time < Ticks() ) {
return( 0 );
}
}
}
if( !LineTestServer(ext) ) return( FALSE );
return( TRUE );
}
int RemoteConnectClient(
PDEVICE_EXTENSION ext)
{
unsigned long time;
if( !Twidle( ext, TRUE ) )
return( FALSE );
switch( ext->CableType ) {
case WATCOM_VAL:
LowerCtl1();
LowerCtl2();
case FMR_VAL:
LowerCtl1();
LowerCtl2();
case LAPLINK_VAL:
LL_LowerCtl1();
break;
case DUTCHMAN_VAL:
FD_LowerCtl1();
break;
}
time = Ticks() + SYNCH_WAIT;
for( ;; ) {
if( Synch(ext) ) {
break;
} else if( time < Ticks() ) {
return( 0 );
}
}
if( !LineTestClient(ext) ) return( FALSE );
return( TRUE );
}
void RemoteDisco(
PDEVICE_EXTENSION ext)
{
unsigned long time;
time = Ticks() + TWIDLE_TIME;
while( time > Ticks() ) { /* delay while other side catches up */ }
WriteData( TWIDLE_OFF ); /* initialize control ports */
XX_RaiseCtl1();
ext->TwidleCount = 0;
ext->CableType = NULL_VAL;
ext->TwidleOn = FALSE;
}
void RemoteLink(
PDEVICE_EXTENSION ext)
{
ext->DataPort = 0;
ext->CtlPort1 = ext->DataPort + 1;
ext->CtlPort2 = ext->CtlPort1 + 1;
WriteData( TWIDLE_OFF ); /* initialize the control ports */
XX_RaiseCtl1();
ext->TwidleCount = 0;
ext->CableType = NULL_VAL;
ext->TwidleOn = FALSE;
}
/****************************************************************************
PARAMETERS:
ParallelPortNumber - Supplies the port number.
PortName - Returns the port name.
ClassName - Returns the class name.
LinkName - Returns the symbolic link name.
RETURNS:
FALSE on Failure, TRUE on Success.
REMARKS:
This routine generates the names \Device\ParallelPortN and
\Device\ParallelDebugN, \DosDevices\DBGPORTn.
****************************************************************************/
BOOLEAN ParMakeNames(
IN ULONG ParallelPortNumber,
OUT PUNICODE_STRING PortName,
OUT PUNICODE_STRING ClassName,
OUT PUNICODE_STRING LinkName)
{
UNICODE_STRING prefix, digits, linkPrefix, linkDigits;
WCHAR digitsBuffer[10], linkDigitsBuffer[10];
UNICODE_STRING portSuffix, classSuffix, linkSuffix;
NTSTATUS status;
// Put together local variables for constructing names.
RtlInitUnicodeString(&prefix, L"\\Device\\");
RtlInitUnicodeString(&linkPrefix, L"\\DosDevices\\");
RtlInitUnicodeString(&portSuffix, DD_PARALLEL_PORT_BASE_NAME_U);
RtlInitUnicodeString(&classSuffix, L"ParallelDebug");
RtlInitUnicodeString(&linkSuffix, L"DBGPORT");
digits.Length = 0;
digits.MaximumLength = 20;
digits.Buffer = digitsBuffer;
linkDigits.Length = 0;
linkDigits.MaximumLength = 20;
linkDigits.Buffer = linkDigitsBuffer;
status = RtlIntegerToUnicodeString(ParallelPortNumber, 10, &digits);
if (!NT_SUCCESS(status))
return FALSE;
status = RtlIntegerToUnicodeString(ParallelPortNumber + 1, 10, &linkDigits);
if (!NT_SUCCESS(status))
return FALSE;
// Make the port name.
PortName->Length = 0;
PortName->MaximumLength = prefix.Length + portSuffix.Length + digits.Length + sizeof(WCHAR);
PortName->Buffer = ExAllocatePool(PagedPool, PortName->MaximumLength);
if (!PortName->Buffer)
return FALSE;
RtlZeroMemory(PortName->Buffer, PortName->MaximumLength);
RtlAppendUnicodeStringToString(PortName, &prefix);
RtlAppendUnicodeStringToString(PortName, &portSuffix);
RtlAppendUnicodeStringToString(PortName, &digits);
// Make the class name.
ClassName->Length = 0;
ClassName->MaximumLength = prefix.Length + classSuffix.Length + digits.Length + sizeof(WCHAR);
ClassName->Buffer = ExAllocatePool(PagedPool, ClassName->MaximumLength);
if (!ClassName->Buffer) {
ExFreePool(PortName->Buffer);
return FALSE;
}
RtlZeroMemory(ClassName->Buffer, ClassName->MaximumLength);
RtlAppendUnicodeStringToString(ClassName, &prefix);
RtlAppendUnicodeStringToString(ClassName, &classSuffix);
RtlAppendUnicodeStringToString(ClassName, &digits);
// Make the link name.
LinkName->Length = 0;
LinkName->MaximumLength = linkPrefix.Length + linkSuffix.Length + linkDigits.Length + sizeof(WCHAR);
LinkName->Buffer = ExAllocatePool(PagedPool, LinkName->MaximumLength);
if (!LinkName->Buffer) {
ExFreePool(PortName->Buffer);
ExFreePool(ClassName->Buffer);
return FALSE;
}
RtlZeroMemory(LinkName->Buffer, LinkName->MaximumLength);
RtlAppendUnicodeStringToString(LinkName, &linkPrefix);
RtlAppendUnicodeStringToString(LinkName, &linkSuffix);
RtlAppendUnicodeStringToString(LinkName, &linkDigits);
return TRUE;
}
/****************************************************************************
PARAMETERS:
Extension - Supplies the device extension.
RETURNS:
STATUS_SUCCESS on Success, !STATUS_SUCCESS on Failure.
REMARKS:
This routine will request the port information from the port driver
and fill it in the device extension.
****************************************************************************/
NTSTATUS ParGetPortInfoFromPortDevice(
IN OUT PDEVICE_EXTENSION Extension)
{
KEVENT event;
PIRP irp;
PARALLEL_PORT_INFORMATION portInfo;
IO_STATUS_BLOCK ioStatus;
NTSTATUS status;
KeInitializeEvent(&event, NotificationEvent, FALSE);
irp = IoBuildDeviceIoControlRequest(IOCTL_INTERNAL_GET_PARALLEL_PORT_INFO,
Extension->PortDeviceObject,
NULL, 0, &portInfo,
sizeof(PARALLEL_PORT_INFORMATION),
TRUE, &event, &ioStatus);
if (!irp)
return STATUS_INSUFFICIENT_RESOURCES;
status = IoCallDriver(Extension->PortDeviceObject, irp);
if (!NT_SUCCESS(status))
return status;
status = KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL);
if (!NT_SUCCESS(status))
return status;
Extension->OriginalController = portInfo.OriginalController;
Extension->Controller = portInfo.Controller;
Extension->SpanOfController = portInfo.SpanOfController;
Extension->TryAllocatePort = portInfo.TryAllocatePort;
Extension->FreePort = portInfo.FreePort;
Extension->AllocFreePortContext = portInfo.Context;
if (Extension->SpanOfController < PARALLEL_REGISTER_SPAN)
return STATUS_INSUFFICIENT_RESOURCES;
return status;
}
/****************************************************************************
PARAMETERS:
DriverObject - Supplies the driver object.
ParallelPortNumber - Supplies the number for this port.
REMARKS:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -