SystemInfoUtils

// Written by Zoltan Csizmadia, zoltan_csizmadia@yahoo.com
// For companies(Austin,TX): If you would like to get my resume, send an email.
//
// The source is free, but if you want to use it, mention my name and e-mail address
//
//
//
// SystemInfo.h, v1.1

#ifndef SYSTEMINFO_H_INCLUDED
#define SYSTEMINFO_H_INCLUDED

#ifndef WINNT
#error You need Windows NT to use this source code. Define WINNT!
#endif

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#pragma warning( disable : 4786 )
#pragma warning( disable : 4200 )

#include <afxtempl.h>

//
//
// Typedefs
//
//

typedef struct _UNICODE_STRING
{
 WORD  Length;
 WORD  MaximumLength;
 PWSTR Buffer;
} UNICODE_STRING;

//
//
// SystemInfoUtils
//
//

// Helper functions

class SystemInfoUtils
{
public:

 //
 // String conversion functions

 // From wide char string to CString
 static void LPCWSTR2CString( LPCWSTR strW, CString& str );
 // From unicode string to CString
 static void Unicode2CString( UNICODE_STRING* strU, CString& str );

 //
 // File name conversion functions

 static BOOL GetDeviceFileName( LPCTSTR, CString& );
 static BOOL GetFsFileName( LPCTSTR, CString& );

 //
 // Information functions

 static DWORD GetNTMajorVersion();
};

//
//
// INtDll
//
//

class INtDll
{
public:
 typedef DWORD (WINAPI *PNtQueryObject)( HANDLE, DWORD, VOID*, DWORD, VOID* );
 typedef DWORD (WINAPI *PNtQuerySystemInformation)( DWORD, VOID*, DWORD, ULONG* );
 typedef DWORD (WINAPI *PNtQueryInformationThread)(HANDLE, ULONG, PVOID, DWORD, DWORD* );
 typedef DWORD (WINAPI *PNtQueryInformationFile)(HANDLE, PVOID, PVOID, DWORD, DWORD );
 typedef DWORD (WINAPI *PNtQueryInformationProcess)(HANDLE, DWORD, PVOID, DWORD, PVOID );
 
public:
 static PNtQuerySystemInformation NtQuerySystemInformation;
 static PNtQueryObject    NtQueryObject;
 static PNtQueryInformationThread NtQueryInformationThread;
 static PNtQueryInformationFile  NtQueryInformationFile;
 static PNtQueryInformationProcess NtQueryInformationProcess;

 static BOOL       NtDllStatus;

 static DWORD      dwNTMajorVersion;

protected:
 static BOOL Init();
};

//
//
// SystemProcessInformation
//
//

class SystemProcessInformation : public INtDll
{
public:
 typedef LARGE_INTEGER   QWORD;

 typedef struct _PROCESS_BASIC_INFORMATION {
   DWORD ExitStatus;
   PVOID PebBaseAddress;
   DWORD AffinityMask;
   DWORD BasePriority;
   DWORD UniqueProcessId;
   DWORD InheritedFromUniqueProcessId;
  } PROCESS_BASIC_INFORMATION;

 typedef struct _VM_COUNTERS
  {
  DWORD PeakVirtualSize;
  DWORD VirtualSize;
  DWORD PageFaultCount;
  DWORD PeakWorkingSetSize;
  DWORD WorkingSetSize;
  DWORD QuotaPeakPagedPoolUsage;
  DWORD QuotaPagedPoolUsage;
  DWORD QuotaPeakNonPagedPoolUsage;
  DWORD QuotaNonPagedPoolUsage;
  DWORD PagefileUsage;
  DWORD PeakPagefileUsage;
  } VM_COUNTERS;

 typedef struct _SYSTEM_THREAD
  {
  DWORD        u1;
  DWORD        u2;
  DWORD        u3;
  DWORD        u4;
  DWORD        ProcessId;
  DWORD        ThreadId;
  DWORD        dPriority;
  DWORD        dBasePriority;
  DWORD        dContextSwitches;
  DWORD        dThreadState;      // 2=running, 5=waiting
  DWORD        WaitReason;
  DWORD        u5;
  DWORD        u6;
  DWORD        u7;
  DWORD        u8;
  DWORD        u9;
  } SYSTEM_THREAD;

 typedef struct _SYSTEM_PROCESS_INFORMATION
  {
  DWORD          dNext;
  DWORD          dThreadCount;
  DWORD          dReserved01;
  DWORD          dReserved02;
  DWORD          dReserved03;
  DWORD          dReserved04;
  DWORD          dReserved05;
  DWORD          dReserved06;
  QWORD          qCreateTime;
  QWORD          qUserTime;
  QWORD          qKernelTime;
  UNICODE_STRING usName;
  DWORD        BasePriority;
  DWORD          dUniqueProcessId;
  DWORD          dInheritedFromUniqueProcessId;
  DWORD          dHandleCount;
  DWORD          dReserved07;
  DWORD          dReserved08;
  VM_COUNTERS    VmCounters;
  DWORD          dCommitCharge;
  SYSTEM_THREAD  Threads[1];
  } SYSTEM_PROCESS_INFORMATION;

 enum { BufferSize = 0x10000 };

public:
 SystemProcessInformation( BOOL bRefresh = FALSE );
 virtual ~SystemProcessInformation();

 BOOL Refresh();

public:
 CMap< DWORD, DWORD&, SYSTEM_PROCESS_INFORMATION*, SYSTEM_PROCESS_INFORMATION*> m_ProcessInfos;
 SYSTEM_PROCESS_INFORMATION* m_pCurrentProcessInfo;

protected:
 UCHAR*      m_pBuffer;
};

//
//
// SystemThreadInformation
//
//

class SystemThreadInformation : public INtDll
{
public:
 typedef struct _THREAD_INFORMATION
  {
  DWORD  ProcessId;
  DWORD  ThreadId;
  HANDLE  ThreadHandle; 
  } THREAD_INFORMATION;

 
 typedef struct _BASIC_THREAD_INFORMATION {
  DWORD u1;
  DWORD u2;
  DWORD u3;
  DWORD ThreadId;
  DWORD u5;
  DWORD u6;
  DWORD u7;
 } BASIC_THREAD_INFORMATION;

public:
 SystemThreadInformation( DWORD pID = (DWORD)-1, BOOL bRefresh = FALSE );

 BOOL Refresh();

public:
 CList< THREAD_INFORMATION, THREAD_INFORMATION& > m_ThreadInfos;
 DWORD m_processId;
};


//
//
// SystemHandleInformation
//
//

class SystemHandleInformation : public INtDll
{
public:
 enum {
  OB_TYPE_UNKNOWN = 0,
  OB_TYPE_TYPE = 1,
  OB_TYPE_DIRECTORY,
  OB_TYPE_SYMBOLIC_LINK,
  OB_TYPE_TOKEN,
  OB_TYPE_PROCESS,
  OB_TYPE_THREAD,
  OB_TYPE_UNKNOWN_7,
  OB_TYPE_EVENT,
  OB_TYPE_EVENT_PAIR,
  OB_TYPE_MUTANT,
  OB_TYPE_UNKNOWN_11,
  OB_TYPE_SEMAPHORE,
  OB_TYPE_TIMER,
  OB_TYPE_PROFILE,
  OB_TYPE_WINDOW_STATION,
  OB_TYPE_DESKTOP,
  OB_TYPE_SECTION,
  OB_TYPE_KEY,
  OB_TYPE_PORT,
  OB_TYPE_WAITABLE_PORT,
  OB_TYPE_UNKNOWN_21,
  OB_TYPE_UNKNOWN_22,
  OB_TYPE_UNKNOWN_23,
  OB_TYPE_UNKNOWN_24,
  //OB_TYPE_CONTROLLER,
  //OB_TYPE_DEVICE,
  //OB_TYPE_DRIVER,
  OB_TYPE_IO_COMPLETION,
  OB_TYPE_FILE                       
 } SystemHandleType;

public:
 typedef struct _SYSTEM_HANDLE
 {
  DWORD ProcessID;
  WORD HandleType;
  WORD HandleNumber;
  DWORD KernelAddress;
  DWORD Flags;
 } SYSTEM_HANDLE;

 typedef struct _SYSTEM_HANDLE_INFORMATION
 {
  DWORD   Count;
  SYSTEM_HANDLE Handles[1];
 } SYSTEM_HANDLE_INFORMATION;

protected:
 typedef struct _GetFileNameThreadParam
 {
  HANDLE  hFile;
  CString* pName;
  ULONG  rc;
 } GetFileNameThreadParam;

public:
 SystemHandleInformation( DWORD pID = (DWORD)-1, BOOL bRefresh = FALSE, LPCTSTR lpTypeFilter = NULL );
 ~SystemHandleInformation();

 BOOL SetFilter( LPCTSTR lpTypeFilter, BOOL bRefresh = TRUE );
 const CString& GetFilter();
 
 BOOL Refresh();

public:
 //Information functions
 static BOOL GetType( HANDLE, WORD&, DWORD processId = GetCurrentProcessId() );
 static BOOL GetTypeToken( HANDLE, CString&, DWORD processId = GetCurrentProcessId() );
 static BOOL GetTypeFromTypeToken( LPCTSTR typeToken, WORD& type );
 static BOOL GetNameByType( HANDLE, WORD, CString& str, DWORD processId = GetCurrentProcessId());
 static BOOL GetName( HANDLE, CString&, DWORD processId = GetCurrentProcessId() );

 //Thread related functions
 static BOOL GetThreadId( HANDLE, DWORD&, DWORD processId = GetCurrentProcessId() );

 //Process related functions
 static BOOL GetProcessId( HANDLE, DWORD&, DWORD processId = GetCurrentProcessId() );
 static BOOL GetProcessPath( HANDLE h, CString& strPath, DWORD processId = GetCurrentProcessId());

 //File related functions
 static BOOL GetFileName( HANDLE, CString&, DWORD processId = GetCurrentProcessId() );

public:
 //For remote handle support
 static HANDLE OpenProcess( DWORD processId );
 static HANDLE DuplicateHandle( HANDLE hProcess, HANDLE hRemote );

protected:
 static void GetFileNameThread( PVOID /* GetFileNameThreadParam* */ );
 BOOL IsSupportedHandle( SYSTEM_HANDLE& handle );

public:
 CList< SYSTEM_HANDLE, SYSTEM_HANDLE& > m_HandleInfos;
 DWORD m_processId;

protected:
 CString m_strTypeFilter;
};

//
//
// SystemModuleInformation
//
//

class SystemModuleInformation
{
public:
 typedef struct _MODULE_INFO
 {
  DWORD ProcessId;
  TCHAR FullPath[_MAX_PATH];
  HMODULE Handle;
 } MODULE_INFO;

public:
 typedef DWORD (WINAPI *PEnumProcessModules)(
    HANDLE hProcess,      // handle to process
    HMODULE *lphModule,   // array of module handles
    DWORD cb,             // size of array
    LPDWORD lpcbNeeded    // number of bytes required
   );

 typedef DWORD (WINAPI *PGetModuleFileNameEx)(
    HANDLE hProcess,    // handle to process
    HMODULE hModule,    // handle to module
    LPTSTR lpFilename,  // path buffer
    DWORD nSize         // maximum characters to retrieve
   );

public:
 SystemModuleInformation( DWORD pID = (DWORD)-1, BOOL bRefresh = FALSE );

 BOOL Refresh();

protected:
 void GetModuleListForProcess( DWORD processID );

public:
 DWORD m_processId;
 CList< MODULE_INFO, MODULE_INFO& > m_ModuleInfos;

protected:
 PEnumProcessModules  m_EnumProcessModules;
 PGetModuleFileNameEx m_GetModuleFileNameEx;
};

//
//
// SystemWindowInformation
//
//

class SystemWindowInformation
{
public:
 enum { MaxCaptionSize = 1024 };

 typedef struct _WINDOW_INFO
 {
  DWORD ProcessId;
  TCHAR Caption[MaxCaptionSize];
  HWND hWnd;
 } WINDOW_INFO;

public:
 SystemWindowInformation( DWORD pID = (DWORD)-1, BOOL bRefresh = FALSE );

 BOOL Refresh();

protected:
 static BOOL CALLBACK EnumerateWindows( HWND hwnd, LPARAM lParam );
 
public:
 DWORD m_processId;
 CList< WINDOW_INFO, WINDOW_INFO& > m_WindowInfos;
};

#endif

// Written by Zoltan Csizmadia, zoltan_csizmadia@yahoo.com
// For companies(Austin,TX): If you would like to get my resume, send an email.
//
// The source is free, but if you want to use it, mention my name and e-mail address
//
//
//
// SystemInfo.cpp v1.1
//
// History:
//
// Date      Version     Description
// --------------------------------------------------------------------------------
// 10/16/00  1.0      Initial version
// 11/09/00  1.1         NT4 doesn't like if we bother the System process fix :)
//                       SystemInfoUtils::GetDeviceFileName() fix (subst drives added)
//                       NT Major version added to INtDLL class
//
//

#include "stdafx.h"
#include <process.h>
#include "SystemInfo.h"

#ifndef WINNT
#error You need Windows NT to use this source code. Define WINNT!
#endif

//
//
// SystemInfoUtils
//
//

// From wide char string to CString
void SystemInfoUtils::LPCWSTR2CString( LPCWSTR strW, CString& str )
{
#ifdef UNICODE
 // if it is already UNICODE, no problem
 str = strW;
#else
 str = _T("");

 TCHAR* actChar = (TCHAR*)strW;

 if ( actChar == _T('{post.abstract}') )
  return;

 ULONG len = wcslen(strW) + 1;
 TCHAR* pBuffer = new TCHAR[ len ];
 TCHAR* pNewStr = pBuffer;

 while ( len-- )
 {
  *(pNewStr++) = *actChar;
  actChar += 2;
 }

 str = pBuffer;

 delete [] pBuffer;
#endif
}

// From wide char string to unicode
void SystemInfoUtils::Unicode2CString( UNICODE_STRING* strU, CString& str )
{
 if ( *(DWORD*)strU != 0 )
  LPCWSTR2CString( (LPCWSTR)strU->Buffer, str );
 else
  str = _T("");
}

// From device file name to DOS filename
BOOL SystemInfoUtils::GetFsFileName( LPCTSTR lpDeviceFileName, CString& fsFileName )
{
 BOOL rc = FALSE;

 TCHAR lpDeviceName[0x1000];
 TCHAR lpDrive[3] = _T("A:");

 // Iterating through the drive letters
 for ( TCHAR actDrive = _T('A'); actDrive <= _T('Z'); actDrive++ )
 {
  lpDrive[0] = actDrive;

  // Query the device for the drive letter
  if ( QueryDosDevice( lpDrive, lpDeviceName, 0x1000 ) != 0 )
  {
   // Network drive?
   if ( _tcsnicmp( _T("/Device/LanmanRedirector/"), lpDeviceName, 25 ) == 0 )
   {
    //Mapped network drive

    char cDriveLetter;
    DWORD dwParam;

    TCHAR lpSharedName[0x1000];

    if ( _stscanf(  lpDeviceName,
        _T("/Device/LanmanRedirector/;%c:%d/%s"),
        &cDriveLetter,
        &dwParam,
        lpSharedName ) != 3 )
      continue;

    _tcscpy( lpDeviceName, _T("/Device/LanmanRedirector/") );
    _tcscat( lpDeviceName, lpSharedName );
   }
   
   // Is this the drive letter we are looking for?
   if ( _tcsnicmp( lpDeviceName, lpDeviceFileName, _tcslen( lpDeviceName ) ) == 0 )
   {
    fsFileName = lpDrive;
    fsFileName += (LPCTSTR)( lpDeviceFileName + _tcslen( lpDeviceName ) );

    rc = TRUE;

    break;
   }
  }
 }

 return rc;
}

// From DOS file name to device file name
BOOL SystemInfoUtils::GetDeviceFileName( LPCTSTR lpFsFileName, CString& deviceFileName )
{
 BOOL rc = FALSE;
 TCHAR lpDrive[3];

 // Get the drive letter
 // unfortunetaly it works only with DOS file names
 _tcsncpy( lpDrive, lpFsFileName, 2 );
 lpDrive[2] = _T('{post.abstract}');

 TCHAR lpDeviceName[0x1000];

 // Query the device for the drive letter
 if ( QueryDosDevice( lpDrive, lpDeviceName, 0x1000 ) != 0 )
 {
  // Subst drive?
  if ( _tcsnicmp( _T("/??/"), lpDeviceName, 4 ) == 0 )
  {
   deviceFileName = lpDeviceName + 4;
   deviceFileName += lpFsFileName + 2;

   return TRUE;
  }
  else
  // Network drive?
  if ( _tcsnicmp( _T("/Device/LanmanRedirector/"), lpDeviceName, 25 ) == 0 )
  {
   //Mapped network drive

   char cDriveLetter;
   DWORD dwParam;

   TCHAR lpSharedName[0x1000];

   if ( _stscanf(  lpDeviceName,
       _T("/Device/LanmanRedirector/;%c:%d/%s"),
       &cDriveLetter,
       &dwParam,
       lpSharedName ) != 3 )
     return FALSE;

   _tcscpy( lpDeviceName, _T("/Device/LanmanRedirector/") );
   _tcscat( lpDeviceName, lpSharedName );
  }

  _tcscat( lpDeviceName, lpFsFileName + 2 );

  deviceFileName = lpDeviceName;

  rc = TRUE;
 }

 return rc;
}

//Get NT version
DWORD SystemInfoUtils::GetNTMajorVersion()
{
   OSVERSIONINFOEX osvi;
   BOOL bOsVersionInfoEx;
  
   // Try calling GetVersionEx using the OSVERSIONINFOEX structure,
   // which is supported on Windows 2000.
   //
   // If that fails, try using the OSVERSIONINFO structure.

   ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
   osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);

   bOsVersionInfoEx = GetVersionEx ((OSVERSIONINFO *) &osvi);

   if( bOsVersionInfoEx == 0 )
   {
      // If OSVERSIONINFOEX doesn't work, try OSVERSIONINFO.

      osvi.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);
      if (! GetVersionEx ( (OSVERSIONINFO *) &osvi) )
         return FALSE;
   }

   return osvi.dwMajorVersion;
}

//
//
// INtDll
//
//
INtDll::PNtQuerySystemInformation INtDll::NtQuerySystemInformation = NULL;
INtDll::PNtQueryObject INtDll::NtQueryObject = NULL;
INtDll::PNtQueryInformationThread INtDll::NtQueryInformationThread = NULL;
INtDll::PNtQueryInformationFile INtDll::NtQueryInformationFile = NULL;
INtDll::PNtQueryInformationProcess INtDll::NtQueryInformationProcess = NULL;
DWORD INtDll::dwNTMajorVersion = SystemInfoUtils::GetNTMajorVersion();

BOOL INtDll::NtDllStatus = INtDll::Init();

BOOL INtDll::Init()
{
 // Get the NtDll function pointers
 NtQuerySystemInformation = (PNtQuerySystemInformation)
     GetProcAddress( GetModuleHandle( _T( "ntdll.dll" ) ),
                    _T("NtQuerySystemInformation") );

 NtQueryObject = (PNtQueryObject)
     GetProcAddress( GetModuleHandle( _T( "ntdll.dll" ) ),
                    _T("NtQueryObject") );

 NtQueryInformationThread = (PNtQueryInformationThread)
     GetProcAddress( GetModuleHandle( _T( "ntdll.dll" ) ),
                    _T("NtQueryInformationThread") );

 NtQueryInformationFile = (PNtQueryInformationFile)
     GetProcAddress( GetModuleHandle( _T( "ntdll.dll" ) ),
                    _T("NtQueryInformationFile") );

 NtQueryInformationProcess = (PNtQueryInformationProcess)
     GetProcAddress( GetModuleHandle( _T( "ntdll.dll" ) ),
                    _T("NtQueryInformationProcess") );

 return  NtQuerySystemInformation != NULL &&
   NtQueryObject    != NULL &&
   NtQueryInformationThread != NULL &&
   NtQueryInformationFile  != NULL &&
   NtQueryInformationProcess != NULL;
}

//
//
// SystemProcessInformation
//
//

SystemProcessInformation::SystemProcessInformation( BOOL bRefresh )
{
 m_pBuffer = (UCHAR*)VirtualAlloc ((void*)0x100000,
      BufferSize,
      MEM_COMMIT,
      PAGE_READWRITE);

 if ( bRefresh )
  Refresh();
}

SystemProcessInformation::~SystemProcessInformation()
{
 VirtualFree( m_pBuffer, 0, MEM_RELEASE );
}

BOOL SystemProcessInformation::Refresh()
{
 m_ProcessInfos.RemoveAll();
 m_pCurrentProcessInfo = NULL;

 if ( !NtDllStatus || m_pBuffer == NULL )
  return FALSE;
 
 // query the process information
 if ( INtDll::NtQuerySystemInformation( 5, m_pBuffer, BufferSize, NULL ) != 0 )
  return FALSE;

 DWORD currentProcessID = GetCurrentProcessId(); //Current Process ID

 SYSTEM_PROCESS_INFORMATION* pSysProcess = (SYSTEM_PROCESS_INFORMATION*)m_pBuffer;
 do
 {
  // fill the process information map
  m_ProcessInfos.SetAt( pSysProcess->dUniqueProcessId, pSysProcess );

  // we found this process
  if ( pSysProcess->dUniqueProcessId == currentProcessID )
   m_pCurrentProcessInfo = pSysProcess;

  // get the next process information block
  if ( pSysProcess->dNext != 0 )
   pSysProcess = (SYSTEM_PROCESS_INFORMATION*)((UCHAR*)pSysProcess + pSysProcess->dNext);
  else
   pSysProcess = NULL;

 } while ( pSysProcess != NULL );

 return TRUE;
}

//
//
// SystemThreadInformation
//
//

SystemThreadInformation::SystemThreadInformation( DWORD pID, BOOL bRefresh )
{
 m_processId = pID;

 if ( bRefresh )
  Refresh();
}

BOOL SystemThreadInformation::Refresh()
{
 // Get the Thread objects ( set the filter to "Thread" )
 SystemHandleInformation hi( m_processId );
 BOOL rc = hi.SetFilter( _T("Thread"), TRUE );

 m_ThreadInfos.RemoveAll();

 if ( !rc )
  return FALSE;

 THREAD_INFORMATION ti;

 // Iterating through the found Thread objects
 for ( POSITION pos = hi.m_HandleInfos.GetHeadPosition(); pos != NULL; )
 {
  SystemHandleInformation::SYSTEM_HANDLE& h = hi.m_HandleInfos.GetNext(pos);
  
  ti.ProcessId = h.ProcessID;
  ti.ThreadHandle = (HANDLE)h.HandleNumber;
  
  // This is one of the threads we are lokking for
  if ( SystemHandleInformation::GetThreadId( ti.ThreadHandle, ti.ThreadId, ti.ProcessId ) )
   m_ThreadInfos.AddTail( ti );
 }

 return TRUE;
}

//
//
// SystemHandleInformation
//
//

SystemHandleInformation::SystemHandleInformation( DWORD pID, BOOL bRefresh, LPCTSTR lpTypeFilter )
{
 m_processId = pID;
 
 // Set the filter
 SetFilter( lpTypeFilter, bRefresh );
}

SystemHandleInformation::~SystemHandleInformation()
{
}

BOOL SystemHandleInformation::SetFilter( LPCTSTR lpTypeFilter, BOOL bRefresh )
{
 // Set the filter ( default = all objects )
 m_strTypeFilter = lpTypeFilter == NULL ? _T("") : lpTypeFilter;

 return bRefresh ? Refresh() : TRUE;
}

const CString& SystemHandleInformation::GetFilter()
{
 return m_strTypeFilter;
}

BOOL SystemHandleInformation::IsSupportedHandle( SYSTEM_HANDLE& handle )
{
 //Here you can filter the handles you don't want in the Handle list

 // Windows 2000 supports everything :)
 if ( dwNTMajorVersion >= 5 )
  return TRUE;

 //NT4 System process doesn't like if we bother his internal security :)
 if ( handle.ProcessID == 2 && handle.HandleType == 16 )
  return FALSE;

 return TRUE;
}

BOOL SystemHandleInformation::Refresh()
{
 DWORD size = 0x2000;
 DWORD needed = 0;
 DWORD i = 0;
 BOOL  ret = TRUE;
 CString strType;

 m_HandleInfos.RemoveAll();

 if ( !INtDll::NtDllStatus )
  return FALSE;

 // Allocate the memory for the buffer
 SYSTEM_HANDLE_INFORMATION* pSysHandleInformation = (SYSTEM_HANDLE_INFORMATION*)
    VirtualAlloc( NULL, size, MEM_COMMIT, PAGE_READWRITE );

 if ( pSysHandleInformation == NULL )
  return FALSE;

 // Query the needed buffer size for the objects ( system wide )
 if ( INtDll::NtQuerySystemInformation( 16, pSysHandleInformation, size, &needed ) != 0 )
 {
  if ( needed == 0 )
  {
   ret = FALSE;
   goto cleanup;
  }

  // The size was not enough
  VirtualFree( pSysHandleInformation, 0, MEM_RELEASE );

  pSysHandleInformation = (SYSTEM_HANDLE_INFORMATION*)
    VirtualAlloc( NULL, size = needed + 256, MEM_COMMIT, PAGE_READWRITE );
 }
 
 if ( pSysHandleInformation == NULL )
  return FALSE;

 // Query the objects ( system wide )
 if ( INtDll::NtQuerySystemInformation( 16, pSysHandleInformation, size, NULL ) != 0 )
 {
  ret = FALSE;
  goto cleanup;
 }
 
 // Iterating through the objects
 for ( i = 0; i < pSysHandleInformation->Count; i++ )
 {
  if ( !IsSupportedHandle( pSysHandleInformation->Handles[i] ) )
   continue;
  
  // ProcessId filtering check
  if ( pSysHandleInformation->Handles[i].ProcessID == m_processId || m_processId == (DWORD)-1 )
  {
   BOOL bAdd = FALSE;
   
   if ( m_strTypeFilter == _T("") )
    bAdd = TRUE;
   else
   {
    // Type filtering
    GetTypeToken( (HANDLE)pSysHandleInformation->Handles[i].HandleNumber, strType, pSysHandleInformation->Handles[i].ProcessID  );

    bAdd = strType == m_strTypeFilter;
   }

   // That's it. We found one.
   if ( bAdd )
   { 
    pSysHandleInformation->Handles[i].HandleType = (WORD)(pSysHandleInformation->Handles[i].HandleType % 256);
    
    m_HandleInfos.AddTail( pSysHandleInformation->Handles[i] );

   }
  }
 }

cleanup:
 
 if ( pSysHandleInformation != NULL )
  VirtualFree( pSysHandleInformation, 0, MEM_RELEASE );

 return ret;
}

HANDLE SystemHandleInformation::OpenProcess( DWORD processId )
{
 // Open the process for handle duplication
 return ::OpenProcess( PROCESS_DUP_HANDLE, TRUE, processId );
}

HANDLE SystemHandleInformation::DuplicateHandle( HANDLE hProcess, HANDLE hRemote )
{
 HANDLE hDup = NULL;

 // Duplicate the remote handle for our process
 ::DuplicateHandle( hProcess, hRemote, GetCurrentProcess(), &hDup, 0, FALSE, DUPLICATE_SAME_ACCESS );

 return hDup;
}

//Information functions
BOOL SystemHandleInformation::GetTypeToken( HANDLE h, CString& str, DWORD processId )
{
 ULONG size = 0x2000;
 UCHAR* lpBuffer = NULL;
 BOOL ret = FALSE;

 HANDLE handle;
 HANDLE hRemoteProcess = NULL;
 BOOL remote = processId != GetCurrentProcessId();
 
 if ( !NtDllStatus )
  return FALSE;

 if ( remote )
 {
  // Open the remote process
  hRemoteProcess = OpenProcess( processId );
  
  if ( hRemoteProcess == NULL )
   return FALSE;

  // Duplicate the handle
  handle = DuplicateHandle( hRemoteProcess, h );
 }
 else
  handle = h;

 // Query the info size
 INtDll::NtQueryObject( handle, 2, NULL, 0, &size );

 lpBuffer = new UCHAR[size];

 // Query the info size ( type )
 if ( INtDll::NtQueryObject( handle, 2, lpBuffer, size, NULL ) == 0 )
 {
  str = _T("");
  SystemInfoUtils::LPCWSTR2CString( (LPCWSTR)(lpBuffer+0x60), str );

  ret = TRUE;
 }

 if ( remote )
 {
  if ( hRemoteProcess != NULL )
   CloseHandle( hRemoteProcess );

  if ( handle != NULL )
   CloseHandle( handle );
 }
 
 if ( lpBuffer != NULL )
  delete [] lpBuffer;

 return ret;
}

BOOL SystemHandleInformation::GetType( HANDLE h, WORD& type, DWORD processId )
{
 CString strType;

 type = OB_TYPE_UNKNOWN;

 if ( !GetTypeToken( h, strType, processId ) )
  return FALSE;

 return GetTypeFromTypeToken( strType, type );
}

BOOL SystemHandleInformation::GetTypeFromTypeToken( LPCTSTR typeToken, WORD& type )
{
 const WORD count = 27;
 CString constStrTypes[count] = {
  _T(""), _T(""), _T("Directory"), _T("SymbolicLink"), _T("Token"),
  _T("Process"), _T("Thread"), _T("Unknown7"), _T("Event"), _T("EventPair"), _T("Mutant"),
  _T("Unknown11"), _T("Semaphore"), _T("Timer"), _T("Profile"), _T("WindowStation"),
  _T("Desktop"), _T("Section"), _T("Key"), _T("Port"), _T("WaitablePort"),
  _T("Unknown21"), _T("Unknown22"), _T("Unknown23"), _T("Unknown24"),
  _T("IoCompletion"), _T("File") };

 type = OB_TYPE_UNKNOWN;

 for ( WORD i = 1; i < count; i++ )
  if ( constStrTypes[i] == typeToken )
  {
   type = i;
   return TRUE;
  }
  
 return FALSE;
}

BOOL SystemHandleInformation::GetName( HANDLE handle, CString& str, DWORD processId )
{
 WORD type = 0;

 if ( !GetType( handle, type, processId  ) )
  return FALSE;

 return GetNameByType( handle, type, str, processId );
}

BOOL SystemHandleInformation::GetNameByType( HANDLE h, WORD type, CString& str, DWORD processId )
{
 ULONG size = 0x2000;
 UCHAR* lpBuffer = NULL;
 BOOL ret = FALSE;

 HANDLE handle;
 HANDLE hRemoteProcess = NULL;
 BOOL remote = processId != GetCurrentProcessId();
 DWORD dwId = 0;
 
 if ( !NtDllStatus )
  return FALSE;

 if ( remote )
 {
  hRemoteProcess = OpenProcess( processId );
  
  if ( hRemoteProcess == NULL )
   return FALSE;

  handle = DuplicateHandle( hRemoteProcess, h );
 }
 else
  handle = h;

 // let's be happy, handle is in our process space, so query the infos :)
 switch( type )
 {
 case OB_TYPE_PROCESS:
  GetProcessId( handle, dwId );
  
  str.Format( _T("PID: 0x%X"), dwId );
   
  ret = TRUE;
  goto cleanup;
  break;

 case OB_TYPE_THREAD:
  GetThreadId( handle, dwId );

  str.Format( _T("TID: 0x%X") , dwId );
    
  ret = TRUE;
  goto cleanup;
  break;

 case OB_TYPE_FILE:
  ret = GetFileName( handle, str );

  // access denied :(
  if ( ret && str == _T("") )
   goto cleanup;
  break;

 };

 INtDll::NtQueryObject ( handle, 1, NULL, 0, &size );

 // let's try to use the default
 if ( size == 0 )
  size = 0x2000;

 lpBuffer = new UCHAR[size];

 if ( INtDll::NtQueryObject( handle, 1, lpBuffer, size, NULL ) == 0 )
 {
  SystemInfoUtils::Unicode2CString( (UNICODE_STRING*)lpBuffer, str );
  ret = TRUE;
 }
 
cleanup:

 if ( remote )
 {
  if ( hRemoteProcess != NULL )
   CloseHandle( hRemoteProcess );

  if ( handle != NULL )
   CloseHandle( handle );
 }

 if ( lpBuffer != NULL )
  delete [] lpBuffer;
 
 return ret;
}

//Thread related functions
BOOL SystemHandleInformation::GetThreadId( HANDLE h, DWORD& threadID, DWORD processId )
{
 SystemThreadInformation::BASIC_THREAD_INFORMATION ti;
 HANDLE handle;
 HANDLE hRemoteProcess = NULL;
 BOOL remote = processId != GetCurrentProcessId();
 
 if ( !NtDllStatus )
  return FALSE;

 if ( remote )
 {
  // Open process
  hRemoteProcess = OpenProcess( processId );
  
  if ( hRemoteProcess == NULL )
   return FALSE;

  // Duplicate handle
  handle = DuplicateHandle( hRemoteProcess, h );
 }
 else
  handle = h;
 
 // Get the thread information
 if ( INtDll::NtQueryInformationThread( handle, 0, &ti, sizeof(ti), NULL ) == 0 )
  threadID = ti.ThreadId;

 if ( remote )
 {
  if ( hRemoteProcess != NULL )
   CloseHandle( hRemoteProcess );

  if ( handle != NULL )
   CloseHandle( handle );
 }

 return TRUE;
}

//Process related functions
BOOL SystemHandleInformation::GetProcessPath( HANDLE h, CString& strPath, DWORD remoteProcessId )
{
 h; strPath; remoteProcessId;

 strPath.Format( _T("%d"), remoteProcessId );

 return TRUE;
}

BOOL SystemHandleInformation::GetProcessId( HANDLE h, DWORD& processId, DWORD remoteProcessId )
{
 BOOL ret = FALSE;
 HANDLE handle;
 HANDLE hRemoteProcess = NULL;
 BOOL remote = remoteProcessId != GetCurrentProcessId();
 SystemProcessInformation::PROCESS_BASIC_INFORMATION pi;
 
 ZeroMemory( &pi, sizeof(pi) );
 processId = 0;
 
 if ( !NtDllStatus )
  return FALSE;

 if ( remote )
 {
  // Open process
  hRemoteProcess = OpenProcess( remoteProcessId );
  
  if ( hRemoteProcess == NULL )
   return FALSE;

  // Duplicate handle
  handle = DuplicateHandle( hRemoteProcess, h );
 }
 else
  handle = h;

 // Get the process information
 if ( INtDll::NtQueryInformationProcess( handle, 0, &pi, sizeof(pi), NULL) == 0 )
 {
  processId = pi.UniqueProcessId;
  ret = TRUE;
 }

 if ( remote )
 {
  if ( hRemoteProcess != NULL )
   CloseHandle( hRemoteProcess );

  if ( handle != NULL )
   CloseHandle( handle );
 }

 return ret;
}

//File related functions
void SystemHandleInformation::GetFileNameThread( PVOID pParam )
{
 // This thread function for getting the filename
 // if access denied, we hang up in this function,
 // so if it times out we just kill this thread
 GetFileNameThreadParam* p = (GetFileNameThreadParam*)pParam;

 UCHAR lpBuffer[0x1000];
 DWORD iob[2];
 
 p->rc = INtDll::NtQueryInformationFile( p->hFile, iob, lpBuffer, sizeof(lpBuffer), 9 );

 if ( p->rc == 0 )
  *p->pName = lpBuffer;
}

BOOL SystemHandleInformation::GetFileName( HANDLE h, CString& str, DWORD processId )
{
 BOOL ret= FALSE;
 HANDLE hThread = NULL;
 GetFileNameThreadParam tp;
 HANDLE handle;
 HANDLE hRemoteProcess = NULL;
 BOOL remote = processId != GetCurrentProcessId();
 
 if ( !NtDllStatus )
  return FALSE;

 if ( remote )
 {
  // Open process
  hRemoteProcess = OpenProcess( processId );
  
  if ( hRemoteProcess == NULL )
   return FALSE;

  // Duplicate handle
  handle = DuplicateHandle( hRemoteProcess, h );
 }
 else
  handle = h;

 tp.hFile = handle;
 tp.pName = &str;
 tp.rc = 0;

 // Let's start the thread to get the file name
 hThread = (HANDLE)_beginthread( GetFileNameThread, 0, &tp );

 if ( hThread == NULL )
 {
  ret = FALSE;
  goto cleanup;
 }

 // Wait for finishing the thread
 if ( WaitForSingleObject( hThread, 100 ) == WAIT_TIMEOUT )
 { 
  // Access denied
  // Terminate the thread
  TerminateThread( hThread, 0 );

  str = _T("");

  ret = TRUE;
 }
 else
  ret = ( tp.rc == 0 );

cleanup:

 if ( remote )
 {
  if ( hRemoteProcess != NULL )
   CloseHandle( hRemoteProcess );

  if ( handle != NULL )
   CloseHandle( handle );
 }
  
 return ret;
}

//
//
// SystemModuleInformation
//
//

SystemModuleInformation::SystemModuleInformation( DWORD pID, BOOL bRefresh )
{
 m_processId = pID;

 if ( bRefresh )
  Refresh();
}

void SystemModuleInformation::GetModuleListForProcess( DWORD processID )
{
 DWORD i = 0;
 DWORD cbNeeded = 0;
 HMODULE* hModules = NULL;
 MODULE_INFO moduleInfo;

 // Open process to read to query the module list
 HANDLE hProcess = OpenProcess( PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, processID );

 if ( hProcess == NULL )
  goto cleanup;

 //Get the number of modules
 if ( !(*m_EnumProcessModules)( hProcess, NULL, 0, &cbNeeded ) )
  goto cleanup;

 hModules = new HMODULE[ cbNeeded / sizeof( HMODULE ) ];

 //Get module handles
    if ( !(*m_EnumProcessModules)( hProcess, hModules, cbNeeded, &cbNeeded ) )
  goto cleanup;
 
 for ( i = 0; i < cbNeeded / sizeof( HMODULE ); i++ )
 {
  moduleInfo.ProcessId = processID;
  moduleInfo.Handle = hModules[i];
  
  //Get module full paths
  if ( (*m_GetModuleFileNameEx)( hProcess, hModules[i], moduleInfo.FullPath, _MAX_PATH ) )
   m_ModuleInfos.AddTail( moduleInfo );
 }

cleanup:
 if ( hModules != NULL )
  delete [] hModules;

 if ( hProcess != NULL )
  CloseHandle( hProcess );
}

BOOL SystemModuleInformation::Refresh()
{
 BOOL rc = FALSE;
 m_EnumProcessModules = NULL;
 m_GetModuleFileNameEx = NULL;

 m_ModuleInfos.RemoveAll();
 
 //Load Psapi.dll
 HINSTANCE hDll = LoadLibrary( "PSAPI.DLL" );
 
 if ( hDll == NULL )
 {
  rc = FALSE;
  goto cleanup;
 }

 //Get Psapi.dll functions
 m_EnumProcessModules = (PEnumProcessModules)GetProcAddress( hDll, "EnumProcessModules" );

 m_GetModuleFileNameEx = (PGetModuleFileNameEx)GetProcAddress( hDll,
#ifdef UNICODE
        "GetModuleFileNameExW" );
#else
        "GetModuleFileNameExA" );
#endif

 if ( m_GetModuleFileNameEx == NULL || m_EnumProcessModules == NULL )
 {
  rc = FALSE;
  goto cleanup;
 }
 
 // Everey process or just a particular one
 if ( m_processId != -1 )
  // For a particular one
  GetModuleListForProcess( m_processId );
 else
 {
  // Get teh process list
  DWORD pID;
  SystemProcessInformation::SYSTEM_PROCESS_INFORMATION* p = NULL;
  SystemProcessInformation pi( TRUE );
  
  if ( pi.m_ProcessInfos.GetStartPosition() == NULL )
  {
   rc = FALSE;
   goto cleanup;
  }

  // Iterating through the processes and get the module list
  for ( POSITION pos = pi.m_ProcessInfos.GetStartPosition(); pos != NULL; )
  {
   pi.m_ProcessInfos.GetNextAssoc( pos, pID, p );
   GetModuleListForProcess( pID );
  }
 }
 
 rc = TRUE;

cleanup:

 //Free psapi.dll
 if ( hDll != NULL )
  FreeLibrary( hDll );

 return rc;
}

//
//
// SystemWindowInformation
//
//

SystemWindowInformation::SystemWindowInformation( DWORD pID, BOOL bRefresh )
{
 m_processId = pID;

 if ( bRefresh )
  Refresh();
}

BOOL SystemWindowInformation::Refresh()
{
 m_WindowInfos.RemoveAll();

 // Enumerating the windows
 EnumWindows( EnumerateWindows, (LPARAM)this );
 
 return TRUE;
}

BOOL CALLBACK SystemWindowInformation::EnumerateWindows( HWND hwnd, LPARAM lParam )
{
 SystemWindowInformation* _this = (SystemWindowInformation*)lParam;
 WINDOW_INFO wi;

 wi.hWnd = hwnd;
 GetWindowThreadProcessId(hwnd, &wi.ProcessId ) ;

 // Filtering by process ID
 if ( _this->m_processId == -1 || _this->m_processId == wi.ProcessId )
 {
  GetWindowText( hwnd, wi.Caption, MaxCaptionSize );

  // That is we are looking for
  if ( GetLastError() == 0 )
   _this->m_WindowInfos.AddTail( wi );
 }

 return TRUE;
};



 
张风 @ 2006-10-26 10:47


//     ComFun/ComFun.h 

#ifndef COMFUN_H
#define COMFUN_H

#define DLG_HWND(ID)  ::GetDlgItem(this->m_hWnd,ID)
#define MAXCHAR_PRELINE 4096

typedef DWORD (WINAPI *Fun0)(void);
typedef DWORD (WINAPI *Fun1)(DWORD);
typedef DWORD (WINAPI *Fun2)(DWORD,DWORD);
typedef DWORD (WINAPI *Fun3)(DWORD,DWORD,DWORD);
typedef DWORD (WINAPI *Fun4)(DWORD,DWORD,DWORD,DWORD);
typedef DWORD (WINAPI *Fun5)(DWORD,DWORD,DWORD,DWORD,DWORD);
typedef DWORD (WINAPI *Fun6)(DWORD,DWORD,DWORD,DWORD,DWORD,DWORD);
typedef DWORD (WINAPI *Fun7)(DWORD,DWORD,DWORD,DWORD,DWORD,DWORD,DWORD);
typedef DWORD (WINAPI *Fun8)(DWORD,DWORD,DWORD,DWORD,DWORD,DWORD,DWORD,DWORD);
typedef DWORD (WINAPI *Fun9)(DWORD,DWORD,DWORD,DWORD,DWORD,DWORD,DWORD,DWORD,DWORD);
typedef DWORD (WINAPI *Fun10)(DWORD,DWORD,DWORD,DWORD,DWORD,DWORD,DWORD,DWORD,DWORD,DWORD);
typedef DWORD (WINAPI *Fun11)(DWORD,DWORD,DWORD,DWORD,DWORD,DWORD,DWORD,DWORD,DWORD,DWORD,DWORD);
typedef DWORD (WINAPI *Fun12)(DWORD,DWORD,DWORD,DWORD,DWORD,DWORD,DWORD,DWORD,DWORD,DWORD,DWORD,DWORD);

typedef DWORD (WINAPIV *VFun0)(void);
typedef DWORD (WINAPIV *VFun1)(DWORD);
typedef DWORD (WINAPIV *VFun2)(DWORD,DWORD);
typedef DWORD (WINAPIV *VFun3)(DWORD,DWORD,DWORD);
typedef DWORD (WINAPIV *VFun4)(DWORD,DWORD,DWORD,DWORD);
typedef DWORD (WINAPIV *VFun5)(DWORD,DWORD,DWORD,DWORD,DWORD);
typedef DWORD (WINAPIV *VFun6)(DWORD,DWORD,DWORD,DWORD,DWORD,DWORD);
typedef DWORD (WINAPIV *VFun7)(DWORD,DWORD,DWORD,DWORD,DWORD,DWORD,DWORD);
typedef DWORD (WINAPIV *VFun8)(DWORD,DWORD,DWORD,DWORD,DWORD,DWORD,DWORD,DWORD);
typedef DWORD (WINAPIV *VFun9)(DWORD,DWORD,DWORD,DWORD,DWORD,DWORD,DWORD,DWORD,DWORD);
typedef DWORD (WINAPIV *VFun10)(DWORD,DWORD,DWORD,DWORD,DWORD,DWORD,DWORD,DWORD,DWORD,DWORD);
typedef DWORD (WINAPIV *VFun11)(DWORD,DWORD,DWORD,DWORD,DWORD,DWORD,DWORD,DWORD,DWORD,DWORD,DWORD);
typedef DWORD (WINAPIV *VFun12)(DWORD,DWORD,DWORD,DWORD,DWORD,DWORD,DWORD,DWORD,DWORD,DWORD,DWORD,DWORD);


#ifndef _PROC_HANDLE_INFO
//#pragma pack(1)
 typedef struct _PROC_HANDLE_INFO
 {
 ULONG ProcessId;    //0  进程的标识ID
 UCHAR ObjectTypeNumber;   //4  对象类型
 UCHAR Flags;     //5  0x01 = PROTECT_FROM_CLOSE,0x02 = INHERIT
 USHORT Handle;     //6  对象句柄的数值
 PVOID Object;     //8  对象句柄所指的内核对象地址
 DWORD GrantedAccess;   //C  创建句柄时所准许的对象的访问权
 }PROC_HANDLE_INFO, * PPROC_HANDLE_INFO;
#endif

typedef enum _tag_DATATPYE //void * ptr 使用
{
    DataType_First  = 0,

 DataType_DWORD = 0,     //DWORD [];
 DataType_int = 1,     //int [];
 DataType_charPA = 2,     //char *[]; Point Arry
 DataType_charPA_NoCase = 3,//char *[]; 不区分大小写
 DataType_charAA = 3,     //char  [][256]     Ary Ary
 DataType_charAS = 4,     //char  [][size]    Ary Ary(size) 指定大小
 DataType_float = 5,     //float [];
 DataType_double = 6,     //double    [];
 DataType_WORD = 7,     //WORD  [];
 DataType_short = 8,     //short [];
 DataType_BYTE = 9,     //BYTE  [];
 DataType_char = 10,     //char  [];
    DataType_LONG   = 11,       //LONG  []; 与 DataType_int = 1
    DataType_PSTR   = 12,
    DataType_PWSTR  = 13,
    DataType_PPSTR  = 14,
    DataType_PPWSTR = 15,

    DataType_Last   = 15
}DATATPYE;


int  Msgb();
int  Msgs(const char *szText,const char *szCapt = NULL);
int  Msgs(const wchar_t *szText,const wchar_t *szCapt = NULL);
int  Msgsd(const char *szText,const char *szCapt = NULL);
int  Msgsd(const wchar_t *szText,const wchar_t *szCapt = NULL);
int  Msgd(DWORD val);
int  Msgd(DWORD val, DWORD val2);
int  Msgd(const char *szText, DWORD val);
int  Msgd(const char *szText, DWORD val1, DWORD val2);
int  MsgA(const char * format, ...);
int  MsgW(const wchar_t * format, ...);
DWORD memvalset(void * mem,BYTE oldval,BYTE newval,DWORD n);
DWORD   StrReplaceChar(TCHAR * pStr, TCHAR tSor, TCHAR tDest);
TCHAR * MemToHex(void * pMem, int nSize, TCHAR * pBuffer, DWORD dwAddress = 0);
int  Msghex(void * dat, DWORD n);
DWORD Convert(DWORD * val,...);
char *      _cdecl zsprintfA(char * str, const char * lpszFormat,...);
wchar_t *   _cdecl zsprintfW(wchar_t * wstr, const wchar_t * lpszFormat,...);
char *      _cdecl zwsprintfA(char * str, const char * lpszFormat,...);
wchar_t *   _cdecl zwsprintfW(wchar_t * wstr, const wchar_t * lpszFormat,...);
char *      _cdecl zsnprintfA(char * str, size_t size, const char * format,...);
wchar_t *   _cdecl zsnprintfW(wchar_t * wstr, size_t size, const wchar_t * format,...);
DWORD MsgFmt(const char * lpszFormat, ...);
DWORD MsgFmt(const wchar_t * lpwzFormat, ...);
int  Msgerr(const char *lpszCapt = NULL);
char * StrIns(char *str, int p, char *InsertStr);
char * StrDel(char *str, int p, int n);
int  StrReplace(char *str, char *scr_str, char *dest_str);
DWORD Str2DWORD(char *str);
DWORD   Str2DWORD(wchar_t *wstr);
DWORD StrtoFormatArry(char *str, char *Arry[], DWORD ArryCount, DWORD ArrySize = 1024);
DWORD   StrtoFormatArry(wchar_t *wstr, wchar_t *Arry[], DWORD ArryCount, DWORD ArrySize = 1024);
DWORD StrFormatCmp(char *str_sp, char *str2); //带通配符比较 ? *
TCHAR * ReadLine(TCHAR * str,TCHAR * outstr); //注意 outstr 有足够大
BOOL Setexecdir(char * lpszCurDir);
char * Getprocmd(DWORD dwPid,char *lpszCmdLine); //调用前请确定权限
DWORD Copystr(const char *lpszStr);
int  Keybd_str(const char *lpszStr,int iTime);
int  Keybd_stream(int arr[][3],int n);
void EdtaddstrA(const char *str, HWND hd);
void    EdtaddstrW(const wchar_t *wstr, HWND hd);
DWORD   DumpMem(char *fname, void * pMem, DWORD dwSize);
DWORD   LogStr(char *fname , const char * lpszFormat, ...);
DWORD zLogstr(char *str,char *fname = NULL);
DWORD   zLogstr(wchar_t *wstr,wchar_t *fname = NULL);
DWORD CreateDir(char *Dir);
bool    DeleteDirectory(char * dirname);
DWORD   CopyDirectoryA(LPCSTR lpDestinationPath, LPCSTR lpSourcePath);
DWORD MsgAry(void * ptr, DWORD n, DATATPYE type, DWORD size = 0);
DWORD Sort(void * ptr, DWORD pOrder[], DWORD n, DATATPYE type);
DWORD GetProcList(TCHAR *szProcName[], DWORD *dwPid, DWORD dwMaxCount);
DWORD GetProcHandle(DWORD pid, PROC_HANDLE_INFO StructHandle[], DWORD dwStructStcCount);

#ifdef UNICODE
#define Msg         MsgW
#define Edtaddstr   EdtaddstrW
#define zsprintf    zsprintfW
#define zwsprintf   zwsprintfW
#define zsnprintf   zsnprintfW
#else
#define Msg MsgA
#define Edtaddstr   EdtaddstrA
#define zsprintf    zsprintfA
#define zwsprintf   zwsprintfA
#define zsnprintf   zsnprintfA
#endif

int     wctoc(const PWSTR instr, LPSTR outstr);
int     ctowc(const PCSTR instr, PWSTR outstr);
LPSTR   TcharToChar (const PTSTR tstr, LPSTR str);
PWSTR   TcharTowChar(const PTSTR tstr, PWSTR wstr);
PTSTR   CharToTchar (const LPSTR  str, PTSTR tstr);
PTSTR   wCharToTchar(const PWSTR wstr, PTSTR tstr);
int     GetInput(HWND hWnd, TCHAR *pCapt, TCHAR * pText, TCHAR * pOutBuf, DWORD dwBufSize, int nWidth = 120, int nHeigh = 62);

 

#endif

//     ComFun/ComFun.h End



//     ComFun/ComFun.cpp 

#include "StdAfx.h"
#include <stdlib.h>
#include <stdio.h>
#include "ComFun.h"

#include <tchar.h>
#pragma warning(disable: 4311 4312 )

int Msgb()
{
 return MessageBeep(0);
}

int Msgs(const char *szText,const char *szCapt)
{
 if(szCapt) return ::MessageBoxA(0,szText,szCapt,MB_OK);
 else  return ::MessageBoxA(0,szText,"Msgs",MB_OK);
}

int Msgs(const wchar_t *szText,const wchar_t *szCapt)
{
 if(szCapt) return ::MessageBoxW(0,szText,szCapt,MB_OK);
 else  return ::MessageBoxW(0,szText,L"Msgs",MB_OK);
}

int Msgsd(const char *szText,const char *szCapt)
{
 char buffer[1000];
 wsprintfA(buffer,"|%s|",szText);
 if(szCapt) return ::MessageBoxA(0,buffer,szCapt,MB_OK);
 else  return  ::MessageBoxA(0,buffer,"Msgsd",MB_OK);
}

int Msgsd(const wchar_t *szText,const wchar_t *szCapt)
{
 wchar_t buffer[1000];
 wsprintfW(buffer,L"|%s|",szText);
 if(szCapt) return ::MessageBoxW(0,buffer,szCapt,MB_OK);
 else  return  ::MessageBoxW(0,buffer,L"Msgsd",MB_OK);
}

int Msgd(DWORD val)
{
 char str[1000];
 wsprintfA(str,"%d Hex:%08X",val,val);
 return ::MessageBoxA(0,str,"Msgd",MB_OK);
}

int Msgd(DWORD val,DWORD val2)
{
 char str[1000];
 wsprintfA(str,"%d Hex:%08X/r/n%d Hex:%08X",val,val,val2,val2);
 return ::MessageBoxA(0,str,"Msgd",MB_OK);
}

int Msgd(const char *szText, DWORD val)
{
 char str[1000];
 wsprintfA(str,"%d Hex:%08X",val,val);
 return ::MessageBoxA(0,str,szText,MB_OK);
}

int Msgd(const char *szText, DWORD val,DWORD val2)
{
 char str[1000];
 wsprintfA(str,"%d Hex:%08X/r/n%d Hex:%08X",val,val,val2,val2);
 return ::MessageBoxA(0,str,szText,MB_OK);
}

int MsgA(const char * format, ...)
{
 DWORD re=-1,size= 0x1000;
 char *buffer = NULL;
 va_list args;
 va_start(args, format);
 for(;re == -1;size *= 2)
 {
  if(buffer) free(buffer);
  buffer = (char *)malloc(size * sizeof(wchar_t) + 2);
  if(buffer == NULL) return 0;
  re=_vsnprintf( buffer, size ,format, args);
 }
 va_end(args);
 re = ::MessageBoxA(0,buffer,"Msg",MB_OK);
 if(buffer) free(buffer);
 return re;
}

int MsgW(const wchar_t * format, ...)
{
 DWORD re=-1,size= 0x1000;
 wchar_t *buffer = NULL;
 va_list args;
 va_start(args, format);
 for(;re == -1;size *= 2)
 {
  if(buffer) free(buffer);
  buffer = (wchar_t *)malloc(size * sizeof(wchar_t) + 2);
  if(buffer == NULL) return 0;
  re=_vsnwprintf( buffer, size ,format, args);
 }
 va_end(args);
 re = ::MessageBoxW(0,buffer,L"Msg",MB_OK);
 if(buffer) free(buffer);
 return re;
}

DWORD memvalset(void * mem,BYTE oldval,BYTE newval,DWORD n)
{
 for(DWORD i=0;i<n;i++)
 {
  if(((BYTE *)mem)[i] == oldval)
   ((BYTE *)mem)[i] = newval;
 }
 return n;
}

DWORD StrReplaceChar(TCHAR * pStr, TCHAR tSor, TCHAR tDest)
{
    DWORD   dwCount = 0, n = (DWORD)_tcslen(pStr);
    for(DWORD i=0;i<n;i++)
    {
        if(pStr[i] == tSor)
        {
            pStr[i] = tDest;
            dwCount ++;
        }
    }
    return dwCount;
}

TCHAR * MemToHex(void * pMem, int nSize, TCHAR * pBuffer, DWORD dwAddress)
{
    BYTE * pDat;
    char buf[1024];
    TCHAR buf1[1024],buf2[1024];
    int i;
    int a,b,p;
    pDat = (BYTE *)pMem;
    a = nSize/16;
    b = nSize%16;
    pBuffer[0] = 0;
    for(i=0; i<a; i++)
    {
        p = i*16;
        memcpy(buf, pDat+p, 16);
        buf[16]=0;
        memvalset(buf,0,' ',16);
        memvalset(buf,9,' ',16);
        memvalset(buf,10,' ',16);
        memvalset(buf,13,' ',16);
        CharToTchar(buf, buf1);
        _stprintf(buf2, _T("%08X: %02X %02X %02X %02X %02X %02X %02X %02X-%02X %02X %02X %02X %02X %02X %02X %02X   %s /r/n"),
            dwAddress,
            pDat[p+0],pDat[p+1],pDat[p+2],pDat[p+3],pDat[p+4],pDat[p+5],pDat[p+6],pDat[p+7],
            pDat[p+8],pDat[p+9],pDat[p+10],pDat[p+11],pDat[p+12],pDat[p+13],pDat[p+14],pDat[p+15],buf1);
        dwAddress += 0x10;
        _tcscat(pBuffer, buf2);
    }
    _stprintf(buf2, _T("%08X: "), dwAddress);
    for(i=0;i<b;i++)
    {
        p=a*16+i;
        if(i == 7) _stprintf(buf1, _T("%02X-"), pDat[p]);
        else  _stprintf(buf1, _T("%02X "), pDat[p]);
        _tcscat(buf2, buf1);
    }
    _stprintf(buf1, _T("%*s"), 50-b*3, _T(" "));
    _tcscat(buf2, buf1);
    memcpy(buf, pDat+a*16, b);
    buf[b]=0;
    memvalset(buf, 0, ' ', b);
    memvalset(buf, 9, ' ', b);
    memvalset(buf,10, ' ', b);
    memvalset(buf,13, ' ', b);
    CharToTchar(buf, buf1);
    _tcscat(pBuffer, buf2);
    _tcscat(pBuffer, buf1);
    return pBuffer;
}

int Msghex(void * dat, DWORD n)
{
 TCHAR *buf;
 buf = (TCHAR *)malloc( (n/16+1)*90*sizeof(TCHAR)  );
    MemToHex(dat, n, buf);
 int re = ::MessageBox(0,buf,_T("Msghex"),MB_OK);
 free(buf);
 return re;
}

DWORD Convert(DWORD * val,...) //convert(&a,fun) convert fun's address to a
{
 DWORD re;
 va_list marker;
 va_start( marker,val);     /* Initialize variable arguments. */
 re=va_arg( marker, DWORD);
 va_end( marker );              /* Reset variable arguments.      */
 if(val) *val=re;
 return re;
}

char * _cdecl zsprintfA(char * str, const char * lpszFormat,...)
{
 va_list args;
 va_start(args, lpszFormat);
 vsprintf(str,lpszFormat,args);
 va_end(args);
 return str;
}

wchar_t * _cdecl zsprintfW(wchar_t * wstr, const wchar_t * lpszFormat,...)
{
    va_list args;
    va_start(args, lpszFormat);
    vswprintf(wstr,lpszFormat,args);
    va_end(args);
    return wstr;
}

char * _cdecl zwsprintfA(char * str, const char * lpszFormat,...)
{
 va_list args;
 va_start(args, lpszFormat);
 wvsprintfA(str,lpszFormat,args);
 va_end(args);
 return str;
}

wchar_t * _cdecl zwsprintfW(wchar_t * wstr, const wchar_t * lpszFormat,...)
{
    va_list args;
    va_start(args, lpszFormat);
    wvsprintfW(wstr,lpszFormat,args);
    va_end(args);
    return wstr;
}

char * _cdecl zsnprintfA(char * str, size_t size, const char * format,...)
{
    va_list args;
    va_start(args, format);
    _vsnprintf( str, size ,format, args);
    va_end(args);
    return str;
}

wchar_t * _cdecl zsnprintfW(wchar_t * wstr, size_t size, const wchar_t * format,...)
{
    va_list args;
    va_start(args, format);
    _vsnwprintf( wstr, size ,format, args);
    va_end(args);
    return wstr;
}

DWORD MsgFmt(const char * lpszFormat, ...)
{
 int re = -1, size = 1024;
 char *buf = NULL;
 va_list args;
 va_start(args, lpszFormat);
 for(;re < 0;size *= 2)
 {
  if(buf) free(buf);
        buf = (char *)malloc(size);
        re = vsprintf(buf, lpszFormat, args);
 }
 va_end(args);
 re = ::MessageBoxA(0,buf,"MsgFmt",MB_OK);
 if(buf) free(buf);
 return re;
}

DWORD MsgFmt(const wchar_t * lpwzFormat, ...)
{
 int re = -1, size = 1024;
 wchar_t *buf = NULL;
 va_list args;
 va_start(args, lpwzFormat);
 for(;re < 0;size *= 2)
 {
  if(buf) free(buf);
        buf = (wchar_t *)malloc(size);
        re = vswprintf(buf, lpwzFormat, args);
 }
 va_end(args);
 re = ::MessageBoxW(0,buf,L"MsgFmt",MB_OK);
 if(buf) free(buf);
 return re;
}

int Msgerr(const char *lpszCapt)
{
 char lpMsgBuf[1000],buf2[1000];
 int a;
 a = GetLastError();
// if(a == 0) return 0;
 FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM,NULL,a,
  MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT),lpMsgBuf,1000,NULL);
 sprintf(buf2,"错误代码: %d    0x%08X/r/n/r/n%s", a, a, lpMsgBuf);
 if(lpszCapt) MessageBoxA( NULL, buf2, lpszCapt, MB_OK|MB_ICONINFORMATION );
 else   MessageBoxA( NULL, buf2, "Msgerr", MB_OK|MB_ICONINFORMATION );
 return a;
}

char * StrIns(char *str, int p, char *InsertStr)
{
 size_t n;
 n = strlen(InsertStr);
 memmove(str+p+n,str+p,strlen(str)+1-p); 
 memcpy(str+p,InsertStr,strlen(InsertStr));
 return str;
}

char * StrDel(char *str, int p, int n)
{
 memmove(str+p,str+p+n,strlen(str)+1-p-n);
 return str;
}

int  StrReplace(char *str, char *scr_str, char *dest_str)
{
 int n = 0;
 char *padd = NULL;
 char *pfind = NULL;
 size_t len1,len2,addn;
 len1 = strlen(scr_str);
 len2 = strlen(dest_str);
 pfind = ::strstr(str,scr_str);
 while(pfind != NULL)
 {
  if(len1 > len2)
  {
   StrDel(str,(int)(pfind-str),(int)(len1-len2));
  }
  else if(len1 < len2)
  {
   addn = len2-len1;
   padd = (char *)::malloc(addn+1);
   if(padd == NULL) {Msgs("malloc ERROR!!!"); return n;}
   memset(padd, ' ',addn);
   padd[addn] = 0;
   StrIns(str, (int)(pfind-str), padd);
   free(padd);
  }
  memcpy(pfind, dest_str, len2);
  n++;
  pfind = ::strstr(pfind+len2,scr_str);
 }
 return n;
}

DWORD Str2DWORD(char *str)
{
 int i = 0;
 size_t len;
 DWORD re;
 len = strlen(str);
 if(str[0] == '0' && (str[1] == 'X' || str[1] == 'x'))
 {
  re = ::strtoul(str,0,16);
 }
 else if(str[len] == 'h' || str[len] == 'H')
 {
  re = ::strtoul(str,0,16);
 }
 else
 {
        re = ::strtoul(str,0,10);
 }
 return re;
}

DWORD Str2DWORD(wchar_t *wstr)
{
    int i = 0;
    size_t len;
    DWORD re;
    len = wcslen(wstr);
    if(wstr[0] == '0' && (wstr[1] == 'X' || wstr[1] == 'x'))
    {
        re = ::wcstoul(wstr,0,16);
    }
    else if(wstr[len] == 'h' || wstr[len] == 'H')
    {
        re = ::wcstoul(wstr,0,16);
    }
    else
    {
        re = ::wcstoul(wstr,0,10);
    }
    return re;
}

TCHAR * ReadLine(TCHAR * str,TCHAR * outstr) //注意 outstr 有足够大
{
 static TCHAR *p = NULL;
 static DWORD n = 0;
 DWORD i = 0;
 if(str == NULL)  //初始化
 {
  p = NULL;
  n = 0;
  return NULL;
 }
 if(outstr == NULL) //返回当前行数
 {
  return (TCHAR *)n;
 }
 if(p == NULL) p = str;
 for(i=0;;i++)
 {
  if(p[i] == 0)      break;
  if(p[i] == 0x0D || p[i] == 0x0A) break;
  outstr[i] = p[i];
 }
 n++;
 if(i == 0) return NULL;
 outstr[i] = 0;
 p += i;
 if(p[0] == 0)       ;
 else if(p[0] == 0x0D && p[1] == 0x0A) p+=2;
 else         p+=1;
 return outstr;
}

// 如(replace "azsdfa/ta" "/" dfh sdg")  ->
// replace 
// "azsdfa a"
// "" dfh sdg"
// token为' ','/t'
DWORD StrtoFormatArry(char *str, char *Arry[], DWORD ArryCount, DWORD ArrySize)
{
 DWORD len,i,j;
 DWORD stringf = 0, Arryn = 0;
 char c;
 len = (DWORD) strlen(str);
 for(i=0, j=0; i<len ;i++)
 {
  if(str[i] == ' ' || str[i] == 0x09) //结束
  {
   if(stringf == 0)
   {
    if(j == 0) continue;
    Arry[Arryn][j] = 0;
    Arryn++;
    if(Arryn >= ArryCount)
    {
     return Arryn;
    }
    j = 0;
   }
   else
   {
    Arry[Arryn][j] = str[i];
    j++;
    if(j >= ArrySize)
    {
     j--;
     Arry[Arryn][j] = 0;
    }
   }
  }
  else if(str[i] == '"')   //字串
  {

   if(stringf == 0)
   {
    if(j == 0)  stringf = 1;
    else     //中间的["]作为字符处理
    {
     Arry[Arryn][j] = str[i];
     j++;
     if(j >= ArrySize)
     {
      j--;
      Arry[Arryn][j] = 0;
     }
    }
   }
   else    stringf = 0;
  }
  else if(str[i] == '/')   //转义字符
  {
   if     (str[i+1] == '/') c = '/';
   else if(str[i+1] == 't') c = 0x09;
   else if(str[i+1] == 'r') c = 0x0D;
   else if(str[i+1] == 'n') c = 0x0A;
   else      c = str[i+1];
   Arry[Arryn][j] = c;
   i++;
   j++;
   if(j >= ArrySize)
   {
    j--;
    Arry[Arryn][j] = 0;
   }
  }
  else
  {
   Arry[Arryn][j] = str[i];
   j++;
   if(j >= ArrySize)
   {
    j--;
    Arry[Arryn][j] = 0;
   }
  }
 }
 Arry[Arryn][j] = 0;
 return Arryn+1;
}

DWORD StrtoFormatArry(wchar_t *wstr, wchar_t *Arry[], DWORD ArryCount, DWORD ArrySize)
{
    DWORD len,i,j;
    DWORD stringf = 0, Arryn = 0;
    wchar_t c;
    len = (DWORD) wcslen(wstr);
    for(i=0, j=0; i<len ;i++)
    {
        if(wstr[i] == ' ' || wstr[i] == 0x09) //结束
        {
            if(stringf == 0)
            {
                if(j == 0) continue;
                Arry[Arryn][j] = 0;
                Arryn++;
                if(Arryn >= ArryCount)
                {
                    return Arryn;
                }
                j = 0;
            }
            else
            {
                Arry[Arryn][j] = wstr[i];
                j++;
                if(j >= ArrySize)
                {
                    j--;
                    Arry[Arryn][j] = 0;
                }
            }
        }
        else if(wstr[i] == '"')   //字串
        {

            if(stringf == 0)
            {
                if(j == 0)  stringf = 1;
                else     //中间的["]作为字符处理
                {
                    Arry[Arryn][j] = wstr[i];
                    j++;
                    if(j >= ArrySize)
                    {
                        j--;
                        Arry[Arryn][j] = 0;
                    }
                }
            }
            else    stringf = 0;
        }
        else if(wstr[i] == '/')   //转义字符
        {
            if     (wstr[i+1] == '/') c = '/';
            else if(wstr[i+1] == 't') c = 0x09;
            else if(wstr[i+1] == 'r') c = 0x0D;
            else if(wstr[i+1] == 'n') c = 0x0A;
            else      c = wstr[i+1];
            Arry[Arryn][j] = c;
            i++;
            j++;
            if(j >= ArrySize)
            {
                j--;
                Arry[Arryn][j] = 0;
            }
        }
        else
        {
            Arry[Arryn][j] = wstr[i];
            j++;
            if(j >= ArrySize)
            {
                j--;
                Arry[Arryn][j] = 0;
            }
        }
    }
    Arry[Arryn][j] = 0;
    return Arryn+1;
}

//#define StrFormatCmp_DBG
#define StrFormatCmp_END1(retval) {::free(buf1); return retval;}
#define StrFormatCmp_END2(retval) {::free(buf1); ::free(buf2); return retval;}
DWORD StrFormatCmp(char *str_sp, char *str2) //带通配符比较 ? *
{
 char *buf1,*buf2,*pfind;
 size_t len, len1,len2,i, j, k, p1;
 buf1 = (char *)::malloc(strlen(str_sp)+1);
 strcpy(buf1,str_sp);
 ::StrReplace(buf1, "**", "*");
 for(i=0; ; i++)
 {
  if     (buf1[i] == '*')  break; //找第一个*
  else if(buf1[i] == 0)    //无*比较
  {
   for(j=0; ; j++)  
   {
    if(buf1[j] == '?')
    {
     if(str2[j] == 0) return 0;
    }
    else
    {
     if     (buf1[j] > str2[j]) StrFormatCmp_END1(1)
     else if(buf1[j] < str2[j]) StrFormatCmp_END1(-1)
     else if(buf1[j] == 0)  StrFormatCmp_END1(0)
    }
   }
  }
 }
 for(j=i+1; ;j++)
 {
  if(buf1[j] == '*') break;  //找第二个*
  if(buf1[j] == 0) break;
 }
 if(buf1[j] == 0)     //没有第二个*
 {
#ifdef StrFormatCmp_DBG
  Msg("%s 没有第二个*/r/n开始与%s比较首末",buf1, str2);
#endif
  for(k=0;k<i;k++)
  {
   if(buf1[k] == '?')  continue;
   if(buf1[k] != str2[k]) StrFormatCmp_END1(1);
  }
  len1 = strlen(buf1);
  len2 = strlen(str2);
  for(k=0; ; k++)
  {
   if(buf1[len1-k] == '?')    continue;
   if(buf1[len1-k] == '*')    StrFormatCmp_END1(0)
   if(buf1[len1-k] != str2[len2-k]) StrFormatCmp_END1(1)
  }
 }
 p1 = j;
 len = j-i-1;
 buf2 = (char *)::malloc( len+1 );
 memcpy(buf2, buf1+i+1, len);
 buf2[len] = 0;      //取中间的字串
 pfind = str2+i;
#ifdef StrFormatCmp_DBG
  Msg("开始在 /"%s/" 中搜索中间字串 /"%s/" ", pfind, buf2);
#endif
 for(; ; )
 {
  for(i=0;;i++)    //带通配?的字符串查找 pfind = strstr(str2+i, buf2)
  {
   if(pfind[i] == 0) break;  //字串搜索完毕
   for(j=0;;j++)
   {
    if(pfind[i+j] == 0)   break;
    if(buf2[j]  == '?')   continue;
    if(buf2[j]  != pfind[i+j]) break;
    if(buf2[j]  == 0)   break;
   }
   if(buf2[j] == 0)
   {
//    pfind = pfind + i;
    break;
   }
  }
  if(pfind[i] == 0) break;
#ifdef StrFormatCmp_DBG
        Msg("找到中间字符串于%s count:%d 开始递归 StrFormatCmp(%s,%s)",pfind, i, buf1 + p1, pfind+i+len);
#endif
        pfind += i;
  if(StrFormatCmp( buf1 + p1, pfind+ len) == 0) StrFormatCmp_END2(0)
 }
 return 1;
}
#undef StrFormatCmp_END1
#undef StrFormatCmp_END2
#undef StrFormatCmp_DBG

BOOL Setexecdir(char * lpszCurDir)
{
 char buffer[MAX_PATH];
 int len, i, re;
 re = GetModuleFileNameA(0,buffer,500);
 if(re == 0) return FALSE;
 len = (int)strlen(buffer);
 for( i=len-1;i>=0;i-- )
 {
  if(buffer[i] == '/')
  {
   buffer[i]=0;
   if(lpszCurDir) strcpy(lpszCurDir, buffer);
   return SetCurrentDirectoryA(buffer);   
  }
 }
 return FALSE;
}

char * Getprocmd(DWORD dwPid,char *lpszCmdLine) //调用前请确定权限
{
 HMODULE hm;
 DWORD addr,size;
 HANDLE phd;
 unsigned char  buf[1024];
 strcpy(lpszCmdLine,"(None)");
 hm=GetModuleHandleA("kernel32.dll");
 addr=(DWORD)GetProcAddress(hm,"GetCommandLineA");
 phd = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, dwPid);
 if(phd == NULL) {return 0;}
 ::ReadProcessMemory(phd,(LPVOID)addr,buf,5,&size);
 if(size !=5) { ::CloseHandle(phd); return 0;}
 if(buf[0] != 0xA1 ){strcpy(lpszCmdLine,"Windows ver differ!"); ::CloseHandle(phd); return lpszCmdLine;} //0xa1 : Mov EAX,
 addr= *(DWORD *)(&buf[1]);
 ::ReadProcessMemory(phd,(LPVOID)addr,buf,4,&size);
 if(size !=4) {::CloseHandle(phd); return 0;}
 addr= *(DWORD *)(&buf[0]);
 ::ReadProcessMemory(phd,(LPVOID)addr,buf,1024,&size);
 if(size == 0) {::CloseHandle(phd); return 0;}
 ::CloseHandle(phd);
 strcpy(lpszCmdLine,(char *)buf);
// Msgs(str);
 return lpszCmdLine;
}

DWORD Copystr(const char *lpszStr)
{
 DWORD len;
 len =(DWORD)strlen(lpszStr);
 if (OpenClipboard(NULL))
 {
  if (EmptyClipboard())
  {
   HGLOBAL hgl = GlobalAlloc(GMEM_FIXED, len+1);
   if (hgl != NULL)
   {
    LPBYTE pbyte=(LPBYTE)GlobalLock(hgl);
    memcpy(pbyte,lpszStr,len);
    pbyte[len]=0;
    GlobalUnlock(pbyte);
    SetClipboardData(CF_TEXT, hgl);
   }
  }
  CloseClipboard();
  return len+1;
 }
 return 0;
}

#define VK_V 0x56 
int Keybd_str(const char *lpszStr,int iTime)
{
 int i,len;
 short v_code = 0;
 BYTE  b;
 if(iTime == 0 )  iTime=10;
 if(iTime == -1)  //复制方式
 {
  Copystr(lpszStr);
  UINT s1=MapVirtualKey(VK_CONTROL,0);
  UINT s2=MapVirtualKey(VK_V,0);
  ::keybd_event(VK_CONTROL,(BYTE)s1,0,0);
  ::keybd_event(VK_V,(BYTE)s2,0,0);
  ::keybd_event(VK_V,(BYTE)s2,2,0);
  ::keybd_event(VK_CONTROL,(BYTE)s1,2,0);
  return (int)strlen(lpszStr);
 }
 len = (int)strlen(lpszStr);
 for(i=0;i<len;i++)
 {
  if((lpszStr[i-1] == 0x0d) && (lpszStr[i] == 0x0a)) continue;
  v_code = VkKeyScan(lpszStr[i]);
  b = (BYTE)v_code;
  UINT s_code1 = MapVirtualKey(b, 0);
  UINT s_code2 = MapVirtualKey(0x10, 0);
  if(v_code&0x0100) ::keybd_event(0x10,(BYTE)s_code2,0,0); //Shift 键
  ::keybd_event(b,(BYTE)s_code1,0,0);      //Down
  Sleep(iTime);
  ::keybd_event(b,(BYTE)s_code1,KEYEVENTF_KEYUP,0);  //Up
  Sleep(iTime);
  if(v_code&0x0100) ::keybd_event(0x10,(BYTE)s_code2,2,0); //Shift 键
 }
 return len;
}

int Keybd_stream(int arr[][3],int n)
{
 for(int i=0;i<n;i++)
 {
  UINT s=MapVirtualKey(arr[i][0],0);
  ::keybd_event((BYTE)arr[i][0],(BYTE)s,(DWORD)arr[i][1],0);
  Sleep(arr[i][2]);
 }
 return n;
}

void EdtaddstrA(const char *str, HWND hd)
{
 ::SendMessage(hd, EM_SETSEL, -2, -1);
 ::SendMessage(hd, EM_REPLACESEL, 0, (DWORD)str);
}

void EdtaddstrW(const wchar_t *wstr, HWND hd)
{
    ::SendMessage(hd, EM_SETSEL, -2, -1);
    ::SendMessage(hd, EM_REPLACESEL, 0, (DWORD)wstr);
}

DWORD DumpMem(char *fname, void * pMem, DWORD dwSize)
{
    DWORD dwRet;
 FILE *fp;
    fp=fopen(fname,"w");
    if(fp == NULL)  return 0;
    dwRet = (DWORD)fwrite(pMem, 1, dwSize, fp);
    fclose(fp);
    return dwRet;
}

DWORD LogStr(char *fname, const TCHAR * lpszFormat, ...)
{
    TCHAR tstr[5*1024];
    char  buf[5*1024];
    va_list args;
    va_start(args, lpszFormat);
    _vstprintf(tstr,lpszFormat,args);
    va_end(args);
    TcharToChar(tstr, buf);
    return zLogstr(buf, fname);
}

DWORD zLogstr(char *str,char *fname)
{
 FILE *fp;
 char strfname[512]="./zLogstr.log";
 if(fname) strcpy(strfname,fname);
 if(str == 0)
 {
  fp=fopen(strfname,"w");
  fclose(fp);
  return 0;
 }
 fp=fopen(strfname,"abw");
    if(fp == NULL) return 0;
 fwrite(str,1,strlen(str),fp);
 fwrite("/r/n",1,2,fp);
 fclose(fp);
 return (DWORD)strlen(str)+2;
}

DWORD zLogstr(wchar_t *wstr,wchar_t *fname)
{
    char *buf;
    FILE *fp;
    char strfname[512]="./zLogstr.log";
    if(fname)   wctoc(fname, strfname);
    if(wstr == NULL)
    {
        fp=fopen(strfname,"w");
        fclose(fp);
        return 0;
    }
    fp=fopen(strfname,"abw");
    if(fp == NULL) return 0;
    buf = (char *)malloc(wcslen(wstr)+1);
    wctoc(wstr, buf);
    fwrite(buf,1,wcslen(wstr),fp);
    free(buf);
    fwrite("/r/n",1,2,fp);
    fclose(fp);
    return (DWORD)wcslen(wstr)+2;
}
#define EdtAdd(Str,Id) Edtaddstr(Str, ::GetDlgItem(this->m_hWnd,Id))

DWORD CreateDir(char *Dir)
{
 char buf[MAX_PATH];
 for(int i=0;Dir[i] != 0;i++)
 {
  if(Dir[i] == '/')
  {
   memcpy(buf,Dir,i);
   buf[i]=0;
   ::CreateDirectoryA(buf,0);
  }
 }
 return ::CreateDirectoryA(Dir,0);
}

bool DeleteDirectory(char * dirname)
{
 WIN32_FIND_DATAA FileData;
 HANDLE hSearch;
 BOOL fFinished = FALSE;
 char olddir[MAX_PATH]="";
 GetCurrentDirectoryA(sizeof(olddir),olddir);
 if(SetCurrentDirectoryA(dirname))
 {
  hSearch = FindFirstFileA("*.*", &FileData);
  if (hSearch == INVALID_HANDLE_VALUE)
  {
   fFinished=true;
  }
  while(!fFinished)
  {
   if(strcmp(FileData.cFileName,".")!=0 && strcmp(FileData.cFileName,"..")!=0)
   {
    SetFileAttributesA(FileData.cFileName,FileData.dwFileAttributes&0xFFFFFFFC);
    if(FileData.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY)
    {
     char tempstr[MAX_PATH]="";
     strcat(tempstr,dirname);
     strcat(tempstr,"/");
     strcat(tempstr,FileData.cFileName);
     if(!DeleteDirectory(tempstr))
     {
      SetCurrentDirectoryA(olddir);
      return false;
     }
    }
    else
    {
     if(DeleteFileA(FileData.cFileName)==0)
     {
      SetCurrentDirectoryA(olddir);
      return false;
     }
    }
   }
   if (!FindNextFileA(hSearch, &FileData)) fFinished=true;
  }
  FindClose(hSearch);
  SetCurrentDirectoryA(olddir);
  if(RemoveDirectoryA(dirname)==0)
  {
   return false;
  }
 }
 else
 {
  return false;
 }
 return true;
}

DWORD CopyDirectoryA(LPCSTR lpDestinationPath, LPCSTR lpSourcePath)
{
    static DWORD Count = 0;
    CHAR szFileName[MAX_PATH];
    CHAR szFullSrcName[MAX_PATH];
    CHAR szFullDstName[MAX_PATH];
    WIN32_FIND_DATAA FindFileData;
    CHAR szSrcDir[MAX_PATH];
    CHAR szDstDir[MAX_PATH];
    HANDLE hFind;
    DWORD re;
    strcpy (szFileName, lpSourcePath);
    strcat (szFileName, "/*.*");
    hFind = FindFirstFileA (szFileName, &FindFileData);
    if (hFind == INVALID_HANDLE_VALUE)
    {
        return FALSE;
    }
    strcpy (szSrcDir, lpSourcePath);
    strcpy (szDstDir, lpDestinationPath);
    if(szSrcDir[strlen(szSrcDir)-1] != '/') strcat(szSrcDir,"/");
    if(szSrcDir[strlen(szDstDir)-1] != '/') strcat(szDstDir,"/");
    for (;;)
    {
        if (strcmp (FindFileData.cFileName, ".") && strcmp (FindFileData.cFileName, ".."))
        {
            strcpy(szFullSrcName, szSrcDir);
            strcpy(szFullDstName, szDstDir);
            strcat (szFullSrcName, FindFileData.cFileName);
            strcat (szFullDstName, FindFileData.cFileName);
            if (FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
            {
                if (!CreateDirectoryExA(szFullSrcName, szFullDstName, NULL))
                {
                    if (GetLastError () != ERROR_ALREADY_EXISTS)
                    {
                        MsgA("Error2: %lu/n", GetLastError());
                        //      FindClose (hFind); return FALSE;
                    }
                }
                Count += CopyDirectoryA (szFullDstName, szFullSrcName);
            }
            else
            {
                if (!CopyFileA (szFullSrcName, szFullDstName, FALSE))
                {
                    MsgA("Error4: %s -> %s %lu/n", szFullSrcName ,szFullDstName, GetLastError());
                    Count += 0x10000;
                }
                else Count += 1;
            }
        }
        if (!FindNextFileA (hFind, &FindFileData))
        {
            if (GetLastError () != ERROR_NO_MORE_FILES)
            {
                MsgA("Error5: %lu/n", GetLastError());
            }
            break;
        }
    }
    FindClose (hFind);
    re = Count;
    Count = 0;
    return re;
}

DWORD MsgAry(void * ptr, DWORD n, DATATPYE type, DWORD size)
{
 char *mbuf,abuf[MAXCHAR_PRELINE];
 DWORD i, nedsize = 0;
 switch(type)
 {
 case DataType_charPA:
  for(i=0;i<n;i++) nedsize += (DWORD)strlen( *((char**)ptr+i) ) + 10;
  break;
 case DataType_charAA: nedsize = n*(256+10); break;
 case DataType_charAS: nedsize = n*(size+10); break;
 default: nedsize = n*(10+10);
 }
 mbuf = (char *)malloc(nedsize);
 mbuf[0] = 0;
 for(i=0;i<n;i++)
 {
  switch(type)
  {
  case DataType_DWORD: sprintf(abuf,"%03d: %08X", i, *((DWORD * )ptr+i)); break;
  case DataType_int  : sprintf(abuf,"%03d: %ld",  i, *((int *   )ptr+i)); break;
  case DataType_float: sprintf(abuf,"%03d: %G",   i, *((float * )ptr+i)); break;
  case DataType_double: sprintf(abuf,"%03d: %G",   i, *((double *)ptr+i)); break;
  default: sprintf(abuf,"%03d: ",i); break;
  }
  strcat(mbuf, abuf);
  switch(type)
  {
  case DataType_charPA: strcat(mbuf, *((char **)ptr+i)); break;
  case DataType_charAA: strcat(mbuf, ((char *)ptr+256*i)); break;
  case DataType_charAS: strcat(mbuf, ((char *)ptr+size*i)); break;
  default: ;
  }
  strcat(mbuf,"/r/n");
 }
//type 0:DWORD[] 1:int[] 2:char*[] 3:char[][256] 4:char[][size] 5:float[] 6:double[]

 switch(type)
 {
 case DataType_DWORD: strcpy(abuf,"DWORD  []"); break;
 case DataType_int  : strcpy(abuf,"int    []"); break;
 case DataType_charPA: strcpy(abuf,"char  *[]"); break;
 case DataType_charAA: strcpy(abuf,"char   [][256]"); break;
 case DataType_charAS: sprintf(abuf,"char   [][%d]",size); break;
 case DataType_float : strcpy(abuf,"float  []"); break;
 case DataType_double: strcpy(abuf,"double []"); break;
 default: ;
 }
 Msgs(mbuf,abuf);
 return nedsize;
}

//#define _Sort_DBG
//type 0:DWORD[] 1:int[] 2:char*[](strcmp) 3:char*[](stricmp) 4:char*[](Mystrcmp) 5:float[] 6:double[]
DWORD Sort(void * ptr, DWORD pOrder[], DWORD n, DATATPYE type)
{
 DWORD i,j;
 DWORD* chain_p;  //下一个链的下标
 int cmpf,cthis,cold = -1,head;
 chain_p = (DWORD*) malloc(sizeof(DWORD) * n);
 head = 0;
 cold = 0;
 for(i=1;i<n;i++)
 {
  cthis = head;  //遍历链
#ifdef _Sort_DBG
#undef _Sort_DBG
  char buf[1024],buf1[1024];
  DWORD tmp1;
   buf[0] = 0;
   tmp1 = head;
   for(j=0;j<i;j++) 
   {
    sprintf(buf1,"%d,",tmp1);
    strcat(buf,buf1);
    tmp1 = chain_p[tmp1];
   }
   zLogstr(buf,"c:/ary.log");
#endif
  for(j=0;j<i;j++)
  {
   switch(type)
   {
    case DataType_DWORD :  cmpf = *((DWORD  *)ptr+i) >= *((DWORD  *)ptr+cthis) ? 1 : -1; break;
    case DataType_int   :  cmpf = *((int    *)ptr+i) >= *((int    *)ptr+cthis) ? 1 : -1; break;
    case DataType_float :  cmpf = *((float  *)ptr+i) >= *((float  *)ptr+cthis) ? 1 : -1; break;
    case DataType_double:  cmpf = *((double *)ptr+i) >= *((double *)ptr+cthis) ? 1 : -1; break;
    case DataType_charPA:   cmpf = strcmp ( *((char**)ptr+i),*((char**)ptr+cthis));  break;
    case DataType_charPA_NoCase: cmpf = stricmp( *((char**)ptr+i),*((char**)ptr+cthis));  break;
    default: cmpf = 0;
   }
   if(cmpf < 0) //小于则从前面插入
   {
    if(head == cthis)  //插入到最前端
    {
     chain_p[i] = head; //指向原来的头
     head = i;   //自己成为头
    }
    else
    {
     chain_p[cold] = i;
     chain_p[i]  = cthis;
    }
    break;
   }
   cold  = cthis;
   cthis = chain_p[cthis];  //下一个链
  }
  if(j >= i)  //比他们全部都大 插入到最后
  {
   chain_p[cold] = i;
  }
 }
 for(i=0;i<n;i++)
 {
  pOrder[i] = head;
  head = chain_p[head];
 }
 free(chain_p);
 return head;
}


/*
NtQuerySystemInformation(
  IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
  OUT PVOID               SystemInformation,
  IN ULONG                SystemInformationLength,
  OUT PULONG              ReturnLength OPTIONAL ); */
#ifndef NT_PROCESSTHREAD_INFO
#define NT_PROCESSTHREAD_INFO 5
#endif

#ifndef STATUS_INFO_LENGTH_MISMATCH
#define STATUS_INFO_LENGTH_MISMATCH (0xC0000004L)
#endif

#ifndef COMFUN_UNICODE_STRING
typedef struct tag_COMFUN_UNICODE_STRING
{
    USHORT   Length;
    USHORT   MaximumLength;
    PWSTR   Buffer;
} COMFUN_UNICODE_STRING, *PCOMFUN_UNICODE_STRING;
#endif

#ifndef _SIMP_SYSTEMPROC
typedef struct _SIMP_SYSTEMPROC
{
 ULONG         NextEntryDelta;         //构成结构序列的偏移量;
 ULONG         ThreadCount;             //线程数目;
 LARGE_INTEGER r1[3];     //Reserved
 LARGE_INTEGER CreateTime;             //创建时间;
 LARGE_INTEGER UserTime;                //用户模式(Ring 3)的CPU时间;
 LARGE_INTEGER KernelTime;             //内核模式(Ring 0)的CPU时间;
 COMFUN_UNICODE_STRING ProcessName;             //进程名称;
 ULONG  BasePriority;            //进程优先权;
 ULONG  ProcessId;     //进程标识符;
 ULONG  InheritedFromProcessId; //父进程的标识符;
 ULONG  HandleCount;             //句柄数目;
 DWORD  Unknow[1];
}SIMP_SYSTEMPROC,*PSIMP_SYSTEMPROC;
#endif

DWORD GetProcList(TCHAR *szProcName[], DWORD *dwPid, DWORD dwMaxCount)
{
 char *mbuf = NULL;
 DWORD re,nedsize = 0,dwProcCount;
 Fun4 QuerySysInfo;
 PSIMP_SYSTEMPROC pSysInfo;
 QuerySysInfo = (Fun4)::GetProcAddress(::LoadLibraryA("NTDLL.DLL"),"NtQuerySystemInformation");
 if(QuerySysInfo == NULL)
 {
  Msg(_T("取NtQuerySystemInformation 函数失败! %d "), ::GetLastError());
  return 0;
 }
 re = QuerySysInfo(NT_PROCESSTHREAD_INFO,0,0,(DWORD)&nedsize);
 if(STATUS_INFO_LENGTH_MISMATCH != re)
 {
  Msg(_T("NtQuerySystemInformation 函数调用失败! %08X"), re);
  return 0;
 }
 if(nedsize == 0) nedsize = 1024*1024;
 mbuf = (char *)malloc(nedsize);
 re = QuerySysInfo(NT_PROCESSTHREAD_INFO,(DWORD)mbuf,nedsize,(DWORD)&nedsize);
 if(re != 0)
 {
  free(mbuf);
  Msg(_T("NtQuerySystemInformation 函数调用失败! %08X"), re);
  return 0;
 }
 pSysInfo = (PSIMP_SYSTEMPROC)mbuf;
 if(szProcName == NULL || dwPid == NULL || dwMaxCount == 0)//得到进程总数目
 {
  for(dwProcCount=1;;dwProcCount++)
  {
   if(pSysInfo->NextEntryDelta == 0) break;
   pSysInfo = (PSIMP_SYSTEMPROC)((BYTE *)pSysInfo + pSysInfo->NextEntryDelta);
  }
  free(mbuf);
  return dwProcCount;
 }
 pSysInfo = (PSIMP_SYSTEMPROC)mbuf;
 _tcscpy(szProcName[0],_T("System Idle"));
    dwPid[0] = pSysInfo->ProcessId;
    if(pSysInfo->NextEntryDelta == 0)
    {
        free(mbuf);
        return 1;
    }
    pSysInfo = (PSIMP_SYSTEMPROC)((BYTE *)pSysInfo + pSysInfo->NextEntryDelta);
 for(dwProcCount=2; dwProcCount<dwMaxCount; dwProcCount++)
 {
        wCharToTchar(pSysInfo->ProcessName.Buffer, szProcName[dwProcCount-1]);
  dwPid[dwProcCount-1] = pSysInfo->ProcessId;
  if(pSysInfo->NextEntryDelta == 0) break;
  pSysInfo = (PSIMP_SYSTEMPROC)((BYTE *)pSysInfo + pSysInfo->NextEntryDelta);
 }
 free(mbuf);
 return dwProcCount;
}

#ifndef SystemHandleInformation
 #define SystemHandleInformation 16
#endif
DWORD GetProcHandle(DWORD pid, PROC_HANDLE_INFO StructHandle[], DWORD dwStructStcCount)
{
 BYTE *mbuf = NULL;
 DWORD re,nedsize,Count;
 DWORD i,nedCount = 0,j;
 Fun4 QuerySysInfo;
 PPROC_HANDLE_INFO pHandleInfo;
 QuerySysInfo = (Fun4)::GetProcAddress(::LoadLibraryA("NTDLL.DLL"),"NtQuerySystemInformation");
 if(QuerySysInfo == NULL)
 {
        MsgA("取NtQuerySystemInformation 函数失败! Code:%08X", ::GetLastError());
  return 0;
 }
 nedsize = 16*1024;
 re = STATUS_INFO_LENGTH_MISMATCH;
 while(STATUS_INFO_LENGTH_MISMATCH == re)
 {
  nedsize *= 2;
  if(mbuf) free(mbuf);
        mbuf = (BYTE *)malloc(nedsize);
        re = QuerySysInfo(SystemHandleInformation,(DWORD)mbuf,nedsize,(DWORD)&nedsize);
  if(nedsize > 20*1024*1024 || (re != STATUS_INFO_LENGTH_MISMATCH && re != 0))
  {
   free(mbuf);
   MsgA("NtQuerySystemInformation 函数调用失败! re:%08X nedsize:%d",re,nedsize);
   return 0;
  }
 }
 Count = *(DWORD *)mbuf;
 pHandleInfo = (PPROC_HANDLE_INFO)(mbuf + sizeof(DWORD));
 if(StructHandle == NULL || dwStructStcCount == 0) //得到Handle总数目
 {
  if(pid == 0) //所有进程的
  {
   nedCount = Count;
  }
  else   //指定进程的
  {
   for(i=0,nedCount=0; i<Count; i++)
   {
    if(pHandleInfo[i].ProcessId == pid) nedCount++;
   }
  }
  free(mbuf);
  return nedCount;
 }
 if(pid == 0) //复制所有进程的
 {
  if(dwStructStcCount > Count) dwStructStcCount = Count;
  memcpy(StructHandle, pHandleInfo, dwStructStcCount*sizeof(PPROC_HANDLE_INFO));
  free(mbuf);
  return dwStructStcCount;
 }
 for(i=0,j=0;i<Count;i++) //复制指定进程的
 {
  if(pHandleInfo[i].ProcessId == pid)
  {
   memcpy(&StructHandle[j], &pHandleInfo[i], sizeof(PROC_HANDLE_INFO));
   j++;
  }
 }
 free(mbuf);
 return j;
}

int wctoc(const PWSTR instr, LPSTR outstr)
{
    int nNeedSize;
    nNeedSize = WideCharToMultiByte(0,0,instr,-1,0,0,0,0);
    return WideCharToMultiByte(0,0,instr,-1,outstr,nNeedSize,0,0);
}

int ctowc(const PCSTR instr, PWSTR outstr)
{
    int nNeedSize;
    nNeedSize = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, instr, -1, outstr, 0);
    return MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, instr, -1, outstr, nNeedSize);
}

LPSTR TcharToChar (const PTSTR tstr, LPSTR str)
{
#ifdef UNICODE
    wctoc((PWSTR)tstr, str);
#else
    _tcscpy(str, tstr);
#endif
    return str;
}

PWSTR TcharTowChar(const PTSTR tstr, PWSTR wstr)
{
#ifdef UNICODE
    wcscpy(wstr, tstr);
#else
    ctowc((PCSTR)tstr, wstr);
#endif
    return wstr;
}

PTSTR CharToTchar (const LPSTR  str, PTSTR tstr)
{
#ifdef UNICODE
    ctowc(str, (PWSTR)tstr);
#else
    strcpy((LPSTR)tstr, str);
#endif
    return tstr;
}

PTSTR wCharToTchar(const PWSTR wstr, PTSTR tstr)
{
#ifdef UNICODE
    wcscpy((PWSTR)tstr, wstr);
#else
    wctoc(wstr, (LPSTR)tstr);
#endif
    return tstr;
}


void * Align(void * p)  //Align by DWORD(4)
{
    DWORD   dwVal;
    dwVal = (DWORD)p;
    dwVal += 3;
    dwVal >>= 2;
    dwVal <<= 2;
    return  (void *)dwVal;
}

BOOL CALLBACK InputProc( HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    static DWORD *p;
    if (uMsg == WM_INITDIALOG)
    {
        p = (DWORD *)lParam;
        ::SetDlgItemText(hwndDlg, 0x1001, (TCHAR *)p[0]);
        return TRUE;  
    }
    if ((uMsg == WM_COMMAND))
    {
        if(LOWORD(wParam) == IDOK)
        {
            ::GetDlgItemText(hwndDlg, 0x1001, (TCHAR *)p[1], p[2]);
            EndDialog (hwndDlg, IDOK);
            return TRUE;
        }
        if(LOWORD(wParam) == IDCANCEL)
        {
            EndDialog (hwndDlg, IDCANCEL);
            return TRUE;
        }
    }  
    if ((uMsg == WM_SYSCOMMAND) && (wParam == SC_CLOSE))
    {    
        EndDialog (hwndDlg, IDCANCEL);
        return TRUE;
    }
    return FALSE;
}

int GetInput(HWND hWnd, TCHAR *pCapt, TCHAR * pText, TCHAR * pOutBuf, DWORD dwBufSize, int nWidth, int nHeigh)
{
    WORD    *p, *pdlgtemplate;
    int     nchar;
    int     nButW = 40, nButH = 12, nDis = 5;
    DWORD   lStyle = 0, lExStyle = 0;
    DWORD   dwMem[3];
    dwMem[0] = (DWORD)pText;
    dwMem[1] = (DWORD)pOutBuf;
    dwMem[2] = dwBufSize;
    pdlgtemplate = p = (PWORD) LocalAlloc (LPTR, 1000);
    ///   Init for DLGTEMPLATEEX     /
    lStyle = DS_MODALFRAME | DS_3DLOOK | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_VISIBLE;
    *p++ = LOWORD (lStyle);             //style
    *p++ = HIWORD (lStyle);             //style
    *p++ = 0;                           // LOWORD (dwExtendedStyle)
    *p++ = 0;                           // HIWORD (dwExtendedStyle)
    *p++ = 3;                           // NumberOfItems
    *p++ = 0;                           // x
    *p++ = 0;                           // y
    *p++ = nWidth;                      // cx
    *p++ = nHeigh;                      // cy
    *p++ = 0;                           // Menu resource Name
    *p++ = 0;                           // Class Name
    TcharTowChar(pCapt, (PWSTR)p);      // title
    nchar = (int)wcslen((LPWSTR)p) + 1;
    p += nchar;                         // title
    p = (WORD *)Align(p);               // Align DWORD boundary
    ///   Init for DLGITEMTEMPLATEEX  Edit 
    lStyle = WS_CHILDWINDOW | WS_VISIBLE |WS_VSCROLL | ES_LEFT | ES_MULTILINE | ES_WANTRETURN;
    lExStyle    = WS_EX_STATICEDGE;
    *p++ = LOWORD (lStyle);             //style
    *p++ = HIWORD (lStyle);             //style
    *p++ = LOWORD (lExStyle);           // LOWORD (dwExtendedStyle)
    *p++ = HIWORD (lExStyle);           // HIWORD (dwExtendedStyle)
    *p++ = nDis;                        // x
    *p++ = nDis;                        // y
    *p++ = nWidth - 2*nDis;             // cx
    *p++ = nHeigh - 3*nDis - nButH;     // cy
    *p++ = 0x1001;                      // ID
    *p++ = (WORD)0xffff;                //Class Name Or Class Ary
    *p++ = (WORD)0x0081;                //0x0080 Edit
    nchar = ctowc(("OK"), (PWSTR)p);    //title
    p += nchar;                         //title
    *p++ = 0;                           //extraCount
    p = (WORD *)Align(p);               // Align DWORD boundary
    ///   DLGITEMTEMPLATEEX OK Button   ///
    lStyle = WS_CHILDWINDOW | WS_VISIBLE | BS_PUSHBUTTON | BS_TEXT;
    *p++ = LOWORD (lStyle);             //style
    *p++ = HIWORD (lStyle);             //style
    *p++ = LOWORD (lExStyle);           // LOWORD (dwExtendedStyle)
    *p++ = HIWORD (lExStyle);           // HIWORD (dwExtendedStyle)
    *p++ = nDis;                        // x
    *p++ = nHeigh - 1*nDis - nButH;     // y
    *p++ = nButW;                       // cx
    *p++ = nButH;                       // cy
    *p++ = IDOK;                        // ID
    *p++ = (WORD)0xffff;                //Class Name Or Class Arry
    *p++ = (WORD)0x0080;                //0x0081 Button
    nchar = ctowc(("OK"), (PWSTR)p);    //title
    p += nchar;                         //title
    *p++ = 0;                           //extraCount
    p = (WORD *)Align(p);               //Align DWORD boundary
    ///   Init for DLGITEMTEMPLATEEX  Cancel  Button  //
    lStyle = WS_CHILDWINDOW | WS_VISIBLE | BS_PUSHBUTTON | BS_TEXT;
    *p++ = LOWORD (lStyle);             //style
    *p++ = HIWORD (lStyle);             //style
    *p++ = LOWORD (lExStyle);           // LOWORD (dwExtendedStyle)
    *p++ = HIWORD (lExStyle);           // HIWORD (dwExtendedStyle)
    *p++ = nWidth - 1*nDis - nButW;     // x
    *p++ = nHeigh - 1*nDis - nButH;     // y
    *p++ = nButW;                       // cx
    *p++ = nButH;                       // cy
    *p++ = IDCANCEL;                    // ID
    *p++ = (WORD)0xffff;                //Class Name Or Class Arry
    *p++ = (WORD)0x0080;                //0x0081 Button
    nchar = ctowc(("Cancel"), (PWSTR)p);//title
    p += nchar;                         //title
    *p++ = 0;                           //extraCount
    p = (WORD *)Align(p);               //Align DWORD boundary
    int nRet = (int)DialogBoxIndirectParam((HINSTANCE)::GetWindowLong(hWnd, GWL_HINSTANCE),
        (LPDLGTEMPLATE)pdlgtemplate, hWnd, (DLGPROC) InputProc, (LPARAM)dwMem);
    LocalFree (LocalHandle (pdlgtemplate));
    return nRet;
}

#pragma warning( default : 4311 4312)

//     ComFun/ComFun.cpp End

 

 


 
张风 @ 2006-10-26 09:58

NEG EAX
SBB EAX,EAX     // -1,1 -> -1   0  -> 0
INC                       // -1,1 -> 0    0  -> 1


_beginthread 与 CreateThread 的使用

! Warning   If you are going to call C run-time routines from a program built with LIBCMT.LIB, you must start your threads with the _beginthread function. Do not use the Win32 functions ExitThread and CreateThread. Using SuspendThread can lead to a deadlock when more than one thread is blocked waiting for the suspended thread to complete its access to a C run-time data structure.
(燃料泄漏啊)


区别:
1.The _beginthread function lets you pass multiple arguments to the thread. (真TNND的方便,不用写结构体了)
The _beginthread function initializes certain C run-time library variables. This is important only if you use the C run-time library in 2.your threads.
3.CreateThread provides control over security attributes. You can use this function to start a thread in a suspended state.

微软的detours 1.5(VC6 只能用这个或更低版本)
对于未公开API detour 不了,啊哈
#define DETOUR_TRAMPOLINE_YOFOO(trampoline,target) /
static PVOID __fastcall _Detours_GetVA_##target(VOID) /
{ /
    return target; /
} /
/
__declspec(naked) trampoline /
{ /
    __asm { nop };/
    __asm { nop };/
    __asm { call _Detours_GetVA_##target };/
    __asm { jmp eax };/
    __asm { ret };/
    __asm { nop };/
    __asm { nop };/
    __asm { nop };/
    __asm { nop };/
    __asm { nop };/
    __asm { nop };/
    __asm { nop };/
    __asm { nop };/
    __asm { nop };/
    __asm { nop };/
    __asm { nop };/
    __asm { nop };/
    __asm { nop };/
    __asm { nop };/
    __asm { nop };/
    __asm { nop };/
    __asm { nop };/
    __asm { nop };/
    __asm { nop };/
    __asm { nop };/
    __asm { nop };/
    __asm { nop };/
}

用这个替换DETOUR_TRAMPOLINE OK!


DisableThreadLibraryCalls
用来屏蔽 DLL_THREAD_ATTACH 和 DLL_THREAD_DETACH消息



 
张风 @ 2006-10-26 09:56

在函数调用过程中,会使用堆栈,这三个表示不同的堆栈调用方式和释放方式。 
比如说__cdecl,它是标准的c方法的堆栈调用方式,就是在函数调用时的参数压入堆栈是与函数的声明顺序相反的,其它两个可以看MSDN,不过这个对我们编程没有太大的作用 
--------------------------------------------------------------- 
 
 
调用约定   
 
调用约定(Calling  convention)决定以下内容:函数参数的压栈顺序,由调用者还是被调用者把参数弹出栈,以及产生函数修饰名的方法。MFC支持以下调用约定: 
 
 
_cdecl   
 
按从右至左的顺序压参数入栈,由调用者把参数弹出栈。对于“C”函数或者变量,修饰名是在函数名前加下划线。对于“C++”函数,有所不同。 
 
如函数void  test(void)的修饰名是_test;对于不属于一个类的“C++”全局函数,修饰名是?test@@ZAXXZ。 
 
这是MFC缺省调用约定。由于是调用者负责把参数弹出栈,所以可以给函数定义个数不定的参数,如printf函数。 
 
 
_stdcall   
 
按从右至左的顺序压参数入栈,由被调用者把参数弹出栈。对于“C”函数或者变量,修饰名以下划线为前缀,然后是函数名,然后是符号“@”及参数的字节数,如函数int  func(int  a,  double  b)的修饰名是_func@12。对于“C++”函数,则有所不同。 
 
所有的Win32  API函数都遵循该约定。 
 
 
_fastcall   
 
头两个DWORD类型或者占更少字节的参数被放入ECX和EDX寄存器,其他剩下的参数按从右到左的顺序压入栈。由被调用者把参数弹出栈,对于“C”函数或者变量,修饰名以“@”为前缀,然后是函数名,接着是符号“@”及参数的字节数,如函数int  func(int  a,  double  b)的修饰名是@func@12。对于“C++”函数,有所不同。 
 
未来的编译器可能使用不同的寄存器来存放参数。 
 
 
thiscall   
 
仅仅应用于“C++”成员函数。this指针存放于CX寄存器,参数从右到左压栈。thiscall不是关键词,因此不能被程序员指定。 
 
 
naked  call   
 
采用1-4的调用约定时,如果必要的话,进入函数时编译器会产生代码来保存ESI,EDI,EBX,EBP寄存器,退出函数时则产生代码恢复这些寄存器的内容。naked  call不产生这样的代码。 
 
naked  call不是类型修饰符,故必须和_declspec共同使用,如下: 
 
__declspec(  naked  )  int  func(  formal_parameters  ) 
 

 
//  Function  body 
 

 
 
函数调用约定
 
原来的一些调用约定可以不再使用。它们被定义成调用约定_stdcall或者_cdecl。例如: 
 
#define  CALLBACK  __stdcall 
#define  WINAPI  __stdcall 
#define  WINAPIV  __cdecl 
#define  APIENTRY  WINAPI 
#define  APIPRIVATE  __stdcall 
#define  PASCAL  __stdcall 
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值