Release 960928
[wine/multimedia.git] / loader / resource.c
blob8017685c2d534fb33c7901de06d550cca5228954
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 "arch.h"
16 #include "windows.h"
17 #include "gdi.h"
18 #include "global.h"
19 #include "neexe.h"
20 #include "accel.h"
21 #include "module.h"
22 #include "resource.h"
23 #include "stddebug.h"
24 #include "debug.h"
25 #include "libres.h"
26 #include "string32.h"
27 #include "xmalloc.h"
29 #define PrintId(name) \
30 if (HIWORD((DWORD)name)) \
31 dprintf_resource( stddeb, "'%s'", (char *)PTR_SEG_TO_LIN(name)); \
32 else \
33 dprintf_resource( stddeb, "#%04x", LOWORD(name));
35 extern WORD WINE_LanguageId;
37 /**********************************************************************
38 * FindResource16 (KERNEL.60)
40 HRSRC16 FindResource16( HMODULE16 hModule, SEGPTR name, SEGPTR type )
42 NE_MODULE *pModule;
44 hModule = GetExePtr( hModule ); /* In case we were passed an hInstance */
45 dprintf_resource(stddeb, "FindResource16: module=%04x type=", hModule );
46 PrintId( type );
47 if (HIWORD(name)) /* Check for '#xxx' name */
49 char *ptr = PTR_SEG_TO_LIN( name );
50 if (ptr[0] == '#') {
51 if (!(name = (SEGPTR)atoi( ptr + 1 ))) return 0;
54 dprintf_resource( stddeb, " name=" );
55 PrintId( name );
56 dprintf_resource( stddeb, "\n" );
57 if (!(pModule = MODULE_GetPtr( hModule ))) return 0;
58 #ifndef WINELIB
59 if (pModule->flags & NE_FFLAGS_WIN32)
61 fprintf(stderr,"Don't know how to FindResource16() for Win32 module\n");
62 return 0;
64 return NE_FindResource( hModule, type, name );
65 #else
66 return LIBRES_FindResource( hModule, name, type );
67 #endif
71 /**********************************************************************
72 * FindResource32A (KERNEL32.128)
74 HANDLE32 FindResource32A( HINSTANCE32 hModule, LPCSTR name, LPCSTR type )
76 return FindResourceEx32A(hModule,name,type,WINE_LanguageId);
79 /**********************************************************************
80 * FindResourceEx32A (KERNEL32.129)
82 HANDLE32 FindResourceEx32A(
83 HINSTANCE32 hModule,LPCSTR name,LPCSTR type,WORD lang
84 ) {
85 LPWSTR xname,xtype;
86 HANDLE32 ret;
88 if (HIWORD((DWORD)name)) xname = STRING32_DupAnsiToUni(name);
89 else xname = (LPWSTR)name;
90 if (HIWORD((DWORD)type)) xtype = STRING32_DupAnsiToUni(type);
91 else xtype = (LPWSTR)type;
92 ret = FindResourceEx32W(hModule,xname,xtype,lang);
93 if (HIWORD((DWORD)name)) free(xname);
94 if (HIWORD((DWORD)type)) free(xtype);
95 return ret;
99 /**********************************************************************
100 * FindResourceEx32W (KERNEL32.130)
102 HRSRC32 FindResourceEx32W(
103 HINSTANCE32 hModule, LPCWSTR name, LPCWSTR type, WORD lang
105 #ifndef WINELIB
106 NE_MODULE *pModule;
108 if (!hModule) hModule = GetTaskDS();
109 hModule = GetExePtr( hModule ); /* In case we were passed an hInstance */
110 dprintf_resource(stddeb, "FindResource32W: module=%08x type=", hModule );
111 PrintId( type );
112 dprintf_resource( stddeb, " name=" );
113 PrintId( name );
114 dprintf_resource( stddeb, "\n" );
115 if (!(pModule = MODULE_GetPtr( hModule ))) return 0;
116 if (!(pModule->flags & NE_FFLAGS_WIN32)) return 0;
117 return PE_FindResourceEx32W(hModule,name,type,lang);
118 #else
119 return LIBRES_FindResource( hModule, name, type );
120 #endif
123 /**********************************************************************
124 * FindResource32W (KERNEL32.131)
126 HRSRC32 FindResource32W( HINSTANCE32 hModule, LPCWSTR name, LPCWSTR type )
128 return FindResourceEx32W(hModule,name,type,WINE_LanguageId);
132 /**********************************************************************
133 * LoadResource16 (KERNEL.61)
135 HGLOBAL16 LoadResource16( HMODULE16 hModule, HRSRC16 hRsrc )
137 NE_MODULE *pModule;
139 hModule = GetExePtr( hModule ); /* In case we were passed an hInstance */
140 dprintf_resource(stddeb, "LoadResource16: module=%04x res=%04x\n",
141 hModule, hRsrc );
142 if (!hRsrc) return 0;
143 if (!(pModule = MODULE_GetPtr( hModule ))) return 0;
144 #ifndef WINELIB
145 if (pModule->flags & NE_FFLAGS_WIN32)
147 fprintf(stderr,"Don't know how to LoadResource16() for Win32 module\n");
148 return 0;
150 return NE_LoadResource( hModule, hRsrc );
151 #else
152 return LIBRES_LoadResource( hModule, hRsrc );
153 #endif
156 /**********************************************************************
157 * LoadResource32 (KERNEL32.370)
159 HGLOBAL32 LoadResource32( HINSTANCE32 hModule, HRSRC32 hRsrc )
161 #ifndef WINELIB
162 NE_MODULE *pModule;
164 if (!hModule) hModule = GetTaskDS(); /* FIXME: see FindResource32W */
165 hModule = GetExePtr( hModule ); /* In case we were passed an hInstance */
166 dprintf_resource(stddeb, "LoadResource32: module=%04x res=%04x\n",
167 hModule, hRsrc );
168 if (!hRsrc) return 0;
170 if (!(pModule = MODULE_GetPtr( hModule ))) return 0;
171 if (!(pModule->flags & NE_FFLAGS_WIN32))
173 fprintf(stderr,"LoadResource32: tried to load a non win32 resource.\n");
174 return 0; /* FIXME? */
176 return PE_LoadResource32(hModule,hRsrc);
177 #else
178 return LIBRES_LoadResource( hModule, hRsrc );
179 #endif
183 /**********************************************************************
184 * LockResource (KERNEL.62)
186 /* 16-bit version */
187 SEGPTR WIN16_LockResource16(HGLOBAL16 handle)
189 #ifndef WINELIB
190 HMODULE16 hModule;
191 NE_MODULE *pModule;
193 dprintf_resource(stddeb, "LockResource: handle=%04x\n", handle );
194 if (!handle) return (SEGPTR)0;
195 hModule = GetExePtr( handle );
196 if (!(pModule = MODULE_GetPtr( hModule ))) return 0;
197 if (pModule->flags & NE_FFLAGS_WIN32)
199 fprintf(stderr,"Don't know how to LockResource() for Win32 module\n");
200 return 0;
202 return NE_LockResource( hModule, handle );
203 #else
204 return LIBRES_LockResource( handle );
205 #endif
208 /* WINELIB 16-bit version */
209 LPVOID LockResource16( HGLOBAL16 handle )
211 #ifndef WINELIB
212 HMODULE16 hModule;
213 NE_MODULE *pModule;
215 dprintf_resource(stddeb, "LockResource: handle=%04x\n", handle );
216 if (!handle) return NULL;
217 hModule = GetExePtr( handle );
218 if (!(pModule = MODULE_GetPtr( hModule ))) return 0;
219 if (pModule->flags & NE_FFLAGS_WIN32)
221 fprintf(stderr,"Don't know how to LockResource16() for Win32 module\n");
222 return 0;
224 return (LPSTR)PTR_SEG_TO_LIN( NE_LockResource( hModule, handle ) );
225 #else
226 return LIBRES_LockResource( handle );
227 #endif
231 /**********************************************************************
232 * LockResource32 (KERNEL32.384)
234 LPVOID LockResource32( HGLOBAL32 handle )
236 return (LPVOID)handle;
240 /**********************************************************************
241 * FreeResource16 (KERNEL.63)
243 BOOL16 FreeResource16( HGLOBAL16 handle )
245 #ifndef WINELIB
246 HMODULE16 hModule;
247 NE_MODULE *pModule;
249 dprintf_resource(stddeb, "FreeResource16: handle=%04x\n", handle );
250 if (!handle) return FALSE;
251 hModule = GetExePtr( handle );
252 if (!(pModule = MODULE_GetPtr( hModule ))) return 0;
253 if (pModule->flags & NE_FFLAGS_WIN32)
255 fprintf(stderr,"Don't know how to FreeResource16() for Win32 module\n");
256 return 0;
258 return NE_FreeResource( hModule, handle );
259 #else
260 return LIBRES_FreeResource( handle );
261 #endif
264 /**********************************************************************
265 * FreeResource32 (KERNEL32.145)
267 BOOL32 FreeResource32( HGLOBAL32 handle )
269 /* no longer used in Win32 */
270 return TRUE;
274 /**********************************************************************
275 * AccessResource16 (KERNEL.64)
277 INT16 AccessResource16( HINSTANCE16 hModule, HRSRC16 hRsrc )
279 NE_MODULE *pModule;
281 hModule = GetExePtr( hModule ); /* In case we were passed an hInstance */
282 dprintf_resource(stddeb, "AccessResource16: module=%04x res=%04x\n",
283 hModule, hRsrc );
284 if (!hRsrc) return 0;
285 if (!(pModule = MODULE_GetPtr( hModule ))) return 0;
286 #ifndef WINELIB
287 if (pModule->flags & NE_FFLAGS_WIN32)
289 fprintf(stderr,"Don't know how to AccessResource16() for Win32 module\n");
290 return 0;
292 return NE_AccessResource( hModule, hRsrc );
293 #else
294 return LIBRES_AccessResource( hModule, hRsrc );
295 #endif
299 /**********************************************************************
300 * AccessResource32 (KERNEL32.64)
302 INT32 AccessResource32( HINSTANCE32 hModule, HRSRC32 hRsrc )
304 hModule = GetExePtr( hModule ); /* In case we were passed an hInstance */
305 dprintf_resource(stddeb, "AccessResource: module=%04x res=%04x\n",
306 hModule, hRsrc );
307 if (!hRsrc) return 0;
308 fprintf(stderr,"AccessResource32: not implemented\n");
309 return 0;
313 /**********************************************************************
314 * SizeofResource16 (KERNEL.65)
316 DWORD SizeofResource16( HMODULE16 hModule, HRSRC16 hRsrc )
318 NE_MODULE *pModule;
320 hModule = GetExePtr( hModule ); /* In case we were passed an hInstance */
321 dprintf_resource(stddeb, "SizeofResource16: module=%04x res=%04x\n",
322 hModule, hRsrc );
323 if (!(pModule = MODULE_GetPtr( hModule ))) return 0;
324 #ifndef WINELIB
325 if (pModule->flags & NE_FFLAGS_WIN32)
327 fprintf(stderr,"Don't know how to SizeOfResource16() for Win32 module\n");
328 return 0;
330 return NE_SizeofResource( hModule, hRsrc );
331 #else
332 return LIBRES_SizeofResource( hModule, hRsrc );
333 #endif
337 /**********************************************************************
338 * SizeofResource32 (KERNEL32.522)
340 DWORD SizeofResource32( HINSTANCE32 hModule, HRSRC32 hRsrc )
342 hModule = GetExePtr( hModule ); /* In case we were passed an hInstance */
343 dprintf_resource(stddeb, "SizeofResource32: module=%04x res=%04x\n",
344 hModule, hRsrc );
345 fprintf(stderr,"SizeofResource32: not implemented\n");
346 return 0;
350 /**********************************************************************
351 * AllocResource16 (KERNEL.66)
353 HGLOBAL16 AllocResource16( HMODULE16 hModule, HRSRC16 hRsrc, DWORD size )
355 NE_MODULE *pModule;
357 hModule = GetExePtr( hModule ); /* In case we were passed an hInstance */
358 dprintf_resource(stddeb, "AllocResource: module=%04x res=%04x size=%ld\n",
359 hModule, hRsrc, size );
360 if (!hRsrc) return 0;
361 if (!(pModule = MODULE_GetPtr( hModule ))) return 0;
362 #ifndef WINELIB
363 if (pModule->flags & NE_FFLAGS_WIN32)
365 fprintf(stderr,"Don't know how to AllocResource() for Win32 module\n");
366 return 0;
368 return NE_AllocResource( hModule, hRsrc, size );
369 #else
370 return LIBRES_AllocResource( hModule, hRsrc, size );
371 #endif
374 /**********************************************************************
375 * DirectResAlloc (KERNEL.168)
377 * Check Schulman, p. 232 for details
379 HANDLE DirectResAlloc(HANDLE hInstance, WORD wType, WORD wSize)
381 dprintf_resource(stddeb,"DirectResAlloc(%04x,%04x,%04x)\n",
382 hInstance, wType, wSize );
383 hInstance = GetExePtr(hInstance);
384 if(!hInstance)return 0;
385 if(wType != 0x10) /* 0x10 is the only observed value, passed from
386 CreateCursorIndirect. */
387 fprintf(stderr, "DirectResAlloc: wType = %x\n", wType);
388 return GLOBAL_Alloc(GMEM_MOVEABLE, wSize, hInstance, FALSE, FALSE, FALSE);
392 /**********************************************************************
393 * LoadAccelerators16 [USER.177]
395 HACCEL16 LoadAccelerators16(HINSTANCE16 instance, SEGPTR lpTableName)
397 HACCEL16 hAccel;
398 HGLOBAL16 rsc_mem;
399 HRSRC16 hRsrc;
400 BYTE *lp;
401 ACCELHEADER *lpAccelTbl;
402 int i, n;
404 if (HIWORD(lpTableName))
405 dprintf_accel( stddeb, "LoadAccelerators: %04x '%s'\n",
406 instance, (char *)PTR_SEG_TO_LIN( lpTableName ) );
407 else
408 dprintf_accel( stddeb, "LoadAccelerators: %04x %04x\n",
409 instance, LOWORD(lpTableName) );
411 if (!(hRsrc = FindResource16( instance, lpTableName, RT_ACCELERATOR )))
412 return 0;
413 if (!(rsc_mem = LoadResource16( instance, hRsrc ))) return 0;
415 lp = (BYTE *)LockResource16(rsc_mem);
416 n = SizeofResource16(instance,hRsrc)/sizeof(ACCELENTRY);
417 hAccel = GlobalAlloc16(GMEM_MOVEABLE,
418 sizeof(ACCELHEADER) + (n + 1)*sizeof(ACCELENTRY));
419 lpAccelTbl = (LPACCELHEADER)GlobalLock16(hAccel);
420 lpAccelTbl->wCount = 0;
421 for (i = 0; i < n; i++) {
422 lpAccelTbl->tbl[i].type = *(lp++);
423 lpAccelTbl->tbl[i].wEvent = *((WORD *)lp);
424 lp += 2;
425 lpAccelTbl->tbl[i].wIDval = *((WORD *)lp);
426 lp += 2;
427 if (lpAccelTbl->tbl[i].wEvent == 0) break;
428 dprintf_accel(stddeb,
429 "Accelerator #%u / event=%04X id=%04X type=%02X \n",
430 i, lpAccelTbl->tbl[i].wEvent, lpAccelTbl->tbl[i].wIDval,
431 lpAccelTbl->tbl[i].type);
432 lpAccelTbl->wCount++;
434 GlobalUnlock16(hAccel);
435 FreeResource16( rsc_mem );
436 return hAccel;
439 /**********************************************************************
440 * LoadAccelerators32W [USER.177]
442 HACCEL32 LoadAccelerators32W(HINSTANCE32 instance,LPCWSTR lpTableName)
444 #if 0
445 HACCEL32 hAccel;
446 HGLOBAL32 rsc_mem;
447 HRSRC32 hRsrc;
448 BYTE *lp;
449 ACCELHEADER *lpAccelTbl;
450 int i, n;
452 if (HIWORD(lpTableName))
453 dprintf_accel( stddeb, "LoadAccelerators: %04x '%s'\n",
454 instance, (char *)( lpTableName ) );
455 else
456 dprintf_accel( stddeb, "LoadAccelerators: %04x %04x\n",
457 instance, LOWORD(lpTableName) );
459 if (!(hRsrc = FindResource32W( instance, lpTableName,
460 (LPCWSTR)RT_ACCELERATOR )))
461 return 0;
462 if (!(rsc_mem = LoadResource32( instance, hRsrc ))) return 0;
464 lp = (BYTE *)LockResource32(rsc_mem);
465 n = SizeofResource32(instance,hRsrc)/sizeof(ACCELENTRY);
466 hAccel = GlobalAlloc16(GMEM_MOVEABLE,
467 sizeof(ACCELHEADER) + (n + 1)*sizeof(ACCELENTRY));
468 lpAccelTbl = (LPACCELHEADER)GlobalLock16(hAccel);
469 lpAccelTbl->wCount = 0;
470 for (i = 0; i < n; i++) {
471 lpAccelTbl->tbl[i].type = *(lp++);
472 lpAccelTbl->tbl[i].wEvent = *((WORD *)lp);
473 lp += 2;
474 lpAccelTbl->tbl[i].wIDval = *((WORD *)lp);
475 lp += 2;
476 if (lpAccelTbl->tbl[i].wEvent == 0) break;
477 dprintf_accel(stddeb,
478 "Accelerator #%u / event=%04X id=%04X type=%02X \n",
479 i, lpAccelTbl->tbl[i].wEvent, lpAccelTbl->tbl[i].wIDval,
480 lpAccelTbl->tbl[i].type);
481 lpAccelTbl->wCount++;
483 GlobalUnlock16(hAccel);
484 FreeResource32(rsc_mem);
485 return hAccel;
486 #else
487 fprintf(stderr,"LoadAcceleratorsW: not implemented\n");
488 return 0x100; /* Return something anyway */
489 #endif
492 HACCEL32 LoadAccelerators32A(HINSTANCE32 instance,LPCSTR lpTableName)
494 LPWSTR uni;
495 HACCEL32 result;
496 if (HIWORD(lpTableName))
497 uni=STRING32_DupAnsiToUni(lpTableName);
498 else
499 uni=(LPWSTR)lpTableName;
500 result=LoadAccelerators32W(instance,uni);
501 if (HIWORD(uni))
502 free(uni);
503 return result;
507 /**********************************************************************
508 * TranslateAccelerator [USER.178]
510 int TranslateAccelerator(HWND hWnd, HANDLE hAccel, LPMSG16 msg)
512 ACCELHEADER *lpAccelTbl;
513 int i;
515 if (hAccel == 0 || msg == NULL) return 0;
516 if (msg->message != WM_KEYDOWN &&
517 msg->message != WM_KEYUP &&
518 msg->message != WM_SYSKEYDOWN &&
519 msg->message != WM_SYSKEYUP &&
520 msg->message != WM_CHAR) return 0;
522 dprintf_accel(stddeb, "TranslateAccelerators hAccel=%04x !\n", hAccel);
524 lpAccelTbl = (LPACCELHEADER)GlobalLock16(hAccel);
525 for (i = 0; i < lpAccelTbl->wCount; i++) {
526 if(lpAccelTbl->tbl[i].type & VIRTKEY_ACCEL) {
527 if(msg->wParam == lpAccelTbl->tbl[i].wEvent &&
528 (msg->message == WM_KEYDOWN || msg->message == WM_SYSKEYDOWN)) {
529 INT mask = 0;
531 if(GetKeyState(VK_SHIFT) & 0x8000) mask |= SHIFT_ACCEL;
532 if(GetKeyState(VK_CONTROL) & 0x8000) mask |= CONTROL_ACCEL;
533 if(GetKeyState(VK_MENU) & 0x8000) mask |= ALT_ACCEL;
534 if(mask == (lpAccelTbl->tbl[i].type &
535 (SHIFT_ACCEL | CONTROL_ACCEL | ALT_ACCEL))) {
536 SendMessage16(hWnd, WM_COMMAND, lpAccelTbl->tbl[i].wIDval,
537 0x00010000L);
538 GlobalUnlock16(hAccel);
539 return 1;
541 if (msg->message == WM_KEYUP || msg->message == WM_SYSKEYUP)
542 return 1;
545 else {
546 if (msg->wParam == lpAccelTbl->tbl[i].wEvent &&
547 msg->message == WM_CHAR) {
548 SendMessage16(hWnd, WM_COMMAND, lpAccelTbl->tbl[i].wIDval, 0x00010000L);
549 GlobalUnlock16(hAccel);
550 return 1;
554 GlobalUnlock16(hAccel);
555 return 0;
558 /**********************************************************************
559 * LoadString16
561 INT16
562 LoadString16(HINSTANCE16 instance,UINT16 resource_id,LPSTR buffer,INT16 buflen)
564 HGLOBAL16 hmem;
565 HRSRC16 hrsrc;
566 unsigned char *p;
567 int string_num;
568 int i;
570 dprintf_resource(stddeb,"LoadString: inst=%04x id=%04x buff=%08x len=%d\n",
571 instance, resource_id, (int) buffer, buflen);
573 hrsrc = FindResource16( instance, (SEGPTR)((resource_id>>4)+1), RT_STRING );
574 if (!hrsrc) return 0;
575 hmem = LoadResource16( instance, hrsrc );
576 if (!hmem) return 0;
578 p = LockResource16(hmem);
579 string_num = resource_id & 0x000f;
580 for (i = 0; i < string_num; i++)
581 p += *p + 1;
583 dprintf_resource( stddeb, "strlen = %d\n", (int)*p );
585 i = MIN(buflen - 1, *p);
586 if (buffer == NULL)
587 return i;
588 if (i > 0) {
589 memcpy(buffer, p + 1, i);
590 buffer[i] = '\0';
591 } else {
592 if (buflen > 1) {
593 buffer[0] = '\0';
594 return 0;
596 fprintf(stderr,"LoadString // I dont know why , but caller give buflen=%d *p=%d !\n", buflen, *p);
597 fprintf(stderr,"LoadString // and try to obtain string '%s'\n", p + 1);
599 FreeResource16( hmem );
601 dprintf_resource(stddeb,"LoadString // '%s' copied !\n", buffer);
602 return i;
605 /**********************************************************************
606 * LoadString32W (USER32.375)
608 INT32
609 LoadString32W(HINSTANCE32 instance,UINT32 resource_id,LPWSTR buffer,int buflen)
611 HGLOBAL32 hmem;
612 HRSRC32 hrsrc;
613 WCHAR *p;
614 int string_num;
615 int i;
617 dprintf_resource(stddeb, "LoadString: instance = %04x, id = %04x, buffer = %08x, "
618 "length = %d\n", instance, (int)resource_id, (int) buffer, buflen);
620 hrsrc = FindResource32W( instance, (LPCWSTR)((resource_id>>4)+1),
621 (LPCWSTR)RT_STRING );
622 if (!hrsrc) return 0;
623 hmem = LoadResource32( instance, hrsrc );
624 if (!hmem) return 0;
626 p = LockResource32(hmem);
627 string_num = resource_id & 0x000f;
628 for (i = 0; i < string_num; i++)
629 p += *p + 1;
631 dprintf_resource( stddeb, "strlen = %d\n", (int)*p );
633 i = MIN(buflen - 1, *p);
634 if (buffer == NULL)
635 return i;
636 if (i > 0) {
637 memcpy(buffer, p + 1, i * sizeof (WCHAR));
638 buffer[i] = (WCHAR) 0;
639 } else {
640 if (buflen > 1) {
641 buffer[0] = (WCHAR) 0;
642 return 0;
644 #if 0
645 fprintf(stderr,"LoadString // I dont know why , but caller give buflen=%d *p=%d !\n", buflen, *p);
646 fprintf(stderr,"LoadString // and try to obtain string '%s'\n", p + 1);
647 #endif
649 #if 0
650 dprintf_resource(stddeb,"LoadString // '%s' copied !\n", buffer);
651 #endif
652 return i;
655 /**********************************************************************
656 * LoadString32A (USER32.374)
658 INT32
659 LoadString32A(HINSTANCE32 instance,UINT32 resource_id,LPSTR buffer,int buflen)
661 LPWSTR buffer2 = buffer?(LPWSTR)xmalloc(buflen*2):NULL;
662 INT32 retval = LoadString32W(instance,resource_id,buffer2,buflen);
664 if (buffer) {
665 STRING32_UniToAnsi(buffer,buffer2);
666 free(buffer2);
668 return retval;
671 /* Messages...used by FormatMessage32* (KERNEL32.something)
673 * They can be specified either directly or using a message ID and
674 * loading them from the resource.
676 * The resourcedata has following format:
677 * start:
678 * 0: DWORD nrofentries
679 * nrofentries * subentry:
680 * 0: DWORD firstentry
681 * 4: DWORD lastentry
682 * 8: DWORD offset from start to the stringentries
684 * (lastentry-firstentry) * stringentry:
685 * 0: WORD len (0 marks end)
686 * 2: WORD unknown (flags?)
687 * 4: CHAR[len-4]
688 * (stringentry i of a subentry refers to the ID 'firstentry+i')
690 * Yes, ANSI strings in win32 resources. Go figure.
693 /**********************************************************************
694 * LoadMessage32A (internal)
696 INT32
697 LoadMessage32A(
698 HINSTANCE32 instance,UINT32 id,WORD lang,LPSTR buffer,int buflen
700 HGLOBAL32 hmem;
701 HRSRC32 hrsrc;
702 BYTE *p;
703 int nrofentries,i,slen;
704 struct _subentry {
705 DWORD firstentry;
706 DWORD lastentry;
707 DWORD offset;
708 } *se;
709 struct _stringentry {
710 WORD len;
711 WORD unknown;
712 CHAR str[1];
713 } *stre;
715 dprintf_resource(stddeb, "LoadMessage: instance = %04x, id = %04x, buffer = %08x, "
716 "length = %d\n", instance, (int)id, (int) buffer, buflen);
718 /*FIXME: I am not sure about the '1' ... But I've only seen those entries*/
719 hrsrc = FindResourceEx32W(instance,(LPWSTR)1,(LPCWSTR)RT_MESSAGELIST,lang);
720 if (!hrsrc) return 0;
721 hmem = LoadResource32( instance, hrsrc );
722 if (!hmem) return 0;
724 p = LockResource32(hmem);
725 nrofentries = *(DWORD*)p;
726 stre = NULL;
727 se = (struct _subentry*)(p+4);
728 for (i=nrofentries;i--;) {
729 if ((id>=se->firstentry) && (id<=se->lastentry)) {
730 stre = (struct _stringentry*)(p+se->offset);
731 id -= se->firstentry;
732 break;
734 se++;
736 if (!stre)
737 return 0;
738 for (i=id;i--;) {
739 if (!(slen=stre->len))
740 return 0;
741 stre = (struct _stringentry*)(((char*)stre)+slen);
743 slen=stre->len;
744 dprintf_resource(stddeb," - strlen=%d\n",slen);
745 i = MIN(buflen - 1, slen);
746 if (buffer == NULL)
747 return slen; /* different to LoadString */
748 if (i>0) {
749 lstrcpyn32A(buffer,stre->str,i);
750 buffer[i]=0;
751 } else {
752 if (buflen>1) {
753 buffer[0]=0;
754 return 0;
757 if (buffer)
758 dprintf_resource(stddeb,"LoadMessage // '%s' copied !\n", buffer);
759 return i;
762 /**********************************************************************
763 * LoadMessage32W (internal)
765 INT32
766 LoadMessage32W(
767 HINSTANCE32 instance,UINT32 id,WORD lang,LPWSTR buffer,int buflen
769 LPSTR buffer2 = buffer?(LPSTR)xmalloc(buflen):NULL;
770 INT32 retval = LoadMessage32A(instance,id,lang,buffer2,buflen);
772 if (buffer) {
773 STRING32_AnsiToUni(buffer,buffer2);
774 free(buffer2);
776 return retval;