4 * Copyright 1993 Robert J. Amstadt
5 * Copyright 1995 Alexandre Julliard
11 #include <sys/types.h>
28 extern WORD WINE_LanguageId
;
31 /**********************************************************************
32 * FindResource32A (KERNEL32.128)
34 HANDLE32 WINAPI
FindResource32A( HMODULE32 hModule
, LPCSTR name
, LPCSTR type
)
36 return FindResourceEx32A(hModule
,name
,type
,WINE_LanguageId
);
39 /**********************************************************************
40 * FindResourceEx32A (KERNEL32.129)
42 HANDLE32 WINAPI
FindResourceEx32A( HMODULE32 hModule
, LPCSTR name
, LPCSTR type
,
48 if (HIWORD((DWORD
)name
))
49 xname
= HEAP_strdupAtoW( GetProcessHeap(), 0, name
);
52 if (HIWORD((DWORD
)type
))
53 xtype
= HEAP_strdupAtoW( GetProcessHeap(), 0, type
);
56 ret
= FindResourceEx32W( hModule
, xname
, xtype
, lang
);
57 if (HIWORD((DWORD
)name
)) HeapFree( GetProcessHeap(), 0, xname
);
58 if (HIWORD((DWORD
)type
)) HeapFree( GetProcessHeap(), 0, xtype
);
63 /**********************************************************************
64 * FindResourceEx32W (KERNEL32.130)
66 HRSRC32 WINAPI
FindResourceEx32W( HMODULE32 hModule
, LPCWSTR name
,
67 LPCWSTR type
, WORD lang
)
69 WINE_MODREF
*wm
= MODULE32_LookupHMODULE(PROCESS_Current(),hModule
);
72 TRACE(resource
, "module=%08x "
73 "type=%s%p name=%s%p\n", wm
->module
,
74 (HIWORD(type
))? "" : "#", type
,
75 (HIWORD(name
))? "" : "#", name
);
77 hrsrc
= LIBRES_FindResource( hModule
, name
, type
);
84 return PE_FindResourceEx32W(wm
,name
,type
,lang
);
86 ERR(module
,"unknown module type %d\n",wm
->type
);
94 /**********************************************************************
95 * FindResource32W (KERNEL32.131)
97 HRSRC32 WINAPI
FindResource32W(HINSTANCE32 hModule
, LPCWSTR name
, LPCWSTR type
)
99 return FindResourceEx32W(hModule
,name
,type
,WINE_LanguageId
);
103 /**********************************************************************
104 * LoadResource32 (KERNEL32.370)
105 * 'loads' a resource. The current implementation just returns a pointer
106 * into the already mapped image.
108 * pointer into the mapped resource of the passed module
110 HGLOBAL32 WINAPI
LoadResource32(
111 HINSTANCE32 hModule
, /* [in] module handle */
112 HRSRC32 hRsrc
) /* [in] resource handle */
114 WINE_MODREF
*wm
= MODULE32_LookupHMODULE(PROCESS_Current(),hModule
);
116 TRACE(resource
, "module=%04x res=%04x\n",
119 ERR(resource
,"hRsrc is 0, return 0.\n");
125 return PE_LoadResource32(wm
,hRsrc
);
127 ERR(resource
,"unknown module type %d\n",wm
->type
);
131 return LIBRES_LoadResource( hModule
, hRsrc
);
136 /**********************************************************************
137 * LockResource32 (KERNEL32.384)
139 LPVOID WINAPI
LockResource32( HGLOBAL32 handle
)
141 return (LPVOID
)handle
;
145 /**********************************************************************
146 * FreeResource32 (KERNEL32.145)
148 BOOL32 WINAPI
FreeResource32( HGLOBAL32 handle
)
150 /* no longer used in Win32 */
155 /**********************************************************************
156 * AccessResource32 (KERNEL32.64)
158 INT32 WINAPI
AccessResource32( HMODULE32 hModule
, HRSRC32 hRsrc
)
160 FIXME(resource
,"(module=%08x res=%08x),not implemented\n", hModule
, hRsrc
);
165 /**********************************************************************
166 * SizeofResource32 (KERNEL32.522)
168 DWORD WINAPI
SizeofResource32( HINSTANCE32 hModule
, HRSRC32 hRsrc
)
170 WINE_MODREF
*wm
= MODULE32_LookupHMODULE(PROCESS_Current(),hModule
);
172 TRACE(resource
, "module=%08x res=%08x\n", hModule
, hRsrc
);
179 ret
= PE_SizeofResource32(hModule
,hRsrc
);
185 ERR(module
,"unknown module type %d\n",wm
->type
);
189 FIXME(module
,"Not implemented for WINELIB\n");
194 /**********************************************************************
195 * LoadAccelerators16 [USER.177]
197 HACCEL16 WINAPI
LoadAccelerators16(HINSTANCE16 instance
, SEGPTR lpTableName
)
201 if (HIWORD(lpTableName
))
202 TRACE(accel
, "%04x '%s'\n",
203 instance
, (char *)PTR_SEG_TO_LIN( lpTableName
) );
205 TRACE(accel
, "%04x %04x\n",
206 instance
, LOWORD(lpTableName
) );
208 if (!(hRsrc
= FindResource16( instance
, lpTableName
, RT_ACCELERATOR16
))) {
209 WARN(accel
, "couldn't find accelerator table resource\n");
213 TRACE(accel
, "returning HACCEL 0x%x\n", hRsrc
);
214 return LoadResource16(instance
,hRsrc
);
217 /**********************************************************************
218 * LoadAccelerators32W [USER.177]
219 * The image layout seems to look like this (not 100% sure):
220 * 00: BYTE type type of accelerator
221 * 01: BYTE pad (to WORD boundary)
224 * 06: WORD pad (to DWORD boundary)
226 HACCEL32 WINAPI
LoadAccelerators32W(HINSTANCE32 instance
,LPCWSTR lpTableName
)
231 if (HIWORD(lpTableName
))
232 TRACE(accel
, "%p '%s'\n",
233 (LPVOID
)instance
, (char *)( lpTableName
) );
235 TRACE(accel
, "%p 0x%04x\n",
236 (LPVOID
)instance
, LOWORD(lpTableName
) );
238 if (!(hRsrc
= FindResource32W( instance
, lpTableName
, RT_ACCELERATOR32W
)))
240 WARN(accel
, "couldn't find accelerator table resource\n");
244 hRetval
= LoadResource32( instance
, hRsrc
);
247 TRACE(accel
, "returning HACCEL 0x%x\n", hRsrc
);
251 HACCEL32 WINAPI
LoadAccelerators32A(HINSTANCE32 instance
,LPCSTR lpTableName
)
255 if (HIWORD(lpTableName
))
256 uni
= HEAP_strdupAtoW( GetProcessHeap(), 0, lpTableName
);
258 uni
= (LPWSTR
)lpTableName
;
259 result
= LoadAccelerators32W(instance
,uni
);
260 if (HIWORD(uni
)) HeapFree( GetProcessHeap(), 0, uni
);
264 /**********************************************************************
265 * CopyAcceleratorTable32A (USER32.58)
267 INT32 WINAPI
CopyAcceleratorTable32A(HACCEL32 src
, LPACCEL32 dst
, INT32 entries
)
269 return CopyAcceleratorTable32W(src
, dst
, entries
);
272 /**********************************************************************
273 * CopyAcceleratorTable32W (USER32.59)
275 * By mortene@pvv.org 980321
277 INT32 WINAPI
CopyAcceleratorTable32W(HACCEL32 src
, LPACCEL32 dst
,
281 LPACCEL32 accel
= (LPACCEL32
)src
;
284 /* Do parameter checking to avoid the explosions and the screaming
285 as far as possible. */
286 if((dst
&& (entries
< 1)) || (src
== (HACCEL32
)NULL
)) {
287 WARN(accel
, "Application sent invalid parameters (%p %p %d).\n",
288 (LPVOID
)src
, (LPVOID
)dst
, entries
);
295 /* Spit out some debugging information. */
296 TRACE(accel
, "accel %d: type 0x%02x, event '%c', IDval 0x%04x.\n",
297 i
, accel
[i
].fVirt
, accel
[i
].key
, accel
[i
].cmd
);
299 /* Copy data to the destination structure array (if dst == NULL,
300 we're just supposed to count the number of entries). */
302 memcpy(&dst
[i
], &accel
[i
], sizeof(ACCEL32
));
304 /* Check if we've reached the end of the application supplied
305 accelerator table. */
307 /* Turn off the high order bit, just in case. */
308 dst
[i
].fVirt
&= 0x7f;
313 /* The highest order bit seems to mark the end of the accelerator
314 resource table. (?) */
315 if((accel
[i
].fVirt
& 0x80) != 0) done
= TRUE
;
323 /*********************************************************************
324 * CreateAcceleratorTable (USER32.64)
326 * By mortene@pvv.org 980321
328 HACCEL32 WINAPI
CreateAcceleratorTable32A(LPACCEL32 lpaccel
, INT32 cEntries
)
332 /* Do parameter checking just in case someone's trying to be
335 WARN(accel
, "Application sent invalid parameters (%p %d).\n",
337 SetLastError(ERROR_INVALID_PARAMETER
);
338 return (HACCEL32
)NULL
;
340 FIXME(accel
, "should check that the accelerator descriptions are valid,"
341 " return NULL and SetLastError() if not.\n");
344 /* Allocate memory and copy the table. */
345 hAccel
= (HACCEL32
)HeapAlloc(GetProcessHeap(), 0,
346 cEntries
* sizeof(ACCEL32
));
347 TRACE(accel
, "handle %p\n", (LPVOID
)hAccel
);
349 WARN(accel
, "Out of memory.\n");
350 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
351 return (HACCEL32
)NULL
;
353 memcpy((LPACCEL32
)hAccel
, lpaccel
, cEntries
* sizeof(ACCEL32
));
355 /* Set the end-of-table terminator. */
356 ((LPACCEL32
)hAccel
)[cEntries
-1].fVirt
|= 0x80;
358 TRACE(accel
, "Allocated accelerator handle %x\n", hAccel
);
363 /******************************************************************************
364 * DestroyAcceleratorTable [USER32.130]
365 * Destroys an accelerator table
368 * By mortene@pvv.org 980321
371 * handle [I] Handle to accelerator table
375 BOOL32 WINAPI
DestroyAcceleratorTable( HACCEL32 handle
)
377 FIXME(accel
, "(0x%x): stub\n", handle
);
380 /* Weird.. I thought this should work. According to the API
381 specification, DestroyAcceleratorTable() should only be called on
382 HACCEL32's made by CreateAcceleratorTable(), but Microsoft Visual
383 Studio 97 calls this function with a series of different handle
384 values without ever calling CreateAcceleratorTable(). Something
385 is very fishy in Denmark... */
386 /* Update: looks like the calls to this function matches the calls
387 to LoadAccelerators() in M$ Visual Studio, except that the handle
388 values are off by some variable size from the HACCEL's returned
389 from LoadAccelerators(). WTH? */
391 /* Parameter checking to avoid any embarassing situations. */
393 /* WARN(accel, "Application sent NULL ptr.\n"); */
394 /* SetLastError(ERROR_INVALID_PARAMETER); */
398 /* HeapFree(GetProcessHeap(), 0, (LPACCEL32)handle); */
403 /**********************************************************************
406 INT16 WINAPI
LoadString16( HINSTANCE16 instance
, UINT16 resource_id
,
407 LPSTR buffer
, INT16 buflen
)
415 TRACE(resource
,"inst=%04x id=%04x buff=%08x len=%d\n",
416 instance
, resource_id
, (int) buffer
, buflen
);
418 hrsrc
= FindResource16( instance
, (SEGPTR
)((resource_id
>>4)+1), RT_STRING16
);
419 if (!hrsrc
) return 0;
420 hmem
= LoadResource16( instance
, hrsrc
);
423 p
= LockResource16(hmem
);
424 string_num
= resource_id
& 0x000f;
425 for (i
= 0; i
< string_num
; i
++)
428 TRACE(resource
, "strlen = %d\n", (int)*p
);
430 i
= MIN(buflen
- 1, *p
);
434 memcpy(buffer
, p
+ 1, i
);
441 WARN(resource
,"Dont know why caller give buflen=%d *p=%d trying to obtain string '%s'\n", buflen
, *p
, p
+ 1);
443 FreeResource16( hmem
);
445 TRACE(resource
,"'%s' copied !\n", buffer
);
449 /**********************************************************************
450 * LoadString32W (USER32.376)
452 INT32 WINAPI
LoadString32W( HINSTANCE32 instance
, UINT32 resource_id
,
453 LPWSTR buffer
, INT32 buflen
)
461 if (HIWORD(resource_id
)==0xFFFF) /* netscape 3 passes this */
462 resource_id
= (UINT32
)(-((INT32
)resource_id
));
463 TRACE(resource
, "instance = %04x, id = %04x, buffer = %08x, "
464 "length = %d\n", instance
, (int)resource_id
, (int) buffer
, buflen
);
466 hrsrc
= FindResource32W( instance
, (LPCWSTR
)((resource_id
>>4)+1),
468 if (!hrsrc
) return 0;
469 hmem
= LoadResource32( instance
, hrsrc
);
472 p
= LockResource32(hmem
);
473 string_num
= resource_id
& 0x000f;
474 for (i
= 0; i
< string_num
; i
++)
477 TRACE(resource
, "strlen = %d\n", (int)*p
);
479 i
= MIN(buflen
- 1, *p
);
483 memcpy(buffer
, p
+ 1, i
* sizeof (WCHAR
));
484 buffer
[i
] = (WCHAR
) 0;
487 buffer
[0] = (WCHAR
) 0;
491 WARN(resource
,"Dont know why caller give buflen=%d *p=%d trying to obtain string '%s'\n", buflen
, *p
, p
+ 1);
495 TRACE(resource
,"'%s' copied !\n", (char *)buffer
);
499 /**********************************************************************
500 * LoadString32A (USER32.375)
502 INT32 WINAPI
LoadString32A( HINSTANCE32 instance
, UINT32 resource_id
,
503 LPSTR buffer
, INT32 buflen
)
506 LPWSTR buffer2
= NULL
;
507 if (buffer
&& buflen
)
508 buffer2
= HeapAlloc( GetProcessHeap(), 0, buflen
* 2 );
509 retval
= LoadString32W(instance
,resource_id
,buffer2
,buflen
);
514 lstrcpynWtoA( buffer
, buffer2
, buflen
);
515 retval
= lstrlen32A( buffer
);
519 HeapFree( GetProcessHeap(), 0, buffer2
);
524 /* Messages...used by FormatMessage32* (KERNEL32.something)
526 * They can be specified either directly or using a message ID and
527 * loading them from the resource.
529 * The resourcedata has following format:
531 * 0: DWORD nrofentries
532 * nrofentries * subentry:
533 * 0: DWORD firstentry
535 * 8: DWORD offset from start to the stringentries
537 * (lastentry-firstentry) * stringentry:
538 * 0: WORD len (0 marks end)
539 * 2: WORD unknown (flags?)
541 * (stringentry i of a subentry refers to the ID 'firstentry+i')
543 * Yes, ANSI strings in win32 resources. Go figure.
546 /**********************************************************************
547 * LoadMessage32A (internal)
549 INT32
LoadMessage32A( HMODULE32 instance
, UINT32 id
, WORD lang
,
550 LPSTR buffer
, INT32 buflen
)
555 int nrofentries
,i
,slen
;
561 struct _stringentry
{
567 TRACE(resource
, "instance = %08lx, id = %08lx, buffer = %p, length = %ld\n", (DWORD
)instance
, (DWORD
)id
, buffer
, (DWORD
)buflen
);
569 /*FIXME: I am not sure about the '1' ... But I've only seen those entries*/
570 hrsrc
= FindResourceEx32W(instance
,(LPWSTR
)1,RT_MESSAGELIST32W
,lang
);
571 if (!hrsrc
) return 0;
572 hmem
= LoadResource32( instance
, hrsrc
);
575 p
= LockResource32(hmem
);
576 nrofentries
= *(DWORD
*)p
;
578 se
= (struct _subentry
*)(p
+4);
579 for (i
=nrofentries
;i
--;) {
580 if ((id
>=se
->firstentry
) && (id
<=se
->lastentry
)) {
581 stre
= (struct _stringentry
*)(p
+se
->offset
);
582 id
-= se
->firstentry
;
590 if (!(slen
=stre
->len
))
592 stre
= (struct _stringentry
*)(((char*)stre
)+slen
);
595 TRACE(resource
," - strlen=%d\n",slen
);
596 i
= MIN(buflen
- 1, slen
);
598 return slen
; /* different to LoadString */
600 lstrcpyn32A(buffer
,stre
->str
,i
);
609 TRACE(resource
,"'%s' copied !\n", buffer
);
613 /**********************************************************************
614 * LoadMessage32W (internal)
616 INT32
LoadMessage32W( HMODULE32 instance
, UINT32 id
, WORD lang
,
617 LPWSTR buffer
, INT32 buflen
)
620 LPSTR buffer2
= NULL
;
621 if (buffer
&& buflen
)
622 buffer2
= HeapAlloc( GetProcessHeap(), 0, buflen
);
623 retval
= LoadMessage32A(instance
,id
,lang
,buffer2
,buflen
);
627 lstrcpynAtoW( buffer
, buffer2
, buflen
);
628 retval
= lstrlen32W( buffer
);
630 HeapFree( GetProcessHeap(), 0, buffer2
);
636 /**********************************************************************
637 * EnumResourceTypesA (KERNEL32.90)
639 BOOL32 WINAPI
EnumResourceTypes32A( HMODULE32 hmodule
,ENUMRESTYPEPROC32A lpfun
,
642 /* FIXME: move WINE_MODREF stuff here */
643 return PE_EnumResourceTypes32A(hmodule
,lpfun
,lParam
);
646 /**********************************************************************
647 * EnumResourceTypesW (KERNEL32.91)
649 BOOL32 WINAPI
EnumResourceTypes32W( HMODULE32 hmodule
,ENUMRESTYPEPROC32W lpfun
,
652 /* FIXME: move WINE_MODREF stuff here */
653 return PE_EnumResourceTypes32W(hmodule
,lpfun
,lParam
);
656 /**********************************************************************
657 * EnumResourceNamesA (KERNEL32.88)
659 BOOL32 WINAPI
EnumResourceNames32A( HMODULE32 hmodule
, LPCSTR type
,
660 ENUMRESNAMEPROC32A lpfun
, LONG lParam
)
662 /* FIXME: move WINE_MODREF stuff here */
663 return PE_EnumResourceNames32A(hmodule
,type
,lpfun
,lParam
);
665 /**********************************************************************
666 * EnumResourceNamesW (KERNEL32.89)
668 BOOL32 WINAPI
EnumResourceNames32W( HMODULE32 hmodule
, LPCWSTR type
,
669 ENUMRESNAMEPROC32W lpfun
, LONG lParam
)
671 /* FIXME: move WINE_MODREF stuff here */
672 return PE_EnumResourceNames32W(hmodule
,type
,lpfun
,lParam
);
675 /**********************************************************************
676 * EnumResourceLanguagesA (KERNEL32.86)
678 BOOL32 WINAPI
EnumResourceLanguages32A( HMODULE32 hmodule
, LPCSTR type
,
679 LPCSTR name
, ENUMRESLANGPROC32A lpfun
,
682 /* FIXME: move WINE_MODREF stuff here */
683 return PE_EnumResourceLanguages32A(hmodule
,type
,name
,lpfun
,lParam
);
685 /**********************************************************************
686 * EnumResourceLanguagesW (KERNEL32.87)
688 BOOL32 WINAPI
EnumResourceLanguages32W( HMODULE32 hmodule
, LPCWSTR type
,
689 LPCWSTR name
, ENUMRESLANGPROC32W lpfun
,
692 /* FIXME: move WINE_MODREF stuff here */
693 return PE_EnumResourceLanguages32W(hmodule
,type
,name
,lpfun
,lParam
);