📄 tdlportio.cpp
字号:
//*** TDLPortIO: DriverLINX Port IO Driver wrapper DLL ***********************
//** **
//** 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 <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <windows.h>
#pragma hdrstop
#include "TDLPortIO.h"
//---------------------------------------------------------------------------
// Constants
//---------------------------------------------------------------------------
// Masks
const unsigned char BIT0 = 0x01;
const unsigned char BIT1 = 0x02;
const unsigned char BIT2 = 0x04;
const unsigned char BIT3 = 0x08;
const unsigned char BIT4 = 0x10;
const unsigned char BIT5 = 0x20;
const unsigned char BIT6 = 0x40;
const unsigned char BIT7 = 0x80;
// Printer Port pin numbers
const ACK_PIN = 10;
const BUSY_PIN = 11;
const PAPEREND_PIN = 12;
const SELECTOUT_PIN = 13;
const ERROR_PIN = 15;
const STROBE_PIN = 1;
const AUTOFD_PIN = 14;
const INIT_PIN = 16;
const SELECTIN_PIN = 17;
// DriverLINX DLL filename
const char* LIBRARY_FILENAME = "DLPortIO.dll";
// WinNT DriverLINX Information
const char* DRIVER_NAME = "DLPortIO";
const char* DISPLAY_NAME = "DriverLINX Port I/O Driver";
const char* DRIVER_GROUP = "SST miniport drivers";
// Maximum length of the LastError string
const MAX_LEN = 100;
//---------------------------------------------------------------------------
// Compilation option
//---------------------------------------------------------------------------
// Define if you want a bit less error-checking when reading/writing the
// ports -- i.e. do not check that the driver is open; assume it is.
#define FAST
//---------------------------------------------------------------------------
// DLL Import Types
// Pointer to functions, to dynamically link into the DLL
//---------------------------------------------------------------------------
typedef unsigned char UCHAR; // BYTE
typedef unsigned short USHORT; // WORD
typedef unsigned long ULONG; // DWORD
typedef UCHAR (__stdcall *TDlPortReadPortUchar)(ULONG Port);
typedef USHORT (__stdcall *TDlPortReadPortUshort)(ULONG Port);
typedef ULONG (__stdcall *TDlPortReadPortUlong)(ULONG Port);
typedef void (__stdcall *TDlPortWritePortUchar)(ULONG Port, UCHAR Value);
typedef void (__stdcall *TDlPortWritePortUshort)(ULONG Port, USHORT Value);
typedef void (__stdcall *TDlPortWritePortUlong)(ULONG Port, ULONG Value);
typedef void (__stdcall *TDlPortReadPortBufferUchar)(ULONG Port, UCHAR *Buffer, ULONG Count);
typedef void (__stdcall *TDlPortReadPortBufferUshort)(ULONG Port, USHORT *Buffer, ULONG Count);
typedef void (__stdcall *TDlPortReadPortBufferUlong)(ULONG Port, ULONG *Buffer, ULONG Count);
typedef void (__stdcall *TDlPortWritePortBufferUchar)(ULONG Port, UCHAR *Buffer, ULONG Count);
typedef void (__stdcall *TDlPortWritePortBufferUshort)(ULONG Port, USHORT *Buffer, ULONG Count);
typedef void (__stdcall *TDlPortWritePortBufferUlong)(ULONG Port, ULONG *Buffer, ULONG Count);
//---------------------------------------------------------------------------
// Global variables internal to DLL
// These are equivalent to the instance variables of the component classes
//---------------------------------------------------------------------------
bool FActiveHW; // Is the DLL loaded?
bool FHardAccess; // Not used: for compatibility only
bool FRunningWinNT; // True when we're running Windows NT
HINSTANCE FDLLInst; // For use with DLL
SC_HANDLE hSCMan; // For use with WinNT Service Control Manager
char FDriverPath[MAX_PATH]; // Full path of WinNT driver
char FDLLPath[MAX_PATH]; // Full path of DriverLINX DLL
char FLastError[MAX_LEN]; // Last error which occurred in Open/CloseDriver()
// Used for the Windows NT version only
bool FDrvPrevInst; // DriverLINX driver already installed?
bool FDrvPrevStart; // DriverLINX driver already running?
// Pointers to the functions within the DLL
TDlPortReadPortUchar DlReadByte;
TDlPortReadPortUshort DlReadWord;
TDlPortReadPortUlong DlReadDWord;
TDlPortWritePortUchar DlWriteByte;
TDlPortWritePortUshort DlWriteWord;
TDlPortWritePortUlong DlWriteDWord;
TDlPortReadPortBufferUchar DlReadBufferByte;
TDlPortReadPortBufferUshort DlReadBufferWord;
TDlPortReadPortBufferUlong DlReadBufferDWord;
TDlPortWritePortBufferUchar DlWriteBufferByte;
TDlPortWritePortBufferUshort DlWriteBufferWord;
TDlPortWritePortBufferUlong DlWriteBufferDWord;
// For the extended LPT functions
BYTE FLPTNumber; // Current number of the printer port, default=1
WORD FLPTBase; // The address of the current printer port (faster)
int FLPTCount; // Number of LPT ports on the system
WORD FLPTAddress[MAX_LPT_PORTS+1];
// List of port addresses installed on the system
//---------------------------------------------------------------------------
// Prototypes not in header file
//---------------------------------------------------------------------------
void _export __stdcall DetectPorts();
void _export __stdcall DetectPorts9x();
void _export __stdcall DetectPortsNT();
//---------------------------------------------------------------------------
// DllEntryPoint()
// Sets up default values within DLL
//---------------------------------------------------------------------------
int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void*)
{
// 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
GetSystemDirectory(FDriverPath, MAX_PATH);
strcat(FDriverPath, "\\DRIVERS");
// Set the default DLL path (to null)
strcpy(FDLLPath, "");
FActiveHW=false; // DLL/Driver not loaded
FHardAccess=true; // Not used, default true
// No errors yet
strcpy(FLastError, "");
//** Set up the Printer Port stuff
// Detect the printer ports available
DetectPorts();
// Set the default LPT number
SetLPTNumber(1);
return 1; // Success
}
//---------------------------------------------------------------------------
// ConnectSCM()
// Connects to the WinNT Service Control Manager
//---------------------------------------------------------------------------
bool __fastcall 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();
sprintf(FLastError, "ConnectSCM: Error #%d", dwStatus);
}
return dwStatus==0; // Success == 0
}
//---------------------------------------------------------------------------
// DisconnectSCM()
// Disconnects from the WinNT Service Control Manager
//---------------------------------------------------------------------------
void __fastcall DisconnectSCM()
{
if (hSCMan != NULL)
{
// Disconnect from our local Service Control Manager
CloseServiceHandle(hSCMan);
hSCMan=NULL;
}
}
//---------------------------------------------------------------------------
// DriverInstall()
// Installs a driver into Windows NT
//---------------------------------------------------------------------------
bool __fastcall 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
char DriverPath[MAX_PATH];
strcpy(DriverPath, FDriverPath);
strcat(DriverPath, "\\");
strcat(DriverPath, DRIVER_NAME);
strcat(DriverPath, ".SYS");
// Is the DriverLINX driver already in the SCM? If so,
// indicate success and set FDrvPrevInst to true.
hService=OpenService(hSCMan, DRIVER_NAME, 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,
DISPLAY_NAME,
SERVICE_START | SERVICE_STOP | DELETE | SERVICE_QUERY_STATUS,
SERVICE_KERNEL_DRIVER,
SERVICE_DEMAND_START,
SERVICE_ERROR_NORMAL,
DriverPath,
DRIVER_GROUP,
NULL, NULL, NULL, NULL);
if (hService==NULL)
dwStatus=GetLastError();
else
// Close the service for now...
CloseServiceHandle(hService);
if (dwStatus!=0)
sprintf(FLastError, "DriverInstall: Error #%d", dwStatus);
return dwStatus==0; // Success == 0
}
//---------------------------------------------------------------------------
// DriverStart()
// Starts a Windows NT driver for use
//---------------------------------------------------------------------------
bool __fastcall 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, 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, 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)
sprintf(FLastError, "DriverStart: Error #%d", dwStatus);
return dwStatus==0; // Success == 0
}
//---------------------------------------------------------------------------
// DriverStop()
// Stops a Windows NT driver from use
//---------------------------------------------------------------------------
bool __fastcall 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,
SERVICE_STOP | SERVICE_QUERY_STATUS);
if (hService!=NULL)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -