📄 tdlportio.cpp
字号:
memset(PortNumberStr, '\0', MAX_PATH);
strncpy(PortNumberStr,
strstr(PortName, "LPT")+3,
strlen(PortName)-(strstr(PortName, "LPT")-PortName)-2);
// Find the port number
PortNumber = atoi(PortNumberStr);
// Find the address
RegCloseKey(CurKey);
strcpy(KeyName, BASE_KEY);
strcat(KeyName, "\\");
strcat(KeyName, KeyList[KeyIndex]);
RegOpenKeyEx(HKEY_DYN_DATA, KeyName, 0, KEY_PERMISSIONS, &CurKey);
DataSize = sizeof(Allocation);
RegQueryValueEx(
CurKey, ALLOCATION, NULL, &DataType,
(unsigned char*)Allocation, &DataSize
);
if (DataType == REG_BINARY)
{
// Decode the Allocation data: the port address is present
// directly after a 0x000C entry (which doesn't have 0x0000
// after it).
for (int pos=0; pos<63; pos++)
if (Allocation[pos] == 0x000C &&
Allocation[pos+1] != 0x0000 &&
PortNumber<=MAX_LPT_PORTS)
{
// Found a port; add it to the list
FLPTAddress[PortNumber] = Allocation[pos+1];
FLPTCount++;
break;
}
}
}
}
}
RegCloseKey(CurKey);
}
// Destroy our key list
for (DWORD index=0; index<=KeyCount; index++)
delete[] KeyList[index];
delete KeyList;
}
//---------------------------------------------------------------------------
// DetectPortsNT()
//---------------------------------------------------------------------------
void __fastcall TDLPrinterPortIO::DetectPortsNT()
{
const char *BASE_KEY = "HARDWARE\\DEVICEMAP\\PARALLEL PORTS";
const char *LOADED_KEY = "HARDWARE\\RESOURCEMAP\\LOADED PARALLEL DRIVER RESOURCES\\Parport";
const char *DOS_DEVICES = "\\DosDevices\\LPT";
const char *DEVICE_PARALLEL = "\\Device\\Parallel";
const REGSAM KEY_PERMISSIONS = KEY_ENUMERATE_SUB_KEYS |
KEY_QUERY_VALUE;
HKEY CurKey; // Current key when using the registry
char KeyName[MAX_PATH]; // A key name when using the registry
char **ValueList; // List of value names
DWORD ValueCount; // Count of the number of value names in ValueList
// Clear the port count
FLPTCount = 0;
// Clear the port array
for (int index=0; index<=MAX_LPT_PORTS; index++)
FLPTAddress[index] = 0;
// Open the registry
if (RegOpenKeyEx(
HKEY_LOCAL_MACHINE, BASE_KEY, 0, KEY_PERMISSIONS, &CurKey
) != ERROR_SUCCESS)
return; // Can't do anything without this BASE_KEY
// Grab all the value names under HKEY_LOCAL_MACHINE
//
// Do this by first counting the number of value names,
// then creating an array big enough to hold them
// using the ValueList pointer.
DWORD DummyLength = MAX_PATH;
DWORD ValueType;
ValueCount = 0;
while (RegEnumValue(
CurKey, ValueCount++, KeyName, &DummyLength,
NULL, &ValueType, NULL, NULL
) != ERROR_NO_MORE_ITEMS)
{
DummyLength = MAX_PATH;
}
ValueList = new char*[ValueCount];
ValueCount = 0;
DummyLength = MAX_PATH;
while (RegEnumValue(
CurKey, ValueCount, KeyName, &DummyLength,
NULL, &ValueType, NULL, NULL
) != ERROR_NO_MORE_ITEMS)
{
ValueList[ValueCount] = new char[DummyLength+1];
strcpy(ValueList[ValueCount], KeyName);
DummyLength = MAX_PATH;
ValueCount++;
}
// Close the key
RegCloseKey(CurKey);
for (DWORD index=0; index<ValueCount; index++)
{
char DosDev[MAX_PATH]; // Key value for \DosDevices\LPT
DWORD DataType, DataSize; // Type and size of data read from the registry
// Is it a \DosDevices\LPT key?
strcpy(KeyName, BASE_KEY);
if (RegOpenKeyEx(
HKEY_LOCAL_MACHINE, KeyName, 0, KEY_PERMISSIONS, &CurKey
) == ERROR_SUCCESS)
{
DataSize = MAX_PATH;
RegQueryValueEx(
CurKey, ValueList[index], NULL, &DataType, DosDev, &DataSize
);
RegCloseKey(CurKey);
// Make sure it was a string
if (DataType != REG_SZ)
strcpy(DosDev, "");
}
else
strcpy(DosDev, "");
if (strstr(DosDev, DOS_DEVICES) != NULL)
{
int PortNumber; // The nubmer of the port
char PortNumberStr[MAX_PATH]; // String version of PortNumber
char PortIDStr[MAX_PATH]; // PortID
memset(PortNumberStr, '\0', MAX_PATH);
strncpy(PortNumberStr,
strstr(DosDev, DOS_DEVICES) + strlen(DOS_DEVICES),
strlen(DosDev) - (strstr(DosDev, DOS_DEVICES)-DosDev)
- strlen(DOS_DEVICES) + 1
);
// Get the Port ID
memset(PortIDStr, '\0', MAX_PATH);
strncpy(PortIDStr,
strstr(ValueList[index], DEVICE_PARALLEL) + strlen(DEVICE_PARALLEL),
strlen(ValueList[index])
- (strstr(ValueList[index], DEVICE_PARALLEL)-ValueList[index])
- strlen(DEVICE_PARALLEL) + 1
);
// Get the port number
PortNumber = atoi(PortNumberStr);
// Get the port address
RegOpenKeyEx(HKEY_LOCAL_MACHINE, LOADED_KEY, 0, KEY_PERMISSIONS, &CurKey);
strcpy(DosDev, "\\Device\\ParallelPort");
strcat(DosDev, PortIDStr);
strcat(DosDev, ".Raw");
if (RegQueryValueEx(
CurKey, DosDev, NULL, &DataType, NULL, NULL
) == ERROR_SUCCESS &&
DataType == REG_RESOURCE_LIST)
{
WORD Allocation[64]; // Binary data with port number inside
// Read in the binary data
DataSize = sizeof(Allocation);
RegQueryValueEx(
CurKey, DosDev, NULL, NULL,
(unsigned char*)Allocation, &DataSize
);
// Found a port; add it to the list
if (DataSize>0 && PortNumber<=MAX_LPT_PORTS)
{
FLPTAddress[PortNumber] = Allocation[12];
FLPTCount++;
}
}
RegCloseKey(CurKey);
}
}
// Destroy our key value list
// Destroy our key list
for (DWORD index=0; index<=ValueCount; index++)
delete[] ValueList[index];
delete ValueList;
}
//---------------------------------------------------------------------------
// SetLPTNumber()
//---------------------------------------------------------------------------
void __fastcall TDLPrinterPortIO::SetLPTNumber(BYTE Number)
{
// Note that we don't make sure it is within the range 1..FLPTCount
// because there _might_ (can someone claify this?) be a port numbered
// as #2, where it may be the _only_ port installed on the system.
if (Number>0 && Number<=MAX_LPT_PORTS)
{
FLPTNumber=Number;
FLPTBase=FLPTAddress[Number];
}
}
//---------------------------------------------------------------------------
// GetPin()
//---------------------------------------------------------------------------
bool __fastcall TDLPrinterPortIO::GetPin(BYTE Index)
{
switch (Index)
{
case 1: return (Port[FLPTBase+2]&BIT0)==0; // Inverted
case 2: return (Port[FLPTBase]&BIT0)!=0;
case 3: return (Port[FLPTBase]&BIT1)!=0;
case 4: return (Port[FLPTBase]&BIT2)!=0;
case 5: return (Port[FLPTBase]&BIT3)!=0;
case 6: return (Port[FLPTBase]&BIT4)!=0;
case 7: return (Port[FLPTBase]&BIT5)!=0;
case 8: return (Port[FLPTBase]&BIT6)!=0;
case 9: return (Port[FLPTBase]&BIT7)!=0;
case 10: return (Port[FLPTBase+1]&BIT6)!=0;
case 11: return (Port[FLPTBase+1]&BIT7)==0; // Inverted
case 12: return (Port[FLPTBase+1]&BIT5)!=0;
case 13: return (Port[FLPTBase+1]&BIT4)!=0;
case 14: return (Port[FLPTBase+2]&BIT1)==0; // Inverted
case 15: return (Port[FLPTBase+1]&BIT3)!=0;
case 16: return (Port[FLPTBase+2]&BIT2)!=0;
case 17: return (Port[FLPTBase+2]&BIT3)==0; // Inverted
default: return false; // pins 18-25 (GND), and other invalid pins
}
}
//---------------------------------------------------------------------------
// SetPin()
//---------------------------------------------------------------------------
void __fastcall TDLPrinterPortIO::SetPin(BYTE Index, bool State)
{
if (State)
switch (Index)
{
case 1: Port[FLPTBase+2]&=~BIT0; break; // Inverted
case 2: Port[FLPTBase]|=BIT0; break;
case 3: Port[FLPTBase]|=BIT1; break;
case 4: Port[FLPTBase]|=BIT2; break;
case 5: Port[FLPTBase]|=BIT3; break;
case 6: Port[FLPTBase]|=BIT4; break;
case 7: Port[FLPTBase]|=BIT5; break;
case 8: Port[FLPTBase]|=BIT6; break;
case 9: Port[FLPTBase]|=BIT7; break;
/*
case 10: Port[FLPTBase+1]|=BIT6; break;
case 11: Port[FLPTBase+1]&=~BIT7; break; // Inverted
case 12: Port[FLPTBase+1]|=BIT5; break;
case 13: Port[FLPTBase+1]|=BIT4; break;
*/
case 14: Port[FLPTBase+2]&=~BIT1; break; // Inverted
/*
case 15: Port[FLPTBase+1]|=BIT3; break;
*/
case 16: Port[FLPTBase+2]|=BIT2; break;
case 17: Port[FLPTBase+2]&=~BIT3; break; // Inverted
default: break; // pins 18-25 (GND), and other invalid pins
}
else
switch (Index)
{
case 1: Port[FLPTBase+2]|=BIT0; break; // Inverted
case 2: Port[FLPTBase]&=~BIT0; break;
case 3: Port[FLPTBase]&=~BIT1; break;
case 4: Port[FLPTBase]&=~BIT2; break;
case 5: Port[FLPTBase]&=~BIT3; break;
case 6: Port[FLPTBase]&=~BIT4; break;
case 7: Port[FLPTBase]&=~BIT5; break;
case 8: Port[FLPTBase]&=~BIT6; break;
case 9: Port[FLPTBase]&=~BIT7; break;
/*
case 10: Port[FLPTBase+1]&=~BIT6; break;
case 11: Port[FLPTBase+1]|=BIT7; break; // Inverted
case 12: Port[FLPTBase+1]&=~BIT5; break;
case 13: Port[FLPTBase+1]&=~BIT4; break;
*/
case 14: Port[FLPTBase+2]|=BIT1; break; // Inverted
/*
case 15: Port[FLPTBase+1]&=~BIT3; break;
*/
case 16: Port[FLPTBase+2]&=~BIT2; break;
case 17: Port[FLPTBase+2]|=BIT3; break; // Inverted
default: break; // pins 18-25 (GND), and other invalid pins
}
}
//---------------------------------------------------------------------------
// LPTPrintChar
// Sends a character to the printer.
// Returns true on success. Repeat as neccessary.
//---------------------------------------------------------------------------
bool __fastcall TDLPrinterPortIO::LPTPrintChar(char Ch)
{
// Write data to Base+0
Port[FLPTBase]=(BYTE)Ch;
// Write 0Dh to Base+2.
Port[FLPTBase+2]=0x0D;
// Make sure there's a delay of at least one microsecond
Sleep(1);
// Write 0Ch to Base+2.
Port[FLPTBase+2]=0x0C;
// Input from Base+1 and check if Bit 7 is 1.
// Return this status as whether the character was printed
return (Port[FLPTBase+1]&BIT7)!=0;
}
//---------------------------------------------------------------------------
namespace Dlportio
{
void __fastcall PACKAGE Register()
{
TComponentClass classes[2] = {__classid(TDLPortIO),
__classid(TDLPrinterPortIO)};
RegisterComponents("DiskDude", classes, 1);
}
}
#pragma package(smart_init)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -