⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tdlportiox.cpp

📁 自制多功能编程器
💻 CPP
📖 第 1 页 / 共 3 页
字号:
//*** 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 + -