使用WDM驱动实现在NT下读取物理端口,特殊寄存器,物理内存的代码(C++驱动加载代码)

驱动写好后,要在应用程序中调用驱动还需要自己写一个驱动加载器,

以下代码能够实现在Windows中加载驱动到系统中,并能调用驱动的I/O例程。

编译成功后,把驱动sys文件与此代码编译好的exe放同一个目录。

 

cpp源文件:

#include "libmio.h"

using namespace std;

CLibmio::CLibmio(void) throw (CLibmioException) :
  m_hDriver(INVALID_HANDLE_VALUE)
{
  OSVERSIONINFO 
    osv;
  
  // check the os whether support this driver.
  osv.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
  ::GetVersionEx(&osv);
  if ( osv.dwPlatformId != VER_PLATFORM_WIN32_NT )
    throw new CLibmioException(ERR_OS_NOT_SUPPORT);

  const char
    * pChar = NULL;

  // get the file path of driver.
  ::GetModuleFileName(NULL, szDriverPath, MAX_PATH);
  pChar = ::strrchr(szDriverPath, '\\');
  if ( !pChar )
    throw new CLibmioException(ERR_DRIVER_NOT_FOUND);

  ::strcpy(const_cast<char*>(++pChar), DRIVER_FILE);
    
  WIN32_FIND_DATA 
    finddata;

  HANDLE 
    hFindDriver = ::FindFirstFile(szDriverPath, &finddata);
  
  // confirm the file path is exist.
  if ( hFindDriver == INVALID_HANDLE_VALUE )
    throw new CLibmioException(ERR_DRIVER_NOT_FOUND);
  ::FindClose(hFindDriver);

  // open the driver
  if ( !OpenDriver() )
  {
    // stop and uninstall the driver.
    StopDriver();
    UninstallDriver();

    // install the driver.
    if ( !InstalDriver() )
      throw new CLibmioException(ERR_DRIVER_INSTALL_FAIL);

    // startup the driver.
    if ( !StartDriver() )
      throw new CLibmioException(ERR_DRIVER_START_FAIL);

    // open the driver.
    if ( !OpenDriver() )
      throw new CLibmioException(ERR_DRIVER_OPEN_FAIL);
  }
}

CLibmio::~CLibmio(void)
{ 
  bool 
    bUns = CanUninstall();
  CloseDriver();
  
  if ( bUns )
  {
    StopDriver();
    UninstallDriver();
  }
}

bool CLibmio::InstalDriver(void)
{
  SC_HANDLE 
    hSCManager,
    hService;

  hSCManager = ::OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
  if ( hSCManager == NULL )
    return false;
    
  hService = ::CreateService(
    hSCManager,
    DRIVER_NAME,
    DRIVER_NAME,
    SERVICE_ALL_ACCESS,
    SERVICE_KERNEL_DRIVER,
    SERVICE_DEMAND_START,
    SERVICE_ERROR_NORMAL,
    szDriverPath,
    NULL, NULL, NULL, NULL, NULL);
  ::CloseServiceHandle(hSCManager);
  
  if ( hService == NULL )
    return false;
  ::CloseServiceHandle(hService);
  
  return true;
}

bool CLibmio::StartDriver(void)
{
  SC_HANDLE 
    hSCManager,
    hService;
    
  bool 
    bResult = false;

  hSCManager = ::OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
  if ( hSCManager == NULL )
    return bResult;
  hService = ::OpenService(hSCManager, DRIVER_NAME, SERVICE_ALL_ACCESS);
  ::CloseServiceHandle(hSCManager);
  if ( hService == NULL )
    return bResult;
  #pragma warning(disable:4800)
  bResult = ::StartService(hService, 0, NULL) || GetLastError() == ERROR_SERVICE_ALREADY_RUNNING;
  ::CloseServiceHandle(hService);
  
  return bResult;
}

bool CLibmio::OpenDriver(void)
{
  m_hDriver = ::CreateFile(
    DEVICE_PATH, GENERIC_READ | GENERIC_WRITE,
    FILE_SHARE_READ | FILE_SHARE_WRITE,
    NULL, OPEN_EXISTING,
    FILE_ATTRIBUTE_NORMAL, NULL);
  return (m_hDriver != INVALID_HANDLE_VALUE);
}

bool CLibmio::CanUninstall(void)
{
  if ( m_hDriver == INVALID_HANDLE_VALUE )
    return true;
    
  DWORD 
    dwBytes = 0,
    dwRef = 0;
  
  if ( !::DeviceIoControl(
       m_hDriver,
       IOCTL_GET_REFCOUNT,
       NULL,
       0,
       &dwRef,
       sizeof(DWORD),
       &dwBytes,
       NULL) )
    return false;
  return (dwRef < 2);
}

void CLibmio::CloseDriver(void)
{
  if ( m_hDriver != INVALID_HANDLE_VALUE )
    ::CloseHandle(m_hDriver);
  m_hDriver = INVALID_HANDLE_VALUE;
}

bool CLibmio::UninstallDriver(void)
{
  SC_HANDLE 
    hSCManager,
    hService;
    
  bool 
    bResult = false;

  hSCManager = ::OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
  if ( hSCManager == NULL )
    return bResult;
  hService = ::OpenService(hSCManager, DRIVER_NAME, SERVICE_ALL_ACCESS);
  ::CloseServiceHandle(hSCManager);
  if ( hService == NULL )
    return bResult;
  #pragma warning(disable:4800)
  bResult = ::DeleteService(hService);
  ::CloseServiceHandle(hService);
  
  return bResult;
}

bool CLibmio::StopDriver(void)
{
  SERVICE_STATUS 
    ServiceStatus;

  SC_HANDLE 
    hSCManager,
    hService;
    
  bool 
    bResult = false;

  hSCManager = ::OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
  if ( hSCManager == NULL )
    return bResult;
  hService = ::OpenService(hSCManager, DRIVER_NAME, SERVICE_ALL_ACCESS);
  ::CloseServiceHandle(hSCManager);
  if ( hService == NULL )
    return bResult;
  #pragma warning(disable:4800)
  bResult = ::ControlService(hService, SERVICE_CONTROL_STOP, &ServiceStatus);
  ::CloseServiceHandle(hService);
  
  return bResult;
}

bool CLibmio::GetVersion(
    DWORD &dwVersion)
{
  if ( m_hDriver == INVALID_HANDLE_VALUE )
    return false;
    
  DWORD 
    dwBytes = 0;

  return 0 != ::DeviceIoControl(
    m_hDriver,
    IOCTL_GET_VERSION,
    NULL, 0,
    &dwVersion,
    sizeof(DWORD),
    &dwBytes,
    NULL);
}

bool CLibmio::GetVersionString(
    char *outString, 
    int length)
{
  DWORD 
    dwVersion = 0;
  
  if ( !outString )
    return false;
    
  if ( !GetVersion(dwVersion) )
    return false;
    
  BYTE
    vers[4];
  
  char
    szStr[18];
    
  ::memcpy(vers, &dwVersion, sizeof(DWORD));
  ::sprintf(szStr, "%d.%d.%d.%d", vers[3], vers[2], vers[1], vers[0]);
  if ( length > strlen(szStr) )
    length = strlen(szStr);
  ::strncpy(outString, szStr, length);
  
  return true;
}

bool CLibmio::Rdmsr(
    DWORD index, 
    ULARGE_INTEGER& out)
{
  if ( m_hDriver == INVALID_HANDLE_VALUE )
    return false;
    
  DWORD 
    dwBytes = 0; 

  return 0 != ::DeviceIoControl(
    m_hDriver,
    IOCTL_READ_MSR,
    &index,
    sizeof(index),
    &out,
    sizeof(out),
    &dwBytes,
    NULL);
}

bool CLibmio::Wrmsr(
    DWORD index, 
    ULARGE_INTEGER value)
{
  if ( m_hDriver == INVALID_HANDLE_VALUE )
    return false;
    
  DWORD 
    dwBytes = 0,
    buff[3];

  buff[0] = index;
  ::memcpy(&buff[1], &value, sizeof(value));
  
  return 0 != ::DeviceIoControl(
    m_hDriver,
    IOCTL_WRITE_MSR,
    buff,
    sizeof(buff),
    NULL,
    0,
    &dwBytes,
    NULL);
}

bool CLibmio::Rdpmc(
    DWORD index, 
    ULARGE_INTEGER& out)
{
  if ( m_hDriver == INVALID_HANDLE_VALUE )
    return false;
    
  DWORD 
    dwBytes = 0; 

  return 0 != ::DeviceIoControl(
    m_hDriver,
    IOCTL_READ_PMC,
    &index,
    sizeof(index),
    &out,
    sizeof(out),
    &dwBytes,
    NULL);
}

bool CLibmio::Inp(
    WORD port, 
    BYTE& out)
{
  if ( m_hDriver == INVALID_HANDLE_VALUE )
    return false;

  DWORD 
    dwBytes = 0;  

  out = 0;
  return 0 != ::DeviceIoControl(
    m_hDriver,
    IOCTL_READ_PORT,
    &port,
    sizeof(port),
    &out,
    sizeof(out),
    &dwBytes,
    NULL);
}

bool CLibmio::Inp(
    WORD port, 
    WORD& out)
{
  if ( m_hDriver == INVALID_HANDLE_VALUE )
    return false;

  DWORD 
    dwBytes = 0;

  out = 0;
  return 0 != ::DeviceIoControl(
    m_hDriver,
    IOCTL_READ_PORT,
    &port,
    sizeof(port),
    &out,
    sizeof(out),
    &dwBytes,
    NULL);
}

bool CLibmio::Inp(
    WORD port, 
    DWORD& out)
{
  if ( m_hDriver == INVALID_HANDLE_VALUE )
    return false;

  DWORD 
    dwBytes = 0; 

  out = 0;
  return 0 != ::DeviceIoControl(
    m_hDriver,
    IOCTL_READ_PORT,
    &port,
    sizeof(port),
    &out,
    sizeof(out),
    &dwBytes,
    NULL);
}

bool CLibmio::Outp(
    WORD port, 
    BYTE data)
{
  if ( m_hDriver == INVALID_HANDLE_VALUE )
    return false;
    
  WORD 
    buff[2];
  DWORD 
    dwBytes = 0;

  buff[0] = port;
  buff[1] = data;
  
  return 0 != ::DeviceIoControl(
    m_hDriver,
    IOCTL_WRITE_PORT,
    buff,
    sizeof(port) + sizeof(data),
    NULL,
    0,
    &dwBytes,
    NULL);
}

bool CLibmio::Outp(
    WORD port, 
    WORD data)
{
  if ( m_hDriver == INVALID_HANDLE_VALUE )
    return false;
    
  WORD 
    buff[2];
  DWORD 
    dwBytes = 0;

  buff[0] = port;
  buff[1] = data;
  
  return 0 != ::DeviceIoControl(
    m_hDriver,
    IOCTL_WRITE_PORT,
    buff,
    sizeof(port) + sizeof(data),
    NULL,
    0,
    &dwBytes,
    NULL);
}

bool CLibmio::Outp(
    WORD port, 
    DWORD data)
{
  if ( m_hDriver == INVALID_HANDLE_VALUE )
    return false;

  WORD 
    buff[3];
  DWORD 
    dwBytes = 0; 
    
  buff[0] = port;
  *((DWORD*)&buff[1]) = data;
  
  return 0 != ::DeviceIoControl(
    m_hDriver,
    IOCTL_WRITE_PORT,
    buff,
    sizeof(port) + sizeof(data),
    NULL,
    0,
    &dwBytes,
    NULL);
}

bool CLibmio::ReadPort(
    WORD port, 
    BYTE& out)
{
  if ( m_hDriver == INVALID_HANDLE_VALUE )
    return false;

  DWORD 
    dwBytes = 0; 

  out = 0;
  return 0 != ::DeviceIoControl(
    m_hDriver,
    IOCTL_READ_PORT_BYTE,
    &port,
    sizeof(port),
    &out,
    sizeof(out),
    &dwBytes,
    NULL);
}

bool CLibmio::ReadPort(
    WORD port, 
    WORD& out)
{
  if ( m_hDriver == INVALID_HANDLE_VALUE )
    return false;

  DWORD 
    dwBytes = 0; 

  out = 0;
  return 0 != ::DeviceIoControl(
    m_hDriver,
    IOCTL_READ_PORT_WORD,
    &port,
    sizeof(port),
    &out,
    sizeof(out),
    &dwBytes,
    NULL);
}

bool CLibmio::ReadPort(
    WORD port, 
    DWORD& out)
{
  if ( m_hDriver == INVALID_HANDLE_VALUE )
    return false;

  DWORD 
    dwBytes = 0; 

  out = 0;
  return 0 != ::DeviceIoControl(
    m_hDriver,
    IOCTL_READ_PORT_DWORD,
    &port,
    sizeof(port),
    &out,
    sizeof(out),
    &dwBytes,
    NULL);
}

bool CLibmio::WritePort(
    WORD port, 
    BYTE data)
{
  if ( m_hDriver == INVALID_HANDLE_VALUE )
    return false;

  DWORD 
    dwBytes = 0,
    buff[2];
    
  buff[0] = port;
  buff[1] = data;
  
  return 0 != ::DeviceIoControl(
    m_hDriver,
    IOCTL_WRITE_PORT_BYTE,
    buff,
    sizeof(buff),
    NULL,
    0,
    &dwBytes,
    NULL);
}

bool CLibmio::WritePort(
    WORD port, 
    WORD data)
{
  if ( m_hDriver == INVALID_HANDLE_VALUE )
    return false;

  DWORD 
    dwBytes = 0,
    buff[2];
    
  buff[0] = port;
  buff[1] = data;
  
  return 0 != ::DeviceIoControl(
    m_hDriver,
    IOCTL_WRITE_PORT_WORD,
    buff,
    sizeof(buff),
    NULL,
    0,
    &dwBytes,
    NULL);
}

bool CLibmio::WritePort(
    WORD port, 
    DWORD data)
{
  if ( m_hDriver == INVALID_HANDLE_VALUE )
    return false;

  DWORD 
    dwBytes = 0,
    buff[2];
    
  buff[0] = port;
  buff[1] = data;
  
  return 0 != ::DeviceIoControl(
    m_hDriver,
    IOCTL_WRITE_PORT_DWORD,
    buff,
    sizeof(buff),
    NULL,
    0,
    &dwBytes,
    NULL);
}

bool CLibmio::PciReadConfig(
    DWORD addr, 
    DWORD offset, 
    LPVOID out, 
    DWORD cbSize)
{
  return PciReadConfig((addr >> 8) & 0xff, (addr >> 3) & 0x1f, addr & 0x7, offset, out, cbSize);
}

bool CLibmio::PciReadConfig(
    WORD bus, 
    WORD dev, 
    WORD fun, 
    DWORD offset, 
    LPVOID out, 
    DWORD cbSize)
{
  if ( m_hDriver == INVALID_HANDLE_VALUE )
    return false;

  DWORD 
    dwBytes = 0,
    buff[3];
    
  buff[0] = bus;
  buff[1] = (fun << 5) | (dev & 0x1f);
  buff[2] = offset;
  
  ::RtlZeroMemory(out, cbSize);
  
  return 0 != ::DeviceIoControl(
    m_hDriver,
    IOCTL_PCI_READ_CONFIG,
    buff,
    sizeof(buff),
    out,
    cbSize,
    &dwBytes,
    NULL);
}

bool CLibmio::PciWriteConfig(
    DWORD addr, 
    DWORD offset, 
    LPVOID out, 
    DWORD cbSize)
{
  return PciWriteConfig((addr >> 8) & 0xff, (addr >> 3) & 0x1f, addr & 0x7, offset, out, cbSize);
}

bool CLibmio::PciWriteConfig(
    WORD bus, 
    WORD dev, 
    WORD fun, 
    DWORD offset, 
    LPVOID out, 
    DWORD cbSize)
{
  if ( m_hDriver == INVALID_HANDLE_VALUE )
    return false;

  DWORD 
    dwBytes = 0,
    dwSize = 0,
    * pBuff;
  
  bool 
    result = false;
    
  dwSize = cbSize + 0x10;
  pBuff = reinterpret_cast<DWORD*>(new BYTE[dwSize]);
  
  pBuff[0] = bus;
  pBuff[1] = (fun << 5) | (dev & 0x1f);
  pBuff[2] = offset;
  pBuff[3] = cbSize;
  
  ::RtlMoveMemory(&pBuff[4], out, cbSize);
  
  result = 0 != ::DeviceIoControl(
    m_hDriver,
    IOCTL_PCI_WRITE_CONFIG,
    pBuff,
    dwSize,
    NULL,
    0,
    &dwBytes,
    NULL);
  
  delete []pBuff;
  
  return result;
}

LPVOID CLibmio::MapPhyMemory(
    LPVOID addr, 
    DWORD cbSize)
{
  if ( m_hDriver == INVALID_HANDLE_VALUE )
    return NULL;
  
  if ( !cbSize )
    return false;

  DWORD 
    dwBytes = 0,
    buff[2];
  
  LPVOID
    out = NULL;

  buff[0] = reinterpret_cast<DWORD>(addr);
  buff[1] = cbSize;
  
  if ( !::DeviceIoControl(
    m_hDriver,
    IOCTL_MAP_PHY_MEMORY,
    buff,
    sizeof(buff),
    &out,
    sizeof(out),
    &dwBytes,
    NULL) )
    return NULL;
    
  return out;
}

bool CLibmio::UnmapPhyMemory(
    LPVOID addr)
{
  if ( m_hDriver == INVALID_HANDLE_VALUE )
    return false;
  
  if ( !addr )
    return false;

  DWORD 
    dwBytes = 0;
  
  return 0 != ::DeviceIoControl(
    m_hDriver,
    IOCTL_UNMAP_PHY_MEMORY,
    &addr,
    sizeof(LPVOID),
    NULL,
    0,
    &dwBytes,
    NULL);
}

bool CLibmio::ReadPhyMemory(
    LPVOID addr, 
    LPVOID buffer, 
    DWORD cbSize)
{
  if ( m_hDriver == INVALID_HANDLE_VALUE )
    return false;
  
  if ( !buffer )
    return false;
  
  if ( !cbSize )
    return false;

  DWORD 
    dwBytes = 0,
    buff[2];

  buff[0] = reinterpret_cast<DWORD>(addr);
  buff[1] = cbSize;
  
  return 0 != ::DeviceIoControl(
    m_hDriver,
    IOCTL_READ_PHY_MEMORY,
    buff,
    sizeof(buff),
    buffer,
    cbSize,
    &dwBytes,
    NULL);
}

bool CLibmio::WritePhyMemory(
    LPVOID addr, 
    LPVOID buffer, 
    DWORD cbSize)
{
  if ( m_hDriver == INVALID_HANDLE_VALUE )
    return false;
  
  if ( !buffer )
    return false;
  
  if ( !cbSize )
    return false;
  
  bool 
    result = false;

  DWORD 
    dwBytes = 0,
    dwSize = cbSize + 2 * sizeof(DWORD),
    * pBuff;

  pBuff = reinterpret_cast<DWORD*>(new BYTE[dwSize]);
  pBuff[0] = reinterpret_cast<DWORD>(addr);
  pBuff[1] = cbSize;
  
  ::RtlMoveMemory(&pBuff[2], buffer, cbSize);
  
  result = 0 != ::DeviceIoControl(
    m_hDriver,
    IOCTL_WRITE_PHY_MEMORY,
    pBuff,
    dwSize,
    NULL,
    0,
    &dwBytes,
    NULL);
  
  delete []pBuff;
  
  return result;
}


libmio.h中的部分内容:

class CLibmioException;

class CLibmio
{
public:
  CLibmio(void) throw (CLibmioException);
  virtual ~CLibmio(void);
  
  bool GetVersion(DWORD &);
  bool GetVersionString(char *, int);
  
  bool Rdmsr(DWORD, ULARGE_INTEGER&);
  bool Wrmsr(DWORD, ULARGE_INTEGER);
  
  bool Rdpmc(DWORD, ULARGE_INTEGER&);
  
  bool Inp(WORD, BYTE&);
  bool Inp(WORD, WORD&);
  bool Inp(WORD, DWORD&);
  
  bool Outp(WORD, BYTE);
  bool Outp(WORD, WORD);
  bool Outp(WORD, DWORD);
  
  bool ReadPort(WORD, BYTE&);
  bool ReadPort(WORD, WORD&);
  bool ReadPort(WORD, DWORD&);
  
  bool WritePort(WORD, BYTE);
  bool WritePort(WORD, WORD);
  bool WritePort(WORD, DWORD);

  bool PciReadConfig(DWORD, DWORD, LPVOID, DWORD);
  bool PciReadConfig(WORD, WORD, WORD, DWORD, LPVOID, DWORD);

  bool PciWriteConfig(DWORD, DWORD, LPVOID, DWORD);
  bool PciWriteConfig(WORD, WORD, WORD, DWORD, LPVOID, DWORD);
  
  LPVOID MapPhyMemory(LPVOID, DWORD);
  bool UnmapPhyMemory(LPVOID);
  
  bool ReadPhyMemory(LPVOID, LPVOID, DWORD);
  bool WritePhyMemory(LPVOID, LPVOID, DWORD);
  
private:
  bool StartDriver(void);
  bool StopDriver(void);
  bool InstalDriver(void);
  bool UninstallDriver(void);
  
  bool CanUninstall(void);

  bool OpenDriver(void);
  void CloseDriver(void);
  
protected:
  HANDLE m_hDriver;
  char szDriverPath[MAX_PATH];

};


 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值