Main Page | Modules | Class Hierarchy | Class List | Directories | File List | Class Members | File Members | Related Pages

pe_resource.c

00001 /*
00002  * PE (Portable Execute) File Resources
00003  *
00004  * Copyright 1995 Thomas Sandford
00005  * Copyright 1996 Martin von Loewis
00006  *
00007  * Based on the Win16 resource handling code in loader/resource.c
00008  * Copyright 1993 Robert J. Amstadt
00009  * Copyright 1995 Alexandre Julliard
00010  * Copyright 1997 Marcus Meissner
00011  *
00012  * Modified for use with MPlayer, detailed CVS changelog at
00013  * http://www.mplayerhq.hu/cgi-bin/cvsweb.cgi/main/
00014  * $Id: pe_resource.c 11593 2005-06-28 18:02:01Z courmisch $
00015  *
00016  */
00017 #include "config.h"
00018 
00019 #include <stdlib.h>
00020 #include <sys/types.h>
00021 #include "wine/winestring.h"
00022 #include "wine/windef.h"
00023 #include "wine/pe_image.h"
00024 #include "wine/module.h"
00025 #include "wine/heap.h"
00026 //#include "task.h"
00027 //#include "process.h"
00028 //#include "stackframe.h"
00029 #include "wine/debugtools.h"
00030 #include "ext.h"
00031 
00032 /**********************************************************************
00033  *  HMODULE32toPE_MODREF 
00034  *
00035  * small helper function to get a PE_MODREF from a passed HMODULE32
00036  */
00037 static PE_MODREF*
00038 HMODULE32toPE_MODREF(HMODULE hmod) {
00039         WINE_MODREF     *wm;
00040 
00041         wm = MODULE32_LookupHMODULE( hmod );
00042         if (!wm || wm->type!=MODULE32_PE)
00043                 return NULL;
00044         return &(wm->binfmt.pe);
00045 }
00046 
00047 /**********************************************************************
00048  *          GetResDirEntryW
00049  *
00050  *      Helper function - goes down one level of PE resource tree
00051  *
00052  */
00053 PIMAGE_RESOURCE_DIRECTORY GetResDirEntryW(PIMAGE_RESOURCE_DIRECTORY resdirptr,
00054                                            LPCWSTR name,DWORD root,
00055                                            WIN_BOOL allowdefault)
00056 {
00057     int entrynum;
00058     PIMAGE_RESOURCE_DIRECTORY_ENTRY entryTable;
00059     int namelen;
00060 
00061     if (HIWORD(name)) {
00062         if (name[0]=='#') {
00063                 char    buf[10];
00064 
00065                 lstrcpynWtoA(buf,name+1,10);
00066                 return GetResDirEntryW(resdirptr,(LPCWSTR)atoi(buf),root,allowdefault);
00067         }
00068         entryTable = (PIMAGE_RESOURCE_DIRECTORY_ENTRY) (
00069                         (BYTE *) resdirptr + 
00070                         sizeof(IMAGE_RESOURCE_DIRECTORY));
00071         namelen = lstrlenW(name);
00072         for (entrynum = 0; entrynum < resdirptr->NumberOfNamedEntries; entrynum++)
00073         {
00074                 PIMAGE_RESOURCE_DIR_STRING_U str =
00075                 (PIMAGE_RESOURCE_DIR_STRING_U) (root + 
00076                         entryTable[entrynum].u1.s.NameOffset);
00077                 if(namelen != str->Length)
00078                         continue;
00079                 if(wcsnicmp(name,str->NameString,str->Length)==0)
00080                         return (PIMAGE_RESOURCE_DIRECTORY) (
00081                                 root +
00082                                 entryTable[entrynum].u2.s.OffsetToDirectory);
00083         }
00084         return NULL;
00085     } else {
00086         entryTable = (PIMAGE_RESOURCE_DIRECTORY_ENTRY) (
00087                         (BYTE *) resdirptr + 
00088                         sizeof(IMAGE_RESOURCE_DIRECTORY) +
00089                         resdirptr->NumberOfNamedEntries * sizeof(IMAGE_RESOURCE_DIRECTORY_ENTRY));
00090         for (entrynum = 0; entrynum < resdirptr->NumberOfIdEntries; entrynum++)
00091             if ((DWORD)entryTable[entrynum].u1.Name == (DWORD)name)
00092                 return (PIMAGE_RESOURCE_DIRECTORY) (
00093                         root +
00094                         entryTable[entrynum].u2.s.OffsetToDirectory);
00095         /* just use first entry if no default can be found */
00096         if (allowdefault && !name && resdirptr->NumberOfIdEntries)
00097                 return (PIMAGE_RESOURCE_DIRECTORY) (
00098                         root +
00099                         entryTable[0].u2.s.OffsetToDirectory);
00100         return NULL;
00101     }
00102 }
00103 
00104 /**********************************************************************
00105  *          GetResDirEntryA
00106  */
00107 PIMAGE_RESOURCE_DIRECTORY GetResDirEntryA( PIMAGE_RESOURCE_DIRECTORY resdirptr,
00108                                            LPCSTR name, DWORD root,
00109                                            WIN_BOOL allowdefault )
00110 {
00111     PIMAGE_RESOURCE_DIRECTORY retv;
00112     LPWSTR nameW = HIWORD(name)? HEAP_strdupAtoW( GetProcessHeap(), 0, name ) 
00113                                : (LPWSTR)name;
00114 
00115     retv = GetResDirEntryW( resdirptr, nameW, root, allowdefault );
00116 
00117     if ( HIWORD(name) ) HeapFree( GetProcessHeap(), 0, nameW );
00118 
00119     return retv;
00120 }
00121 
00122 /**********************************************************************
00123  *          PE_FindResourceEx32W
00124  */
00125 HANDLE PE_FindResourceExW(
00126         WINE_MODREF *wm,LPCWSTR name,LPCWSTR type,WORD lang
00127 ) {
00128     PIMAGE_RESOURCE_DIRECTORY resdirptr;
00129     DWORD root;
00130     HANDLE result;
00131     PE_MODREF   *pem = &(wm->binfmt.pe);
00132 
00133     if (!pem || !pem->pe_resource)
00134         return 0;
00135 
00136     resdirptr = pem->pe_resource;
00137     root = (DWORD) resdirptr;
00138     if ((resdirptr = GetResDirEntryW(resdirptr, type, root, FALSE)) == NULL)
00139         return 0;
00140     if ((resdirptr = GetResDirEntryW(resdirptr, name, root, FALSE)) == NULL)
00141         return 0;
00142     result = (HANDLE)GetResDirEntryW(resdirptr, (LPCWSTR)(UINT)lang, root, FALSE);
00143         /* Try LANG_NEUTRAL, too */
00144     if(!result)
00145         return (HANDLE)GetResDirEntryW(resdirptr, (LPCWSTR)0, root, TRUE);
00146     return result;
00147 }
00148 
00149 
00150 /**********************************************************************
00151  *          PE_LoadResource32
00152  */
00153 HANDLE PE_LoadResource( WINE_MODREF *wm, HANDLE hRsrc )
00154 {
00155     if (!hRsrc || !wm || wm->type!=MODULE32_PE)
00156         return 0;
00157     return (HANDLE) (wm->module + ((PIMAGE_RESOURCE_DATA_ENTRY)hRsrc)->OffsetToData);
00158 }
00159 
00160 
00161 /**********************************************************************
00162  *          PE_SizeofResource32
00163  */
00164 DWORD PE_SizeofResource( HINSTANCE hModule, HANDLE hRsrc )
00165 {
00166     /* we don't need hModule */
00167     if (!hRsrc)
00168          return 0;
00169     return ((PIMAGE_RESOURCE_DATA_ENTRY)hRsrc)->Size;
00170 }
00171 
00172 /**********************************************************************
00173  *          PE_EnumResourceTypes32A
00174  */
00175 WIN_BOOL
00176 PE_EnumResourceTypesA(HMODULE hmod,ENUMRESTYPEPROCA lpfun,LONG lparam) {
00177     PE_MODREF   *pem = HMODULE32toPE_MODREF(hmod);
00178     int         i;
00179     PIMAGE_RESOURCE_DIRECTORY           resdir;
00180     PIMAGE_RESOURCE_DIRECTORY_ENTRY     et;
00181     WIN_BOOL    ret;
00182     HANDLE      heap = GetProcessHeap();        
00183 
00184     if (!pem || !pem->pe_resource)
00185         return FALSE;
00186 
00187     resdir = (PIMAGE_RESOURCE_DIRECTORY)pem->pe_resource;
00188     et =(PIMAGE_RESOURCE_DIRECTORY_ENTRY)((LPBYTE)resdir+sizeof(IMAGE_RESOURCE_DIRECTORY));
00189     ret = FALSE;
00190     for (i=0;i<resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries;i++) {
00191         LPSTR   name;
00192 
00193         if (et[i].u1.s.NameIsString)
00194                 name = HEAP_strdupWtoA(heap,0,(LPWSTR)((LPBYTE)pem->pe_resource+et[i].u1.s.NameOffset));
00195         else
00196                 name = (LPSTR)(int)et[i].u1.Id;
00197         ret = lpfun(hmod,name,lparam);
00198         if (HIWORD(name))
00199                 HeapFree(heap,0,name);
00200         if (!ret)
00201                 break;
00202     }
00203     return ret;
00204 }
00205 
00206 /**********************************************************************
00207  *          PE_EnumResourceTypes32W
00208  */
00209 WIN_BOOL
00210 PE_EnumResourceTypesW(HMODULE hmod,ENUMRESTYPEPROCW lpfun,LONG lparam) {
00211     PE_MODREF   *pem = HMODULE32toPE_MODREF(hmod);
00212     int         i;
00213     PIMAGE_RESOURCE_DIRECTORY           resdir;
00214     PIMAGE_RESOURCE_DIRECTORY_ENTRY     et;
00215     WIN_BOOL    ret;
00216 
00217     if (!pem || !pem->pe_resource)
00218         return FALSE;
00219 
00220     resdir = (PIMAGE_RESOURCE_DIRECTORY)pem->pe_resource;
00221     et =(PIMAGE_RESOURCE_DIRECTORY_ENTRY)((LPBYTE)resdir+sizeof(IMAGE_RESOURCE_DIRECTORY));
00222     ret = FALSE;
00223     for (i=0;i<resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries;i++) {
00224         LPWSTR  type;
00225         if (et[i].u1.s.NameIsString)
00226                 type = (LPWSTR)((LPBYTE)pem->pe_resource+et[i].u1.s.NameOffset);
00227         else
00228                 type = (LPWSTR)(int)et[i].u1.Id;
00229 
00230         ret = lpfun(hmod,type,lparam);
00231         if (!ret)
00232                 break;
00233     }
00234     return ret;
00235 }
00236 
00237 /**********************************************************************
00238  *          PE_EnumResourceNames32A
00239  */
00240 WIN_BOOL
00241 PE_EnumResourceNamesA(
00242         HMODULE hmod,LPCSTR type,ENUMRESNAMEPROCA lpfun,LONG lparam
00243 ) {
00244     PE_MODREF   *pem = HMODULE32toPE_MODREF(hmod);
00245     int         i;
00246     PIMAGE_RESOURCE_DIRECTORY           resdir;
00247     PIMAGE_RESOURCE_DIRECTORY_ENTRY     et;
00248     WIN_BOOL    ret;
00249     HANDLE      heap = GetProcessHeap();        
00250     LPWSTR      typeW;
00251 
00252     if (!pem || !pem->pe_resource)
00253         return FALSE;
00254     resdir = (PIMAGE_RESOURCE_DIRECTORY)pem->pe_resource;
00255     if (HIWORD(type))
00256         typeW = HEAP_strdupAtoW(heap,0,type);
00257     else
00258         typeW = (LPWSTR)type;
00259     resdir = GetResDirEntryW(resdir,typeW,(DWORD)pem->pe_resource,FALSE);
00260     if (HIWORD(typeW))
00261         HeapFree(heap,0,typeW);
00262     if (!resdir)
00263         return FALSE;
00264     et =(PIMAGE_RESOURCE_DIRECTORY_ENTRY)((LPBYTE)resdir+sizeof(IMAGE_RESOURCE_DIRECTORY));
00265     ret = FALSE;
00266     for (i=0;i<resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries;i++) {
00267         LPSTR   name;
00268 
00269         if (et[i].u1.s.NameIsString)
00270             name = HEAP_strdupWtoA(heap,0,(LPWSTR)((LPBYTE)pem->pe_resource+et[i].u1.s.NameOffset));
00271         else
00272             name = (LPSTR)(int)et[i].u1.Id;
00273         ret = lpfun(hmod,type,name,lparam);
00274         if (HIWORD(name)) HeapFree(heap,0,name);
00275         if (!ret)
00276                 break;
00277     }
00278     return ret;
00279 }
00280 
00281 /**********************************************************************
00282  *          PE_EnumResourceNames32W
00283  */
00284 WIN_BOOL
00285 PE_EnumResourceNamesW(
00286         HMODULE hmod,LPCWSTR type,ENUMRESNAMEPROCW lpfun,LONG lparam
00287 ) {
00288     PE_MODREF   *pem = HMODULE32toPE_MODREF(hmod);
00289     int         i;
00290     PIMAGE_RESOURCE_DIRECTORY           resdir;
00291     PIMAGE_RESOURCE_DIRECTORY_ENTRY     et;
00292     WIN_BOOL    ret;
00293 
00294     if (!pem || !pem->pe_resource)
00295         return FALSE;
00296 
00297     resdir = (PIMAGE_RESOURCE_DIRECTORY)pem->pe_resource;
00298     resdir = GetResDirEntryW(resdir,type,(DWORD)pem->pe_resource,FALSE);
00299     if (!resdir)
00300         return FALSE;
00301     et =(PIMAGE_RESOURCE_DIRECTORY_ENTRY)((LPBYTE)resdir+sizeof(IMAGE_RESOURCE_DIRECTORY));
00302     ret = FALSE;
00303     for (i=0;i<resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries;i++) {
00304         LPWSTR  name;
00305         if (et[i].u1.s.NameIsString)
00306                 name = (LPWSTR)((LPBYTE)pem->pe_resource+et[i].u1.s.NameOffset);
00307         else
00308                 name = (LPWSTR)(int)et[i].u1.Id;
00309         ret = lpfun(hmod,type,name,lparam);
00310         if (!ret)
00311                 break;
00312     }
00313     return ret;
00314 }
00315 
00316 /**********************************************************************
00317  *          PE_EnumResourceNames32A
00318  */
00319 WIN_BOOL
00320 PE_EnumResourceLanguagesA(
00321         HMODULE hmod,LPCSTR name,LPCSTR type,ENUMRESLANGPROCA lpfun,
00322         LONG lparam
00323 ) {
00324     PE_MODREF   *pem = HMODULE32toPE_MODREF(hmod);
00325     int         i;
00326     PIMAGE_RESOURCE_DIRECTORY           resdir;
00327     PIMAGE_RESOURCE_DIRECTORY_ENTRY     et;
00328     WIN_BOOL    ret;
00329     HANDLE      heap = GetProcessHeap();        
00330     LPWSTR      nameW,typeW;
00331 
00332     if (!pem || !pem->pe_resource)
00333         return FALSE;
00334 
00335     resdir = (PIMAGE_RESOURCE_DIRECTORY)pem->pe_resource;
00336     if (HIWORD(name))
00337         nameW = HEAP_strdupAtoW(heap,0,name);
00338     else
00339         nameW = (LPWSTR)name;
00340     resdir = GetResDirEntryW(resdir,nameW,(DWORD)pem->pe_resource,FALSE);
00341     if (HIWORD(nameW))
00342         HeapFree(heap,0,nameW);
00343     if (!resdir)
00344         return FALSE;
00345     if (HIWORD(type))
00346         typeW = HEAP_strdupAtoW(heap,0,type);
00347     else
00348         typeW = (LPWSTR)type;
00349     resdir = GetResDirEntryW(resdir,typeW,(DWORD)pem->pe_resource,FALSE);
00350     if (HIWORD(typeW))
00351         HeapFree(heap,0,typeW);
00352     if (!resdir)
00353         return FALSE;
00354     et =(PIMAGE_RESOURCE_DIRECTORY_ENTRY)((LPBYTE)resdir+sizeof(IMAGE_RESOURCE_DIRECTORY));
00355     ret = FALSE;
00356     for (i=0;i<resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries;i++) {
00357         /* languages are just ids... I hopem */
00358         ret = lpfun(hmod,name,type,et[i].u1.Id,lparam);
00359         if (!ret)
00360                 break;
00361     }
00362     return ret;
00363 }
00364 
00365 /**********************************************************************
00366  *          PE_EnumResourceLanguages32W
00367  */
00368 WIN_BOOL
00369 PE_EnumResourceLanguagesW(
00370         HMODULE hmod,LPCWSTR name,LPCWSTR type,ENUMRESLANGPROCW lpfun,
00371         LONG lparam
00372 ) {
00373     PE_MODREF   *pem = HMODULE32toPE_MODREF(hmod);
00374     int         i;
00375     PIMAGE_RESOURCE_DIRECTORY           resdir;
00376     PIMAGE_RESOURCE_DIRECTORY_ENTRY     et;
00377     WIN_BOOL    ret;
00378 
00379     if (!pem || !pem->pe_resource)
00380         return FALSE;
00381 
00382     resdir = (PIMAGE_RESOURCE_DIRECTORY)pem->pe_resource;
00383     resdir = GetResDirEntryW(resdir,name,(DWORD)pem->pe_resource,FALSE);
00384     if (!resdir)
00385         return FALSE;
00386     resdir = GetResDirEntryW(resdir,type,(DWORD)pem->pe_resource,FALSE);
00387     if (!resdir)
00388         return FALSE;
00389     et =(PIMAGE_RESOURCE_DIRECTORY_ENTRY)((LPBYTE)resdir+sizeof(IMAGE_RESOURCE_DIRECTORY));
00390     ret = FALSE;
00391     for (i=0;i<resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries;i++) {
00392         ret = lpfun(hmod,name,type,et[i].u1.Id,lparam);
00393         if (!ret)
00394                 break;
00395     }
00396     return ret;
00397 }

Generated on Tue Dec 20 10:14:21 2005 for vlc-0.8.4a by  doxygen 1.4.2