📄 tdlportiox.cpp
字号:
// Get a handle to the service to remove
hService = OpenService(
hSCMan,
DRIVER_NAME.c_str(),
DELETE);
if (hService!=NULL)
{
// Remove the driver then close the service again
if (!DeleteService(hService))
dwStatus = GetLastError();
// Close the service
CloseServiceHandle(hService);
}
else
dwStatus = GetLastError();
if (dwStatus!=0)
FLastError="DriverRemove: Error #"+IntToStr(dwStatus);
return dwStatus==0; // Success == 0
}
//---------------------------------------------------------------------------
// OpenDriver()
// Opens the DLL dynamically
//---------------------------------------------------------------------------
void __fastcall TDLPortIOX::OpenDriver()
{
// If the DLL/driver is already open, then forget it!
if (IsLoaded()) return;
// If we're running Windows NT, install the driver then start it
if (FRunningWinNT)
{
// Connect to the Service Control Manager
if (!ConnectSCM()) return;
// Install the driver
if (!DriverInstall())
{
// Driver install failed, so disconnect from the SCM
DisconnectSCM();
return;
}
// Start the driver
if (!DriverStart())
{
// Driver start failed, so remove it then disconnect from SCM
DriverRemove();
DisconnectSCM();
return;
}
}
// Load DLL library
AnsiString LibraryFileName = LIBRARY_FILENAME;
if (FDLLPath.Length()>0)
LibraryFileName = FDLLPath+"\\"+LIBRARY_FILENAME;
FDLLInst=LoadLibrary(LibraryFileName.c_str());
if (FDLLInst!=NULL)
{
DlReadByte=(TDlPortReadPortUchar)
GetProcAddress(FDLLInst,"DlPortReadPortUchar");
DlReadWord=(TDlPortReadPortUshort)
GetProcAddress(FDLLInst,"DlPortReadPortUshort");
DlReadDWord=(TDlPortReadPortUlong)
GetProcAddress(FDLLInst,"DlPortReadPortUlong");
DlWriteByte=(TDlPortWritePortUchar)
GetProcAddress(FDLLInst,"DlPortWritePortUchar");
DlWriteWord=(TDlPortWritePortUshort)
GetProcAddress(FDLLInst,"DlPortWritePortUshort");
DlWriteDWord=(TDlPortWritePortUlong)
GetProcAddress(FDLLInst,"DlPortWritePortUlong");
DlReadBufferByte=(TDlPortReadPortBufferUchar)
GetProcAddress(FDLLInst,"DlPortReadPortBufferUchar");
DlReadBufferWord=(TDlPortReadPortBufferUshort)
GetProcAddress(FDLLInst,"DlPortReadPortBufferUshort");
DlReadBufferDWord=(TDlPortReadPortBufferUlong)
GetProcAddress(FDLLInst,"DlPortReadPortBufferUlong");
DlWriteBufferByte=(TDlPortWritePortBufferUchar)
GetProcAddress(FDLLInst,"DlPortWritePortBufferUchar");
DlWriteBufferWord=(TDlPortWritePortBufferUshort)
GetProcAddress(FDLLInst,"DlPortWritePortBufferUshort");
DlWriteBufferDWord=(TDlPortWritePortBufferUlong)
GetProcAddress(FDLLInst,"DlPortWritePortBufferUlong");
// Make sure all our functions are there
if (DlReadByte!=NULL && DlReadWord!=NULL && DlReadDWord!=NULL &&
DlWriteByte!=NULL && DlWriteWord!=NULL && DlWriteDWord!=NULL &&
DlReadBufferByte!=NULL && DlReadBufferWord!=NULL &&
DlReadBufferDWord!=NULL && DlWriteBufferByte!=NULL &&
DlWriteBufferWord!=NULL && DlWriteBufferDWord!=NULL)
FActiveHW=true; // Success
}
// Did we fail?
if (!FActiveHW)
{
// If we're running Windows NT, stop the driver then remove it
// Forget about any return (error) values we might get...
if (FRunningWinNT)
{
DriverStop();
DriverRemove();
DisconnectSCM();
}
// Free the library
if (FDLLInst!=NULL)
{
FreeLibrary(FDLLInst);
FDLLInst=NULL;
}
}
}
//---------------------------------------------------------------------------
// CloseDriver()
// Closes the dynamically opened DLL
//---------------------------------------------------------------------------
void __fastcall TDLPortIOX::CloseDriver()
{
// Don't close anything if it wasn't opened previously
if (!IsLoaded()) return;
// If we're running Windows NT, stop the driver then remove it
if (FRunningWinNT)
{
if (!DriverStop()) return;
if (!DriverRemove()) return;
DisconnectSCM();
}
// Free the library
if (FreeLibrary(FDLLInst)==0) return;
FDLLInst=NULL;
FActiveHW=false; // Success
}
//*************************************************************************//
// TDLPrinterPortIO class implementation
//*************************************************************************//
//---------------------------------------------------------------------------
// TDLPrinterPortIO()
//---------------------------------------------------------------------------
__fastcall TDLPrinterPortIOX::TDLPrinterPortIOX(TComponent *Owner)
: TDLPortIOX(Owner),
FLPTNumber(0), // No LPT selected
FLPTBase(0), // No base address
FLPTCount(0) // No printer ports counted
{
// Detect the printer ports available
DetectPorts();
// Set the default LPT number
SetLPTNumber(1);
}
//---------------------------------------------------------------------------
// Paint()
// Paints our little icon
//---------------------------------------------------------------------------
void __fastcall TDLPrinterPortIOX::Paint()
{
// The icon, as a BMP :-)
const BYTE Icon[] = {0x42, 0x4D, 0xF6, 0x01, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x76, 0x00, 0x00, 0x00, 0x28, 0x00,
0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x1C, 0x00,
0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x02, 0x00,
0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0xC3, 0x0E,
0x00, 0x00, 0xC3, 0x0E, 0x00, 0x00, 0x10, 0x00,
0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80,
0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x80, 0x00,
0x00, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x80,
0x00, 0x00, 0xC0, 0xC0, 0xC0, 0x00, 0x80, 0x80,
0x80, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF,
0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0x00,
0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF,
0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x1C, 0x88,
0x00, 0x00, 0x02, 0xF7, 0x18, 0x77, 0x02, 0x78,
0x00, 0x00, 0x00, 0x04, 0xF7, 0x87, 0x16, 0x77,
0x02, 0x78, 0x00, 0x00, 0x00, 0x04, 0xF7, 0x87,
0x16, 0x77, 0x02, 0x78, 0x00, 0x00, 0x00, 0x0A,
0xF7, 0x87, 0x00, 0x00, 0x00, 0x00, 0x10, 0x77,
0x02, 0x78, 0x00, 0x00, 0x00, 0x0C, 0xF7, 0x00,
0x88, 0x88, 0x87, 0x07, 0x0E, 0x77, 0x02, 0x78,
0x00, 0x00, 0x00, 0x0C, 0xF7, 0x77, 0x77, 0x77,
0x78, 0x87, 0x0E, 0x77, 0x02, 0x78, 0x00, 0x00,
0x00, 0x0C, 0xF7, 0x77, 0x77, 0x77, 0x78, 0x80,
0x0E, 0x77, 0x02, 0x78, 0x00, 0x00, 0x00, 0x0C,
0xF7, 0x77, 0x77, 0x77, 0x70, 0x00, 0x0E, 0x77,
0x02, 0x78, 0x00, 0x00, 0x00, 0x0E, 0xF7, 0x77,
0x77, 0x77, 0x0F, 0x88, 0x07, 0x00, 0x0C, 0x77,
0x02, 0x78, 0x00, 0x00, 0x00, 0x0E, 0xF7, 0x77,
0x77, 0x78, 0xF7, 0x77, 0x80, 0x00, 0x0C, 0x77,
0x02, 0x78, 0x00, 0x00, 0x00, 0x0E, 0xF7, 0x77,
0x77, 0x78, 0xF7, 0x77, 0x80, 0x00, 0x0C, 0x77,
0x02, 0x78, 0x00, 0x00, 0x00, 0x0E, 0xF7, 0x77,
0x77, 0x78, 0xF7, 0x77, 0x80, 0x00, 0x0A, 0x00,
0x00, 0x04, 0x77, 0x78, 0x00, 0x00, 0x00, 0x1C,
0xF7, 0x77, 0x77, 0x8F, 0x77, 0x77, 0x78, 0x07,
0x77, 0x77, 0x77, 0x07, 0x07, 0x78, 0x00, 0x00,
0x00, 0x0E, 0xF7, 0x77, 0x77, 0x8F, 0xFF, 0xFF,
0xFF, 0x00, 0x0A, 0x00, 0x00, 0x04, 0x70, 0x78,
0x00, 0x00, 0x00, 0x1C, 0xF7, 0x77, 0x77, 0x7B,
0x3B, 0x33, 0xB3, 0x77, 0x77, 0xBB, 0xB7, 0x70,
0x00, 0x78, 0x00, 0x00, 0x02, 0xF7, 0x08, 0x77,
0x02, 0x70, 0x08, 0x77, 0x00, 0x08, 0x17, 0x70,
0x70, 0x78, 0x00, 0x00, 0x02, 0xF7, 0x08, 0x77,
0x02, 0x70, 0x0C, 0x00, 0x00, 0x04, 0x77, 0x08,
0x00, 0x00, 0x02, 0xF7, 0x08, 0x77, 0x02, 0x70,
0x0A, 0x77, 0x00, 0x06, 0x07, 0x07, 0x08, 0x00,
0x00, 0x00, 0x02, 0xF7, 0x0A, 0x77, 0x0A, 0x00,
0x00, 0x06, 0x70, 0x70, 0x08, 0x00, 0x00, 0x00,
0x02, 0xF7, 0x0A, 0x77, 0x02, 0x70, 0x08, 0xFF,
0x00, 0x06, 0x07, 0x07, 0x08, 0x00, 0x00, 0x00,
0x02, 0xF7, 0x0C, 0x77, 0x00, 0x0E, 0x0F, 0x00,
0x00, 0x0F, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00,
0x02, 0xF7, 0x0C, 0x77, 0x00, 0x0E, 0x0F, 0xFF,
0xFF, 0xFF, 0xF0, 0x77, 0x78, 0x00, 0x00, 0x00,
0x02, 0xF7, 0x0C, 0x77, 0x00, 0x0E, 0x70, 0xF0,
0x00, 0x00, 0xF0, 0x77, 0x78, 0x00, 0x00, 0x00,
0x02, 0xF7, 0x0C, 0x77, 0x02, 0x70, 0x08, 0xFF,
0x00, 0x04, 0x07, 0x78, 0x00, 0x00, 0x02, 0xF7,
0x0E, 0x77, 0x08, 0x00, 0x00, 0x04, 0x07, 0x78,
0x00, 0x00, 0x02, 0xF7, 0x18, 0x77, 0x02, 0x78,
0x00, 0x00, 0x1C, 0xFF, 0x00, 0x01};
TMemoryStream *Buffer;
Graphics::TBitmap *Bitmap;
Buffer = new TMemoryStream();
if (Buffer==NULL) return;
Bitmap = new Graphics::TBitmap();
if (Bitmap==NULL)
{
delete Buffer;
return;
}
Buffer->Write(Icon, 502);
Buffer->Seek(0, soFromBeginning);
Bitmap->LoadFromStream(Buffer);
Canvas->Draw(0, 0, Bitmap);
delete Bitmap;
delete Buffer;
}
//---------------------------------------------------------------------------
// DetectPorts()
//---------------------------------------------------------------------------
void __fastcall TDLPrinterPortIOX::DetectPorts()
{
bool RunningWinNT;
// Are we running Windows NT?
OSVERSIONINFO os;
memset(&os, NULL, sizeof(OSVERSIONINFO));
os.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
GetVersionEx(&os);
RunningWinNT=(os.dwPlatformId==VER_PLATFORM_WIN32_NT);
// Detect the printer ports available
if (RunningWinNT)
DetectPortsNT(); // WinNT version
else
DetectPorts9x(); // Win9x version
}
//---------------------------------------------------------------------------
// DetectPorts9x()
//---------------------------------------------------------------------------
void __fastcall TDLPrinterPortIOX::DetectPorts9x()
{
const char *BASE_KEY = "Config Manager\\Enum";
const char *PROBLEM = "Problem";
const char *ALLOCATION = "Allocation";
const char *PORTNAME = "PortName";
const char *HARDWARE_KEY = "HardwareKey";
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 **KeyList; // List of keys
DWORD KeyCount; // Count of the number of keys in KeyList
// 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
RegOpenKeyEx(HKEY_DYN_DATA, BASE_KEY, 0, KEY_PERMISSIONS, &CurKey);
// Grab all the key names under HKEY_DYN_DATA
//
// Do this by first counting the number of keys,
// then creating an array big enough to hold them
// using the KeyList pointer.
FILETIME DummyFileTime;
DWORD DummyLength = MAX_PATH;
KeyCount = 0;
while (RegEnumKeyEx(
CurKey, KeyCount++, KeyName, &DummyLength,
NULL, NULL, NULL, &DummyFileTime
) != ERROR_NO_MORE_ITEMS)
{
DummyLength = MAX_PATH;
}
KeyList = new char*[KeyCount];
KeyCount = 0;
DummyLength = MAX_PATH;
while (RegEnumKeyEx(
CurKey, KeyCount, KeyName, &DummyLength,
NULL, NULL, NULL, &DummyFileTime
) != ERROR_NO_MORE_ITEMS)
{
KeyList[KeyCount] = new char[DummyLength+1];
strcpy(KeyList[KeyCount], KeyName);
DummyLength = MAX_PATH;
KeyCount++;
}
// Close the key
RegCloseKey(CurKey);
// Cycle through all keys; looking for a string valued subkey called
// 'HardWareKey' which is not NULL, and another subkey called 'Problem'
// whose fields are all valued 0.
for (DWORD KeyIndex=0; KeyIndex<KeyCount; KeyIndex++)
{
bool HasProblem = false; // Is 'Problem' non-zero? Assume it is Ok
// Open the key
strcpy(KeyName, BASE_KEY);
strcat(KeyName, "\\");
strcat(KeyName, KeyList[KeyIndex]);
if (RegOpenKeyEx(
HKEY_DYN_DATA, KeyName, 0, KEY_PERMISSIONS, &CurKey
) != ERROR_SUCCESS)
continue;
// Test for a 0 valued Problem sub-key,
// which must only consist of raw data
DWORD DataType, DataSize;
RegQueryValueEx(CurKey, PROBLEM, NULL, &DataType, NULL, &DataSize);
if (DataType == REG_BINARY)
{
// We have a valid, binary "Problem" sub-key
// Test to see if the fields are zero
char HardwareSubKey[MAX_PATH];
// Data from the "Hardware" sub-key
BYTE *Data = new BYTE[DataSize];
// Data from "Problem" sub-key
// Read the data from the "Problem" sub-key
if (RegQueryValueEx(
CurKey, PROBLEM, NULL,
NULL, Data, &DataSize
) == ERROR_SUCCESS)
{
// See if it has any problems
for (DWORD index=0; index<DataSize; index++)
HasProblem |= Data[index];
}
else
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -