📄 tdlportiox.cpp
字号:
//*** TDLPortIO: DriverLINX Port IO Driver wrapper component *****************
//** **
//** File: TDLPortIO.cpp **
//** **
//** Copyright (c) 1999 John Pappas (DiskDude). All rights reserved. **
//** This software is FreeWare. **
//** **
//** Please notify me if you make any changes to this file. **
//** Email: diskdude@poboxes.com **
//** **
//** **
//** The following resources helped in developing the install, start, stop **
//** and remove code for dynamically opening/closing the DriverLINX WinNT **
//** kernel mode driver. **
//** **
//** "Dynamically Loading Drivers in Windows NT" by Paula Tomlinson **
//** from "Windows Developer's Journal", Volume 6, Issue 5. (C code) **
//** ftp://ftp.mfi.com/pub/windev/1995/may95.zip **
//** **
//** "Hardware I/O Port Programming with Delphi and NT" by Graham Wideman **
//** http://www.wideman-one.com/tech/Delphi/IOPM/index.htm **
//** **
//** **
//** Special thanks to Peter Holm <comtext3@post4.tele.dk> for his **
//** algorithm and code for detecting the number and addresses of the **
//** installed printer ports, on which the detection code below is based. **
//** **
//*** http://diskdude.cjb.net/ ***********************************************
#include <vcl.h>
#include <stdlib.h>
#include <string.h>
#pragma hdrstop
#include "TDLPortIOX.h"
//---------------------------------------------------------------------------
// Constants
//---------------------------------------------------------------------------
// DriverLINX DLL filename
const AnsiString LIBRARY_FILENAME = "DLPortIO.dll";
// WinNT DriverLINX Information
const AnsiString DRIVER_NAME = "DLPortIO";
const AnsiString DISPLAY_NAME = "DriverLINX Port I/O Driver";
const AnsiString DRIVER_GROUP = "SST miniport drivers";
// Define to do a little less error checking
#define FAST
//*************************************************************************//
// TDLPortIO class implementation
//*************************************************************************//
//---------------------------------------------------------------------------
// TDLPortIO()
//---------------------------------------------------------------------------
__fastcall TDLPortIOX::TDLPortIOX(TComponent *Owner) : TCustomControl(Owner)
{
// Are we running Windows NT?
OSVERSIONINFO os;
memset(&os, NULL, sizeof(OSVERSIONINFO));
os.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
GetVersionEx(&os);
FRunningWinNT=(os.dwPlatformId==VER_PLATFORM_WIN32_NT);
// Set default WinNT driver path
char Buffer[MAX_PATH];
GetSystemDirectory(Buffer, MAX_PATH);
FDriverPath = AnsiString(Buffer)+"\\DRIVERS";
// Set the default DLL path
FDLLPath="";
FActiveHW=false; // DLL/Driver not loaded
FHardAccess=true; // Not used, default true
FLastError=""; // No errors yet
}
//---------------------------------------------------------------------------
// ~TDLPortIO()
//---------------------------------------------------------------------------
__fastcall TDLPortIOX::~TDLPortIOX()
{
// Make sure we close the DLL
if (IsLoaded()) CloseDriver();
}
//---------------------------------------------------------------------------
// Paint()
// Paints our little icon
//---------------------------------------------------------------------------
void __fastcall TDLPortIOX::Paint()
{
// The icon, as a BMP :-)
const BYTE Icon[] = {0x42, 0x4D, 0x22, 0x02, 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, 0xAC, 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, 0x00, 0x06, 0xF8, 0x70, 0x07, 0x00,
0x14, 0x77, 0x02, 0x78, 0x00, 0x00, 0x00, 0x06,
0xF8, 0x70, 0x07, 0x00, 0x14, 0x77, 0x02, 0x78,
0x00, 0x00, 0x00, 0x06, 0xF8, 0x70, 0x00, 0x00,
0x14, 0x77, 0x02, 0x78, 0x00, 0x00, 0x00, 0x04,
0xF8, 0x78, 0x0C, 0x00, 0x02, 0x07, 0x08, 0x77,
0x02, 0x78, 0x00, 0x00, 0x00, 0x06, 0xF8, 0x87,
0x80, 0x00, 0x0C, 0x00, 0x08, 0x77, 0x02, 0x78,
0x00, 0x00, 0x02, 0xF0, 0x0A, 0x88, 0x00, 0x10,
0x87, 0x77, 0x00, 0x07, 0x77, 0x77, 0x77, 0x78,
0x00, 0x00, 0x00, 0x06, 0xF7, 0x00, 0x08, 0x00,
0x08, 0x88, 0x00, 0x0E, 0x87, 0x70, 0x07, 0x77,
0x77, 0x77, 0x78, 0x00, 0x00, 0x00, 0x02, 0xF7,
0x0C, 0x77, 0x00, 0x0E, 0x78, 0x80, 0x07, 0x77,
0x77, 0x77, 0x78, 0x00, 0x00, 0x00, 0x02, 0xF7,
0x0C, 0x77, 0x00, 0x0E, 0x78, 0x80, 0x07, 0x77,
0x77, 0x77, 0x78, 0x00, 0x00, 0x00, 0x02, 0xF7,
0x0C, 0x77, 0x00, 0x0E, 0x78, 0x88, 0x00, 0x77,
0x77, 0x77, 0x78, 0x00, 0x00, 0x00, 0x02, 0xF7,
0x0C, 0x77, 0x00, 0x0E, 0x78, 0x88, 0x80, 0x07,
0x77, 0x77, 0x78, 0x00, 0x00, 0x00, 0x02, 0xF7,
0x0C, 0x77, 0x00, 0x0E, 0x70, 0x00, 0x00, 0x07,
0x77, 0x77, 0x78, 0x00, 0x00, 0x00, 0x02, 0xF7,
0x0C, 0x77, 0x08, 0x00, 0x00, 0x06, 0x77, 0x77,
0x78, 0x00, 0x00, 0x00, 0x02, 0xF7, 0x0A, 0x77,
0x00, 0x10, 0x70, 0xFF, 0x88, 0x88, 0x80, 0x77,
0x77, 0x78, 0x00, 0x00, 0x02, 0xF7, 0x0A, 0x77,
0x00, 0x10, 0x70, 0xFF, 0x77, 0x77, 0x70, 0x07,
0x77, 0x78, 0x00, 0x00, 0x02, 0xF7, 0x08, 0x77,
0x00, 0x04, 0x78, 0xFF, 0x08, 0x77, 0x00, 0x06,
0x80, 0x77, 0x78, 0x00, 0x00, 0x00, 0x02, 0xF7,
0x08, 0x77, 0x00, 0x04, 0x78, 0xFF, 0x08, 0x77,
0x00, 0x06, 0x80, 0x07, 0x78, 0x00, 0x00, 0x00,
0x02, 0xF7, 0x08, 0x77, 0x00, 0x04, 0x78, 0xFF,
0x08, 0x77, 0x00, 0x06, 0x80, 0x07, 0x78, 0x00,
0x00, 0x00, 0x02, 0xF7, 0x08, 0x77, 0x00, 0x04,
0x78, 0xFF, 0x08, 0x77, 0x00, 0x06, 0x80, 0x07,
0x78, 0x00, 0x00, 0x00, 0x02, 0xF7, 0x08, 0x77,
0x00, 0x04, 0x78, 0xFF, 0x08, 0x77, 0x00, 0x06,
0x80, 0x07, 0x78, 0x00, 0x00, 0x00, 0x02, 0xF7,
0x08, 0x77, 0x00, 0x04, 0x78, 0xFF, 0x08, 0x77,
0x00, 0x06, 0x80, 0x07, 0x78, 0x00, 0x00, 0x00,
0x00, 0x0C, 0xF7, 0x77, 0x77, 0x77, 0x78, 0xFF,
0x0A, 0x77, 0x00, 0x06, 0x78, 0x80, 0x78, 0x00,
0x00, 0x00, 0x00, 0x0C, 0xF7, 0x77, 0x77, 0x77,
0x78, 0xFF, 0x0A, 0x77, 0x00, 0x06, 0x78, 0x80,
0x08, 0x00, 0x00, 0x00, 0x00, 0x0A, 0xF7, 0x77,
0x77, 0x77, 0x78, 0x00, 0x0E, 0xFF, 0x00, 0x04,
0xF0, 0x08, 0x00, 0x00, 0x00, 0x0A, 0xF7, 0x77,
0x77, 0x77, 0x78, 0x00, 0x0E, 0xFF, 0x00, 0x04,
0xF0, 0x08, 0x00, 0x00, 0x02, 0xF7, 0x08, 0x77,
0x00, 0x12, 0x7B, 0xB3, 0x3B, 0xB3, 0x3B, 0xB8,
0x8B, 0xB7, 0x78, 0x00, 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, 546);
Buffer->Seek(0, soFromBeginning);
Bitmap->LoadFromStream(Buffer);
Canvas->Draw(0, 0, Bitmap);
delete Bitmap;
delete Buffer;
}
//---------------------------------------------------------------------------
// ConnectSCM()
// Connects to the WinNT Service Control Manager
//---------------------------------------------------------------------------
bool TDLPortIOX::ConnectSCM()
{
DWORD dwStatus = 0; // Assume success, until we prove otherwise
DWORD scAccess; // Access mode when connecting to SCM
// Try and connect as administrator
scAccess = SC_MANAGER_CONNECT |
SC_MANAGER_QUERY_LOCK_STATUS |
SC_MANAGER_ENUMERATE_SERVICE |
SC_MANAGER_CREATE_SERVICE; // Admin only
// Connect to the SCM
hSCMan = OpenSCManager(NULL, NULL, scAccess);
// If we're not in administrator mode, try and reconnect
if (hSCMan==NULL && GetLastError()==ERROR_ACCESS_DENIED)
{
scAccess = SC_MANAGER_CONNECT |
SC_MANAGER_QUERY_LOCK_STATUS |
SC_MANAGER_ENUMERATE_SERVICE;
// Connect to the SCM
hSCMan = OpenSCManager(NULL, NULL, scAccess);
}
// Did it succeed?
if (hSCMan==NULL)
{
// Failed, save error information
dwStatus=GetLastError();
FLastError="ConnectSCM: Error #"+IntToStr(dwStatus);
}
return dwStatus==0; // Success == 0
}
//---------------------------------------------------------------------------
// DisconnectSCM()
// Disconnects from the WinNT Service Control Manager
//---------------------------------------------------------------------------
void TDLPortIOX::DisconnectSCM()
{
if (hSCMan != NULL)
{
// Disconnect from our local Service Control Manager
CloseServiceHandle(hSCMan);
hSCMan=NULL;
}
}
//---------------------------------------------------------------------------
// DriverInstall()
// Installs the DriverLINX driver into Windows NT's registry
//---------------------------------------------------------------------------
bool TDLPortIOX::DriverInstall()
{
SC_HANDLE hService; // Handle to the new service
DWORD dwStatus = 0; // Assume success, until we prove otherwise
FDrvPrevInst=false; // Assume the driver wasn't installed previously
// Path including filename
AnsiString DriverPath = FDriverPath+"\\"+DRIVER_NAME+".SYS";
// Is the DriverLINX driver already in the SCM? If so,
// indicate success and set FDrvPrevInst to true.
hService=OpenService(hSCMan, DRIVER_NAME.c_str(), SERVICE_QUERY_STATUS);
if (hService!=NULL)
{
FDrvPrevInst=true; // Driver previously installed, don't remove
CloseServiceHandle(hService); // Close the service
return true; // Success
}
// Add to our Service Control Manager's database
hService=CreateService(
hSCMan,
DRIVER_NAME.c_str(),
DISPLAY_NAME.c_str(),
SERVICE_START | SERVICE_STOP | DELETE | SERVICE_QUERY_STATUS,
SERVICE_KERNEL_DRIVER,
SERVICE_DEMAND_START,
SERVICE_ERROR_NORMAL,
DriverPath.c_str(),
DRIVER_GROUP.c_str(),
NULL, NULL, NULL, NULL);
if (hService==NULL)
dwStatus=GetLastError();
else
// Close the service for now...
CloseServiceHandle(hService);
if (dwStatus!=0)
FLastError="DriverInstall: Error #"+IntToStr(dwStatus);
return dwStatus==0; // Success == 0
}
//---------------------------------------------------------------------------
// DriverStart()
// Starts the Windows NT DriverLINX driver for use
//---------------------------------------------------------------------------
bool TDLPortIOX::DriverStart()
{
SC_HANDLE hService; // Handle to the service to start
DWORD dwStatus = 0; // Assume success, until we prove otherwise
SERVICE_STATUS sStatus;
FDrvPrevStart=false; // Assume the driver was not already running
hService = OpenService(hSCMan, DRIVER_NAME.c_str(), SERVICE_QUERY_STATUS);
if (hService!=NULL && QueryServiceStatus(hService, &sStatus))
{
// Got the service status, now check it
if (sStatus.dwCurrentState==SERVICE_RUNNING)
{
FDrvPrevStart=true; // Driver was previously started
CloseServiceHandle(hService); // Close service
return true; // Success
}
else if (sStatus.dwCurrentState==SERVICE_STOPPED)
{
// Driver was stopped. Start the driver.
CloseServiceHandle(hService);
hService = OpenService(hSCMan, DRIVER_NAME.c_str(), SERVICE_START);
if (!StartService(hService, 0, NULL))
dwStatus=GetLastError();
CloseServiceHandle(hService); // Close service
}
else dwStatus=-1; // Can't run the service
}
else
dwStatus=GetLastError();
if (dwStatus!=0)
FLastError="DriverStart: Error #"+IntToStr(dwStatus);
return dwStatus==0; // Success == 0
}
//---------------------------------------------------------------------------
// DriverStop()
// Stops a Windows NT driver from use
//---------------------------------------------------------------------------
bool TDLPortIOX::DriverStop()
{
SC_HANDLE hService; // Handle to the service to start
DWORD dwStatus = 0; // Assume success, until we prove otherwise
// If we didn't start the driver, then don't stop it.
// Pretend we stopped it, by indicating success.
if (FDrvPrevStart) return true;
// Get a handle to the service to stop
hService = OpenService(
hSCMan,
DRIVER_NAME.c_str(),
SERVICE_STOP | SERVICE_QUERY_STATUS);
if (hService!=NULL)
{
// Stop the driver, then close the service
SERVICE_STATUS sStatus;
if (!ControlService(hService, SERVICE_CONTROL_STOP, &sStatus))
dwStatus = GetLastError();
// Close the service
CloseServiceHandle(hService);
}
else
dwStatus = GetLastError();
if (dwStatus!=0)
FLastError="DriverStop: Error #"+IntToStr(dwStatus);
return dwStatus==0; // Success == 0
}
//---------------------------------------------------------------------------
// DriverRemove()
// Removes a driver from the Windows NT system (service manager)
//---------------------------------------------------------------------------
bool TDLPortIOX::DriverRemove()
{
SC_HANDLE hService; // Handle to the service to start
DWORD dwStatus = 0; // Assume success, until we prove otherwise
// If we didn't install the driver, then don't remove it.
// Pretend we removed it, by indicating success.
if (FDrvPrevInst) return true;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -