pe_resource.c
上传用户:kjfoods
上传日期:2020-07-06
资源大小:29949k
文件大小:12k
源码类别:

midi

开发平台:

Unix_Linux

  1. /*
  2.  * PE (Portable Execute) File Resources
  3.  * $Id: 5e54e5e711d7f287e860ad24e494238679ca244e $
  4.  *
  5.  * Copyright 1995 Thomas Sandford
  6.  * Copyright 1996 Martin von Loewis
  7.  *
  8.  * Based on the Win16 resource handling code in loader/resource.c
  9.  * Copyright 1993 Robert J. Amstadt
  10.  * Copyright 1995 Alexandre Julliard
  11.  * Copyright 1997 Marcus Meissner
  12.  *
  13.  * Modified for use with MPlayer, detailed CVS changelog at
  14.  * http://www.mplayerhq.hu/cgi-bin/cvsweb.cgi/main/
  15.  *
  16.  * File now distributed as part of VLC media player with no modifications.
  17.  *
  18.  * This program is free software; you can redistribute it and/or modify
  19.  * it under the terms of the GNU General Public License as published by
  20.  * the Free Software Foundation; either version 2 of the License, or
  21.  * (at your option) any later version.
  22.  *
  23.  * This program is distributed in the hope that it will be useful,
  24.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  25.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  26.  * GNU General Public License for more details.
  27.  *
  28.  * You should have received a copy of the GNU General Public License
  29.  * along with this program; if not, write to the Free Software
  30.  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
  31.  */
  32. #include "config.h"
  33. #include <stdlib.h>
  34. #include <sys/types.h>
  35. #include "wine/winestring.h"
  36. #include "wine/windef.h"
  37. #include "wine/pe_image.h"
  38. #include "wine/module.h"
  39. #include "wine/heap.h"
  40. //#include "task.h"
  41. //#include "process.h"
  42. //#include "stackframe.h"
  43. #include "wine/debugtools.h"
  44. #include "ext.h"
  45. /**********************************************************************
  46.  *  HMODULE32toPE_MODREF 
  47.  *
  48.  * small helper function to get a PE_MODREF from a passed HMODULE32
  49.  */
  50. static PE_MODREF*
  51. HMODULE32toPE_MODREF(HMODULE hmod) {
  52. WINE_MODREF *wm;
  53. wm = MODULE32_LookupHMODULE( hmod );
  54. if (!wm || wm->type!=MODULE32_PE)
  55. return NULL;
  56. return &(wm->binfmt.pe);
  57. }
  58. /**********************************************************************
  59.  *     GetResDirEntryW
  60.  *
  61.  * Helper function - goes down one level of PE resource tree
  62.  *
  63.  */
  64. PIMAGE_RESOURCE_DIRECTORY GetResDirEntryW(PIMAGE_RESOURCE_DIRECTORY resdirptr,
  65.    LPCWSTR name,DWORD root,
  66.    WIN_BOOL allowdefault)
  67. {
  68.     int entrynum;
  69.     PIMAGE_RESOURCE_DIRECTORY_ENTRY entryTable;
  70.     int namelen;
  71.     if (HIWORD(name)) {
  72.      if (name[0]=='#') {
  73. char buf[10];
  74. lstrcpynWtoA(buf,name+1,10);
  75. return GetResDirEntryW(resdirptr,(LPCWSTR)atoi(buf),root,allowdefault);
  76. }
  77. entryTable = (PIMAGE_RESOURCE_DIRECTORY_ENTRY) (
  78. (BYTE *) resdirptr + 
  79.                         sizeof(IMAGE_RESOURCE_DIRECTORY));
  80. namelen = lstrlenW(name);
  81. for (entrynum = 0; entrynum < resdirptr->NumberOfNamedEntries; entrynum++)
  82. {
  83. PIMAGE_RESOURCE_DIR_STRING_U str =
  84. (PIMAGE_RESOURCE_DIR_STRING_U) (root + 
  85. entryTable[entrynum].u1.s.NameOffset);
  86. if(namelen != str->Length)
  87. continue;
  88. if(wcsnicmp(name,str->NameString,str->Length)==0)
  89. return (PIMAGE_RESOURCE_DIRECTORY) (
  90. root +
  91. entryTable[entrynum].u2.s.OffsetToDirectory);
  92. }
  93. return NULL;
  94.     } else {
  95. entryTable = (PIMAGE_RESOURCE_DIRECTORY_ENTRY) (
  96. (BYTE *) resdirptr + 
  97.                         sizeof(IMAGE_RESOURCE_DIRECTORY) +
  98. resdirptr->NumberOfNamedEntries * sizeof(IMAGE_RESOURCE_DIRECTORY_ENTRY));
  99. for (entrynum = 0; entrynum < resdirptr->NumberOfIdEntries; entrynum++)
  100.     if ((DWORD)entryTable[entrynum].u1.Name == (DWORD)name)
  101. return (PIMAGE_RESOURCE_DIRECTORY) (
  102. root +
  103. entryTable[entrynum].u2.s.OffsetToDirectory);
  104. /* just use first entry if no default can be found */
  105. if (allowdefault && !name && resdirptr->NumberOfIdEntries)
  106. return (PIMAGE_RESOURCE_DIRECTORY) (
  107. root +
  108. entryTable[0].u2.s.OffsetToDirectory);
  109. return NULL;
  110.     }
  111. }
  112. /**********************************************************************
  113.  *     GetResDirEntryA
  114.  */
  115. PIMAGE_RESOURCE_DIRECTORY GetResDirEntryA( PIMAGE_RESOURCE_DIRECTORY resdirptr,
  116.    LPCSTR name, DWORD root,
  117.    WIN_BOOL allowdefault )
  118. {
  119.     PIMAGE_RESOURCE_DIRECTORY retv;
  120.     LPWSTR nameW = HIWORD(name)? HEAP_strdupAtoW( GetProcessHeap(), 0, name ) 
  121.                                : (LPWSTR)name;
  122.     retv = GetResDirEntryW( resdirptr, nameW, root, allowdefault );
  123.     if ( HIWORD(name) ) HeapFree( GetProcessHeap(), 0, nameW );
  124.     return retv;
  125. }
  126. /**********************************************************************
  127.  *     PE_FindResourceEx32W
  128.  */
  129. HANDLE PE_FindResourceExW(
  130. WINE_MODREF *wm,LPCWSTR name,LPCWSTR type,WORD lang
  131. ) {
  132.     PIMAGE_RESOURCE_DIRECTORY resdirptr;
  133.     DWORD root;
  134.     HANDLE result;
  135.     PE_MODREF *pem = &(wm->binfmt.pe);
  136.     if (!pem || !pem->pe_resource)
  137.      return 0;
  138.     resdirptr = pem->pe_resource;
  139.     root = (DWORD) resdirptr;
  140.     if ((resdirptr = GetResDirEntryW(resdirptr, type, root, FALSE)) == NULL)
  141. return 0;
  142.     if ((resdirptr = GetResDirEntryW(resdirptr, name, root, FALSE)) == NULL)
  143. return 0;
  144.     result = (HANDLE)GetResDirEntryW(resdirptr, (LPCWSTR)(UINT)lang, root, FALSE);
  145. /* Try LANG_NEUTRAL, too */
  146.     if(!result)
  147.         return (HANDLE)GetResDirEntryW(resdirptr, (LPCWSTR)0, root, TRUE);
  148.     return result;
  149. }
  150. /**********************************************************************
  151.  *     PE_LoadResource32
  152.  */
  153. HANDLE PE_LoadResource( WINE_MODREF *wm, HANDLE hRsrc )
  154. {
  155.     if (!hRsrc || !wm || wm->type!=MODULE32_PE)
  156.      return 0;
  157.     return (HANDLE) (wm->module + ((PIMAGE_RESOURCE_DATA_ENTRY)hRsrc)->OffsetToData);
  158. }
  159. /**********************************************************************
  160.  *     PE_SizeofResource32
  161.  */
  162. DWORD PE_SizeofResource( HINSTANCE hModule, HANDLE hRsrc )
  163. {
  164.     /* we don't need hModule */
  165.     if (!hRsrc)
  166.      return 0;
  167.     return ((PIMAGE_RESOURCE_DATA_ENTRY)hRsrc)->Size;
  168. }
  169. /**********************************************************************
  170.  *     PE_EnumResourceTypes32A
  171.  */
  172. WIN_BOOL
  173. PE_EnumResourceTypesA(HMODULE hmod,ENUMRESTYPEPROCA lpfun,LONG lparam) {
  174.     PE_MODREF *pem = HMODULE32toPE_MODREF(hmod);
  175.     int i;
  176.     PIMAGE_RESOURCE_DIRECTORY resdir;
  177.     PIMAGE_RESOURCE_DIRECTORY_ENTRY et;
  178.     WIN_BOOL ret;
  179.     HANDLE heap = GetProcessHeap();
  180.     if (!pem || !pem->pe_resource)
  181.      return FALSE;
  182.     resdir = (PIMAGE_RESOURCE_DIRECTORY)pem->pe_resource;
  183.     et =(PIMAGE_RESOURCE_DIRECTORY_ENTRY)((LPBYTE)resdir+sizeof(IMAGE_RESOURCE_DIRECTORY));
  184.     ret = FALSE;
  185.     for (i=0;i<resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries;i++) {
  186.      LPSTR name;
  187. if (et[i].u1.s.NameIsString)
  188. name = HEAP_strdupWtoA(heap,0,(LPWSTR)((LPBYTE)pem->pe_resource+et[i].u1.s.NameOffset));
  189. else
  190. name = (LPSTR)(int)et[i].u1.Id;
  191. ret = lpfun(hmod,name,lparam);
  192. if (HIWORD(name))
  193. HeapFree(heap,0,name);
  194. if (!ret)
  195. break;
  196.     }
  197.     return ret;
  198. }
  199. /**********************************************************************
  200.  *     PE_EnumResourceTypes32W
  201.  */
  202. WIN_BOOL
  203. PE_EnumResourceTypesW(HMODULE hmod,ENUMRESTYPEPROCW lpfun,LONG lparam) {
  204.     PE_MODREF *pem = HMODULE32toPE_MODREF(hmod);
  205.     int i;
  206.     PIMAGE_RESOURCE_DIRECTORY resdir;
  207.     PIMAGE_RESOURCE_DIRECTORY_ENTRY et;
  208.     WIN_BOOL ret;
  209.     if (!pem || !pem->pe_resource)
  210.      return FALSE;
  211.     resdir = (PIMAGE_RESOURCE_DIRECTORY)pem->pe_resource;
  212.     et =(PIMAGE_RESOURCE_DIRECTORY_ENTRY)((LPBYTE)resdir+sizeof(IMAGE_RESOURCE_DIRECTORY));
  213.     ret = FALSE;
  214.     for (i=0;i<resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries;i++) {
  215. LPWSTR type;
  216.      if (et[i].u1.s.NameIsString)
  217. type = (LPWSTR)((LPBYTE)pem->pe_resource+et[i].u1.s.NameOffset);
  218. else
  219. type = (LPWSTR)(int)et[i].u1.Id;
  220. ret = lpfun(hmod,type,lparam);
  221. if (!ret)
  222. break;
  223.     }
  224.     return ret;
  225. }
  226. /**********************************************************************
  227.  *     PE_EnumResourceNames32A
  228.  */
  229. WIN_BOOL
  230. PE_EnumResourceNamesA(
  231. HMODULE hmod,LPCSTR type,ENUMRESNAMEPROCA lpfun,LONG lparam
  232. ) {
  233.     PE_MODREF *pem = HMODULE32toPE_MODREF(hmod);
  234.     int i;
  235.     PIMAGE_RESOURCE_DIRECTORY resdir;
  236.     PIMAGE_RESOURCE_DIRECTORY_ENTRY et;
  237.     WIN_BOOL ret;
  238.     HANDLE heap = GetProcessHeap();
  239.     LPWSTR typeW;
  240.     if (!pem || !pem->pe_resource)
  241.      return FALSE;
  242.     resdir = (PIMAGE_RESOURCE_DIRECTORY)pem->pe_resource;
  243.     if (HIWORD(type))
  244. typeW = HEAP_strdupAtoW(heap,0,type);
  245.     else
  246. typeW = (LPWSTR)type;
  247.     resdir = GetResDirEntryW(resdir,typeW,(DWORD)pem->pe_resource,FALSE);
  248.     if (HIWORD(typeW))
  249.      HeapFree(heap,0,typeW);
  250.     if (!resdir)
  251.      return FALSE;
  252.     et =(PIMAGE_RESOURCE_DIRECTORY_ENTRY)((LPBYTE)resdir+sizeof(IMAGE_RESOURCE_DIRECTORY));
  253.     ret = FALSE;
  254.     for (i=0;i<resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries;i++) {
  255.      LPSTR name;
  256. if (et[i].u1.s.NameIsString)
  257.     name = HEAP_strdupWtoA(heap,0,(LPWSTR)((LPBYTE)pem->pe_resource+et[i].u1.s.NameOffset));
  258. else
  259.     name = (LPSTR)(int)et[i].u1.Id;
  260. ret = lpfun(hmod,type,name,lparam);
  261. if (HIWORD(name)) HeapFree(heap,0,name);
  262. if (!ret)
  263. break;
  264.     }
  265.     return ret;
  266. }
  267. /**********************************************************************
  268.  *     PE_EnumResourceNames32W
  269.  */
  270. WIN_BOOL
  271. PE_EnumResourceNamesW(
  272. HMODULE hmod,LPCWSTR type,ENUMRESNAMEPROCW lpfun,LONG lparam
  273. ) {
  274.     PE_MODREF *pem = HMODULE32toPE_MODREF(hmod);
  275.     int i;
  276.     PIMAGE_RESOURCE_DIRECTORY resdir;
  277.     PIMAGE_RESOURCE_DIRECTORY_ENTRY et;
  278.     WIN_BOOL ret;
  279.     if (!pem || !pem->pe_resource)
  280.      return FALSE;
  281.     resdir = (PIMAGE_RESOURCE_DIRECTORY)pem->pe_resource;
  282.     resdir = GetResDirEntryW(resdir,type,(DWORD)pem->pe_resource,FALSE);
  283.     if (!resdir)
  284.      return FALSE;
  285.     et =(PIMAGE_RESOURCE_DIRECTORY_ENTRY)((LPBYTE)resdir+sizeof(IMAGE_RESOURCE_DIRECTORY));
  286.     ret = FALSE;
  287.     for (i=0;i<resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries;i++) {
  288. LPWSTR name;
  289.      if (et[i].u1.s.NameIsString)
  290. name = (LPWSTR)((LPBYTE)pem->pe_resource+et[i].u1.s.NameOffset);
  291. else
  292. name = (LPWSTR)(int)et[i].u1.Id;
  293. ret = lpfun(hmod,type,name,lparam);
  294. if (!ret)
  295. break;
  296.     }
  297.     return ret;
  298. }
  299. /**********************************************************************
  300.  *     PE_EnumResourceNames32A
  301.  */
  302. WIN_BOOL
  303. PE_EnumResourceLanguagesA(
  304. HMODULE hmod,LPCSTR name,LPCSTR type,ENUMRESLANGPROCA lpfun,
  305. LONG lparam
  306. ) {
  307.     PE_MODREF *pem = HMODULE32toPE_MODREF(hmod);
  308.     int i;
  309.     PIMAGE_RESOURCE_DIRECTORY resdir;
  310.     PIMAGE_RESOURCE_DIRECTORY_ENTRY et;
  311.     WIN_BOOL ret;
  312.     HANDLE heap = GetProcessHeap();
  313.     LPWSTR nameW,typeW;
  314.     if (!pem || !pem->pe_resource)
  315.      return FALSE;
  316.     resdir = (PIMAGE_RESOURCE_DIRECTORY)pem->pe_resource;
  317.     if (HIWORD(name))
  318. nameW = HEAP_strdupAtoW(heap,0,name);
  319.     else
  320.      nameW = (LPWSTR)name;
  321.     resdir = GetResDirEntryW(resdir,nameW,(DWORD)pem->pe_resource,FALSE);
  322.     if (HIWORD(nameW))
  323.      HeapFree(heap,0,nameW);
  324.     if (!resdir)
  325.      return FALSE;
  326.     if (HIWORD(type))
  327. typeW = HEAP_strdupAtoW(heap,0,type);
  328.     else
  329. typeW = (LPWSTR)type;
  330.     resdir = GetResDirEntryW(resdir,typeW,(DWORD)pem->pe_resource,FALSE);
  331.     if (HIWORD(typeW))
  332.      HeapFree(heap,0,typeW);
  333.     if (!resdir)
  334.      return FALSE;
  335.     et =(PIMAGE_RESOURCE_DIRECTORY_ENTRY)((LPBYTE)resdir+sizeof(IMAGE_RESOURCE_DIRECTORY));
  336.     ret = FALSE;
  337.     for (i=0;i<resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries;i++) {
  338.      /* languages are just ids... I hopem */
  339. ret = lpfun(hmod,name,type,et[i].u1.Id,lparam);
  340. if (!ret)
  341. break;
  342.     }
  343.     return ret;
  344. }
  345. /**********************************************************************
  346.  *     PE_EnumResourceLanguages32W
  347.  */
  348. WIN_BOOL
  349. PE_EnumResourceLanguagesW(
  350. HMODULE hmod,LPCWSTR name,LPCWSTR type,ENUMRESLANGPROCW lpfun,
  351. LONG lparam
  352. ) {
  353.     PE_MODREF *pem = HMODULE32toPE_MODREF(hmod);
  354.     int i;
  355.     PIMAGE_RESOURCE_DIRECTORY resdir;
  356.     PIMAGE_RESOURCE_DIRECTORY_ENTRY et;
  357.     WIN_BOOL ret;
  358.     if (!pem || !pem->pe_resource)
  359.      return FALSE;
  360.     resdir = (PIMAGE_RESOURCE_DIRECTORY)pem->pe_resource;
  361.     resdir = GetResDirEntryW(resdir,name,(DWORD)pem->pe_resource,FALSE);
  362.     if (!resdir)
  363.      return FALSE;
  364.     resdir = GetResDirEntryW(resdir,type,(DWORD)pem->pe_resource,FALSE);
  365.     if (!resdir)
  366.      return FALSE;
  367.     et =(PIMAGE_RESOURCE_DIRECTORY_ENTRY)((LPBYTE)resdir+sizeof(IMAGE_RESOURCE_DIRECTORY));
  368.     ret = FALSE;
  369.     for (i=0;i<resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries;i++) {
  370. ret = lpfun(hmod,name,type,et[i].u1.Id,lparam);
  371. if (!ret)
  372. break;
  373.     }
  374.     return ret;
  375. }