PE资源结构及读取

本文深入探讨了Windows可执行文件(PE)的资源结构,包括对话框、字符串、图像等,并详细阐述了如何从PE文件中提取和读取这些资源。通过实例解析,了解微软的资源管理机制,有助于提升对Windows程序逆向分析和二进制修改的理解。

 

PE 资源结构及读取
作者: Sunline               lisunlin0@yahoo.com.cn       2007 7
源代码下载 :http://download.youkuaiyun.com/source/359338   其中的 Source 文件夹中 .

      
下面的一些函数是我在学习 PE 结构时参考 Matt Pietrek 的《 A Tour of the Win32 Portable Executable File Format 》和 Microsoft 的《 Visual Studio, Microsoft Portable Executable and Common Object File Format Specification 》以及部分网上的代码所写成的,是研究如何直接读取 PE 资源的一手资料 ( 比如其中的 LoadString LoadAccelerators LoadMenu LoadIcon 函数,没有其它任何可用的参考资料 , VC 调试时跟踪到相应的函数内部,通过汇编代码和自己丰富的想象力才搞清楚的。 ) ,希望可以给研究 PE 格式的朋友一些帮助。其中大部分是自己 Debug 得出的,可能有不妥的地方,敬请斧正。
// ResFunc.cpp
// 描述:
//             从PE文件中取得资源
// 作者:
//             SunLine 2007年07月
// Description:
//             get resources from a pe module
// Authority:
//             Write by Sunline July, 2007
// All rights reserved.
 
 
#include <windows.h>
#include "ResFunc.h"
#include "libc.h"
 
extern "C"
{     
       DWORD __stdcall _SizeofResource(HMODULE hModule, HRSRC hResInfo)
       {
              DWORD dwRet;
              if(hResInfo)
                     dwRet = PIMAGE_RESOURCE_DATA_ENTRY(hResInfo)->Size;
              else
                     dwRet = 0;
              return dwRet;
       }
 
       HGLOBAL __stdcall _LoadResource( HMODULE hModule, HRSRC hResInfo)
       {
              HGLOBAL hRet;
              if(hResInfo)
                     hRet = HGLOBAL((LPBYTE)hModule + PIMAGE_RESOURCE_DATA_ENTRY(hResInfo)->OffsetToData);
              else
                     hRet = NULL;
              return hRet;
       }
 
       LPVOID __stdcall _LockResource(HGLOBAL hResData)
       {
              return (LPVOID)hResData;
       }
 
       HRSRC   __stdcall _FindResourceA( HMODULE hModule, LPCSTR lpName, LPCSTR lpType)
       {
              return _FindResourceExA(hModule, lpType, lpName, 0);
       }
       HRSRC   __stdcall _FindResourceW( HMODULE hModule, LPCWSTR lpName, LPCWSTR lpType)
       {
              return _FindResourceExW(hModule, lpType, lpName, 0);
       }
 
       HRSRC   __stdcall _FindResourceExA(HMODULE hModule, LPCSTR lpType, LPCSTR lpName, WORD wLanguage)
       {
              HRSRC hRsrc = NULL;
              WCHAR wTypeName[MAX_PATH];
              WCHAR wResName[MAX_PATH];
              LPWSTR pwTypeName;
              LPWSTR pwResName;
              if(MAKEINTRESOURCEA(lpType) == lpType)
              {
                     pwTypeName = (LPWSTR)lpType;
              }
              else
              {
                     int nTypeLen = lstrlenA(lpType) + 1;
                     int nUnicodeStrLen = nTypeLen * sizeof(WCHAR);
                     pwTypeName = (LPWSTR)_malloc(nUnicodeStrLen);
                     nUnicodeStrLen = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, /
                            lpType, nTypeLen, wTypeName, nUnicodeStrLen);
                     pwTypeName = wTypeName;
              }
 
              if(MAKEINTRESOURCEA(lpName) == lpName)
              {
                     pwResName = (LPWSTR)lpName;
              }
              else
              {
                     int nNameLen = lstrlenA(lpName) + 1;
                     int nUnicodeStrLen = nNameLen * sizeof(WCHAR);
                     nUnicodeStrLen = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, /
                            lpType, nNameLen, wResName, nUnicodeStrLen);
                     pwResName = wResName;
              }
 
              if(pwTypeName && pwResName)
              {
                     hRsrc = _FindResourceExW(hModule, pwTypeName, pwResName, wLanguage);
              }
              else
                     hRsrc = NULL;
              return hRsrc;
       }
 
       HRSRC   __stdcall _FindResourceExW(HMODULE hModule, LPCWSTR lpType, LPCWSTR lpName, WORD wLanguage)
       {
              PIMAGE_RESOURCE_DATA_ENTRY res = NULL;
              if(hModule == NULL)
                     hModule = GetModuleHandleW(NULL);
              if((lpName != 0) && (lpType != 0))
              {
                     if(!hModule)
                            hModule = GetModuleHandleA(NULL);
                     PIMAGE_RESOURCE_DIRECTORY pResDir = PIMAGE_RESOURCE_DIRECTORY( /
                            LPBYTE(hModule) + PIMAGE_NT_HEADERS((LPBYTE)hModule + /
                            PIMAGE_DOS_HEADER(hModule)->e_lfanew)->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress/
                            );
                     ProcRes(res, hModule, LPBYTE(pResDir), pResDir, LEVELE_RESDIR, lpName, lpType, wLanguage);
              }
              return (HRSRC)res;
       }
 
       // Accelerators function
       HACCEL __stdcall _LoadAcceleratorsA( HINSTANCE hInst, LPCSTR lpTableName)
       {
              int nAccItem = 0;
              PACCTABENTRY pAccTabEntry = (PACCTABENTRY)_GetResDataA(hInst, lpTableName, (LPCSTR)RT_ACCELERATOR);
              for(nAccItem = 0; TRUE; nAccItem++)
              {
                     WORD wFlags = pAccTabEntry[nAccItem].fFlags;
                     if(wFlags & 0x80) // The entry is last in an accelerator table.
                     {
                            if(wFlags & 0x60) // 0x60 is binary 01100000, the low 5 bits is legal;
                                   nAccItem = 0;
                            else
                                   nAccItem++;
                            break;
                     }
              }
              LPACCEL lpAcc = (LPACCEL)_malloc(nAccItem * sizeof(ACCEL));
              for(int i = 0; i < nAccItem; i++)
              {
                     //lpAcc[i].fVirt = pAccTabEntry[i].fFlags;
                     //lpAcc[i].key = pAccTabEntry[i].wAnsi;
                     //lpAcc[i].cmd = pAccTabEntry[i].wId;
                     lpAcc[i] = (ACCEL&)(pAccTabEntry[i]);
              }
              HACCEL hRet = CreateAcceleratorTableW(lpAcc, nAccItem);
              return hRet;
       }
 
       HACCEL __stdcall _LoadAcceleratorsW( HINSTANCE hInst, LPCWSTR lpTableName)
       {
              int nAccItem = 0;
              PACCTABENTRY pAccTabEntry = (PACCTABENTRY)_LoadResource((HMODULE)hInst,
                     _FindResourceW(hInst, (LPCWSTR)lpTableName, (LPCWSTR)RT_ACCELERATOR));
              int i;
              for(nAccItem = 0; TRUE; nAccItem++)
              {
                     WORD wFlags = pAccTabEntry[nAccItem].fFlags;
                     if(wFlags & 0x80) // The entry is last in an accelerator table.
                     {
                            if(wFlags & 0x60) // 0x60 is binary 01100000, the low 5 bits is legal;
                                   nAccItem = 0;
                            else
                                   nAccItem++;
                            break;
                     }
              };
              LPACCEL lpAcc = (LPACCEL)_malloc(nAccItem * sizeof(ACCEL));
              for(i = 0; i < nAccItem; i++)
              {
                     //lpAcc[i].fVirt = pAccTabEntry[i].fFlags;
                     //lpAcc[i].key = pAccTabEntry[i].wAnsi;
                     //lpAcc[i].cmd = pAccTabEntry[i].wId;
                     lpAcc[i] = (ACCEL&)(pAccTabEntry[i]);
              }
              return CreateAcceleratorTableW(lpAcc, nAccItem);
       }
 
       BOOL     __stdcall _DestroyAcceleratorTable(HACCEL hAccel)
       {
              if(hAccel)
              {
                     _free(hAccel);
                     return TRUE;
              }
              else
                     return FALSE;
       }
 
       // String functions
       int           __stdcall _LoadStringA(LPVOID hInst, UINT uID, LPSTR lpBuffer, int nBufMax)
       {
              int nLen = 0;
              LPCWSTR lpwStr = 0;
              int nItem = (uID & 0xF);
              PIMAGE_RESOURCE_DATA_ENTRY res = NULL;
              ULONG_PTR uName = (LOWORD(uID)>>4) + 1;
              if((uID != 0) && (lpBuffer != 0) && (nBufMax != 0))
              {
                     PIMAGE_RESOURCE_DIRECTORY pResDir = PIMAGE_RESOURCE_DIRECTORY( /
                            LPBYTE(hInst) + PIMAGE_NT_HEADERS((LPBYTE)hInst + PIMAGE_DOS_HEADER(hInst)->e_lfanew)->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress/
                            );
 
                     if(0 == ProcRes(res, hInst, LPBYTE(pResDir), pResDir, LEVELE_RESDIR, (LPCWSTR)uName, (LPCWSTR)RT_STRING, 0))
                     {
                            PWCHAR lpVoid = PWCHAR((LPBYTE)hInst + res->OffsetToData);
                            while(nItem != 0)
                            {
                                   nItem--;
                                   lpVoid += *(PWORD)lpVoid;
                                   lpVoid++;
                            }
                            // nLen = *PWORD( lpVoid - sizeof(WORD));
                            PUSTR pStr = (PUSTR)lpVoid;
                            if(pStr->wLen <= nBufMax)
                            {
                                   nLen = WideCharToMultiByte(CP_ACP, WC_NO_BEST_FIT_CHARS, pStr->pBuffer, pStr->wLen, lpBuffer, nBufMax, 0, 0);
                                   *((PCHAR)lpBuffer + nLen) = 0;
                            }
                            else
                                   nLen = 0;
                     }
              }
              return nLen;
       }
       int           __stdcall _LoadStringW(LPVOID hInst, UINT uID, LPWSTR lpBuffer, int nBufMax)
       {
              int nLen = 0;
              LPCWSTR lpwStr = 0;
              int nItem = (uID & 0xF);
              PIMAGE_RESOURCE_DATA_ENTRY res = NULL;
              ULONG_PTR uName = (LOWORD(uID)>>4) + 1; // 字符串是以字符串的ID号的16的模来分组的,即GroupId = uID / 16, String order in group = uID % 16
              if((uID != 0) && (lpBuffer != 0) && (nBufMax != 0))
              {
                     PIMAGE_RESOURCE_DIRECTORY pResDir = PIMAGE_RESOURCE_DIRECTORY( /
                            LPBYTE(hInst) + PIMAGE_NT_HEADERS((LPBYTE)hInst + PIMAGE_DOS_HEADER(hInst)->e_lfanew)->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress/
                            );
 
                     if(0 == ProcRes(res, hInst, LPBYTE(pResDir), pResDir, LEVELE_RESDIR, (LPCWSTR)uName, (LPCWSTR)RT_STRING, 0))
                     {
                            PWCHAR lpVoid = PWCHAR((LPBYTE)hInst + res->OffsetToData);
                            while(nItem != 0)
                            {
                                   nItem--;
                                   lpVoid += *(PWORD)lpVoid;
                                   lpVoid++;
                            }
                            //nLen = *PWORD( lpVoid - sizeof(WORD));
                            PUSTR pStr = (PUSTR)lpVoid;
                            if(pStr->wLen <= nBufMax)
                            {
                                   nLen = pStr->wLen;
                                   lstrcpyW((LPWSTR)lpBuffer, pStr->pBuffer);
                                   *((PWCHAR)lpBuffer + nLen) = 0; // Write 0 to the trail
                            }
                            else
                                   nLen = 0;
                     }
              }
              return nLen;
       }
 
       // ICON, Cursor and other image functions
       // 使用ResourceHack.exe查看生成的ICON组,可以发现ICON是首先按 颜色升序,然后按 图标大小 降序来排列的
       //
       int           __stdcall _LookupIconIdFromDirectory( PBYTE presbits, BOOL fIcon)
       {
              if(!presbits)
                     return 0;
              int nRet = 0;
              int cx_icon = GetSystemMetrics(SM_CXICON);
              int cy_icon = GetSystemMetrics(SM_CYICON);
              unsigned int dmBitsPerPel;
              DEVMODE dvm;
              BOOL bRet = EnumDisplaySettings(NULL,ENUM_CURRENT_SETTINGS,&dvm);
              dmBitsPerPel = dvm.dmBitsPerPel;
              PRESICONCURSORHEADER pIconCursorHeader = (PRESICONCURSORHEADER)presbits;
              int nItemCount = pIconCursorHeader->wItemCount;
              PRESDIR pResDir = 0;
              PRESDIR pRetResDir = 0;
              pResDir = pRetResDir = (PRESDIR)(presbits + sizeof(RESICONCURSORHEADER));
              if(fIcon) // lookup for icon
              {
                     for( ; nItemCount > 0; nItemCount--)
                     {
                            unsigned int n;
                            n = dmBitsPerPel - pResDir->ResInfo.Icon.ColorCount;
                            if((n > 0) && ((pResDir->ResInfo.Icon.ColorCount - pRetResDir->ResInfo.Icon.ColorCount) > 0))
                            {
                                   n = cx_icon - pResDir->ResInfo.Icon.Width;
                                   if((n >= 0) && ((pResDir->ResInfo.Icon.Width - pRetResDir->ResInfo.Icon.Width) >= 0))
                                   {
                                          n = cy_icon - pResDir->ResInfo.Icon.Height;
                                          if(n >= 0)
                                          {
                                                 pRetResDir = pResDir;
                                          }
                                   }
                            }
                            else if(n == 0)
                            {
                                   n = cx_icon - pResDir->ResInfo.Icon.Width;
                                   if((n >= 0) && ((pResDir->ResInfo.Icon.Width - pRetResDir->ResInfo.Icon.Width) >= 0))
                                   {
                                          n = cy_icon - pResDir->ResInfo.Icon.Height;
                                          if(n >= 0)
                                          {
                                                 pRetResDir = pResDir;
                                          }
                                   }
                            }
                            pResDir++;
                     }
              }
              else // lookup for cursor
              {
                     for( ; nItemCount > 0; nItemCount--)
                     {
                            unsigned int n;
                            n = cx_icon - pResDir->ResInfo.Cursor.Width;
                            if((n > 0) && ((pResDir->ResInfo.Cursor.Width - pRetResDir->ResInfo.Cursor.Width) > 0))
                            {
                                   n = cy_icon - pResDir->ResInfo.Cursor.Height;
                                   if(n >= 0)
                                   {
                                          pRetResDir = pResDir;
                                   }
                            }
                            else if(n == 0)
                            {
                                   n = cy_icon - pResDir->ResInfo.Cursor.Height;
                                   if(n >= 0)
                                   {
                                          pRetResDir = pResDir;
                                   }
                            }
                            pResDir++;
                     }
              }
              nRet = pRetResDir->IconCursorId;
              return nRet;
       }
 
       HICON   __stdcall _LoadIconA( HINSTANCE hInst, LPCSTR lpIconName)
       {
              HICON hIcon;
              HRSRC   hRsrc = NULL;
              HGLOBAL      hGlobal = NULL;
              LPVOID lpRes = NULL;
              int        nID;
              if(lpIconName > (LPCSTR)0x8000)
                     hIcon = LoadIconA(hInst, lpIconName);
              else
              {
                     if( (lpRes = _GetResDataA(hInst, lpIconName, (LPCSTR)RT_GROUP_ICON)) == NULL)
                            return NULL;
                     nID = _LookupIconIdFromDirectory( (PBYTE)lpRes, TRUE );
                     if( (hRsrc = _FindResourceA( hInst, MAKEINTRESOURCEA(nID), (LPCSTR)RT_ICON )) == NULL )
                            return NULL;
                     if( (hGlobal = _LoadResource( hInst, hRsrc )) == NULL )
                            return NULL;
                     if( (lpRes = _LockResource(hGlobal)) == NULL )
                            return NULL;
                     hIcon = CreateIconFromResource( (PBYTE)lpRes, _SizeofResource(hInst, hRsrc), TRUE, 0x00030000 );
              }
              return hIcon;
       }
 
       HICON   __stdcall _LoadIconW( HINSTANCE hInst, LPCWSTR lpIconName)
       {
              HICON hIcon;
              HRSRC   hRsrc = NULL;
              HGLOBAL      hGlobal = NULL;
              LPVOID lpRes = NULL;
              int        nID;
              if(lpIconName > (LPCWSTR)0x8000)
                     hIcon = LoadIconW(hInst, lpIconName);
              else
              {
                     if( (lpRes = _GetResDataW(hInst, lpIconName, RT_GROUP_ICON)) == NULL)
                            return NULL;
                     nID = _LookupIconIdFromDirectory( (PBYTE)lpRes, TRUE );
                     if( (hRsrc = _FindResourceW( hInst, MAKEINTRESOURCEW(nID), (LPCWSTR)RT_ICON )) == NULL )
                            return NULL;
                     if( (hGlobal = _LoadResource( hInst, hRsrc )) == NULL )
                            return NULL;
                     if( (lpRes = _LockResource(hGlobal)) == NULL )
                            return NULL;
                     hIcon = CreateIconFromResource( (PBYTE)lpRes, _SizeofResource(hInst, hRsrc), TRUE, 0x00030000 );
              }
              return hIcon;
       }
 
       BOOL     __stdcall _DestroyIcon(HICON hIcon)
       {
              return DestroyIcon(hIcon);
       }
 
       HCURSOR __stdcall _LoadCursorA(HINSTANCE hInst, LPCSTR lpCursorName)
       {
              HCURSOR hCursor;
              HRSRC   hRsrc = NULL;
              HGLOBAL      hGlobal = NULL;
              LPVOID lpRes = NULL;
              int        nID;
              if(lpCursorName > (LPCSTR)0x1000)
                     hCursor = LoadCursorA(hInst, lpCursorName);
              else
              {
                     if( (lpRes = _GetResDataA(hInst, lpCursorName, (LPCSTR)RT_GROUP_CURSOR)) == NULL )
                            return NULL;
 
                     nID = _LookupIconIdFromDirectory( (PBYTE)lpRes, FALSE );
                     if( (hRsrc = _FindResourceA( hInst, MAKEINTRESOURCEA(nID), (LPCSTR)RT_CURSOR)) == NULL )
                            return NULL;
                     if( (hGlobal = _LoadResource( hInst, hRsrc )) == NULL )
                            return NULL;
                     if( (lpRes = _LockResource(hGlobal)) == NULL )
                            return NULL;
                     hCursor = CreateIconFromResource( (PBYTE)lpRes, _SizeofResource(hInst,hRsrc), FALSE, 0x00030000 );
              }
              return hCursor;
       }
 
       HCURSOR __stdcall _LoadCursorW(HINSTANCE hInst, LPCWSTR lpCursorName)
       {
              HCURSOR hCursor;
              HRSRC   hRsrc = NULL;
              HGLOBAL      hGlobal = NULL;
              LPVOID lpRes = NULL;
              int        nID;
              if(lpCursorName > (LPCWSTR)0x1000)
                     hCursor = LoadCursorW(hInst, lpCursorName);
              else
              {
                     if( (lpRes = _GetResDataW(hInst, lpCursorName, RT_GROUP_CURSOR)) == NULL )
                            return NULL;
 
                     nID = _LookupIconIdFromDirectory( (PBYTE)lpRes, FALSE );
                     if( (hRsrc = _FindResourceW( hInst, MAKEINTRESOURCEW(nID), (LPCWSTR)RT_CURSOR)) == NULL )
                            return NULL;
                     if( (hGlobal = _LoadResource( hInst, hRsrc )) == NULL )
                            return NULL;
                     if( (lpRes = _LockResource(hGlobal)) == NULL )
                            return NULL;
                     hCursor = CreateIconFromResource( (PBYTE)lpRes, _SizeofResource(hInst,hRsrc), FALSE, 0x00030000 );
              }
              return hCursor;
       }
 
       BOOL     __stdcall _DestroyCursor(HCURSOR hCursor)
       {
              return DestroyCursor(hCursor);
       }
 
       HBITMAP __stdcall _LoadBitmapA( HINSTANCE hInst, LPCSTR lpBitmapName)
       {
              HBITMAP hRet = NULL;
              BITMAP *pBitMap;
              HGLOBAL hResData = _GetResDataA(hInst, lpBitmapName, (LPCSTR)RT_BITMAP);
              if(hResData)
              {
                     pBitMap = (BITMAP *)_LockResource(hResData);
                     hRet = CreateBitmapIndirect(pBitMap);
              }
              return hRet;
       }
 
       HBITMAP __stdcall _LoadBitmapW( HINSTANCE hInst, LPCWSTR lpBitmapName)
       {
              HBITMAP hRet;
              BITMAP *pBitMap = (BITMAP *)_GetResDataW(hInst, lpBitmapName, RT_BITMAP);
              if(pBitMap)
                     hRet = CreateBitmapIndirect(pBitMap);
              else
                     hRet = NULL;
              return hRet;
       }
 
       BOOL     __stdcall _DeleteObject(HGDIOBJ hObject)
       {
              return DeleteObject(hObject);
       }
 
       // Memu functions
       HMENU __stdcall _LoadMenuA( HINSTANCE hInst, LPCSTR lpMenuName)
       {
              HMENU hMenu = NULL;
              MENUTEMPLATEW *pMemnuTemplate = (MENUTEMPLATEW *)_GetResDataA(hInst, lpMenuName, (LPCSTR)RT_MENU);
              if(pMemnuTemplate)
                     hMenu = LoadMenuIndirectA(pMemnuTemplate);
              return hMenu;
       }
 
       HMENU __stdcall _LoadMenuW( HINSTANCE hInst, LPCWSTR lpMenuName)
       {
              HMENU hMenu = NULL;
              MENUTEMPLATEW *pMemnuTemplate = (MENUTEMPLATEW *)_GetResDataW(hInst, lpMenuName, RT_MENU);
              if(pMemnuTemplate)
                     hMenu = LoadMenuIndirectW(pMemnuTemplate);
              return hMenu;
       }
 
       BOOL     __stdcall _DestroyMenu(HMENU hMenu)
       {
              return DestroyMenu(hMenu);
       }
 
       // Dialog functions
       HWND WINAPI _CreateDialogParamA( HINSTANCE hInst, LPCSTR lpTemplateName, HWND hWndParent,
              DLGPROC lpDialogFunc, LPARAM dwInitParam)
       {
              HWND hWnd = 0;
              LPCDLGTEMPLATEA pDlgTemplate = (LPCDLGTEMPLATEA)_GetResDataA(hInst, lpTemplateName, (LPCSTR)RT_DIALOG);
              if(pDlgTemplate)
                     hWnd = CreateDialogIndirectParamA(hInst, pDlgTemplate,       hWndParent, lpDialogFunc, dwInitParam);
              return hWnd;
       }
 
       HWND WINAPI _CreateDialogParamW( HINSTANCE hInst, LPCWSTR lpTemplateName, HWND hWndParent,
              DLGPROC lpDialogFunc, LPARAM dwInitParam)
       {
              HWND hWnd = 0;
              LPCDLGTEMPLATEW pDlgTemplate = (LPCDLGTEMPLATEW)_GetResDataW(hInst, lpTemplateName, (LPCWSTR)RT_DIALOG);
              if(pDlgTemplate)
                     hWnd = CreateDialogIndirectParamW(hInst, pDlgTemplate,      hWndParent, lpDialogFunc, dwInitParam);
              return hWnd;
       }
 
       INT_PTR __stdcall _DialogBoxParamA( HINSTANCE hInst, LPCSTR lpTemplateName, /
              HWND hWndParent, DLGPROC lpDialogFunc, LPARAM dwInitParam)
       {
              INT_PTR hWnd = 0;
              LPCDLGTEMPLATEA pDlgTemplate = (LPCDLGTEMPLATEA)_GetResDataA(hInst, lpTemplateName, (LPCSTR)RT_DIALOG);
              if(pDlgTemplate)
                     hWnd = DialogBoxIndirectParamA(hInst, pDlgTemplate, hWndParent, lpDialogFunc, dwInitParam);
              return hWnd;
       }
 
       INT_PTR __stdcall _DialogBoxParamW( HINSTANCE hInst, LPCWSTR lpTemplateName, /
              HWND hWndParent, DLGPROC lpDialogFunc, LPARAM dwInitParam)
       {
              INT_PTR hWnd = 0;
              LPCDLGTEMPLATEW pDlgTemplate = (LPCDLGTEMPLATEW)_GetResDataW(hInst, lpTemplateName, (LPCWSTR)RT_DIALOG);
              if(pDlgTemplate)
                     hWnd = DialogBoxIndirectParamW(hInst, pDlgTemplate, hWndParent, lpDialogFunc, dwInitParam);
              return hWnd;
       }
 
       // some assist functions
       int           __stdcall ProcRes(PIMAGE_RESOURCE_DATA_ENTRY &lpSResource,LPVOID lpFile, LPVOID lpResBase, /
              PIMAGE_RESOURCE_DIRECTORY lpResDir, int dwLevel, LPCWSTR lpResName, LPCWSTR lpResType, WORD wLanguage)
       {
              int nRet = ERROR_UNKNOW;
              __try
              {
                     PIMAGE_RESOURCE_DIRECTORY pResDir = lpResDir;
                     WORD nResCount = pResDir->NumberOfIdEntries + pResDir->NumberOfNamedEntries;
                     PIMAGE_RESOURCE_DIRECTORY_ENTRY pResDirEntry = PIMAGE_RESOURCE_DIRECTORY_ENTRY((LPBYTE)pResDir + sizeof(IMAGE_RESOURCE_DIRECTORY));
                     nRet = ERROR_NORES;
                     while(nResCount != 0)
                     {
                            if(pResDirEntry->DataIsDirectory)
                            {
                                   PIMAGE_RESOURCE_DIRECTORY lpSubResDir = PIMAGE_RESOURCE_DIRECTORY((LPBYTE)lpResBase + pResDirEntry->OffsetToDirectory);
                                   if(dwLevel == LEVELE_RESDIR)
                                   {
                                          if(pResDirEntry->NameIsString)
                                          {
                                                 PIMAGE_RESOURCE_DIR_STRING_U lpName = PIMAGE_RESOURCE_DIR_STRING_U((LPBYTE)lpResBase + pResDirEntry->NameOffset);
                                                 WORD nLen = lpName->Length;
                                                 PWCHAR pwStr = lpName->NameString;                                     
                                                 if((_CmpNameW((LPCWSTR)lpResType, pwStr) == 0))
                                                        nRet = ProcRes(lpSResource,lpFile, lpResBase, lpSubResDir, LEVELE_RESITEM, lpResName, lpResType, wLanguage);                
                                          }
                                          else
                                          {
                                                 if( 0 == ((LPBYTE)lpResType - pResDirEntry->Name))
                                                        nRet = ProcRes(lpSResource,lpFile, lpResBase, lpSubResDir, LEVELE_RESITEM, lpResName, lpResType, wLanguage);
                                          }
                                   }
                                   else if(dwLevel == LEVELE_RESITEM)
                                   {
                                          if(pResDirEntry->NameIsString)   // 以字符串方式命名
                                          {
                                                 PIMAGE_RESOURCE_DIR_STRING_U lpName = PIMAGE_RESOURCE_DIR_STRING_U((LPBYTE)lpResBase + pResDirEntry->NameOffset);
                                                 WORD nLen = lpName->Length;
                                                 PWCHAR pwStr = lpName->NameString;
                                                 if( 0 == _CmpNameW((LPCWSTR)lpName, pwStr))
                                                        nRet = ProcRes(lpSResource,lpFile, lpResBase, lpSubResDir, LEVELE_RES, lpResName, lpResType, wLanguage);
                                          }
                                          else         // 以ID方式命名
                                          {
                                                 if( 0 == ((LPBYTE)lpResName - pResDirEntry->Name))
                                                        nRet = ProcRes(lpSResource,lpFile, lpResBase, lpSubResDir, LEVELE_RES, lpResName, lpResType, wLanguage);
                                          }
                                   }
                                   else
                                   {
                                          nRet = ERROR_UNKNOW;
                                          break;     // error
                                   }
                            }
                            else         // dwLevel == LEVELE_RES
                            {
                                   lpSResource = PIMAGE_RESOURCE_DATA_ENTRY((LPBYTE)lpResBase + pResDirEntry->OffsetToData);
                                   if(wLanguage != 0)
                                   {
                                          if(lpSResource->CodePage == (UINT)wLanguage)
                                          {
                                                 nRet = ERROR_SUCCESS;
                                          }
                                          else
                                                 nRet = ERROR_LANGUAGE;
                                   }
                                   else // wLanguage == 0 , ignore the langue type
                                   {
                                          nRet = ERROR_SUCCESS;
                                   }
                            }
                            if(nRet == ERROR_SUCCESS)                               
                                   break;                         
                            pResDirEntry++;
                            nResCount--;
                     }
              }
              __except(EXCEPTION_EXECUTE_HANDLER)
              {
                     nRet = ERROR_UNKNOW;
              }
              return nRet;
       }
 
       //LPVOID __stdcall GetResW(LPVOID hInst, LPCWSTR lpName, LPCWSTR lpType)
       //{
       //     //RESOURCE res = {0, 0};
       //     PIMAGE_RESOURCE_DATA_ENTRY res;
       //     if((lpName != 0) && (lpType != 0))
       //     {
       //            PIMAGE_RESOURCE_DIRECTORY pResDir = PIMAGE_RESOURCE_DIRECTORY( /
       //                   LPBYTE(hInst) + PIMAGE_NT_HEADERS((LPBYTE)hInst + PIMAGE_DOS_HEADER(hInst)->e_lfanew)->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress/
       //                   );
       //            ProcRes(res, hInst, LPBYTE(pResDir), pResDir, LEVELE_RESDIR, lpName, lpType, 0);
       //     }
       //     return (LPBYTE)hInst + res->OffsetToData;
       //}
       // common resource functions
       // Accelerators function
       // ICON, Cursor and other image functions
       BOOL     __stdcall IsStringA(LPCSTR lpcStr)
       {
              BOOL fRet;
              /* version 1 */
              //SYSTEM_INFO SystemInfo;
              //GetSystemInfo(&SystemInfo);
              //if((lpString > SystemInfo.lpMinimumApplicationAddress) && (lpString < SystemInfo.lpMaximumApplicationAddress))
              //{
              //     fRet = TRUE;
              //}
              //else
              //     fRet = FALSE;
 
              /* version 2 */
              //if( ((LOWORD)lpcStr != 0) && ((ULONG_PTR)lpcStr >> (8*sizeof(WORD)) )
              //     fRet = TRUE;
              //else
              //     fRet = FALSE;
 
              /* version 3 */
              __try
              {
                     while(*lpcStr);
                     fRet = TRUE;
              }
              __except(EXCEPTION_EXECUTE_HANDLER)
              {
                     fRet = FALSE;
              }
              return fRet;
       }
       BOOL     __stdcall IsStringW(LPCWSTR lpcwStr)
       {
              BOOL fRet;
              /* version 1 */
              //SYSTEM_INFO SystemInfo;
              //GetSystemInfo(&SystemInfo);
              //if((lpString > SystemInfo.lpMinimumApplicationAddress) && (lpString < SystemInfo.lpMaximumApplicationAddress))
              //{
              //     fRet = TRUE;
              //}
              //else
              //     fRet = FALSE;
 
              /* version 2 */
              //if( ((LOWORD)lpcStr != 0) && ((ULONG_PTR)lpcStr >> (8*sizeof(WORD)) )
              //     fRet = TRUE;
              //else
              //     fRet = FALSE;
 
              /* version 3 */
              __try
              {
                     while(*lpcwStr);
                     fRet = TRUE;
              }
              __except(EXCEPTION_EXECUTE_HANDLER)
              {
                     fRet = FALSE;
              }
              return fRet;
       }
 
       int           __stdcall _CmpNameW(LPCWSTR lpName1, LPCWSTR lpName2)
       {
              int nRet = 1;
              __try
              {
                     while( *lpName1 & *lpName2)
                     {
                            nRet = *lpName1 - *lpName2;
                            lpName1++;
                            lpName2++;
                     }
              }
              __except(EXCEPTION_EXECUTE_HANDLER)
              {
                     nRet = 1;
              }
              return nRet;
       }
}
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值