4 * Copyright 1993 Robert J. Amstadt
5 * Copyright 1995 Alexandre Julliard
12 #include <sys/types.h>
29 extern WORD WINE_LanguageId
;
32 /**********************************************************************
33 * FindResource32A (KERNEL32.128)
35 HANDLE32 WINAPI
FindResource32A( HMODULE32 hModule
, LPCSTR name
, LPCSTR type
)
37 return FindResourceEx32A(hModule
,name
,type
,WINE_LanguageId
);
40 /**********************************************************************
41 * FindResourceEx32A (KERNEL32.129)
43 HANDLE32 WINAPI
FindResourceEx32A( HMODULE32 hModule
, LPCSTR name
, LPCSTR type
,
49 if (HIWORD((DWORD
)name
))
50 xname
= HEAP_strdupAtoW( GetProcessHeap(), 0, name
);
53 if (HIWORD((DWORD
)type
))
54 xtype
= HEAP_strdupAtoW( GetProcessHeap(), 0, type
);
57 ret
= FindResourceEx32W( hModule
, xname
, xtype
, lang
);
58 if (HIWORD((DWORD
)name
)) HeapFree( GetProcessHeap(), 0, xname
);
59 if (HIWORD((DWORD
)type
)) HeapFree( GetProcessHeap(), 0, xtype
);
64 /**********************************************************************
65 * FindResourceEx32W (KERNEL32.130)
67 HRSRC32 WINAPI
FindResourceEx32W( HMODULE32 hModule
, LPCWSTR name
,
68 LPCWSTR type
, WORD lang
)
70 WINE_MODREF
*wm
= MODULE32_LookupHMODULE(PROCESS_Current(),hModule
);
73 TRACE(resource
, "module=%08x "
74 "type=%s%p name=%s%p\n", wm
->module
,
75 (HIWORD(type
))? "" : "#", type
,
76 (HIWORD(name
))? "" : "#", name
);
78 hrsrc
= LIBRES_FindResource( hModule
, name
, type
);
85 return PE_FindResourceEx32W(wm
,name
,type
,lang
);
87 ERR(module
,"unknown module type %d\n",wm
->type
);
95 /**********************************************************************
96 * FindResource32W (KERNEL32.131)
98 HRSRC32 WINAPI
FindResource32W(HINSTANCE32 hModule
, LPCWSTR name
, LPCWSTR type
)
100 return FindResourceEx32W(hModule
,name
,type
,WINE_LanguageId
);
104 /**********************************************************************
105 * LoadResource32 (KERNEL32.370)
106 * 'loads' a resource. The current implementation just returns a pointer
107 * into the already mapped image.
109 * pointer into the mapped resource of the passed module
111 HGLOBAL32 WINAPI
LoadResource32(
112 HINSTANCE32 hModule
, /* [in] module handle */
113 HRSRC32 hRsrc
) /* [in] resource handle */
115 WINE_MODREF
*wm
= MODULE32_LookupHMODULE(PROCESS_Current(),hModule
);
117 TRACE(resource
, "module=%04x res=%04x\n",
120 ERR(resource
,"hRsrc is 0, return 0.\n");
126 return PE_LoadResource32(wm
,hRsrc
);
128 ERR(resource
,"unknown module type %d\n",wm
->type
);
132 return LIBRES_LoadResource( hModule
, hRsrc
);
137 /**********************************************************************
138 * LockResource32 (KERNEL32.384)
140 LPVOID WINAPI
LockResource32( HGLOBAL32 handle
)
142 return (LPVOID
)handle
;
146 /**********************************************************************
147 * FreeResource32 (KERNEL32.145)
149 BOOL32 WINAPI
FreeResource32( HGLOBAL32 handle
)
151 /* no longer used in Win32 */
156 /**********************************************************************
157 * AccessResource32 (KERNEL32.64)
159 INT32 WINAPI
AccessResource32( HMODULE32 hModule
, HRSRC32 hRsrc
)
161 FIXME(resource
,"(module=%08x res=%08x),not implemented\n", hModule
, hRsrc
);
166 /**********************************************************************
167 * SizeofResource32 (KERNEL32.522)
169 DWORD WINAPI
SizeofResource32( HINSTANCE32 hModule
, HRSRC32 hRsrc
)
171 WINE_MODREF
*wm
= MODULE32_LookupHMODULE(PROCESS_Current(),hModule
);
173 TRACE(resource
, "module=%08x res=%08x\n", hModule
, hRsrc
);
180 ret
= PE_SizeofResource32(hModule
,hRsrc
);
186 ERR(module
,"unknown module type %d\n",wm
->type
);
190 fprintf(stderr
,"SizeofResource32: not implemented for WINELIB\n");
195 /**********************************************************************
196 * LoadAccelerators16 [USER.177]
198 HACCEL16 WINAPI
LoadAccelerators16(HINSTANCE16 instance
, SEGPTR lpTableName
)
202 if (HIWORD(lpTableName
))
203 TRACE(accel
, "%04x '%s'\n",
204 instance
, (char *)PTR_SEG_TO_LIN( lpTableName
) );
206 TRACE(accel
, "%04x %04x\n",
207 instance
, LOWORD(lpTableName
) );
209 if (!(hRsrc
= FindResource16( instance
, lpTableName
, RT_ACCELERATOR16
))) {
210 WARN(accel
, "couldn't find accelerator table resource\n");
214 TRACE(accel
, "returning HACCEL 0x%x\n", hRsrc
);
215 return LoadResource16(instance
,hRsrc
);
218 /**********************************************************************
219 * LoadAccelerators32W [USER.177]
220 * The image layout seems to look like this (not 100% sure):
221 * 00: BYTE type type of accelerator
222 * 01: BYTE pad (to WORD boundary)
225 * 06: WORD pad (to DWORD boundary)
227 HACCEL32 WINAPI
LoadAccelerators32W(HINSTANCE32 instance
,LPCWSTR lpTableName
)
232 if (HIWORD(lpTableName
))
233 TRACE(accel
, "%p '%s'\n",
234 (LPVOID
)instance
, (char *)( lpTableName
) );
236 TRACE(accel
, "%p 0x%04x\n",
237 (LPVOID
)instance
, LOWORD(lpTableName
) );
239 if (!(hRsrc
= FindResource32W( instance
, lpTableName
, RT_ACCELERATOR32W
)))
241 WARN(accel
, "couldn't find accelerator table resource\n");
245 hRetval
= LoadResource32( instance
, hRsrc
);
248 TRACE(accel
, "returning HACCEL 0x%x\n", hRsrc
);
252 HACCEL32 WINAPI
LoadAccelerators32A(HINSTANCE32 instance
,LPCSTR lpTableName
)
256 if (HIWORD(lpTableName
))
257 uni
= HEAP_strdupAtoW( GetProcessHeap(), 0, lpTableName
);
259 uni
= (LPWSTR
)lpTableName
;
260 result
= LoadAccelerators32W(instance
,uni
);
261 if (HIWORD(uni
)) HeapFree( GetProcessHeap(), 0, uni
);
265 /**********************************************************************
266 * CopyAcceleratorTable32A (USER32.58)
268 INT32 WINAPI
CopyAcceleratorTable32A(HACCEL32 src
, LPACCEL32 dst
, INT32 entries
)
270 return CopyAcceleratorTable32W(src
, dst
, entries
);
273 /**********************************************************************
274 * CopyAcceleratorTable32W (USER32.59)
276 * By mortene@pvv.org 980321
278 INT32 WINAPI
CopyAcceleratorTable32W(HACCEL32 src
, LPACCEL32 dst
,
282 LPACCEL32 accel
= (LPACCEL32
)src
;
285 /* Do parameter checking to avoid the explosions and the screaming
286 as far as possible. */
287 if((dst
&& (entries
< 1)) || (src
== (HACCEL32
)NULL
)) {
288 WARN(accel
, "Application sent invalid parameters (%p %p %d).\n",
289 (LPVOID
)src
, (LPVOID
)dst
, entries
);
296 /* Spit out some debugging information. */
297 TRACE(accel
, "accel %d: type 0x%02x, event '%c', IDval 0x%04x.\n",
298 i
, accel
[i
].fVirt
, accel
[i
].key
, accel
[i
].cmd
);
300 /* Copy data to the destination structure array (if dst == NULL,
301 we're just supposed to count the number of entries). */
303 memcpy(&dst
[i
], &accel
[i
], sizeof(ACCEL32
));
305 /* Check if we've reached the end of the application supplied
306 accelerator table. */
308 /* Turn off the high order bit, just in case. */
309 dst
[i
].fVirt
&= 0x7f;
314 /* The highest order bit seems to mark the end of the accelerator
315 resource table. (?) */
316 if((accel
[i
].fVirt
& 0x80) != 0) done
= TRUE
;
324 /*********************************************************************
325 * CreateAcceleratorTable (USER32.64)
327 * By mortene@pvv.org 980321
329 HACCEL32 WINAPI
CreateAcceleratorTable32A(LPACCEL32 lpaccel
, INT32 cEntries
)
333 /* Do parameter checking just in case someone's trying to be
336 WARN(accel
, "Application sent invalid parameters (%p %d).\n",
338 SetLastError(ERROR_INVALID_PARAMETER
);
339 return (HACCEL32
)NULL
;
341 FIXME(accel
, "should check that the accelerator descriptions are valid,"
342 " return NULL and SetLastError() if not.\n");
345 /* Allocate memory and copy the table. */
346 hAccel
= (HACCEL32
)HeapAlloc(GetProcessHeap(), 0,
347 cEntries
* sizeof(ACCEL32
));
348 TRACE(accel
, "handle %p\n", (LPVOID
)hAccel
);
350 WARN(accel
, "Out of memory.\n");
351 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
352 return (HACCEL32
)NULL
;
354 memcpy((LPACCEL32
)hAccel
, lpaccel
, cEntries
* sizeof(ACCEL32
));
356 /* Set the end-of-table terminator. */
357 ((LPACCEL32
)hAccel
)[cEntries
-1].fVirt
|= 0x80;
359 TRACE(accel
, "Allocated accelerator handle %x\n", hAccel
);
364 /******************************************************************************
365 * DestroyAcceleratorTable [USER32.130]
366 * Destroys an accelerator table
369 * By mortene@pvv.org 980321
372 * handle [I] Handle to accelerator table
376 BOOL32 WINAPI
DestroyAcceleratorTable( HACCEL32 handle
)
378 FIXME(accel
, "(0x%x): stub\n", handle
);
381 /* Weird.. I thought this should work. According to the API
382 specification, DestroyAcceleratorTable() should only be called on
383 HACCEL32's made by CreateAcceleratorTable(), but Microsoft Visual
384 Studio 97 calls this function with a series of different handle
385 values without ever calling CreateAcceleratorTable(). Something
386 is very fishy in Denmark... */
387 /* Update: looks like the calls to this function matches the calls
388 to LoadAccelerators() in M$ Visual Studio, except that the handle
389 values are off by some variable size from the HACCEL's returned
390 from LoadAccelerators(). WTH? */
392 /* Parameter checking to avoid any embarassing situations. */
394 /* WARN(accel, "Application sent NULL ptr.\n"); */
395 /* SetLastError(ERROR_INVALID_PARAMETER); */
399 /* HeapFree(GetProcessHeap(), 0, (LPACCEL32)handle); */
404 /**********************************************************************
407 INT16 WINAPI
LoadString16( HINSTANCE16 instance
, UINT16 resource_id
,
408 LPSTR buffer
, INT16 buflen
)
416 TRACE(resource
,"inst=%04x id=%04x buff=%08x len=%d\n",
417 instance
, resource_id
, (int) buffer
, buflen
);
419 hrsrc
= FindResource16( instance
, (SEGPTR
)((resource_id
>>4)+1), RT_STRING16
);
420 if (!hrsrc
) return 0;
421 hmem
= LoadResource16( instance
, hrsrc
);
424 p
= LockResource16(hmem
);
425 string_num
= resource_id
& 0x000f;
426 for (i
= 0; i
< string_num
; i
++)
429 TRACE(resource
, "strlen = %d\n", (int)*p
);
431 i
= MIN(buflen
- 1, *p
);
435 memcpy(buffer
, p
+ 1, i
);
442 WARN(resource
,"Dont know why caller give buflen=%d *p=%d trying to obtain string '%s'\n", buflen
, *p
, p
+ 1);
444 FreeResource16( hmem
);
446 TRACE(resource
,"'%s' copied !\n", buffer
);
450 /**********************************************************************
451 * LoadString32W (USER32.376)
453 INT32 WINAPI
LoadString32W( HINSTANCE32 instance
, UINT32 resource_id
,
454 LPWSTR buffer
, INT32 buflen
)
462 if (HIWORD(resource_id
)==0xFFFF) /* netscape 3 passes this */
463 resource_id
= (UINT32
)(-((INT32
)resource_id
));
464 TRACE(resource
, "instance = %04x, id = %04x, buffer = %08x, "
465 "length = %d\n", instance
, (int)resource_id
, (int) buffer
, buflen
);
467 hrsrc
= FindResource32W( instance
, (LPCWSTR
)((resource_id
>>4)+1),
469 if (!hrsrc
) return 0;
470 hmem
= LoadResource32( instance
, hrsrc
);
473 p
= LockResource32(hmem
);
474 string_num
= resource_id
& 0x000f;
475 for (i
= 0; i
< string_num
; i
++)
478 TRACE(resource
, "strlen = %d\n", (int)*p
);
480 i
= MIN(buflen
- 1, *p
);
484 memcpy(buffer
, p
+ 1, i
* sizeof (WCHAR
));
485 buffer
[i
] = (WCHAR
) 0;
488 buffer
[0] = (WCHAR
) 0;
492 WARN(resource
,"Dont know why caller give buflen=%d *p=%d trying to obtain string '%s'\n", buflen
, *p
, p
+ 1);
496 TRACE(resource
,"'%s' copied !\n", (char *)buffer
);
500 /**********************************************************************
501 * LoadString32A (USER32.375)
503 INT32 WINAPI
LoadString32A( HINSTANCE32 instance
, UINT32 resource_id
,
504 LPSTR buffer
, INT32 buflen
)
507 LPWSTR buffer2
= NULL
;
508 if (buffer
&& buflen
)
509 buffer2
= HeapAlloc( GetProcessHeap(), 0, buflen
* 2 );
510 retval
= LoadString32W(instance
,resource_id
,buffer2
,buflen
);
515 lstrcpynWtoA( buffer
, buffer2
, buflen
);
516 retval
= lstrlen32A( buffer
);
520 HeapFree( GetProcessHeap(), 0, buffer2
);
525 /* Messages...used by FormatMessage32* (KERNEL32.something)
527 * They can be specified either directly or using a message ID and
528 * loading them from the resource.
530 * The resourcedata has following format:
532 * 0: DWORD nrofentries
533 * nrofentries * subentry:
534 * 0: DWORD firstentry
536 * 8: DWORD offset from start to the stringentries
538 * (lastentry-firstentry) * stringentry:
539 * 0: WORD len (0 marks end)
540 * 2: WORD unknown (flags?)
542 * (stringentry i of a subentry refers to the ID 'firstentry+i')
544 * Yes, ANSI strings in win32 resources. Go figure.
547 /**********************************************************************
548 * LoadMessage32A (internal)
550 INT32
LoadMessage32A( HMODULE32 instance
, UINT32 id
, WORD lang
,
551 LPSTR buffer
, INT32 buflen
)
556 int nrofentries
,i
,slen
;
562 struct _stringentry
{
568 TRACE(resource
, "instance = %08lx, id = %08lx, buffer = %p, length = %ld\n", (DWORD
)instance
, (DWORD
)id
, buffer
, (DWORD
)buflen
);
570 /*FIXME: I am not sure about the '1' ... But I've only seen those entries*/
571 hrsrc
= FindResourceEx32W(instance
,(LPWSTR
)1,RT_MESSAGELIST32W
,lang
);
572 if (!hrsrc
) return 0;
573 hmem
= LoadResource32( instance
, hrsrc
);
576 p
= LockResource32(hmem
);
577 nrofentries
= *(DWORD
*)p
;
579 se
= (struct _subentry
*)(p
+4);
580 for (i
=nrofentries
;i
--;) {
581 if ((id
>=se
->firstentry
) && (id
<=se
->lastentry
)) {
582 stre
= (struct _stringentry
*)(p
+se
->offset
);
583 id
-= se
->firstentry
;
591 if (!(slen
=stre
->len
))
593 stre
= (struct _stringentry
*)(((char*)stre
)+slen
);
596 TRACE(resource
," - strlen=%d\n",slen
);
597 i
= MIN(buflen
- 1, slen
);
599 return slen
; /* different to LoadString */
601 lstrcpyn32A(buffer
,stre
->str
,i
);
610 TRACE(resource
,"'%s' copied !\n", buffer
);
614 /**********************************************************************
615 * LoadMessage32W (internal)
617 INT32
LoadMessage32W( HMODULE32 instance
, UINT32 id
, WORD lang
,
618 LPWSTR buffer
, INT32 buflen
)
621 LPSTR buffer2
= NULL
;
622 if (buffer
&& buflen
)
623 buffer2
= HeapAlloc( GetProcessHeap(), 0, buflen
);
624 retval
= LoadMessage32A(instance
,id
,lang
,buffer2
,buflen
);
628 lstrcpynAtoW( buffer
, buffer2
, buflen
);
629 retval
= lstrlen32W( buffer
);
631 HeapFree( GetProcessHeap(), 0, buffer2
);
637 /**********************************************************************
638 * EnumResourceTypesA (KERNEL32.90)
640 BOOL32 WINAPI
EnumResourceTypes32A( HMODULE32 hmodule
,ENUMRESTYPEPROC32A lpfun
,
643 /* FIXME: move WINE_MODREF stuff here */
644 return PE_EnumResourceTypes32A(hmodule
,lpfun
,lParam
);
647 /**********************************************************************
648 * EnumResourceTypesW (KERNEL32.91)
650 BOOL32 WINAPI
EnumResourceTypes32W( HMODULE32 hmodule
,ENUMRESTYPEPROC32W lpfun
,
653 /* FIXME: move WINE_MODREF stuff here */
654 return PE_EnumResourceTypes32W(hmodule
,lpfun
,lParam
);
657 /**********************************************************************
658 * EnumResourceNamesA (KERNEL32.88)
660 BOOL32 WINAPI
EnumResourceNames32A( HMODULE32 hmodule
, LPCSTR type
,
661 ENUMRESNAMEPROC32A lpfun
, LONG lParam
)
663 /* FIXME: move WINE_MODREF stuff here */
664 return PE_EnumResourceNames32A(hmodule
,type
,lpfun
,lParam
);
666 /**********************************************************************
667 * EnumResourceNamesW (KERNEL32.89)
669 BOOL32 WINAPI
EnumResourceNames32W( HMODULE32 hmodule
, LPCWSTR type
,
670 ENUMRESNAMEPROC32W lpfun
, LONG lParam
)
672 /* FIXME: move WINE_MODREF stuff here */
673 return PE_EnumResourceNames32W(hmodule
,type
,lpfun
,lParam
);
676 /**********************************************************************
677 * EnumResourceLanguagesA (KERNEL32.86)
679 BOOL32 WINAPI
EnumResourceLanguages32A( HMODULE32 hmodule
, LPCSTR type
,
680 LPCSTR name
, ENUMRESLANGPROC32A lpfun
,
683 /* FIXME: move WINE_MODREF stuff here */
684 return PE_EnumResourceLanguages32A(hmodule
,type
,name
,lpfun
,lParam
);
686 /**********************************************************************
687 * EnumResourceLanguagesW (KERNEL32.87)
689 BOOL32 WINAPI
EnumResourceLanguages32W( HMODULE32 hmodule
, LPCWSTR type
,
690 LPCWSTR name
, ENUMRESLANGPROC32W lpfun
,
693 /* FIXME: move WINE_MODREF stuff here */
694 return PE_EnumResourceLanguages32W(hmodule
,type
,name
,lpfun
,lParam
);