| /* |
| * WINElib-Resources |
| * |
| * Copied and modified heavily from loader/resource.c |
| */ |
| |
| #include <stdlib.h> |
| #include "wine/winestring.h" |
| #include "libres.h" |
| #include "resource.h" |
| #include "debugtools.h" |
| #include "heap.h" |
| #include "crtdll.h" |
| #include "xmalloc.h" |
| |
| DEFAULT_DEBUG_CHANNEL(resource) |
| |
| typedef struct RLE |
| { |
| const wrc_resource32_t * const * Resources; /* NULL-terminated array of pointers */ |
| struct RLE* next; |
| } ResListE; |
| |
| static ResListE* ResourceList=NULL; |
| |
| void LIBRES_RegisterResources(const wrc_resource32_t * const * Res) |
| { |
| ResListE** Curr; |
| ResListE* n; |
| for(Curr=&ResourceList; *Curr; Curr=&((*Curr)->next)) { } |
| n=xmalloc(sizeof(ResListE)); |
| n->Resources=Res; |
| n->next=NULL; |
| *Curr=n; |
| } |
| |
| /********************************************************************** |
| * LIBRES_FindResource |
| */ |
| typedef int (*CmpFunc_t)(LPCWSTR a, LPCWSTR b, int c); |
| |
| int CompareOrdinal(LPCWSTR ordinal, LPCWSTR resstr, int resid) |
| { |
| return !resstr && (resid == LOWORD(ordinal)); |
| } |
| |
| int CompareName(LPCWSTR name, LPCWSTR resstr, int resid) |
| { |
| return resstr && !CRTDLL__wcsnicmp(resstr+1, name, *(resstr)); |
| } |
| |
| HRSRC LIBRES_FindResource( HINSTANCE hModule, LPCWSTR name, LPCWSTR type ) |
| { |
| LPCWSTR nameid = name, typeid = type; |
| ResListE* ResBlock; |
| const wrc_resource32_t* const * Res; |
| CmpFunc_t EqualNames = CompareOrdinal; |
| CmpFunc_t EqualTypes = CompareOrdinal; |
| |
| if(HIWORD(name)) |
| { |
| if(*name=='#') |
| { |
| LPSTR nameA = HEAP_strdupWtoA( GetProcessHeap(), 0, name ); |
| nameid = (LPCWSTR) atoi(nameA+1); |
| HeapFree( GetProcessHeap(), 0, nameA ); |
| } |
| else |
| EqualNames = CompareName; |
| } |
| |
| if(HIWORD(type)) |
| { |
| if(*type=='#') |
| { |
| LPSTR typeA = HEAP_strdupWtoA( GetProcessHeap(), 0, type ); |
| typeid= (LPCWSTR) atoi(typeA+1); |
| HeapFree( GetProcessHeap(), 0, typeA ); |
| } |
| else |
| EqualTypes = CompareName; |
| } |
| |
| for(ResBlock=ResourceList; ResBlock; ResBlock=ResBlock->next) |
| for(Res=ResBlock->Resources; *Res; Res++) |
| if (EqualNames(nameid, (*Res)->resname, (*Res)->resid) && |
| EqualTypes(typeid, (*Res)->restypename, (*Res)->restype)) |
| return (HRSRC)*Res; |
| |
| return 0; |
| } |
| |
| |
| /********************************************************************** |
| * LIBRES_LoadResource |
| */ |
| HGLOBAL LIBRES_LoadResource( HINSTANCE hModule, HRSRC hRsrc ) |
| { |
| return (HGLOBAL)(((wrc_resource32_t*)hRsrc)->data); |
| } |
| |
| |
| /********************************************************************** |
| * LIBRES_SizeofResource |
| */ |
| DWORD LIBRES_SizeofResource( HINSTANCE hModule, HRSRC hRsrc ) |
| { |
| return (DWORD)(((wrc_resource32_t*)hRsrc)->datasize); |
| } |