4 * Copyright 1993 Robert J. Amstadt
5 * Copyright 1995 Alexandre Julliard
13 #include <sys/types.h>
18 #include "wine/winbase.h"
19 #include "wine/windef.h"
20 #include "wine/winuser.h"
21 #include "wine/heap.h"
22 #include "wine/module.h"
23 #include "wine/debugtools.h"
24 #include "wine/winerror.h"
29 WORD WINE_LanguageId
=0x409;//english
31 #define HRSRC_MAP_BLOCKSIZE 16
33 typedef struct _HRSRC_ELEM
39 typedef struct _HRSRC_MAP
46 static HRSRC
RES_FindResource2( HMODULE hModule
, LPCSTR type
,
47 LPCSTR name
, WORD lang
, int unicode
)
50 LPWSTR typeStr
, nameStr
;
51 WINE_MODREF
*wm
= MODULE32_LookupHMODULE( hModule
);
55 /* 32-bit PE module */
58 if ( HIWORD( type
) && (!unicode
))
59 typeStr
= HEAP_strdupAtoW( GetProcessHeap(), 0, type
);
61 typeStr
= (LPWSTR
)type
;
62 if ( HIWORD( name
) && (!unicode
))
63 nameStr
= HEAP_strdupAtoW( GetProcessHeap(), 0, name
);
65 nameStr
= (LPWSTR
)name
;
67 hRsrc
= PE_FindResourceExW( wm
, nameStr
, typeStr
, lang
);
69 if ( HIWORD( type
) && (!unicode
))
70 HeapFree( GetProcessHeap(), 0, typeStr
);
71 if ( HIWORD( name
) && (!unicode
))
72 HeapFree( GetProcessHeap(), 0, nameStr
);
77 /**********************************************************************
81 static HRSRC
RES_FindResource( HMODULE hModule
, LPCSTR type
,
82 LPCSTR name
, WORD lang
, int unicode
)
87 hRsrc
= RES_FindResource2(hModule
, type
, name
, lang
, unicode
);
89 // __EXCEPT(page_fault)
91 // WARN("page fault\n");
92 // SetLastError(ERROR_INVALID_PARAMETER);
99 /**********************************************************************
102 static DWORD
RES_SizeofResource( HMODULE hModule
, HRSRC hRsrc
)
107 // HMODULE16 hMod16 = MapHModuleLS( hModule );
108 // NE_MODULE *pModule = NE_GetPtr( hMod16 );
109 // WINE_MODREF *wm = pModule && pModule->module32?
110 // MODULE32_LookupHMODULE( pModule->module32 ) : NULL;
111 WINE_MODREF
*wm
= MODULE32_LookupHMODULE( hModule
);
113 if ( !hModule
|| !hRsrc
) return 0;
115 /* 32-bit PE module */
116 /* If we got a 16-bit hRsrc, convert it */
117 // hRsrc32 = HIWORD(hRsrc)? hRsrc : MapHRsrc16To32( pModule, hRsrc );
120 printf("16-bit hRsrcs not supported\n");
123 size
= PE_SizeofResource( hModule
, hRsrc
);
127 /**********************************************************************
130 static HFILE
RES_AccessResource( HMODULE hModule
, HRSRC hRsrc
)
132 HFILE hFile
= HFILE_ERROR
;
134 WINE_MODREF
*wm
= MODULE32_LookupHMODULE( hModule
);
136 if ( !hModule
|| !hRsrc
) return HFILE_ERROR
;
138 /* 32-bit PE module */
139 FIXME("32-bit modules not yet supported.\n" );
145 /**********************************************************************
148 static HGLOBAL
RES_LoadResource( HMODULE hModule
, HRSRC hRsrc
)
152 WINE_MODREF
*wm
= MODULE32_LookupHMODULE( hModule
);
155 if ( !hModule
|| !hRsrc
) return 0;
157 /* 32-bit PE module */
159 /* If we got a 16-bit hRsrc, convert it */
160 // hRsrc32 = HIWORD(hRsrc)? hRsrc : MapHRsrc16To32( pModule, hRsrc );
163 printf("16-bit hRsrcs not supported\n");
166 hMem
= PE_LoadResource( wm
, hRsrc
);
171 /**********************************************************************
174 static LPVOID
RES_LockResource( HGLOBAL handle
)
178 TRACE("(%08x, %s)\n", handle
, "PE" );
180 bits
= (LPVOID
)handle
;
185 /**********************************************************************
188 static WIN_BOOL
RES_FreeResource( HGLOBAL handle
)
190 HGLOBAL retv
= handle
;
191 return (WIN_BOOL
)retv
;
194 /**********************************************************************
195 * FindResourceA (KERNEL32.128)
197 HANDLE WINAPI
FindResourceA( HMODULE hModule
, LPCSTR name
, LPCSTR type
)
199 return RES_FindResource( hModule
, type
, name
,
202 HANDLE WINAPI
FindResourceW( HMODULE hModule
, LPCWSTR name
, LPCWSTR type
)
204 return RES_FindResource( hModule
, (LPCSTR
)type
, (LPCSTR
)name
,
208 /**********************************************************************
209 * FindResourceExA (KERNEL32.129)
211 HANDLE WINAPI
FindResourceExA( HMODULE hModule
,
212 LPCSTR type
, LPCSTR name
, WORD lang
)
214 return RES_FindResource( hModule
, type
, name
,
218 HANDLE WINAPI
FindResourceExW( HMODULE hModule
,
219 LPCWSTR type
, LPCWSTR name
, WORD lang
)
221 return RES_FindResource( hModule
, (LPCSTR
)type
, (LPCSTR
)name
,
227 /**********************************************************************
228 * LockResource (KERNEL32.384)
230 LPVOID WINAPI
LockResource( HGLOBAL handle
)
232 return RES_LockResource( handle
);
236 /**********************************************************************
237 * FreeResource (KERNEL32.145)
239 WIN_BOOL WINAPI
FreeResource( HGLOBAL handle
)
241 return RES_FreeResource( handle
);
245 /**********************************************************************
246 * AccessResource (KERNEL32.64)
248 INT WINAPI
AccessResource( HMODULE hModule
, HRSRC hRsrc
)
250 return RES_AccessResource( hModule
, hRsrc
);
252 /**********************************************************************
253 * SizeofResource (KERNEL32.522)
255 DWORD WINAPI
SizeofResource( HINSTANCE hModule
, HRSRC hRsrc
)
257 return RES_SizeofResource( hModule
, hRsrc
);
261 INT WINAPI
LoadStringW( HINSTANCE instance
, UINT resource_id
,
262 LPWSTR buffer
, INT buflen
);
264 /**********************************************************************
265 * LoadStringA (USER32.375)
267 INT WINAPI
LoadStringA( HINSTANCE instance
, UINT resource_id
,
268 LPSTR buffer
, INT buflen
)
276 if ( buffer
!= NULL
&& buflen
> 0 )
279 wbuflen
= LoadStringW(instance
,resource_id
,NULL
,0);
285 wbuf
= (LPWSTR
) HeapAlloc( GetProcessHeap(), 0, wbuflen
* sizeof(WCHAR
) );
286 wbuflen
= LoadStringW(instance
,resource_id
,wbuf
,wbuflen
);
289 abuflen
= WideCharToMultiByte(CP_ACP
,0,wbuf
,wbuflen
,NULL
,0,NULL
,NULL
);
292 if ( buffer
== NULL
|| buflen
== 0 )
296 abuf
= (LPSTR
) HeapAlloc( GetProcessHeap(), 0, abuflen
* sizeof(CHAR
) );
297 abuflen
= WideCharToMultiByte(CP_ACP
,0,wbuf
,wbuflen
,abuf
,abuflen
,NULL
,NULL
);
300 abuflen
= min(abuflen
,buflen
- 1);
301 memcpy( buffer
, abuf
, abuflen
);
305 HeapFree( GetProcessHeap(), 0, abuf
);
309 HeapFree( GetProcessHeap(), 0, wbuf
);
314 /**********************************************************************
315 * LoadStringW (USER32.376)
317 INT WINAPI
LoadStringW( HINSTANCE instance
, UINT resource_id
,
318 LPWSTR buffer
, INT buflen
)
326 if (HIWORD(resource_id
)==0xFFFF) /* netscape 3 passes this */
327 resource_id
= (UINT
)(-((INT
)resource_id
));
328 TRACE("instance = %04x, id = %04x, buffer = %08x, "
329 "length = %d\n", instance
, (int)resource_id
, (int) buffer
, buflen
);
331 /* Use bits 4 - 19 (incremented by 1) as resourceid, mask out
333 hrsrc
= FindResourceW( instance
, (LPCWSTR
)(((resource_id
>>4)&0xffff)+1),
335 if (!hrsrc
) return 0;
336 hmem
= LoadResource( instance
, hrsrc
);
339 p
= (WCHAR
*) LockResource(hmem
);
340 string_num
= resource_id
& 0x000f;
341 for (i
= 0; i
< string_num
; i
++)
344 TRACE("strlen = %d\n", (int)*p
);
346 if (buffer
== NULL
) return *p
;
347 i
= min(buflen
- 1, *p
);
349 memcpy(buffer
, p
+ 1, i
* sizeof (WCHAR
));
350 buffer
[i
] = (WCHAR
) 0;
353 buffer
[0] = (WCHAR
) 0;
357 WARN("Don't know why caller give buflen=%d *p=%d trying to obtain string '%s'\n", buflen
, *p
, p
+ 1);
361 TRACE("String loaded !\n");
365 /* Messages...used by FormatMessage32* (KERNEL32.something)
367 * They can be specified either directly or using a message ID and
368 * loading them from the resource.
370 * The resourcedata has following format:
372 * 0: DWORD nrofentries
373 * nrofentries * subentry:
374 * 0: DWORD firstentry
376 * 8: DWORD offset from start to the stringentries
378 * (lastentry-firstentry) * stringentry:
379 * 0: WORD len (0 marks end)
382 * (stringentry i of a subentry refers to the ID 'firstentry+i')
384 * Yes, ANSI strings in win32 resources. Go figure.
387 /**********************************************************************
388 * LoadMessageA (internal)
390 INT WINAPI
LoadMessageA( HMODULE instance
, UINT id
, WORD lang
,
391 LPSTR buffer
, INT buflen
)
395 PMESSAGE_RESOURCE_DATA mrd
;
396 PMESSAGE_RESOURCE_BLOCK mrb
;
397 PMESSAGE_RESOURCE_ENTRY mre
;
400 TRACE("instance = %08lx, id = %08lx, buffer = %p, length = %ld\n", (DWORD
)instance
, (DWORD
)id
, buffer
, (DWORD
)buflen
);
402 /*FIXME: I am not sure about the '1' ... But I've only seen those entries*/
403 hrsrc
= FindResourceExW(instance
,RT_MESSAGELISTW
,(LPWSTR
)1,lang
);
404 if (!hrsrc
) return 0;
405 hmem
= LoadResource( instance
, hrsrc
);
408 mrd
= (PMESSAGE_RESOURCE_DATA
)LockResource(hmem
);
410 mrb
= &(mrd
->Blocks
[0]);
411 for (i
=mrd
->NumberOfBlocks
;i
--;) {
412 if ((id
>=mrb
->LowId
) && (id
<=mrb
->HighId
)) {
413 mre
= (PMESSAGE_RESOURCE_ENTRY
)(((char*)mrd
)+mrb
->OffsetToEntries
);
424 mre
= (PMESSAGE_RESOURCE_ENTRY
)(((char*)mre
)+(mre
->Length
));
427 TRACE(" - strlen=%d\n",slen
);
428 i
= min(buflen
- 1, slen
);
432 lstrcpynA(buffer
,(char*)mre
->Text
,i
);
441 TRACE("'%s' copied !\n", buffer
);
447 /**********************************************************************
448 * EnumResourceTypesA (KERNEL32.90)
450 WIN_BOOL WINAPI
EnumResourceTypesA( HMODULE hmodule
,ENUMRESTYPEPROCA lpfun
,
453 /* FIXME: move WINE_MODREF stuff here */
454 return PE_EnumResourceTypesA(hmodule
,lpfun
,lParam
);
457 /**********************************************************************
458 * EnumResourceNamesA (KERNEL32.88)
460 WIN_BOOL WINAPI
EnumResourceNamesA( HMODULE hmodule
, LPCSTR type
,
461 ENUMRESNAMEPROCA lpfun
, LONG lParam
)
463 /* FIXME: move WINE_MODREF stuff here */
464 return PE_EnumResourceNamesA(hmodule
,type
,lpfun
,lParam
);
466 /**********************************************************************
467 * EnumResourceLanguagesA (KERNEL32.86)
469 WIN_BOOL WINAPI
EnumResourceLanguagesA( HMODULE hmodule
, LPCSTR type
,
470 LPCSTR name
, ENUMRESLANGPROCA lpfun
,
473 /* FIXME: move WINE_MODREF stuff here */
474 return PE_EnumResourceLanguagesA(hmodule
,type
,name
,lpfun
,lParam
);
476 /**********************************************************************
477 * LoadResource (KERNEL32.370)
479 HGLOBAL WINAPI
LoadResource( HINSTANCE hModule
, HRSRC hRsrc
)
481 return RES_LoadResource( hModule
, hRsrc
);