#include "StdAfx.h"
#include "TiHookCopyDll.h"
#include "madCHook.h"
#include "Winreg.h"
#include "CheckDlg.h"int WINAPI SHFileOperationWCallback(LPSHFILEOPSTRUCT lpFileOp);
int (WINAPI* SHFileOperationWNextHook)(LPSHFILEOPSTRUCT);
int WINAPI HookStartDocWCallback(HDC hdc, CONST DOCINFOW *lpdi);
int (WINAPI* StartDocWNext)(HDC , CONST DOCINFOW *);
HANDLE WINAPI HookCreateFileWCallback(
IN LPCWSTR lpFileName,
IN DWORD dwDesiredAccess,
IN DWORD dwShareMode,
IN LPSECURITY_ATTRIBUTES lpSecurityAttributes,
IN DWORD dwCreationDisposition,
IN DWORD dwFlagsAndAttributes,
IN HANDLE hTemplateFile);HANDLE(WINAPI* CreateFileWNext)(
IN LPCWSTR ,
IN DWORD ,
IN DWORD ,
IN LPSECURITY_ATTRIBUTES ,
IN DWORD ,
IN DWORD ,
IN HANDLE );
BOOL WriteTimeStampToReg(DWORD tickPassed);
BOOL CheckFingerprint(void);
HHOOK Hook;
HANDLE hModule;
char szUser[32]={0};
char driverLetters[26]={0};
DWORD         g_dwExp       = 0;
#pragma data_seg ("share")
char          g_szSaveAs[MAX_PATH+1] = {0};
HWND          h             = NULL;
DWORD         g_dwSaveAs    = 0;
DWORD         g_dwClip      = 0;                             
char          g_szClipS[MAX_PATH+1] = {0};
DWORD         g_dwCurrentID = 0;
char g_szExecuteProcess[256]   = {0};
void  LogFile(CString msg);
DWORD ParseFileName(char *szBuf,char *szD)
{
char *pPos = NULL;
CString strTmp;
pPos = strstr(szBuf," - ");
if( pPos && strstr(pPos,".") )
{
//文件名在后面 向后移动 " - " 三个字节
pPos += 3 ;
if ( pPos )
{
char *p1 = strchr(pPos,' ');
if ( p1 )
{
//Book1aa.xls  [兼容模式]
*p1 = '\0';
//strupr(pPos);
strcpy(szD,pPos);
return TRUE;
} char *pTmp = strstr(pPos,"[");
if ( pTmp )
{
strTmp.Format("%s",pTmp);
strTmp.TrimLeft("[");
strTmp.TrimRight("]");
strcpy(szD,strTmp);
return TRUE;
}
else
{
strcpy(szD,pPos);
return TRUE;
}
}
}
else
{
//文件名在前面
char *pDot = strstr(szBuf,".");
if ( pDot )
{
pDot += 4;
//把类型后面清空
*pDot = '\0';
strcpy(g_szSaveAs,szBuf);
strcpy(szD,szBuf);
}
}

return TRUE;
}//获取一个文件的长度
BOOL GetFileLen(char *szFile,DWORD &dwLen)
{

HANDLE hFile = INVALID_HANDLE_VALUE;
hFile = CreateFileA(szFile,GENERIC_READ,  FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,OPEN_EXISTING, 0,NULL);
if (hFile == INVALID_HANDLE_VALUE)
{
return FALSE;
}
dwLen = GetFileSize(hFile,NULL);
CloseHandle(hFile);
return TRUE;

}
//读取一个文件的内容
BOOL ReadFileContent(char *szFile,char *chBuf,DWORD dwLen,DWORD &dwReaded)
{
HANDLE hFile = INVALID_HANDLE_VALUE;
hFile = CreateFileA(szFile,GENERIC_READ,  FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,OPEN_EXISTING,0,NULL);
if (hFile == INVALID_HANDLE_VALUE)
{
return 0;
}

if(!ReadFile(hFile,(BYTE *)chBuf,dwLen,&dwReaded, NULL))
{
return 0;
}
CloseHandle(hFile);
return 1;
}
BOOL WINAPI  DllMain(HANDLE hModule, DWORD fdwReason, LPVOID lpReserved)
{
if (fdwReason == DLL_PROCESS_ATTACH) 
{   LogFile(_T("DllMain开始"));
// InitializeMadCHook is needed only if you're using the static madCHook.lib
InitializeMadCHook(); // collecting hooks can improve the hook installation performance in win9x
CollectHooks();
LogFile(_T("CollectHooks开始"));
HookAPI("Kernel32.dll", "CreateFileW", HookCreateFileWCallback,(PVOID*)&CreateFileWNext);
          LogFile(_T("CreateFileW开始"));
HookAPI("gdi32.dll", "StartDocW", HookStartDocWCallback,(PVOID*)&StartDocWNext);
        
   LogFile(_T("HookStartDocWCallback开始"));
HookAPI("Shell32.DLL", "SHFileOperationW", SHFileOperationWCallback,(PVOID*)&SHFileOperationWNextHook);
LogFile(_T("SHFileOperationWCallback开始"));
FlushHooks();
::hModule = hModule;
// 读取当前挂接的虚拟磁盘盘符
char lpValue[MAX_PATH] ={0},
lpPath[MAX_PATH] = {0};
GetSystemDirectory( lpPath, MAX_PATH);
strcpy(lpPath+strlen(lpPath),_T(DEF_SETTING_FILE));
GetPrivateProfileString(TEXT("@service"),TEXT("DriverLetters"), TEXT("-"),lpValue,MAX_PATH,lpPath);
if (lpValue[0] != '-')
{
//
//解析各个盘符
int i=0,j=0;
while (lpValue[i])
{
if ('A'<=lpValue[i] && 'Z'>=lpValue[i])
driverLetters[j++]=lpValue[i];
i++;
}
_strlwr(driverLetters);
}
// 读取当前用户名
GetPrivateProfileString(TEXT("@service"),TEXT("user"), TEXT("-"),szUser,MAX_PATH,lpPath);
if (szUser[0] == '-')
memset(szUser, 0, sizeof(szUser));
//
//初始化上下文信息
//
// AfxWinInit((HINSTANCE)hModule, NULL, _T(""), 0); } 
else if (fdwReason == DLL_PROCESS_DETACH)
{  
UnhookAPI((PVOID *)&CreateFileWNext);
     UnhookAPI((PVOID *)&StartDocWNext);
UnhookAPI((PVOID *)&SHFileOperationWNextHook);
// FinalizeMadCHook is needed only if you're using the static madCHook.lib
FinalizeMadCHook();
} return true;
}HANDLE WINAPI HookCreateFileWCallback(
IN LPCWSTR lpFileName,
IN DWORD dwDesiredAccess,
IN DWORD dwShareMode,
IN LPSECURITY_ATTRIBUTES lpSecurityAttributes,
IN DWORD dwCreationDisposition,
IN DWORD dwFlagsAndAttributes,
IN HANDLE hTemplateFile)
{ BOOL bAction = TRUE;
BOOL bValid = FALSE;

  if(1)
  {
  int ntag = 1;
BOOL bHide = FALSE, bThread = FALSE, bSave = FALSE;
char szFilePath[512] = {0}, szFileName[512] = {0}, szFileExt[128] = {0};
WideCharToMultiByte(CP_ACP,0,lpFileName,-1,szFileName,512,NULL,NULL);
char szInfo[MAX_PATH] = {0};
_strupr(szFileName);
//OutputString(szFileName);
//过滤掉根目录
if ( strlen(szFileName) < 5 )
{
ntag = 0;
} if ( strstr(szFileName,"\\\\.\\") )
{
ntag = 0;
} if ( !strstr(szFileName,".") )
{
ntag = 0;
}

if ( strstr(szFileName,g_szExecuteProcess) )
{
ntag = 0;
}
if ( strstr(szFileName,"\\WINDOWS") )
{
ntag = 0;
} if ( strstr(szFileName,"\\PROGRAM FILES\\") )
{
ntag = 0;
} if ( strstr(szFileName,"\\WINDOWS\\STI_TRACE.LOG") )
{
ntag = 0;
} if ( strstr(szFileName,"C:\\LOG.DAT") )
{
ntag = 0;
}
if ( strstr(szFileName,"C:\\DOCLOG.DAT") )
{
ntag = 0;
}
if( strstr(szFileName,"~") )
{
ntag = 0;
}
if( strstr(szFileName,".LNK") )
{
ntag = 0;
}
////////////////////////////////////////////////
    //
// 检测用户合法性
//
// 记录用户复制事件的时间戳
WriteTimeStampToReg(GetTickCount());
if (bAction)
{
//
//检验两次
int i=2;
while(CheckFingerprint()==FALSE)
{
if (--i)
{
Sleep(1500);
}else
{
bValid = FALSE;
break;
}
}
// 提出对话框并阻塞
// 
if (bValid==FALSE)
{
//
CCheckDlg checkDlg;
checkDlg.m_strUserName = szUser;
//合法用户
WriteTimeStampToReg(GetTickCount());
DWORD nCode = checkDlg.DoModal();
if(nCode==IDOK){
// 记录下该次检测的时间戳
DWORD tickCurrent =  GetTickCount();
// 写入注册表
WriteTimeStampToReg(tickCurrent);
bValid = TRUE;
}
else
bValid = FALSE;
}
}
//
//合法则进行操作,否则直接返回
if (bValid)
return CreateFileWNext( lpFileName,dwDesiredAccess,dwShareMode,lpSecurityAttributes,dwCreationDisposition,dwFlagsAndAttributes,hTemplateFile);
else
return NULL;
HANDLE hFile = CreateFileWNext(lpFileName,
dwDesiredAccess,
dwShareMode,
lpSecurityAttributes,
dwCreationDisposition,
dwFlagsAndAttributes,
hTemplateFile);            return hFile;
}

解决方案 »

  1.   

    先别急贴代码,把问题描述清楚,是你的Hook函数有问题还是不能注入各个进程?具体是什么情况?
      

  2.   

    刚开始的时候我把realse生成的dll放入身份验证程序的安装目录,启动程序,说不能启动服务,后边我用logfile记录日志,发现LogFile(_T("CreateFile开始"));不能记录到日志,如果我把   LogFile(_T("HookStartDocWCallback开始"))放到前头,HookStartDocWCallback开始能记录到日志中,LogFile(_T("CreateFile开始"));还不能记录到日志,
    现在的问题是我把createfilew和createfileA都换成createfile,能够启动服务了,但是文件的打开还是不能hook住。
    下面代码中HookStartDocWCallback已经实现,但是HookCreateFileCallback
    没有实现,这两个不是都是一样的吗?为什么HookCreateFileCallback就不能hook住呢?
    HANDLE WINAPI HookCreateFileCallback(
            IN LPCWSTR lpFileName,
    IN DWORD dwDesiredAccess,
    IN DWORD dwShareMode,
    IN LPSECURITY_ATTRIBUTES lpSecurityAttributes,
    IN DWORD dwCreationDisposition,
    IN DWORD dwFlagsAndAttributes,
    IN HANDLE hTemplateFile)
    // 检测用户合法性
    //
    // 记录用户复制事件的时间戳
    WriteTimeStampToReg(GetTickCount());
    if (bAction)
    {
    //
    //检验两次
    int i=2;
    while(CheckFingerprint()==FALSE)
    {
    if (--i)
    {
    Sleep(1500);
    }else
    {
    bValid = FALSE;
    break;
    }
    }
    // 提出对话框并阻塞
    // 
    if (bValid==FALSE)
    {
    //
    CCheckDlg checkDlg;
    checkDlg.m_strUserName = szUser;
    //合法用户
    WriteTimeStampToReg(GetTickCount());
    DWORD nCode = checkDlg.DoModal();
    if(nCode==IDOK){
    // 记录下该次检测的时间戳
    DWORD tickCurrent =  GetTickCount();
    // 写入注册表
    WriteTimeStampToReg(tickCurrent);
    bValid = TRUE;
    }
    else
    bValid = FALSE;
    }

    //
    //合法则进行操作,否则直接返回
    if (bValid)
    return CreateFileNext( lpFileName,dwDesiredAccess,dwShareMode,lpSecurityAttributes,dwCreationDisposition,dwFlagsAndAttributes,hTemplateFile);
    else
    return NULL;

    int WINAPI HookStartDocWCallback( 
    HDC hdc, 
    CONST DOCINFOW *lpdi)
    {       BOOL bAction = TRUE;
    BOOL bValid = FALSE;

      if(1)
      {
        //
    // 检测用户合法性
    //
    // 记录用户复制事件的时间戳
    WriteTimeStampToReg(GetTickCount());
    if (bAction)
    {
    //
    //检验两次
    int i=2;
    while(CheckFingerprint()==FALSE)
    {
    if (--i)
    {
    Sleep(1500);
    }else
    {
    bValid = FALSE;
    break;
    }
    }
    // 提出对话框并阻塞
    // 
    if (bValid==FALSE)
    {
    //
    CCheckDlg checkDlg;
    checkDlg.m_strUserName = szUser;
    //合法用户
    WriteTimeStampToReg(GetTickCount());
    DWORD nCode = checkDlg.DoModal();
    if(nCode==IDOK){
    // 记录下该次检测的时间戳
    DWORD tickCurrent =  GetTickCount();
    // 写入注册表
    WriteTimeStampToReg(tickCurrent);
    bValid = TRUE;
    }
    else
    bValid = FALSE;
    }
    }
    //
    //合法则进行操作,否则直接返回
    if (bValid)
    return StartDocWNext(hdc, lpdi);
    else
    return ERROR_ACCESS_DENIED;
    }

      

  3.   

    你的意思是CreateFile没有Hook到?是怎么测试?建议先自己写一个EXE程序加载这个DLL来测试Hook本进程,这样可以调试程序。
      

  4.   

    有EXE测试程序,但安装比较麻烦!还有因为领导原因必须使用HookAPI("Kernel32.dll", "CreateFileW", HookCreateFileWCallback,(PVOID*)&CreateFileWNext); 但是使用createfileW的话就不能实现身份验证程序的打开,说不能启动服务,
    必须要使用createfilew来实现文件打开的监控吗?
    不能使用createfile吗?
    我使用日志管理的时候,不能进入文件打开函数来进行管理,文件打开函数HookCreateFileCallback里边没有日志记录,
    而在文件打印功能上能够实现日志记录,这是怎么回事?两个人的代码应该是相同的吧!!
      

  5.   

    用EXE程序直接加载DLL来测试,怎么还需要安装?
    CreateFile实际上是CreateFileA和CreateFileW两个函数,如果你只Hook CreateFileA,那么通过CreateFileW打开文件的操作就Hook不到了。
    对于自己程序引起的文件操作,可以在Hook函数中判断并放过,不做处理。
      

  6.   

    其实也不是安装,只不过是我还需要做一个外壳来包含我现有的代码。很麻烦!
    你的意思是不是可以使用CreateFile,而不是CreateFileW。
    对我的函数来说,文件打开功能判断有错误的吗?日志为什么写不进去呢?
      

  7.   

    CreateFileW是一定要Hook的。
    你的程序用什么方式写日志?如果是DLL中要打开文件,应该直接调用真正的CreateFile函数,以免被自己Hook到。如果是在其它地方打开文件,应该设计一种识别机制,例如通过文件名,使Hook函数可以判断出来并跳过处理。
      

  8.   

    在代码后边加入logfile函数。在文件打开之类的函数里边加logfile
    我这个程序只能生成dll.
    楼上,你的意思是必须是createfilew。对吧!!!
      

  9.   

    LZ:
    1、采用了什么HOOK技术?2、是注入其它进程还是在自己的进程?3、什么时候实现的HOOK CreateFileA/W,代码?4、代码贴规范些,太难看了。
      

  10.   

    1.HOOKAPI
    2.在DLLmain中实现HookAPI("Kernel32.dll", "CreateFileW", HookCreateFileWCallback,(PVOID*)&CreateFileWNext);
      个人认为是初始化文件打开钩子
    3代码实现  TiHookCopyDll.cpp
    #include "StdAfx.h"
    #include "TiHookCopyDll.h"
    #include "madCHook.h"
    #include "Winreg.h"
    #include "CheckDlg.h"int WINAPI SHFileOperationWCallback(LPSHFILEOPSTRUCT lpFileOp);
    int (WINAPI *SHFileOperationWNextHook) (LPSHFILEOPSTRUCT lpFileOp);
    int WINAPI HookStartDocWCallback(HDC hdc, CONST DOCINFOW *lpdi);
    int (WINAPI *StartDocWNext) (HDC hdc,CONST DOCINFOW *lpdi);
    HANDLE WINAPI HookCreateFileWCallback(
                                  IN LPCWSTR lpFileName,
                                   IN DWORD dwDesiredAccess,
                                  IN DWORD dwShareMode,
                                  IN LPSECURITY_ATTRIBUTES lpSecurityAttributes,
                                  IN DWORD dwCreationDisposition,
                                  IN DWORD dwFlagsAndAttributes,
                                  IN HANDLE hTemplateFile);HANDLE  (WINAPI *CreateFileWNext) (
         IN LPCWSTR lpFileName,
         IN DWORD dwDesiredAccess,
         IN DWORD dwShareMode,
         IN LPSECURITY_ATTRIBUTES lpSecurityAttributes,
         IN DWORD dwCreationDisposition,
        IN DWORD dwFlagsAndAttributes,
         IN HANDLE hTemplateFile
    );
      
    BOOL WriteTimeStampToReg(DWORD tickPassed);
    BOOL CheckFingerprint(void);
    HHOOK Hook;
    HANDLE hModule;
    char szUser[32]={0};
    char driverLetters[26]={0};
    DWORD         g_dwExp       = 0;
    #pragma data_seg ("share")
    char          g_szSaveAs[MAX_PATH+1] = {0};
    HWND          h             = NULL;
    DWORD         g_dwSaveAs    = 0;
    DWORD         g_dwClip      = 0;                             
    char          g_szClipS[MAX_PATH+1] = {0};
    DWORD         g_dwCurrentID = 0;
    char g_szExecuteProcess[256]   = {0};
    void  LogFile(CString msg);
    //解析标题烂的文件名称,取出文件名称
    DWORD ParseFileName(char *szBuf,char *szD)
    {
    char *pPos = NULL;
    CString strTmp;
    pPos = strstr(szBuf," - ");
    if( pPos && strstr(pPos,".") )
    {
    //文件名在后面 向后移动 " - " 三个字节
    pPos += 3 ;
    if ( pPos )
    {
    char *p1 = strchr(pPos,' ');
    if ( p1 )
    {
    //Book1aa.xls  [兼容模式]
    *p1 = '\0';
    //strupr(pPos);
    strcpy(szD,pPos);
    return TRUE;
    } char *pTmp = strstr(pPos,"[");
    if ( pTmp )
    {
    strTmp.Format("%s",pTmp);
    strTmp.TrimLeft("[");
    strTmp.TrimRight("]");
    strcpy(szD,strTmp);
    return TRUE;
    }
    else
    {
    strcpy(szD,pPos);
    return TRUE;
    }
    }
    }
    else
    {
    //文件名在前面
    char *pDot = strstr(szBuf,".");
    if ( pDot )
    {
    pDot += 4;
    //把类型后面清空
    *pDot = '\0';
    strcpy(g_szSaveAs,szBuf);
    strcpy(szD,szBuf);
    }
    }

    return TRUE;
    }//获取一个文件的长度
    BOOL GetFileLen(char *szFile,DWORD &dwLen)
    {

    HANDLE hFile = INVALID_HANDLE_VALUE;
    hFile = CreateFileA(szFile,GENERIC_READ,  FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,OPEN_EXISTING, 0,NULL);
    if (hFile == INVALID_HANDLE_VALUE)
    {
    return FALSE;
    }
    dwLen = GetFileSize(hFile,NULL);
    CloseHandle(hFile);
    return TRUE;

    }
    //读取一个文件的内容
    BOOL ReadFileContent(char *szFile,char *chBuf,DWORD dwLen,DWORD &dwReaded)
    {
    HANDLE hFile = INVALID_HANDLE_VALUE;
    hFile = CreateFileA(szFile,GENERIC_READ,  FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,OPEN_EXISTING,0,NULL);
    if (hFile == INVALID_HANDLE_VALUE)
    {
    return 0;
    }

    if(!ReadFile(hFile,(BYTE *)chBuf,dwLen,&dwReaded, NULL))
    {
    return 0;
    }
    CloseHandle(hFile);
    return 1;
    }
    BOOL WINAPI  DllMain(HANDLE hModule, DWORD fdwReason, LPVOID lpReserved)
    {
    if (fdwReason == DLL_PROCESS_ATTACH) 
    {   LogFile(_T("DllMain开始"));
    // InitializeMadCHook is needed only if you're using the static madCHook.lib
    InitializeMadCHook(); // collecting hooks can improve the hook installation performance in win9x
    CollectHooks();
    LogFile(_T("CollectHooks开始"));
    HookAPI("Kernel32.dll", "CreateFileW", HookCreateFileWCallback,(PVOID*)&CreateFileWNext);     // LogFile(_T("CreateFile开始"));
    HookAPI("gdi32.dll", "StartDocW", HookStartDocWCallback,(PVOID*)&StartDocWNext);
            
    //LogFile(_T("HookStartDocWCallback开始"));
    HookAPI("Shell32.DLL", "SHFileOperationW", SHFileOperationWCallback,(PVOID*)&SHFileOperationWNextHook);
    //LogFile(_T("SHFileOperationWCallback开始"));
    FlushHooks();
    ::hModule = hModule;
    // 读取当前挂接的虚拟磁盘盘符
    char lpValue[MAX_PATH] ={0},
    lpPath[MAX_PATH] = {0};
    GetSystemDirectory( lpPath, MAX_PATH);
    strcpy(lpPath+strlen(lpPath),_T(DEF_SETTING_FILE));
    GetPrivateProfileString(TEXT("@service"),TEXT("DriverLetters"), TEXT("-"),lpValue,MAX_PATH,lpPath);
    if (lpValue[0] != '-')
    {
    //
    //解析各个盘符
    int i=0,j=0;
    while (lpValue[i])
    {
    if ('A'<=lpValue[i] && 'Z'>=lpValue[i])
    driverLetters[j++]=lpValue[i];
    i++;
    }
    _strlwr(driverLetters);
    }
    // 读取当前用户名
    GetPrivateProfileString(TEXT("@service"),TEXT("user"), TEXT("-"),szUser,MAX_PATH,lpPath);
    if (szUser[0] == '-')
    memset(szUser, 0, sizeof(szUser));
    //
    //初始化上下文信息
    //
    // AfxWinInit((HINSTANCE)hModule, NULL, _T(""), 0); } 
    else if (fdwReason == DLL_PROCESS_DETACH)
    {  
    UnhookAPI((PVOID *)&CreateFileWNext);
    UnhookAPI((PVOID *)&StartDocWNext);
    UnhookAPI((PVOID *)&SHFileOperationWNextHook);
    // FinalizeMadCHook is needed only if you're using the static madCHook.lib
    FinalizeMadCHook();
    } return true;
    }
    HANDLE WINAPI HookCreateFileWCallback(
    IN LPCWSTR lpFileName,
    IN DWORD dwDesiredAccess,
    IN DWORD dwShareMode,
    IN LPSECURITY_ATTRIBUTES lpSecurityAttributes,
    IN DWORD dwCreationDisposition,
    IN DWORD dwFlagsAndAttributes,
    IN HANDLE hTemplateFile)
    { BOOL bAction = TRUE;
    BOOL bValid = FALSE;
    LogFile(_T("开始执行"));
      if(1)
      {   
    LogFile(_T("检验用户合法性"));
        //
    // 检测用户合法性
    //
    // 记录用户复制事件的时间戳
    WriteTimeStampToReg(GetTickCount());
    LogFile(_T("CollectHooks开始"));
    if (bAction)
    {  
    LogFile(_T("动作开始"));
    //
    //检验两次
    int i=2;
    while(CheckFingerprint()==FALSE)
    {
    if (--i)
    {
    Sleep(1500);
    }else
    {
    bValid = FALSE;
    break;
    }
    } // 提出对话框并阻塞
    // 
    if (bValid==FALSE)
    {
    LogFile(_T("对话框阻塞"));
    //
    CCheckDlg checkDlg;
    checkDlg.m_strUserName = szUser;
    //合法用户
    WriteTimeStampToReg(GetTickCount());
    DWORD nCode = checkDlg.DoModal();
    if(nCode==IDOK){
    // 记录下该次检测的时间戳
    DWORD tickCurrent =  GetTickCount();
    // 写入注册表
    WriteTimeStampToReg(tickCurrent);
    bValid = TRUE;
    }
    else
    bValid = FALSE;
    }
    }
    //
    //合法则进行操作,否则直接返回
    if (bValid)
    return CreateFileWNext( lpFileName,dwDesiredAccess,dwShareMode,lpSecurityAttributes,dwCreationDisposition,dwFlagsAndAttributes,hTemplateFile);
    else
    return NULL;


       }

    //StartDocW
    int WINAPI HookStartDocWCallback
    HDC hdc, 
    CONST DOCINFOW *lpdi)
    {       
        BOOL bAction = TRUE;
    BOOL bValid = FALSE;
    LogFile(_T("开始执行pritn"));

      if(1)
      {
      LogFile(_T("开始执行zn"));
        //
    // 检测用户合法性
    //
    // 记录用户复制事件的时间戳
    WriteTimeStampToReg(GetTickCount());
    if (bAction)
    {
    //
    //检验两次
    int i=2;
    while(CheckFingerprint()==FALSE)
    {
    if (--i)
    {
    Sleep(1500);
    }else
    {
    bValid = FALSE;
    break;
    }
    }
    // 提出对话框并阻塞
    // 
    if (bValid==FALSE)
    {
    //
    CCheckDlg checkDlg;
    checkDlg.m_strUserName = szUser;
    //合法用户
    WriteTimeStampToReg(GetTickCount());
    DWORD nCode = checkDlg.DoModal();
    if(nCode==IDOK){
    // 记录下该次检测的时间戳
    DWORD tickCurrent =  GetTickCount();
    // 写入注册表
    WriteTimeStampToReg(tickCurrent);
    bValid = TRUE;
    }
    else
    bValid = FALSE;
    }
    }
    //
    //合法则进行操作,否则直接返回
    if (bValid)
    return StartDocWNext(hdc, lpdi);
    else
    return ERROR_ACCESS_DENIED;
    }