📄 directio.cpp
字号:
// DirectIO.cpp : CDirectIO 的实现
#include "stdafx.h"
#include "DirectIO.h"
#include ".\directio.h"
#define DEVICE_NAME_STRING L"ZNtPort"
#define IOPM_VERSION 110 // decimal
#define IOPM_TEST0 0123
#define IOPM_TEST1 1234
#define IOPM_TEST2 2345
// Device type -- in the "User Defined" range."
#define IOPMD_TYPE 0xF100 // used several places
// The IOCTL function codes from 0x800 to 0xFFF are for non-Microsoft use.
// LIOPM means "local I/O Permission Map" maintained by this driver.
//--------------------------
// Test functions
#define IOCTL_IOPMD_READ_TEST CTL_CODE(IOPMD_TYPE, 0x900, METHOD_BUFFERED, FILE_ANY_ACCESS ) // returns IOPM_TEST
#define IOCTL_IOPMD_READ_VERSION CTL_CODE(IOPMD_TYPE, 0x901, METHOD_BUFFERED, FILE_ANY_ACCESS ) // returns IOPM_VERSION
// Manipulate local IOPM
#define IOCTL_IOPMD_CLEAR_LIOPM CTL_CODE(IOPMD_TYPE, 0x910, METHOD_BUFFERED, FILE_ANY_ACCESS ) // set map to block perm on all I/O addresses
#define IOCTL_IOPMD_SET_LIOPM CTL_CODE(IOPMD_TYPE, 0x911, METHOD_BUFFERED, FILE_ANY_ACCESS ) // set a byte (8 ports-worth) in LIOPM
#define IOCTL_IOPMD_GET_LIOPMB CTL_CODE(IOPMD_TYPE, 0x912, METHOD_BUFFERED, FILE_ANY_ACCESS ) // get a byte from LIOPM (diagnostic)
#define IOCTL_IOPMD_GET_LIOPMA CTL_CODE(IOPMD_TYPE, 0x913, METHOD_BUFFERED, FILE_ANY_ACCESS ) // get entire array of current LIOPM
// Interact with kernel
#define IOCTL_IOPMD_ACTIVATE_KIOPM CTL_CODE(IOPMD_TYPE, 0x920, METHOD_BUFFERED, FILE_ANY_ACCESS ) // copy LIOPM to be active map
#define IOCTL_IOPMD_DEACTIVATE_KIOPM CTL_CODE(IOPMD_TYPE, 0x921, METHOD_BUFFERED, FILE_ANY_ACCESS ) // tell NT to forget map
#define IOCTL_IOPMD_QUERY_KIOPM CTL_CODE(IOPMD_TYPE, 0x922, METHOD_BUFFERED, FILE_ANY_ACCESS ) // get OS's IOPM into LIOPM?
// CDirectIO
const DISPID_IN=1;
const DISPID_OUT=2;
const DISPID_ENABLEPORTS=3;
const DISPID_DISABLEPORTS=4;
//const DISPID_GETERRORSTRING=5;
//const DISPID_GETSCRIPTFUNCTION=6;
//const DISPID_LOADSCRIPTRESOURCE=7;
//const DISPID_LOADSCRIPT=8;
//const DISPID_ADDSCRIPT=9;
//const DISPID_RUNPROCEDURE=10;
//const DISPID_EXECUTESTATEMENT=11;
STDMETHODIMP CDirectIO::GetIDsOfNames(
GUID* riid,
OLECHAR** rgszNames,
unsigned int cNames,
unsigned long lcid,
long* rgdispid)
{
USES_CONVERSION;
char* szAnsi=OLE2A(rgszNames[0]);
if(strnicmp("in",szAnsi,2)==0)
rgdispid[0]=DISPID_IN;
else if(strnicmp("Out",szAnsi,3)==0)
rgdispid[0]=DISPID_OUT;
else if(strnicmp("EnablePorts",szAnsi,11)==0)
rgdispid[0]=DISPID_ENABLEPORTS;
else if(strnicmp("DisablePorts",szAnsi,12)==0)
rgdispid[0]=DISPID_DISABLEPORTS;
/*else if(strnicmp("GetErrorString",szAnsi,8)==0)
rgdispid[0]=DISPID_GETERRORSTRING;
else if(strnicmp("GetScriptFunction",szAnsi,17)==0)
rgdispid[0]=DISPID_GETSCRIPTFUNCTION;
else if(strnicmp("LoadScriptResource",szAnsi,18)==0)
rgdispid[0]=DISPID_LOADSCRIPTRESOURCE;
else if(strnicmp("LoadScript",szAnsi,10)==0)
rgdispid[0]=DISPID_LOADSCRIPT;
else if(strnicmp("AddScript",szAnsi,9)==0)
rgdispid[0]=DISPID_ADDSCRIPT;
else if(strnicmp("RunProcedure",szAnsi,12)==0)
rgdispid[0]=DISPID_RUNPROCEDURE;
else if(strnicmp("ExecuteStatement",szAnsi,16)==0)
rgdispid[0]=DISPID_EXECUTESTATEMENT;*/
else
return (DISPID_UNKNOWN);
return S_OK;
}
STDMETHODIMP CDirectIO::Invoke(DISPID dispidMember,REFIID riid, LCID lcid, WORD wFlags,
DISPPARAMS * pdispparams, VARIANT * pvarResult,
EXCEPINFO * pexcepinfo, UINT * puArgErr)
{
int nIndex;
switch(dispidMember)
{
case DISPID_IN:
In(pdispparams->rgvarg[0],pvarResult);
break;
case DISPID_OUT:
Out(pdispparams->rgvarg[1],pdispparams->rgvarg[0]);
break;
case DISPID_ENABLEPORTS:
EnablePorts(pdispparams->rgvarg[1],pdispparams->rgvarg[0]);
break;
case DISPID_DISABLEPORTS:
DisablePorts(pdispparams->rgvarg[1],pdispparams->rgvarg[0]);
break;
//case DISPID_GETNAMEAT:
// nIndex=pdispparams->rgvarg[0].lVal ;
// if( nIndex>= 0 && nIndex < m_FunctionList.size())
// {
// stl_string_list::iterator iter = m_FunctionList.begin();
// while( nIndex > 0)
// {
// iter++;
// nIndex--;
// }
// USES_CONVERSION;
// pvarResult->bstrVal=T2OLE( (*iter).c_str());
// }
// else
// pvarResult->bstrVal=NULL;
// break;
//case DISPID_RESET:
// this->Reset();
// break;
//case DISPID_GETERRORSTRING:
// GetErrorString(pvarResult);
// break;
//case DISPID_GETSCRIPTFUNCTION:
// this->GetScriptFunction(pdispparams->rgvarg[0],pvarResult);
// break;
//case DISPID_LOADSCRIPTRESOURCE:
// this->LoadScriptResource(pdispparams->rgvarg[2],pdispparams->rgvarg[1],pdispparams->rgvarg[0],pvarResult);
// break;
//case DISPID_LOADSCRIPT:
// LoadScript(pdispparams->rgvarg[0],pvarResult);
// break;
//case DISPID_ADDSCRIPT:
// AddScript(pdispparams->rgvarg[0],pvarResult);
//case DISPID_RUNPROCEDURE:
// this->RunProcedure(pdispparams->rgvarg[2],pdispparams->rgvarg[1],&pdispparams->rgvarg[0],pvarResult);
// break;
//case DISPID_EXECUTESTATEMENT:
// ExecuteStatement(pdispparams->rgvarg[0],pvarResult);
// break;
}
return S_OK;
}
STDMETHODIMP CDirectIO::In(VARIANT vPort, VARIANT* pVal)
{
HRESULT hr=VariantChangeType(&vPort,&vPort,0,VT_UI2);
if (FAILED(hr)) {
return DISP_E_TYPEMISMATCH;
}
switch(pVal->vt) {
case VT_I1:
case VT_UI1:
{
char c;
_asm mov dx,vPort.uiVal
_asm in al,dx
_asm mov c,al
pVal->cVal=c;
}
break;
case VT_I2:
case VT_UI2:
{
WORD w;
_asm xor ax,ax
_asm mov dx,vPort.uiVal
_asm in al,dx
_asm mov w,ax
pVal->uiVal=w;
}
break;
case VT_I4:
case VT_UI4:
{
DWORD dw;
_asm xor eax,eax
_asm mov dx,vPort.uiVal
_asm in al,dx
_asm mov dw,eax
pVal->ulVal=dw;
}
default:
break;
}
return S_OK;
}
STDMETHODIMP CDirectIO::Out(VARIANT vPort, VARIANT vVal)
{
HRESULT hr=VariantChangeType(&vPort,&vPort,0,VT_UI2);
if (FAILED(hr)) {
return DISP_E_TYPEMISMATCH;
}
switch(vVal.vt) {
case VT_I1:
case VT_UI1:
_asm mov dx,vPort.uiVal
_asm mov al,vVal.cVal
_asm out dx,al
break;
case VT_I2:
case VT_UI2:
_asm mov dx,vPort.uiVal
_asm mov ax,vVal.uiVal
_asm out dx,al
break;
case VT_I4:
case VT_UI4:
_asm mov dx,vPort.uiVal
_asm mov eax,vVal.ulVal
_asm out dx,al
default:
break;
}
return S_OK;
}
STDMETHODIMP CDirectIO::EnablePorts(VARIANT vPortStart, VARIANT vEnableNum)
{
DWORD dw[3];
HRESULT hr=VariantChangeType(&vPortStart,&vPortStart,0,VT_UI4);
if (FAILED(hr)) {
return DISP_E_TYPEMISMATCH;
}
hr=VariantChangeType(&vEnableNum,&vEnableNum,0,VT_UI4);
if (FAILED(hr)) {
return DISP_E_TYPEMISMATCH;
}
dw[0]=vPortStart.ulVal;
dw[1]=0x00000000;
sc.WriteIo(IOCTL_IOPMD_QUERY_KIOPM,dw,sizeof dw );
for(int i=0;i<vEnableNum.ulVal;i++){
DWORD d;
d=dw[0];
dw[0]=dw[0]>>3;
sc.ReadIo(IOCTL_IOPMD_GET_LIOPMB,dw,sizeof dw);
dw[0]=d;
dw[0] %= 8;
int j=1;
dw[1]=dw[1] & (0xff-j<<dw[0]);
dw[0]=d>>3;
sc.WriteIo(IOCTL_IOPMD_SET_LIOPM,dw,sizeof dw );
dw[0]=d+1;
}
return S_OK;
}
STDMETHODIMP CDirectIO::DisablePorts(VARIANT vPortStart, VARIANT vDisableNum)
{
DWORD dw[3];
HRESULT hr=VariantChangeType(&vPortStart,&vPortStart,0,VT_UI4);
if (FAILED(hr)) {
return DISP_E_TYPEMISMATCH;
}
hr=VariantChangeType(&vDisableNum,&vDisableNum,0,VT_UI4);
if (FAILED(hr)) {
return DISP_E_TYPEMISMATCH;
}
dw[0]=vPortStart.ulVal;
dw[1]=0x00000000;
sc.WriteIo(IOCTL_IOPMD_QUERY_KIOPM,dw,sizeof dw );
for(int i=0;i<vDisableNum.ulVal;i++){
DWORD d;
d=dw[0];
dw[0]=dw[0]>>3;
sc.ReadIo(IOCTL_IOPMD_GET_LIOPMB,dw,sizeof dw);
dw[0]=d;
dw[0] %= 8;
int j=1;
dw[1]=dw[1] | (j<<dw[0]);
dw[0]=d>>3;
sc.WriteIo(IOCTL_IOPMD_SET_LIOPM,dw,sizeof dw );
dw[0]=d+1;
}
sc.WriteIo(IOCTL_IOPMD_CLEAR_LIOPM,dw,sizeof dw );
return S_OK;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -