Release 980329
[wine/multimedia.git] / loader / resource.c
blob24d87f2260a388d3d402cf7acf8ee965d5b14c2c
1 /*
2 * Resources
4 * Copyright 1993 Robert J. Amstadt
5 * Copyright 1995 Alexandre Julliard
6 */
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <string.h>
11 #include <sys/types.h>
12 #include <sys/stat.h>
13 #include <fcntl.h>
14 #include <unistd.h>
15 #include "windows.h"
16 #include "gdi.h"
17 #include "global.h"
18 #include "heap.h"
19 #include "neexe.h"
20 #include "task.h"
21 #include "module.h"
22 #include "resource.h"
23 #include "debug.h"
24 #include "libres.h"
25 #include "winerror.h"
27 extern WORD WINE_LanguageId;
29 /* error message when 16-bit resource function is called for Win32 module */
30 static const char* NEWin32FailureString = "fails with Win32 module\n";
31 /* error message when 32-bit resource function is called for Win16 module */
32 static const char* PEWin16FailureString = "fails with Win16 module\n";
34 /**********************************************************************
35 * FindResource16 (KERNEL.60)
37 HRSRC16 WINAPI FindResource16( HMODULE16 hModule, SEGPTR name, SEGPTR type )
39 NE_MODULE *pModule;
41 hModule = MODULE_HANDLEtoHMODULE16( hModule );
43 if (HIWORD(name)) /* Check for '#xxx' name */
45 char *ptr = PTR_SEG_TO_LIN( name );
46 if (ptr[0] == '#')
47 if (!(name = (SEGPTR)atoi( ptr + 1 ))) {
48 WARN(resource, "Incorrect resource name: %s\n", ptr);
49 return 0;
53 if (HIWORD(type)) /* Check for '#xxx' type */
55 char *ptr = PTR_SEG_TO_LIN( type );
56 if (ptr[0] == '#')
57 if (!(type = (SEGPTR)atoi( ptr + 1 ))){
58 WARN(resource, "Incorrect resource type: %s\n", ptr);
59 return 0;
63 TRACE(resource, "module=%04x name=%s type=%s\n",
64 hModule, debugres(PTR_SEG_TO_LIN(name)),
65 debugres(PTR_SEG_TO_LIN(type)) );
67 if ((pModule = MODULE_GetPtr( hModule )))
69 if (!__winelib)
71 if (pModule->flags & NE_FFLAGS_WIN32)
72 fprintf(stderr,"FindResource16: %s", NEWin32FailureString);
73 else
74 return NE_FindResource( hModule, type, name );
76 else return LIBRES_FindResource16( hModule,
77 (LPCSTR)PTR_SEG_TO_LIN(name),
78 (LPCSTR)PTR_SEG_TO_LIN(type) );
80 return 0;
84 /**********************************************************************
85 * FindResource32A (KERNEL32.128)
87 HANDLE32 WINAPI FindResource32A( HINSTANCE32 hModule, LPCSTR name, LPCSTR type)
89 return FindResourceEx32A(hModule,name,type,WINE_LanguageId);
92 /**********************************************************************
93 * FindResourceEx32A (KERNEL32.129)
95 HANDLE32 WINAPI FindResourceEx32A( HINSTANCE32 hModule, LPCSTR name,
96 LPCSTR type, WORD lang )
98 LPWSTR xname,xtype;
99 HANDLE32 ret;
101 if (HIWORD((DWORD)name))
102 xname = HEAP_strdupAtoW( GetProcessHeap(), 0, name );
103 else
104 xname = (LPWSTR)name;
105 if (HIWORD((DWORD)type))
106 xtype = HEAP_strdupAtoW( GetProcessHeap(), 0, type);
107 else
108 xtype = (LPWSTR)type;
109 ret = FindResourceEx32W( hModule, xname, xtype, lang );
110 if (HIWORD((DWORD)name)) HeapFree( GetProcessHeap(), 0, xname );
111 if (HIWORD((DWORD)type)) HeapFree( GetProcessHeap(), 0, xtype );
112 return ret;
116 /**********************************************************************
117 * FindResourceEx32W (KERNEL32.130)
119 HRSRC32 WINAPI FindResourceEx32W( HINSTANCE32 hModule, LPCWSTR name,
120 LPCWSTR type, WORD lang )
122 if (!__winelib)
124 NE_MODULE *pModule;
126 if (!hModule) hModule = GetTaskDS();
127 hModule = MODULE_HANDLEtoHMODULE32( hModule );
128 TRACE(resource, "module=%08x "
129 "type=%s%p name=%s%p\n", hModule,
130 (HIWORD(type))? "" : "#", type,
131 (HIWORD(name))? "" : "#", name);
133 if (!(pModule = MODULE_GetPtr( hModule ))) return 0;
134 if (!(pModule->flags & NE_FFLAGS_WIN32)) return 0;
135 return PE_FindResourceEx32W(hModule,name,type,lang);
137 else return LIBRES_FindResource32( hModule, name, type );
140 /**********************************************************************
141 * FindResource32W (KERNEL32.131)
143 HRSRC32 WINAPI FindResource32W(HINSTANCE32 hModule, LPCWSTR name, LPCWSTR type)
145 return FindResourceEx32W(hModule,name,type,WINE_LanguageId);
149 /**********************************************************************
150 * LoadResource16 (KERNEL.61)
152 HGLOBAL16 WINAPI LoadResource16( HMODULE16 hModule, HRSRC16 hRsrc )
154 NE_MODULE *pModule;
156 hModule = MODULE_HANDLEtoHMODULE16( hModule );
157 TRACE(resource, "module=%04x res=%04x\n",
158 hModule, hRsrc );
159 if (!hRsrc) return 0;
160 if ((pModule = MODULE_GetPtr( hModule )))
162 if (!__winelib)
164 if (pModule->flags & NE_FFLAGS_WIN32)
165 fprintf(stderr,"LoadResource16: %s", NEWin32FailureString);
166 else
167 return NE_LoadResource( hModule, hRsrc );
169 else return LIBRES_LoadResource( hModule, hRsrc );
171 return 0;
174 /**********************************************************************
175 * LoadResource32 (KERNEL32.370)
177 HGLOBAL32 WINAPI LoadResource32( HINSTANCE32 hModule, HRSRC32 hRsrc )
179 if (!__winelib)
181 NE_MODULE *pModule;
183 if (!hModule) hModule = GetTaskDS(); /* FIXME: see FindResource32W */
184 hModule = MODULE_HANDLEtoHMODULE32( hModule );
185 TRACE(resource, "module=%04x res=%04x\n",
186 hModule, hRsrc );
187 if (!hRsrc) return 0;
189 if (!(pModule = MODULE_GetPtr( hModule ))) return 0;
190 if (!(pModule->flags & NE_FFLAGS_WIN32))
192 fprintf(stderr,"LoadResource32: %s", PEWin16FailureString );
193 return 0; /* FIXME? */
195 return PE_LoadResource32(hModule,hRsrc);
197 else return LIBRES_LoadResource( hModule, hRsrc );
201 /**********************************************************************
202 * LockResource (KERNEL.62)
204 /* 16-bit version */
205 SEGPTR WINAPI WIN16_LockResource16(HGLOBAL16 handle)
207 HMODULE16 hModule;
208 NE_MODULE *pModule;
210 TRACE(resource, "handle=%04x\n", handle );
211 if (!handle) return (SEGPTR)0;
212 hModule = MODULE_HANDLEtoHMODULE16( handle );
213 if (!(pModule = MODULE_GetPtr( hModule ))) return 0;
214 if (pModule->flags & NE_FFLAGS_WIN32)
216 fprintf(stderr,"LockResource16: %s", NEWin32FailureString);
217 return 0;
219 return NE_LockResource( hModule, handle );
222 /* Winelib 16-bit version */
223 LPVOID WINAPI LockResource16( HGLOBAL16 handle )
225 if (!__winelib)
227 HMODULE16 hModule;
228 NE_MODULE *pModule;
230 TRACE(resource, "handle=%04x\n", handle );
231 if (!handle) return NULL;
232 hModule = MODULE_HANDLEtoHMODULE16( handle );
233 if (!(pModule = MODULE_GetPtr( hModule ))) return 0;
234 if (pModule->flags & NE_FFLAGS_WIN32)
236 fprintf(stderr,"LockResource16: %s", NEWin32FailureString);
237 return 0;
239 return (LPSTR)PTR_SEG_TO_LIN( NE_LockResource( hModule, handle ) );
241 else return LIBRES_LockResource( handle );
245 /**********************************************************************
246 * LockResource32 (KERNEL32.384)
248 LPVOID WINAPI LockResource32( HGLOBAL32 handle )
250 return (LPVOID)handle;
254 /**********************************************************************
255 * FreeResource16 (KERNEL.63)
257 BOOL16 WINAPI FreeResource16( HGLOBAL16 handle )
259 if (!__winelib)
261 HMODULE16 hModule;
262 NE_MODULE *pModule;
264 TRACE(resource, "handle=%04x\n", handle );
265 if (!handle) return FALSE;
266 hModule = MODULE_HANDLEtoHMODULE16( handle );
267 if (!(pModule = MODULE_GetPtr( hModule ))) return 0;
268 if (pModule->flags & NE_FFLAGS_WIN32)
270 fprintf(stderr,"FreeResource16: %s", NEWin32FailureString);
271 return 0;
273 return NE_FreeResource( hModule, handle );
275 else return LIBRES_FreeResource( handle );
278 /**********************************************************************
279 * FreeResource32 (KERNEL32.145)
281 BOOL32 WINAPI FreeResource32( HGLOBAL32 handle )
283 /* no longer used in Win32 */
284 return TRUE;
288 /**********************************************************************
289 * AccessResource16 (KERNEL.64)
291 INT16 WINAPI AccessResource16( HINSTANCE16 hModule, HRSRC16 hRsrc )
293 NE_MODULE *pModule;
295 hModule = MODULE_HANDLEtoHMODULE16( hModule );
296 TRACE(resource, "module=%04x res=%04x\n",
297 hModule, hRsrc );
298 if (!hRsrc) return 0;
299 if (!(pModule = MODULE_GetPtr( hModule ))) return 0;
300 if (!__winelib)
302 if (pModule->flags & NE_FFLAGS_WIN32)
304 fprintf(stderr,"AccessResource16: %s", NEWin32FailureString);
305 return 0;
307 return NE_AccessResource( hModule, hRsrc );
309 else return LIBRES_AccessResource( hModule, hRsrc );
313 /**********************************************************************
314 * AccessResource32 (KERNEL32.64)
316 INT32 WINAPI AccessResource32( HINSTANCE32 hModule, HRSRC32 hRsrc )
318 hModule = MODULE_HANDLEtoHMODULE32( hModule );
319 TRACE(resource, "module=%04x res=%04x\n",
320 hModule, hRsrc );
321 if (!hRsrc) return 0;
322 fprintf(stderr,"AccessResource32: not implemented\n");
323 return 0;
327 /**********************************************************************
328 * SizeofResource16 (KERNEL.65)
330 DWORD WINAPI SizeofResource16( HMODULE16 hModule, HRSRC16 hRsrc )
332 NE_MODULE *pModule;
334 hModule = MODULE_HANDLEtoHMODULE16( hModule );
335 TRACE(resource, "module=%04x res=%04x\n",
336 hModule, hRsrc );
337 if (!(pModule = MODULE_GetPtr( hModule ))) return 0;
338 if (!__winelib)
340 if (pModule->flags & NE_FFLAGS_WIN32)
342 fprintf(stderr,"SizeOfResource16: %s", NEWin32FailureString);
343 return 0;
345 return NE_SizeofResource( hModule, hRsrc );
347 else return LIBRES_SizeofResource( hModule, hRsrc );
351 /**********************************************************************
352 * SizeofResource32 (KERNEL32.522)
354 DWORD WINAPI SizeofResource32( HINSTANCE32 hModule, HRSRC32 hRsrc )
356 hModule = MODULE_HANDLEtoHMODULE32( hModule );
357 TRACE(resource, "module=%04x res=%04x\n",
358 hModule, hRsrc );
359 if (!__winelib) return PE_SizeofResource32(hModule,hRsrc);
360 else
362 fprintf(stderr,"SizeofResource32: not implemented\n");
363 return 0;
368 /**********************************************************************
369 * AllocResource16 (KERNEL.66)
371 HGLOBAL16 WINAPI AllocResource16( HMODULE16 hModule, HRSRC16 hRsrc, DWORD size)
373 NE_MODULE *pModule;
375 hModule = MODULE_HANDLEtoHMODULE16( hModule );
376 TRACE(resource, "module=%04x res=%04x size=%ld\n",
377 hModule, hRsrc, size );
378 if (!hRsrc) return 0;
379 if (!(pModule = MODULE_GetPtr( hModule ))) return 0;
380 if (!__winelib)
382 if (pModule->flags & NE_FFLAGS_WIN32)
384 fprintf(stderr,"AllocResource16: %s", NEWin32FailureString);
385 return 0;
387 return NE_AllocResource( hModule, hRsrc, size );
389 else return LIBRES_AllocResource( hModule, hRsrc, size );
392 /**********************************************************************
393 * DirectResAlloc (KERNEL.168)
395 * Check Schulman, p. 232 for details
397 HGLOBAL16 WINAPI DirectResAlloc( HINSTANCE16 hInstance, WORD wType,
398 UINT16 wSize )
400 TRACE(resource,"(%04x,%04x,%04x)\n",
401 hInstance, wType, wSize );
402 hInstance = MODULE_HANDLEtoHMODULE16(hInstance);
403 if(!hInstance)return 0;
404 if(wType != 0x10) /* 0x10 is the only observed value, passed from
405 CreateCursorIndirect. */
406 fprintf(stderr, "DirectResAlloc: wType = %x\n", wType);
407 return GLOBAL_Alloc(GMEM_MOVEABLE, wSize, hInstance, FALSE, FALSE, FALSE);
411 /**********************************************************************
412 * LoadAccelerators16 [USER.177]
414 HACCEL16 WINAPI LoadAccelerators16(HINSTANCE16 instance, SEGPTR lpTableName)
416 HRSRC16 hRsrc;
417 HACCEL16 hAccel;
419 if (HIWORD(lpTableName))
420 TRACE(accel, "%04x '%s'\n",
421 instance, (char *)PTR_SEG_TO_LIN( lpTableName ) );
422 else
423 TRACE(accel, "%04x %04x\n",
424 instance, LOWORD(lpTableName) );
426 if (!(hRsrc = FindResource16( instance, lpTableName, RT_ACCELERATOR ))) {
427 WARN(accel, "couldn't find accelerator table resource\n");
428 return 0;
431 TRACE(accel, "returning HACCEL 0x%x\n", hRsrc);
432 return LoadResource16(instance,hRsrc);
435 /**********************************************************************
436 * LoadAccelerators32W [USER.177]
437 * The image layout seems to look like this (not 100% sure):
438 * 00: BYTE type type of accelerator
439 * 01: BYTE pad (to WORD boundary)
440 * 02: WORD event
441 * 04: WORD IDval
442 * 06: WORD pad (to DWORD boundary)
444 HACCEL32 WINAPI LoadAccelerators32W(HINSTANCE32 instance,LPCWSTR lpTableName)
446 HRSRC32 hRsrc;
447 HACCEL32 hRetval;
449 if (HIWORD(lpTableName))
450 TRACE(accel, "%p '%s'\n",
451 (LPVOID)instance, (char *)( lpTableName ) );
452 else
453 TRACE(accel, "%p 0x%04x\n",
454 (LPVOID)instance, LOWORD(lpTableName) );
456 if (!(hRsrc = FindResource32W( instance, lpTableName,
457 (LPCWSTR)RT_ACCELERATOR ))) {
458 WARN(accel, "couldn't find accelerator table resource\n");
459 hRetval = 0;
461 else {
462 hRetval = LoadResource32( instance, hRsrc );
465 TRACE(accel, "returning HACCEL 0x%x\n", hRsrc);
466 return hRetval;
469 HACCEL32 WINAPI LoadAccelerators32A(HINSTANCE32 instance,LPCSTR lpTableName)
471 LPWSTR uni;
472 HACCEL32 result;
473 if (HIWORD(lpTableName))
474 uni = HEAP_strdupAtoW( GetProcessHeap(), 0, lpTableName );
475 else
476 uni = (LPWSTR)lpTableName;
477 result = LoadAccelerators32W(instance,uni);
478 if (HIWORD(uni)) HeapFree( GetProcessHeap(), 0, uni);
479 return result;
482 /**********************************************************************
483 * CopyAcceleratorTable32A (USER32.58)
485 INT32 WINAPI CopyAcceleratorTable32A(HACCEL32 src, LPACCEL32 dst, INT32 entries)
487 return CopyAcceleratorTable32W(src, dst, entries);
490 /**********************************************************************
491 * CopyAcceleratorTable32W (USER32.59)
493 * By mortene@pvv.org 980321
495 INT32 WINAPI CopyAcceleratorTable32W(HACCEL32 src, LPACCEL32 dst,
496 INT32 entries)
498 int i;
499 LPACCEL32 accel = (LPACCEL32)src;
500 BOOL32 done = FALSE;
502 /* Do parameter checking to avoid the explosions and the screaming
503 as far as possible. */
504 if((dst && (entries < 1)) || (src == (HACCEL32)NULL)) {
505 WARN(accel, "Application sent invalid parameters (%p %p %d).\n",
506 (LPVOID)src, (LPVOID)dst, entries);
507 return 0;
511 i=0;
512 while(!done) {
513 /* Spit out some debugging information. */
514 TRACE(accel, "accel %d: type 0x%02x, event '%c', IDval 0x%04x.\n",
515 i, accel[i].fVirt, accel[i].key, accel[i].cmd);
517 /* Copy data to the destination structure array (if dst == NULL,
518 we're just supposed to count the number of entries). */
519 if(dst) {
520 memcpy(&dst[i], &accel[i], sizeof(ACCEL32));
522 /* Check if we've reached the end of the application supplied
523 accelerator table. */
524 if(i+1 == entries) {
525 /* Turn off the high order bit, just in case. */
526 dst[i].fVirt &= 0x7f;
527 done = TRUE;
531 /* The highest order bit seems to mark the end of the accelerator
532 resource table. (?) */
533 if((accel[i].fVirt & 0x80) != 0) done = TRUE;
535 i++;
538 return i;
541 /*********************************************************************
542 * CreateAcceleratorTable (USER32.64)
544 * By mortene@pvv.org 980321
546 HACCEL32 WINAPI CreateAcceleratorTable32A(LPACCEL32 lpaccel, INT32 cEntries)
548 HACCEL32 hAccel;
550 /* Do parameter checking just in case someone's trying to be
551 funny. */
552 if(cEntries < 1) {
553 WARN(accel, "Application sent invalid parameters (%p %d).\n",
554 lpaccel, cEntries);
555 SetLastError(ERROR_INVALID_PARAMETER);
556 return (HACCEL32)NULL;
558 FIXME(accel, "should check that the accelerator descriptions are valid,"
559 " return NULL and SetLastError() if not.\n");
562 /* Allocate memory and copy the table. */
563 hAccel = (HACCEL32)HeapAlloc(GetProcessHeap(), 0,
564 cEntries * sizeof(ACCEL32));
565 TRACE(accel, "handle %p\n", (LPVOID)hAccel);
566 if(!hAccel) {
567 WARN(accel, "Out of memory.\n");
568 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
569 return (HACCEL32)NULL;
571 memcpy((LPACCEL32)hAccel, lpaccel, cEntries * sizeof(ACCEL32));
573 /* Set the end-of-table terminator. */
574 ((LPACCEL32)hAccel)[cEntries-1].fVirt |= 0x80;
576 TRACE(accel, "Allocated accelerator handle %x\n", hAccel);
577 return hAccel;
580 /**********************************************************************
581 * DestroyAcceleratorTable (USER32.130)
583 * By mortene@pvv.org 980321
585 BOOL32 WINAPI DestroyAcceleratorTable( HACCEL32 handle )
587 FIXME(accel, "stub (handle 0x%x)\n", handle);
590 /* Weird.. I thought this should work. According to the API
591 specification, DestroyAcceleratorTable() should only be called on
592 HACCEL32's made by CreateAcceleratorTable(), but Microsoft Visual
593 Studio 97 calls this function with a series of different handle
594 values without ever calling CreateAcceleratorTable(). Something
595 is very fishy in Denmark... */
596 /* Update: looks like the calls to this function matches the calls
597 to LoadAccelerators() in M$ Visual Studio, except that the handle
598 values are off by some variable size from the HACCEL's returned
599 from LoadAccelerators(). WTH? */
601 /* Parameter checking to avoid any embarassing situations. */
602 /* if(!handle) { */
603 /* WARN(accel, "Application sent NULL ptr.\n"); */
604 /* SetLastError(ERROR_INVALID_PARAMETER); */
605 /* return FALSE; */
606 /* } */
608 /* HeapFree(GetProcessHeap(), 0, (LPACCEL32)handle); */
610 return TRUE;
613 /**********************************************************************
614 * LoadString16
616 INT16 WINAPI LoadString16( HINSTANCE16 instance, UINT16 resource_id,
617 LPSTR buffer, INT16 buflen )
619 HGLOBAL16 hmem;
620 HRSRC16 hrsrc;
621 unsigned char *p;
622 int string_num;
623 int i;
625 TRACE(resource,"inst=%04x id=%04x buff=%08x len=%d\n",
626 instance, resource_id, (int) buffer, buflen);
628 hrsrc = FindResource16( instance, (SEGPTR)((resource_id>>4)+1), RT_STRING );
629 if (!hrsrc) return 0;
630 hmem = LoadResource16( instance, hrsrc );
631 if (!hmem) return 0;
633 p = LockResource16(hmem);
634 string_num = resource_id & 0x000f;
635 for (i = 0; i < string_num; i++)
636 p += *p + 1;
638 TRACE(resource, "strlen = %d\n", (int)*p );
640 i = MIN(buflen - 1, *p);
641 if (buffer == NULL)
642 return i;
643 if (i > 0) {
644 memcpy(buffer, p + 1, i);
645 buffer[i] = '\0';
646 } else {
647 if (buflen > 1) {
648 buffer[0] = '\0';
649 return 0;
651 fprintf(stderr,"LoadString // I dont know why , but caller give buflen=%d *p=%d !\n", buflen, *p);
652 fprintf(stderr,"LoadString // and try to obtain string '%s'\n", p + 1);
654 FreeResource16( hmem );
656 TRACE(resource,"'%s' copied !\n", buffer);
657 return i;
660 /**********************************************************************
661 * LoadString32W (USER32.375)
663 INT32 WINAPI LoadString32W( HINSTANCE32 instance, UINT32 resource_id,
664 LPWSTR buffer, INT32 buflen )
666 HGLOBAL32 hmem;
667 HRSRC32 hrsrc;
668 WCHAR *p;
669 int string_num;
670 int i;
672 if (HIWORD(resource_id)==0xFFFF) /* netscape 3 passes this */
673 resource_id = (UINT32)(-((INT32)resource_id));
674 TRACE(resource, "instance = %04x, id = %04x, buffer = %08x, "
675 "length = %d\n", instance, (int)resource_id, (int) buffer, buflen);
677 hrsrc = FindResource32W( instance, (LPCWSTR)((resource_id>>4)+1),
678 (LPCWSTR)RT_STRING );
679 if (!hrsrc) return 0;
680 hmem = LoadResource32( instance, hrsrc );
681 if (!hmem) return 0;
683 p = LockResource32(hmem);
684 string_num = resource_id & 0x000f;
685 for (i = 0; i < string_num; i++)
686 p += *p + 1;
688 TRACE(resource, "strlen = %d\n", (int)*p );
690 i = MIN(buflen - 1, *p);
691 if (buffer == NULL)
692 return i;
693 if (i > 0) {
694 memcpy(buffer, p + 1, i * sizeof (WCHAR));
695 buffer[i] = (WCHAR) 0;
696 } else {
697 if (buflen > 1) {
698 buffer[0] = (WCHAR) 0;
699 return 0;
701 #if 0
702 fprintf(stderr,"LoadString // I dont know why , but caller give buflen=%d *p=%d !\n", buflen, *p);
703 fprintf(stderr,"LoadString // and try to obtain string '%s'\n", p + 1);
704 #endif
707 TRACE(resource,"'%s' copied !\n", (char *)buffer);
708 return i;
711 /**********************************************************************
712 * LoadString32A (USER32.374)
714 INT32 WINAPI LoadString32A( HINSTANCE32 instance, UINT32 resource_id,
715 LPSTR buffer, INT32 buflen )
717 INT32 retval;
718 LPWSTR buffer2 = NULL;
719 if (buffer && buflen)
720 buffer2 = HeapAlloc( GetProcessHeap(), 0, buflen * 2 );
721 retval = LoadString32W(instance,resource_id,buffer2,buflen);
723 if (buffer2)
725 if (retval) {
726 lstrcpynWtoA( buffer, buffer2, buflen );
727 retval = lstrlen32A( buffer );
729 HeapFree( GetProcessHeap(), 0, buffer2 );
731 return retval;
734 /* Messages...used by FormatMessage32* (KERNEL32.something)
736 * They can be specified either directly or using a message ID and
737 * loading them from the resource.
739 * The resourcedata has following format:
740 * start:
741 * 0: DWORD nrofentries
742 * nrofentries * subentry:
743 * 0: DWORD firstentry
744 * 4: DWORD lastentry
745 * 8: DWORD offset from start to the stringentries
747 * (lastentry-firstentry) * stringentry:
748 * 0: WORD len (0 marks end)
749 * 2: WORD unknown (flags?)
750 * 4: CHAR[len-4]
751 * (stringentry i of a subentry refers to the ID 'firstentry+i')
753 * Yes, ANSI strings in win32 resources. Go figure.
756 /**********************************************************************
757 * LoadMessage32A (internal)
759 INT32 LoadMessage32A( HINSTANCE32 instance, UINT32 id, WORD lang,
760 LPSTR buffer, INT32 buflen )
762 HGLOBAL32 hmem;
763 HRSRC32 hrsrc;
764 BYTE *p;
765 int nrofentries,i,slen;
766 struct _subentry {
767 DWORD firstentry;
768 DWORD lastentry;
769 DWORD offset;
770 } *se;
771 struct _stringentry {
772 WORD len;
773 WORD unknown;
774 CHAR str[1];
775 } *stre;
777 TRACE(resource, "instance = %08lx, id = %08lx, buffer = %p, length = %ld\n", (DWORD)instance, (DWORD)id, buffer, (DWORD)buflen);
779 /*FIXME: I am not sure about the '1' ... But I've only seen those entries*/
780 hrsrc = FindResourceEx32W(instance,(LPWSTR)1,(LPCWSTR)RT_MESSAGELIST,lang);
781 if (!hrsrc) return 0;
782 hmem = LoadResource32( instance, hrsrc );
783 if (!hmem) return 0;
785 p = LockResource32(hmem);
786 nrofentries = *(DWORD*)p;
787 stre = NULL;
788 se = (struct _subentry*)(p+4);
789 for (i=nrofentries;i--;) {
790 if ((id>=se->firstentry) && (id<=se->lastentry)) {
791 stre = (struct _stringentry*)(p+se->offset);
792 id -= se->firstentry;
793 break;
795 se++;
797 if (!stre)
798 return 0;
799 for (i=id;i--;) {
800 if (!(slen=stre->len))
801 return 0;
802 stre = (struct _stringentry*)(((char*)stre)+slen);
804 slen=stre->len;
805 TRACE(resource," - strlen=%d\n",slen);
806 i = MIN(buflen - 1, slen);
807 if (buffer == NULL)
808 return slen; /* different to LoadString */
809 if (i>0) {
810 lstrcpyn32A(buffer,stre->str,i);
811 buffer[i]=0;
812 } else {
813 if (buflen>1) {
814 buffer[0]=0;
815 return 0;
818 if (buffer)
819 TRACE(resource,"'%s' copied !\n", buffer);
820 return i;
823 /**********************************************************************
824 * LoadMessage32W (internal)
826 INT32 LoadMessage32W( HINSTANCE32 instance, UINT32 id, WORD lang,
827 LPWSTR buffer, INT32 buflen )
829 INT32 retval;
830 LPSTR buffer2 = NULL;
831 if (buffer && buflen)
832 buffer2 = HeapAlloc( GetProcessHeap(), 0, buflen );
833 retval = LoadMessage32A(instance,id,lang,buffer2,buflen);
834 if (buffer)
836 if (retval) {
837 lstrcpynAtoW( buffer, buffer2, buflen );
838 retval = lstrlen32W( buffer );
840 HeapFree( GetProcessHeap(), 0, buffer2 );
842 return retval;
846 /**********************************************************************
847 * SetResourceHandler (KERNEL.43)
849 FARPROC16 WINAPI SetResourceHandler( HMODULE16 hModule, SEGPTR s,
850 FARPROC16 resourceHandler )
852 NE_MODULE *pModule;
854 hModule = GetExePtr( hModule );
856 TRACE(resource, "module=%04x type=%s\n",
857 hModule, debugres(PTR_SEG_TO_LIN(s)) );
859 if ((pModule = MODULE_GetPtr( hModule )))
861 if (pModule->flags & NE_FFLAGS_WIN32)
862 fprintf(stderr,"SetResourceHandler: %s\n", NEWin32FailureString);
863 else if (pModule->res_table)
864 return NE_SetResourceHandler( hModule, s, resourceHandler );
866 return NULL;
870 /**********************************************************************
871 * EnumResourceTypesA (KERNEL32.90)
873 BOOL32 WINAPI EnumResourceTypes32A( HMODULE32 hmodule,ENUMRESTYPEPROC32A lpfun,
874 LONG lParam)
876 return PE_EnumResourceTypes32A(hmodule,lpfun,lParam);
879 /**********************************************************************
880 * EnumResourceTypesW (KERNEL32.91)
882 BOOL32 WINAPI EnumResourceTypes32W( HMODULE32 hmodule,ENUMRESTYPEPROC32W lpfun,
883 LONG lParam)
885 return PE_EnumResourceTypes32W(hmodule,lpfun,lParam);
888 /**********************************************************************
889 * EnumResourceNamesA (KERNEL32.88)
891 BOOL32 WINAPI EnumResourceNames32A( HMODULE32 hmodule, LPCSTR type,
892 ENUMRESNAMEPROC32A lpfun, LONG lParam )
894 return PE_EnumResourceNames32A(hmodule,type,lpfun,lParam);
896 /**********************************************************************
897 * EnumResourceNamesW (KERNEL32.89)
899 BOOL32 WINAPI EnumResourceNames32W( HMODULE32 hmodule, LPCWSTR type,
900 ENUMRESNAMEPROC32W lpfun, LONG lParam )
902 return PE_EnumResourceNames32W(hmodule,type,lpfun,lParam);
905 /**********************************************************************
906 * EnumResourceLanguagesA (KERNEL32.86)
908 BOOL32 WINAPI EnumResourceLanguages32A( HMODULE32 hmodule, LPCSTR type,
909 LPCSTR name, ENUMRESLANGPROC32A lpfun,
910 LONG lParam)
912 return PE_EnumResourceLanguages32A(hmodule,type,name,lpfun,lParam);
914 /**********************************************************************
915 * EnumResourceLanguagesW (KERNEL32.87)
917 BOOL32 WINAPI EnumResourceLanguages32W( HMODULE32 hmodule, LPCWSTR type,
918 LPCWSTR name, ENUMRESLANGPROC32W lpfun,
919 LONG lParam)
921 return PE_EnumResourceLanguages32W(hmodule,type,name,lpfun,lParam);