转载的透视降压

H 头文件

#ifndef __Cmd_Api__
#define __Cmd_Api__

#define WIN32_LEAN_AND_MEAN             //  从 Windows 头文件中排除极少使用的信息

#include <windows.h>
#include <stdio.h>

#define CN_PUB_Server_Ip "127.0.0.1"
#define CN_PUB_Server_Port 36868
#define CN_PUB_DEFHINT "未解析"
//
const char* CN_PUB_INI_Title = "Set";
const char* CN_PUB_INI_Host = "ServerHost";
const char* CN_PUB_INI_Port ="ServerPort";
//
#define CN_PUB_RES "CmdRes\\"
#define CN_PUB_CFGFILE "Cfg.ini"
#define CN_PUB_APINAME "CmdApi.dll"
//
const int CN_CMDBUFFSIZE  = 0x3000;
#define P_ERROR(Condition)  if (!(Condition)) goto Exit0;

//输出调试信息标志位
#define LOG_DBG 1
#if LOG_DBG
    #define CN_LOG_TAG "CmdPlugin   "
#endif

#pragma pack(push, 1)
    
//特殊Hook    堆栈保存结构
typedef struct _HookCodeExParam32
{
    DWORD dwEax, dwEbx, dwEcx, dwEdx, dwEsp, dwEbp, dwEsi, dwEdi;
}THookCodeExParam32,*PHookCodeExParam32;

//滤境解析结果
typedef struct _FilterRet
{
    bool bVis;
    bool bCom;
    char cName[128];
}TFilterRet,*PFilterRet;

//Init
typedef void (__stdcall *TCmdApiInit)(void* Param);
//UnInit
typedef void (__stdcall *TCmdApiUnInit)();
//特征码扫描
typedef unsigned int (__stdcall *TCmdApiMemSigScan)(char* cModName,char* cSigCode);
//CheckBox控制函数
typedef void (__stdcall *TMyCheckBoxProc)(bool bCheck);
//创建CheckBox
typedef bool (__stdcall *TCmdApiCreateCheckBox)(char* cCaption,TMyCheckBoxProc onClick,bool bCheck);
//滤镜解析
typedef bool (__stdcall *TCmdApiFilterOper)(char* pData,int iDataLen,unsigned char byOrd,PFilterRet pRet);
//写HexLog
typedef void (__stdcall *TCmdApiWriteLogProc)(char* sType,char* sTypeEx,char* pData,int iDataLen,int iSock);
//执行指令
typedef void (__stdcall *TCmdApiExecuteCmdProc)(char* sHexCmd);
//设置执行指令函数
typedef void (__stdcall *TCmdApiSetFunc_ExecuteCmd)(TCmdApiExecuteCmdProc pFunc);
//标准Hook
typedef void (__stdcall *TCmdApiHookCodeNormal)(void* CodeAdr,void* NewFunc,void* OldFunc);
//标准UnHook
typedef bool (__stdcall *TCmdApiUnHookCodeNormal)(void* nextHook);
//特殊Hook,直接寄存器操作,方便用于代码被VM的情况
typedef void* (__stdcall *TCmdApiHookCodeEx)(void* CodeAdr,void* NewFunc);
//特殊UnHook
typedef void (__stdcall *TCmdApiUnHookCodeEx)(void* OldFunc);
//设置发送Sock
typedef void (__stdcall *TCmdApiSetSendSock)(int iSock);
//获取设置的发送Sock
typedef int (__stdcall *TCmdApiGetSendSock)();
//判断是否是工具Sock
typedef bool (__stdcall *TCmdApiIsToolSock)(int iSock);

//
typedef struct _InitIO
{
    //Api接口
    typedef struct _CmdApi
    {
        char Path[MAX_PATH];
        HMODULE Handle;
        TCmdApiInit Init;
        TCmdApiUnInit UnInit;
        TCmdApiMemSigScan MemSigScan;
        TCmdApiCreateCheckBox CreateCheckBox;
        TCmdApiFilterOper FilterOper;
        TCmdApiWriteLogProc WriteLog;
        TCmdApiSetFunc_ExecuteCmd SetFunc_ExecuteCmd;
        TCmdApiHookCodeNormal HookCodeNormal;
        TCmdApiUnHookCodeNormal UnHookCodeNormal;
        TCmdApiHookCodeEx HookCodeEx;
        TCmdApiUnHookCodeEx UnHookCodeEx;
        TCmdApiSetSendSock SetSendSock;
        TCmdApiGetSendSock GetSendSock;
        TCmdApiIsToolSock IsToolSock;
    }TCmdApi,*PCmdApi;
    //工具所在目录
    char sPath[MAX_PATH];
    //控制端Ip
    char sIp[20];
    //控制端Port
    int iPort;
    TCmdApi Api;
}TInitIO,*PInitIO;

//API接口
TInitIO g_InitIO= {0};
//默认配置文件
char g_Cfg[MAX_PATH] = {0};
//用于获取存储模块自身句柄
HMODULE g_hModuleThisDll = 0;
//预留执行的buff
char g_ExecuteCmdBuff[CN_CMDBUFFSIZE] = {0};

#pragma pack(pop)

//记录调试信息
void LogDbg( char* fmt,... )
{
    #if LOG_DBG
        int         i = 0;
        char        output[0x200] = {0};
        try{    
            strcat_s(output,0x200,CN_LOG_TAG);
            va_list arg_ptr;
            va_start(arg_ptr, fmt);
            int iTagLen = strlen(CN_LOG_TAG);
            i = _vsnprintf_s(&output[iTagLen],0x200 - iTagLen,_TRUNCATE,fmt,arg_ptr);
            va_end(arg_ptr);
            OutputDebugStringA(output);
        }
        catch(...){
        }
    #else
    #endif
}

//初始化接口
bool CmdApiInit(PInitIO pIO)
{
    bool hRel = false;
    try{
        P_ERROR(pIO);
        memset(&pIO->Api,0,sizeof(pIO->Api));
        //生成库路径
        memcpy(&pIO->Api.Path,&pIO->sPath,sizeof(pIO->sPath));
        strcat_s(pIO->Api.Path,sizeof(pIO->Api.Path),CN_PUB_RES);
        strcat_s(pIO->Api.Path,sizeof(pIO->Api.Path),CN_PUB_APINAME);
        LogDbg("pIO->Api.Path: %s",pIO->Api.Path);
        //加载库,执行初始化
        pIO->Api.Handle = GetModuleHandleA(pIO->Api.Path);
        if (NULL == pIO->Api.Handle){
            pIO->Api.Handle = LoadLibrary(pIO->Api.Path);
        }
        LogDbg("pIO->Api.Handle: %.8X",pIO->Api.Handle);
        P_ERROR(pIO->Api.Handle);
        pIO->Api.Init = TCmdApiInit(GetProcAddress(pIO->Api.Handle, "Init"));
        P_ERROR(pIO->Api.Init);
        //初始化
        pIO->Api.Init(&g_InitIO);
        //判断接口
        P_ERROR(pIO->Api.UnInit);
        P_ERROR(pIO->Api.MemSigScan);
        P_ERROR(pIO->Api.CreateCheckBox);
        P_ERROR(pIO->Api.FilterOper);
        P_ERROR(pIO->Api.WriteLog);
        P_ERROR(pIO->Api.SetFunc_ExecuteCmd);
        P_ERROR(pIO->Api.HookCodeNormal);
        P_ERROR(pIO->Api.UnHookCodeNormal);
        P_ERROR(pIO->Api.HookCodeEx);
        P_ERROR(pIO->Api.UnHookCodeEx);
        P_ERROR(pIO->Api.SetSendSock);
        P_ERROR(pIO->Api.GetSendSock);
        P_ERROR(pIO->Api.IsToolSock);
        hRel = true;
    }
    catch(...){
    }
Exit0:
    return hRel;
}

//读配置文件
void Init_Cfg(const char*sToolPath)
{
    try{
        //配置文件
        memcpy(g_Cfg,sToolPath,strlen(sToolPath));
        strcat_s(g_Cfg,MAX_PATH,CN_PUB_CFGFILE);
        //读取Ip
        GetPrivateProfileString(CN_PUB_INI_Title,CN_PUB_INI_Host,CN_PUB_Server_Ip,g_InitIO.sIp,sizeof(g_InitIO.sIp),g_Cfg);
        //读取Port
        g_InitIO.iPort = GetPrivateProfileInt(CN_PUB_INI_Title,CN_PUB_INI_Port,CN_PUB_Server_Port,g_Cfg);
        //
        LogDbg("Init_Cfg %s %s %d",g_Cfg,g_InitIO.sIp,g_InitIO.iPort);
    }
    catch(...){
    }
}

void PathOper(char* cPath,int iLen,bool bFlag)
{
    for (int i = iLen - 1;i> -1;i--){
        if (0x5C == cPath[i]){
            if (bFlag){
                cPath[i] = 0;
            }
            break;
        }
        cPath[i] = 0;
    }
}

//获取工具路径
void GetToolPath(char* cPath,int iLen)
{
    try{
        if (NULL != cPath){
            GetModuleFileNameA(g_hModuleThisDll,cPath,iLen);
            PathOper(cPath,iLen,false);
            PathOper(cPath,iLen,true);
            PathOper(cPath,iLen,false);
            PathOper(cPath,iLen,true);
            PathOper(cPath,iLen,false);
        }
        LogDbg("g_hModuleThisDll: %.8X %s",g_hModuleThisDll,cPath);
    }
    catch (...){
    }   
}

//插件公用初始化函数
bool Init_Plugin_Pub()
{
    bool bRet = false;
    //获取工具所在目录  
    GetToolPath(g_InitIO.sPath,sizeof(g_InitIO.sPath));
    //读配置文件
    Init_Cfg(g_InitIO.sPath);
    //接口初始化
    if (CmdApiInit(&g_InitIO)){
        bRet = true;
    }
    return bRet;
}

//卸载插件
void UnInit_Plugin()
{
    LogDbg("UnInit_Plugin");
    g_InitIO.Api.UnInit();
    FreeLibrary(g_InitIO.Api.Handle);
}

#endif

#include "CmdApi.h"
#include"tlhelp32.h"
//相关头文件
#include"d3d9.h"
#pragma comment(lib, "d3d9.lib")
//
#define NAKED __declspec(naked) 
#define CN_D3D_Stride 50
#define D3D9DLLName "d3d9.dll"
#define Ini_App "D3D9"
#define Ini_Key_SearchBase "SearchBase"
#define Ini_Key_ParamType "ParamType"
#define Ini_Key_CpuSleep "CpuSleep"
#define Ini_Key_Stride "Stride"
#define Ini_Key_KeyBoardSwitch "KeyBoardSwitch"
#define Ini_Key_GameClass "GameClass"

//IDirect3DDevice9::DrawIndexedPrimitive method函数原型
typedef HRESULT (__stdcall *TDrawIndexedPrimitive)(LPDIRECT3DDEVICE9 pDevice,D3DPRIMITIVETYPE type,INT BaseVertexIndex,UINT MinVertexIndex,UINT NumVertices,UINT startIndex,UINT primCount);

//IDirect3DDevice9::Present method函数原型  
typedef HRESULT (__stdcall *TPresent)(LPDIRECT3DDEVICE9 pDevice,const RECT *pSourceRect,const RECT *pDestRect,HWND hDestWindowOverride,const RGNDATA *pDirtyRegion);

//
DWORD g_Adr_DrawIndexedPrimitive = 0;
TDrawIndexedPrimitive OldDrawIndexedPrimitive = NULL;
DWORD g_Oft_DrawIndexedPrimitive = (83 - 1)*4;

DWORD g_Param_DrawIndexedPrimitive = 0;
void* OldDrawIndexedPrimitiveParam = NULL;
//
DWORD g_Adr_Present = 0;
TPresent OldPresent = NULL;
DWORD g_Oft_Present = (18 - 1)*4;
//
//游戏窗口句柄
HWND g_Game_Hwnd = NULL;
//原窗口处理函数
WNDPROC g_OldlWindowProc = NULL;
bool g_KeyBoardSwitch = false;
int g_CpuSleep = 0;
DWORD g_Stride = 0;

//HookCodeEx方式获取参数
void __stdcall NewDrawIndexedPrimitiveParam(PHookCodeExParam32 pParam)
{
    try{
        if (0 == g_Param_DrawIndexedPrimitive){
            g_Param_DrawIndexedPrimitive = *(PDWORD)(pParam->dwEsp + 4);
            LogDbg("NewDrawIndexedPrimitiveParam %.8X %.8X %.8X",*(PDWORD)(pParam->dwEsp),g_Param_DrawIndexedPrimitive,*(PDWORD)(*(PDWORD)(g_Param_DrawIndexedPrimitive) + g_Oft_DrawIndexedPrimitive));
        }
    }
    catch (...){    
    }
}
void __stdcall HookDrawIndexedPrimitiveParam(bool bHook)
{
    if (bHook){ 
            OldDrawIndexedPrimitiveParam = g_InitIO.Api.HookCodeEx((void*)g_Adr_DrawIndexedPrimitive, &NewDrawIndexedPrimitiveParam);
    }
    else{
            g_InitIO.Api.UnHookCodeEx(OldDrawIndexedPrimitiveParam);
    }
}



//NewDrawIndexedPrimitive
HRESULT __stdcall NewDrawIndexedPrimitive(LPDIRECT3DDEVICE9 pDevice,D3DPRIMITIVETYPE type,INT BaseVertexIndex,UINT MinVertexIndex,UINT NumVertices,UINT startIndex,UINT primCount)
{
    HRESULT hRet = S_OK;
    IDirect3DVertexBuffer9* pStreamData = NULL;
    UINT iOffsetInBytes,iStride;
    if(D3D_OK == pDevice->GetStreamSource(0,&pStreamData,&iOffsetInBytes,&iStride)){
        pStreamData->Release();
    }
    if(iStride == g_Stride){
        pDevice->SetRenderState(D3DRS_ZENABLE,FALSE);//禁用Z轴缓冲
        hRet = OldDrawIndexedPrimitive(pDevice,type,BaseVertexIndex,MinVertexIndex,NumVertices,startIndex,primCount);
        pDevice->SetRenderState(D3DRS_ZENABLE,TRUE );//恢复Z轴缓冲
    }
    else{
        hRet = OldDrawIndexedPrimitive(pDevice,type,BaseVertexIndex,MinVertexIndex,NumVertices,startIndex,primCount);
    }
    return hRet;  
}


//输出调试的Stride值
void DrawDC()
{
    HDC TmpDc = GetDC(NULL);
    char aBuff[26] = {0};
    sprintf_s(aBuff,20,"Stride:%d   ",g_Stride);
    TextOut(TmpDc,0,0,aBuff,strlen(aBuff));
    ReleaseDC(NULL, TmpDc);
    LogDbg("%s",aBuff);
}

//窗口处理函数
LRESULT CALLBACK WindowProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
    if(WM_KEYDOWN == uMsg){
        if(VK_UP == wParam){
            g_Stride += 1;
            DrawDC();
        }
        if(VK_DOWN == wParam){
            g_Stride -= 1;
            DrawDC();
        }
    }
    return CallWindowProc(g_OldlWindowProc,hwnd,uMsg,wParam,lParam);
}

//窗口处理函数Hook
void __stdcall HookKeyBoard(bool bHook)
{
    if (g_KeyBoardSwitch){
        if (bHook){
            if (NULL == g_Game_Hwnd){
                char aBuff[256] = {0};
                GetPrivateProfileString(Ini_App,Ini_Key_GameClass,"",aBuff,sizeof(aBuff),g_Cfg);
                LogDbg("HookKeyBoard %s %s",Ini_Key_GameClass,aBuff);
                g_Game_Hwnd = ::FindWindowA(aBuff,NULL);
            }
            if (NULL != g_Game_Hwnd){
                    DWORD dwPid = 0;
                    GetWindowThreadProcessId(g_Game_Hwnd,&dwPid);
                    if(dwPid == GetCurrentProcessId()){
                        g_OldlWindowProc = (WNDPROC)SetWindowLong(g_Game_Hwnd,GWL_WNDPROC,(LONG)WindowProc);
                    }
            }
        }
        else{
            if ((NULL != g_Game_Hwnd) && (NULL != g_OldlWindowProc)){
                SetWindowLong(g_Game_Hwnd,GWL_WNDPROC,(LONG)g_OldlWindowProc);
            }
        }
    }
}

//Hook_DrawIndexedPrimitiv指针
void __stdcall HookD3D9_DrawIndexedPrimitive_Mem(bool bHook)
{
    if (bHook){
        g_Stride = GetPrivateProfileInt(Ini_App,Ini_Key_Stride,CN_D3D_Stride,g_Cfg);
        g_KeyBoardSwitch =  GetPrivateProfileInt(Ini_App,Ini_Key_KeyBoardSwitch,0,g_Cfg) > 0 ? true:false;
        OldDrawIndexedPrimitive = (TDrawIndexedPrimitive)g_Adr_DrawIndexedPrimitive;
        *(PDWORD)(*(PDWORD)(g_Param_DrawIndexedPrimitive) + g_Oft_DrawIndexedPrimitive) = DWORD(NewDrawIndexedPrimitive); 
    }
    else{
        OldDrawIndexedPrimitive = NULL;
        *(PDWORD)(*(PDWORD)(g_Param_DrawIndexedPrimitive) + g_Oft_DrawIndexedPrimitive) = g_Adr_DrawIndexedPrimitive; 
    }
    HookKeyBoard(bHook);
}

//NewPresent    
HRESULT __stdcall NewPresent(LPDIRECT3DDEVICE9 pDevice,const RECT *pSourceRect,const RECT *pDestRect,HWND hDestWindowOverride,const RGNDATA *pDirtyRegion)
{
    HRESULT hRet = S_OK;
    if (-1 == g_CpuSleep){      //黑屏,直接返回
        Sleep(168);
        return hRet;
    };
    //执行原函数
    hRet = OldPresent(pDevice,pSourceRect,pDestRect,hDestWindowOverride,pDirtyRegion);
    //Sleep降压
    if (g_CpuSleep > 0){
        Sleep(g_CpuSleep);
    }
    return hRet;
}

//Hook_Present指针
void __stdcall HookD3D9_Present_Mem(bool bHook)
{
    if (bHook){
        g_CpuSleep = GetPrivateProfileIntA(Ini_App,Ini_Key_CpuSleep,0,g_Cfg);
        LogDbg("%d",g_CpuSleep);
        OldPresent = (TPresent)g_Adr_Present;
        *(PDWORD)(*(PDWORD)(g_Param_DrawIndexedPrimitive) + g_Oft_Present) = DWORD(NewPresent); 
    }
    else{
        OldPresent = NULL;
        *(PDWORD)(*(PDWORD)(g_Param_DrawIndexedPrimitive) + g_Oft_Present) = g_Adr_Present; 
    }
}

//Hook方式获取参数_修改代码
void __stdcall GetD3DParam_Hook()
{
    while (0 == g_Param_DrawIndexedPrimitive){
        HookDrawIndexedPrimitiveParam(true);
        Sleep(2);
        HookDrawIndexedPrimitiveParam(false);
        Sleep(168);
    }
}

//全进程搜索参数_不修改代码
DWORD __stdcall GetD3DParam_Search()
{
    DWORD dwRet = 0;
    DWORD dwTmp;
    DWORD dwCurrent = DWORD(GetModuleHandleA(NULL));
    DWORD dwMax = 0x7F000000;
    while (dwCurrent < dwMax){
        dwTmp = dwCurrent;
        if (!IsBadReadPtr((void*)(dwTmp),4)){
            dwTmp = *(PDWORD)dwTmp + g_Oft_DrawIndexedPrimitive;
            if (!IsBadReadPtr((void*)(dwTmp),4)){
                if (*PDWORD(dwTmp) == g_Adr_DrawIndexedPrimitive){
                    dwRet = dwCurrent;
                    LogDbg("GetD3DParam_Search %.8X %.8X",dwRet,g_Adr_DrawIndexedPrimitive);
                    break;
                }
            }
        }
        dwCurrent += 4;
    }
    return dwRet;
}

//在主模块搜索一级基址
void __stdcall SearchBaseAdr(DWORD dwParam)
{   
    bool bFound = false;  
    HANDLE hModuleSnap = INVALID_HANDLE_VALUE;  
    MODULEENTRY32 me32 ={0};  
    if (0 == dwParam){
        goto Exit0;
    }   
    //创建进程快照  
    hModuleSnap = ::CreateToolhelp32Snapshot(TH32CS_SNAPMODULE,GetCurrentProcessId());
    if(INVALID_HANDLE_VALUE == hModuleSnap){     
        goto Exit0;  
    }  
    //递归枚举模块
    me32.dwSize = sizeof(MODULEENTRY32);  
    if(::Module32First(hModuleSnap,&me32))  
    {  
        do{
            DWORD dwCurrent = DWORD(me32.hModule);
            LogDbg("Module %.8X %.8X %s",dwCurrent,me32.modBaseSize,me32.szExePath);
            DWORD dwOft = 0;
            while (dwOft <= me32.modBaseSize){
                if (!IsBadReadPtr((void*)(dwCurrent + dwOft),4)){
                    if (*(PDWORD)(dwCurrent + dwOft) == dwParam){
                        LogDbg("BaseAdr %.8X %.8X",dwCurrent,dwOft);
                    }
                }
                dwOft += 4;
            }
        }while(::Module32Next(hModuleSnap,&me32));  
    }  
Exit0:
    if(INVALID_HANDLE_VALUE != hModuleSnap){
        CloseHandle(hModuleSnap);   
    }
    LogDbg("SearchBaseAdr End");
    return;
}  

bool GetD3DAdr(){
    bool bRet = false;
    LPDIRECT3D9         Tmp_pD3D = NULL; 
    LPDIRECT3DDEVICE9   Tmp_pd3dDevice = NULL; 
    if (NULL == ::GetModuleHandleA(D3D9DLLName)){
        goto Exit0;
    }
    if (NULL == (Tmp_pD3D = Direct3DCreate9(D3D_SDK_VERSION))){
        goto Exit0;
    }
    D3DPRESENT_PARAMETERS d3dpp;
    ZeroMemory( &d3dpp, sizeof( d3dpp ) );
    d3dpp.Windowed = TRUE;
    d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
    d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;
    if (S_OK == Tmp_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,GetDesktopWindow(),
                                      D3DCREATE_SOFTWARE_VERTEXPROCESSING,
                                      &d3dpp,&Tmp_pd3dDevice)){
        try{
            g_Adr_DrawIndexedPrimitive = *(PDWORD)(*(PDWORD)Tmp_pd3dDevice + g_Oft_DrawIndexedPrimitive);
            g_Adr_Present = *(PDWORD)(*(PDWORD)Tmp_pd3dDevice + g_Oft_Present);
            LogDbg("g_Adr_DrawIndexedPrimitive:%.8X g_Adr_Present:%.8X",g_Adr_DrawIndexedPrimitive,g_Adr_Present);
            bRet = true;
        }
        catch (...){    
        }
    }
Exit0:
    if( Tmp_pd3dDevice != NULL ){
        Tmp_pd3dDevice->Release();
    }
    if( Tmp_pD3D != NULL ){
        Tmp_pD3D->Release();
    }
    return bRet;
}

DWORD __stdcall Init_Plugin_MyThread(VOID* lpArgc)
{
    while (!GetD3DAdr()){
        Sleep(100);
    }
    //创建降压CheckBox
    g_InitIO.Api.CreateCheckBox("D3D_CPU降压", HookD3D9_Present_Mem, false);
    //获取参数
    if (0 == GetPrivateProfileIntA(Ini_App,Ini_Key_ParamType,0,g_Cfg)){ 
        GetD3DParam_Hook();
        LogDbg("GetD3DParam_Hook End");
    }
    else{   
        g_Param_DrawIndexedPrimitive = GetD3DParam_Search();
        LogDbg("GetD3DParam_Search End");
    }
    //创建透视CheckBox
    g_InitIO.Api.CreateCheckBox("D3D_透视", HookD3D9_DrawIndexedPrimitive_Mem, false);
    //搜索模块中对应一级基址,对于特定的游戏可以避免Hook或搜索而直接读取参数
    if (0 != GetPrivateProfileIntA(Ini_App,Ini_Key_SearchBase,0,g_Cfg)){    
        SearchBaseAdr(g_Param_DrawIndexedPrimitive);
    }
    LogDbg("Init_Plugin_MyThread End");
    return true;
}

void Init_Plugin_My()
{
    DWORD dwThreadId = 0;
    HANDLE hTmp = CreateThread(NULL, 0, Init_Plugin_MyThread, NULL, CREATE_SUSPENDED, &dwThreadId);
    SetThreadPriority(hTmp,THREAD_PRIORITY_TIME_CRITICAL);
    ResumeThread(hTmp);
    CloseHandle(hTmp);
}

void Init_Plugin()
{
    LogDbg("_init in");
    if (Init_Plugin_Pub()){
        Init_Plugin_My();
        LogDbg("_init ok");
    }
}

BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                     )
{
    if (0 == g_hModuleThisDll){
        g_hModuleThisDll = hModule;     
    }
    switch(ul_reason_for_call)
    {
        case DLL_PROCESS_ATTACH:
            Init_Plugin();
        break;
        case DLL_PROCESS_DETACH:
            UnInit_Plugin();
        break;
        default:
            break;
    }
    return TRUE;
}


上一篇:Delphi 调用惯例 register, pascal, cdecl, stdcall, safecall 介绍


下一篇:商城类项目商品多规格表设计