Release 961222
[wine/multimedia.git] / loader / resource.c
blob3ae68215fa89496f4a8ed3230b75144e3c40a917
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 "heap.h"
20 #include "neexe.h"
21 #include "accel.h"
22 #include "module.h"
23 #include "resource.h"
24 #include "stddebug.h"
25 #include "debug.h"
26 #include "libres.h"
28 #define PrintId(name) \
29 if (HIWORD((DWORD)name)) \
30 dprintf_resource( stddeb, "'%s'", (char *)PTR_SEG_TO_LIN(name)); \
31 else \
32 dprintf_resource( stddeb, "#%04x", LOWORD(name));
34 extern WORD WINE_LanguageId;
36 /**********************************************************************
37 * FindResource16 (KERNEL.60)
39 HRSRC16 FindResource16( HMODULE16 hModule, SEGPTR name, SEGPTR type )
41 NE_MODULE *pModule;
43 hModule = GetExePtr( hModule ); /* In case we were passed an hInstance */
44 dprintf_resource(stddeb, "FindResource16: module=%04x type=", hModule );
45 PrintId( type );
46 if (HIWORD(name)) /* Check for '#xxx' name */
48 char *ptr = PTR_SEG_TO_LIN( name );
49 if (ptr[0] == '#') {
50 if (!(name = (SEGPTR)atoi( ptr + 1 ))) return 0;
53 dprintf_resource( stddeb, " name=" );
54 PrintId( name );
55 dprintf_resource( stddeb, "\n" );
56 if (!(pModule = MODULE_GetPtr( hModule ))) return 0;
57 #ifndef WINELIB
58 if (pModule->flags & NE_FFLAGS_WIN32)
60 fprintf(stderr,"Don't know how to FindResource16() for Win32 module\n");
61 return 0;
63 return NE_FindResource( hModule, type, name );
64 #else
65 return LIBRES_FindResource16( hModule, name, type );
66 #endif
70 /**********************************************************************
71 * FindResource32A (KERNEL32.128)
73 HANDLE32 FindResource32A( HINSTANCE32 hModule, LPCSTR name, LPCSTR type )
75 return FindResourceEx32A(hModule,name,type,WINE_LanguageId);
78 /**********************************************************************
79 * FindResourceEx32A (KERNEL32.129)
81 HANDLE32 FindResourceEx32A(
82 HINSTANCE32 hModule,LPCSTR name,LPCSTR type,WORD lang
83 ) {
84 LPWSTR xname,xtype;
85 HANDLE32 ret;
87 if (HIWORD((DWORD)name))
88 xname = HEAP_strdupAtoW( GetProcessHeap(), 0, name );
89 else
90 xname = (LPWSTR)name;
91 if (HIWORD((DWORD)type))
92 xtype = HEAP_strdupAtoW( GetProcessHeap(), 0, type);
93 else
94 xtype = (LPWSTR)type;
95 ret = FindResourceEx32W( hModule, xname, xtype, lang );
96 if (HIWORD((DWORD)name)) HeapFree( GetProcessHeap(), 0, xname );
97 if (HIWORD((DWORD)type)) HeapFree( GetProcessHeap(), 0, xtype );
98 return ret;
102 /**********************************************************************
103 * FindResourceEx32W (KERNEL32.130)
105 HRSRC32 FindResourceEx32W(
106 HINSTANCE32 hModule, LPCWSTR name, LPCWSTR type, WORD lang
108 #ifndef WINELIB
109 NE_MODULE *pModule;
111 if (!hModule) hModule = GetTaskDS();
112 hModule = GetExePtr( hModule ); /* In case we were passed an hInstance */
113 dprintf_resource(stddeb, "FindResource32W: module=%08x type=", hModule );
114 PrintId( type );
115 dprintf_resource( stddeb, " name=" );
116 PrintId( name );
117 dprintf_resource( stddeb, "\n" );
118 if (!(pModule = MODULE_GetPtr( hModule ))) return 0;
119 if (!(pModule->flags & NE_FFLAGS_WIN32)) return 0;
120 return PE_FindResourceEx32W(hModule,name,type,lang);
121 #else
122 return LIBRES_FindResource32( hModule, name, type );
123 #endif
126 /**********************************************************************
127 * FindResource32W (KERNEL32.131)
129 HRSRC32 FindResource32W( HINSTANCE32 hModule, LPCWSTR name, LPCWSTR type )
131 return FindResourceEx32W(hModule,name,type,WINE_LanguageId);
135 /**********************************************************************
136 * LoadResource16 (KERNEL.61)
138 HGLOBAL16 LoadResource16( HMODULE16 hModule, HRSRC16 hRsrc )
140 NE_MODULE *pModule;
142 hModule = GetExePtr( hModule ); /* In case we were passed an hInstance */
143 dprintf_resource(stddeb, "LoadResource16: module=%04x res=%04x\n",
144 hModule, hRsrc );
145 if (!hRsrc) return 0;
146 if (!(pModule = MODULE_GetPtr( hModule ))) return 0;
147 #ifndef WINELIB
148 if (pModule->flags & NE_FFLAGS_WIN32)
150 fprintf(stderr,"Don't know how to LoadResource16() for Win32 module\n");
151 return 0;
153 return NE_LoadResource( hModule, hRsrc );
154 #else
155 return LIBRES_LoadResource( hModule, hRsrc );
156 #endif
159 /**********************************************************************
160 * LoadResource32 (KERNEL32.370)
162 HGLOBAL32 LoadResource32( HINSTANCE32 hModule, HRSRC32 hRsrc )
164 #ifndef WINELIB
165 NE_MODULE *pModule;
167 if (!hModule) hModule = GetTaskDS(); /* FIXME: see FindResource32W */
168 hModule = GetExePtr( hModule ); /* In case we were passed an hInstance */
169 dprintf_resource(stddeb, "LoadResource32: module=%04x res=%04x\n",
170 hModule, hRsrc );
171 if (!hRsrc) return 0;
173 if (!(pModule = MODULE_GetPtr( hModule ))) return 0;
174 if (!(pModule->flags & NE_FFLAGS_WIN32))
176 fprintf(stderr,"LoadResource32: tried to load a non win32 resource.\n");
177 return 0; /* FIXME? */
179 return PE_LoadResource32(hModule,hRsrc);
180 #else
181 return LIBRES_LoadResource( hModule, hRsrc );
182 #endif
186 /**********************************************************************
187 * LockResource (KERNEL.62)
189 /* 16-bit version */
190 SEGPTR WIN16_LockResource16(HGLOBAL16 handle)
192 #ifndef WINELIB
193 HMODULE16 hModule;
194 NE_MODULE *pModule;
196 dprintf_resource(stddeb, "LockResource: handle=%04x\n", handle );
197 if (!handle) return (SEGPTR)0;
198 hModule = GetExePtr( handle );
199 if (!(pModule = MODULE_GetPtr( hModule ))) return 0;
200 if (pModule->flags & NE_FFLAGS_WIN32)
202 fprintf(stderr,"Don't know how to LockResource() for Win32 module\n");
203 return 0;
205 return NE_LockResource( hModule, handle );
206 #else
207 return LIBRES_LockResource( handle );
208 #endif
211 /* WINELIB 16-bit version */
212 LPVOID LockResource16( HGLOBAL16 handle )
214 #ifndef WINELIB
215 HMODULE16 hModule;
216 NE_MODULE *pModule;
218 dprintf_resource(stddeb, "LockResource: handle=%04x\n", handle );
219 if (!handle) return NULL;
220 hModule = GetExePtr( handle );
221 if (!(pModule = MODULE_GetPtr( hModule ))) return 0;
222 if (pModule->flags & NE_FFLAGS_WIN32)
224 fprintf(stderr,"Don't know how to LockResource16() for Win32 module\n");
225 return 0;
227 return (LPSTR)PTR_SEG_TO_LIN( NE_LockResource( hModule, handle ) );
228 #else
229 return LIBRES_LockResource( handle );
230 #endif
234 /**********************************************************************
235 * LockResource32 (KERNEL32.384)
237 LPVOID LockResource32( HGLOBAL32 handle )
239 return (LPVOID)handle;
243 /**********************************************************************
244 * FreeResource16 (KERNEL.63)
246 BOOL16 FreeResource16( HGLOBAL16 handle )
248 #ifndef WINELIB
249 HMODULE16 hModule;
250 NE_MODULE *pModule;
252 dprintf_resource(stddeb, "FreeResource16: handle=%04x\n", handle );
253 if (!handle) return FALSE;
254 hModule = GetExePtr( handle );
255 if (!(pModule = MODULE_GetPtr( hModule ))) return 0;
256 if (pModule->flags & NE_FFLAGS_WIN32)
258 fprintf(stderr,"Don't know how to FreeResource16() for Win32 module\n");
259 return 0;
261 return NE_FreeResource( hModule, handle );
262 #else
263 return LIBRES_FreeResource( handle );
264 #endif
267 /**********************************************************************
268 * FreeResource32 (KERNEL32.145)
270 BOOL32 FreeResource32( HGLOBAL32 handle )
272 /* no longer used in Win32 */
273 return TRUE;
277 /**********************************************************************
278 * AccessResource16 (KERNEL.64)
280 INT16 AccessResource16( HINSTANCE16 hModule, HRSRC16 hRsrc )
282 NE_MODULE *pModule;
284 hModule = GetExePtr( hModule ); /* In case we were passed an hInstance */
285 dprintf_resource(stddeb, "AccessResource16: module=%04x res=%04x\n",
286 hModule, hRsrc );
287 if (!hRsrc) return 0;
288 if (!(pModule = MODULE_GetPtr( hModule ))) return 0;
289 #ifndef WINELIB
290 if (pModule->flags & NE_FFLAGS_WIN32)
292 fprintf(stderr,"Don't know how to AccessResource16() for Win32 module\n");
293 return 0;
295 return NE_AccessResource( hModule, hRsrc );
296 #else
297 return LIBRES_AccessResource( hModule, hRsrc );
298 #endif
302 /**********************************************************************
303 * AccessResource32 (KERNEL32.64)
305 INT32 AccessResource32( HINSTANCE32 hModule, HRSRC32 hRsrc )
307 hModule = GetExePtr( hModule ); /* In case we were passed an hInstance */
308 dprintf_resource(stddeb, "AccessResource: module=%04x res=%04x\n",
309 hModule, hRsrc );
310 if (!hRsrc) return 0;
311 fprintf(stderr,"AccessResource32: not implemented\n");
312 return 0;
316 /**********************************************************************
317 * SizeofResource16 (KERNEL.65)
319 DWORD SizeofResource16( HMODULE16 hModule, HRSRC16 hRsrc )
321 NE_MODULE *pModule;
323 hModule = GetExePtr( hModule ); /* In case we were passed an hInstance */
324 dprintf_resource(stddeb, "SizeofResource16: module=%04x res=%04x\n",
325 hModule, hRsrc );
326 if (!(pModule = MODULE_GetPtr( hModule ))) return 0;
327 #ifndef WINELIB
328 if (pModule->flags & NE_FFLAGS_WIN32)
330 fprintf(stderr,"Don't know how to SizeOfResource16() for Win32 module\n");
331 return 0;
333 return NE_SizeofResource( hModule, hRsrc );
334 #else
335 return LIBRES_SizeofResource( hModule, hRsrc );
336 #endif
340 /**********************************************************************
341 * SizeofResource32 (KERNEL32.522)
343 DWORD SizeofResource32( HINSTANCE32 hModule, HRSRC32 hRsrc )
345 hModule = GetExePtr( hModule ); /* In case we were passed an hInstance */
346 dprintf_resource(stddeb, "SizeofResource32: module=%04x res=%04x\n",
347 hModule, hRsrc );
348 fprintf(stderr,"SizeofResource32: not implemented\n");
349 return 0;
353 /**********************************************************************
354 * AllocResource16 (KERNEL.66)
356 HGLOBAL16 AllocResource16( HMODULE16 hModule, HRSRC16 hRsrc, DWORD size )
358 NE_MODULE *pModule;
360 hModule = GetExePtr( hModule ); /* In case we were passed an hInstance */
361 dprintf_resource(stddeb, "AllocResource: module=%04x res=%04x size=%ld\n",
362 hModule, hRsrc, size );
363 if (!hRsrc) return 0;
364 if (!(pModule = MODULE_GetPtr( hModule ))) return 0;
365 #ifndef WINELIB
366 if (pModule->flags & NE_FFLAGS_WIN32)
368 fprintf(stderr,"Don't know how to AllocResource() for Win32 module\n");
369 return 0;
371 return NE_AllocResource( hModule, hRsrc, size );
372 #else
373 return LIBRES_AllocResource( hModule, hRsrc, size );
374 #endif
377 /**********************************************************************
378 * DirectResAlloc (KERNEL.168)
380 * Check Schulman, p. 232 for details
382 HGLOBAL16 DirectResAlloc( HINSTANCE16 hInstance, WORD wType, UINT16 wSize )
384 dprintf_resource(stddeb,"DirectResAlloc(%04x,%04x,%04x)\n",
385 hInstance, wType, wSize );
386 hInstance = GetExePtr(hInstance);
387 if(!hInstance)return 0;
388 if(wType != 0x10) /* 0x10 is the only observed value, passed from
389 CreateCursorIndirect. */
390 fprintf(stderr, "DirectResAlloc: wType = %x\n", wType);
391 return GLOBAL_Alloc(GMEM_MOVEABLE, wSize, hInstance, FALSE, FALSE, FALSE);
395 /**********************************************************************
396 * LoadAccelerators16 [USER.177]
398 HACCEL16 LoadAccelerators16(HINSTANCE16 instance, SEGPTR lpTableName)
400 HACCEL16 hAccel;
401 HGLOBAL16 rsc_mem;
402 HRSRC16 hRsrc;
403 BYTE *lp;
404 ACCELHEADER *lpAccelTbl;
405 int i, n;
407 if (HIWORD(lpTableName))
408 dprintf_accel( stddeb, "LoadAccelerators: %04x '%s'\n",
409 instance, (char *)PTR_SEG_TO_LIN( lpTableName ) );
410 else
411 dprintf_accel( stddeb, "LoadAccelerators: %04x %04x\n",
412 instance, LOWORD(lpTableName) );
414 if (!(hRsrc = FindResource16( instance, lpTableName, RT_ACCELERATOR )))
415 return 0;
416 if (!(rsc_mem = LoadResource16( instance, hRsrc ))) return 0;
418 lp = (BYTE *)LockResource16(rsc_mem);
419 n = SizeofResource16(instance,hRsrc)/sizeof(ACCELENTRY);
420 hAccel = GlobalAlloc16(GMEM_MOVEABLE,
421 sizeof(ACCELHEADER) + (n + 1)*sizeof(ACCELENTRY));
422 lpAccelTbl = (LPACCELHEADER)GlobalLock16(hAccel);
423 lpAccelTbl->wCount = 0;
424 for (i = 0; i < n; i++) {
425 lpAccelTbl->tbl[i].type = *(lp++);
426 lpAccelTbl->tbl[i].wEvent = *((WORD *)lp);
427 lp += 2;
428 lpAccelTbl->tbl[i].wIDval = *((WORD *)lp);
429 lp += 2;
430 if (lpAccelTbl->tbl[i].wEvent == 0) break;
431 dprintf_accel(stddeb,
432 "Accelerator #%u / event=%04X id=%04X type=%02X \n",
433 i, lpAccelTbl->tbl[i].wEvent, lpAccelTbl->tbl[i].wIDval,
434 lpAccelTbl->tbl[i].type);
435 lpAccelTbl->wCount++;
437 GlobalUnlock16(hAccel);
438 FreeResource16( rsc_mem );
439 return hAccel;
442 /**********************************************************************
443 * LoadAccelerators32W [USER.177]
445 HACCEL32 LoadAccelerators32W(HINSTANCE32 instance,LPCWSTR lpTableName)
447 #if 0
448 HACCEL32 hAccel;
449 HGLOBAL32 rsc_mem;
450 HRSRC32 hRsrc;
451 BYTE *lp;
452 ACCELHEADER *lpAccelTbl;
453 int i, n;
455 if (HIWORD(lpTableName))
456 dprintf_accel( stddeb, "LoadAccelerators: %04x '%s'\n",
457 instance, (char *)( lpTableName ) );
458 else
459 dprintf_accel( stddeb, "LoadAccelerators: %04x %04x\n",
460 instance, LOWORD(lpTableName) );
462 if (!(hRsrc = FindResource32W( instance, lpTableName,
463 (LPCWSTR)RT_ACCELERATOR )))
464 return 0;
465 if (!(rsc_mem = LoadResource32( instance, hRsrc ))) return 0;
467 lp = (BYTE *)LockResource32(rsc_mem);
468 n = SizeofResource32(instance,hRsrc)/sizeof(ACCELENTRY);
469 hAccel = GlobalAlloc16(GMEM_MOVEABLE,
470 sizeof(ACCELHEADER) + (n + 1)*sizeof(ACCELENTRY));
471 lpAccelTbl = (LPACCELHEADER)GlobalLock16(hAccel);
472 lpAccelTbl->wCount = 0;
473 for (i = 0; i < n; i++) {
474 lpAccelTbl->tbl[i].type = *(lp++);
475 lpAccelTbl->tbl[i].wEvent = *((WORD *)lp);
476 lp += 2;
477 lpAccelTbl->tbl[i].wIDval = *((WORD *)lp);
478 lp += 2;
479 if (lpAccelTbl->tbl[i].wEvent == 0) break;
480 dprintf_accel(stddeb,
481 "Accelerator #%u / event=%04X id=%04X type=%02X \n",
482 i, lpAccelTbl->tbl[i].wEvent, lpAccelTbl->tbl[i].wIDval,
483 lpAccelTbl->tbl[i].type);
484 lpAccelTbl->wCount++;
486 GlobalUnlock16(hAccel);
487 FreeResource32(rsc_mem);
488 return hAccel;
489 #else
490 fprintf(stderr,"LoadAcceleratorsW: not implemented\n");
491 return 0x100; /* Return something anyway */
492 #endif
495 HACCEL32 LoadAccelerators32A(HINSTANCE32 instance,LPCSTR lpTableName)
497 LPWSTR uni;
498 HACCEL32 result;
499 if (HIWORD(lpTableName))
500 uni = HEAP_strdupAtoW( GetProcessHeap(), 0, lpTableName );
501 else
502 uni = (LPWSTR)lpTableName;
503 result = LoadAccelerators32W(instance,uni);
504 if (HIWORD(uni)) HeapFree( GetProcessHeap(), 0, uni);
505 return result;
509 /**********************************************************************
510 * LoadString16
512 INT16
513 LoadString16(HINSTANCE16 instance,UINT16 resource_id,LPSTR buffer,INT16 buflen)
515 HGLOBAL16 hmem;
516 HRSRC16 hrsrc;
517 unsigned char *p;
518 int string_num;
519 int i;
521 dprintf_resource(stddeb,"LoadString: inst=%04x id=%04x buff=%08x len=%d\n",
522 instance, resource_id, (int) buffer, buflen);
524 hrsrc = FindResource16( instance, (SEGPTR)((resource_id>>4)+1), RT_STRING );
525 if (!hrsrc) return 0;
526 hmem = LoadResource16( instance, hrsrc );
527 if (!hmem) return 0;
529 p = LockResource16(hmem);
530 string_num = resource_id & 0x000f;
531 for (i = 0; i < string_num; i++)
532 p += *p + 1;
534 dprintf_resource( stddeb, "strlen = %d\n", (int)*p );
536 i = MIN(buflen - 1, *p);
537 if (buffer == NULL)
538 return i;
539 if (i > 0) {
540 memcpy(buffer, p + 1, i);
541 buffer[i] = '\0';
542 } else {
543 if (buflen > 1) {
544 buffer[0] = '\0';
545 return 0;
547 fprintf(stderr,"LoadString // I dont know why , but caller give buflen=%d *p=%d !\n", buflen, *p);
548 fprintf(stderr,"LoadString // and try to obtain string '%s'\n", p + 1);
550 FreeResource16( hmem );
552 dprintf_resource(stddeb,"LoadString // '%s' copied !\n", buffer);
553 return i;
556 /**********************************************************************
557 * LoadString32W (USER32.375)
559 INT32
560 LoadString32W(HINSTANCE32 instance,UINT32 resource_id,LPWSTR buffer,int buflen)
562 HGLOBAL32 hmem;
563 HRSRC32 hrsrc;
564 WCHAR *p;
565 int string_num;
566 int i;
568 dprintf_resource(stddeb, "LoadString: instance = %04x, id = %04x, buffer = %08x, "
569 "length = %d\n", instance, (int)resource_id, (int) buffer, buflen);
571 hrsrc = FindResource32W( instance, (LPCWSTR)((resource_id>>4)+1),
572 (LPCWSTR)RT_STRING );
573 if (!hrsrc) return 0;
574 hmem = LoadResource32( instance, hrsrc );
575 if (!hmem) return 0;
577 p = LockResource32(hmem);
578 string_num = resource_id & 0x000f;
579 for (i = 0; i < string_num; i++)
580 p += *p + 1;
582 dprintf_resource( stddeb, "strlen = %d\n", (int)*p );
584 i = MIN(buflen - 1, *p);
585 if (buffer == NULL)
586 return i;
587 if (i > 0) {
588 memcpy(buffer, p + 1, i * sizeof (WCHAR));
589 buffer[i] = (WCHAR) 0;
590 } else {
591 if (buflen > 1) {
592 buffer[0] = (WCHAR) 0;
593 return 0;
595 #if 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);
598 #endif
600 #if 0
601 dprintf_resource(stddeb,"LoadString // '%s' copied !\n", buffer);
602 #endif
603 return i;
606 /**********************************************************************
607 * LoadString32A (USER32.374)
609 INT32
610 LoadString32A(HINSTANCE32 instance,UINT32 resource_id,LPSTR buffer,int buflen)
612 INT32 retval;
613 LPWSTR buffer2 = NULL;
614 if (buffer) buffer2 = HeapAlloc( GetProcessHeap(), 0, buflen * 2 );
615 retval = LoadString32W(instance,resource_id,buffer2,buflen);
617 if (buffer)
619 lstrcpynWtoA( buffer, buffer2, buflen );
620 HeapFree( GetProcessHeap(), 0, buffer2 );
622 return retval;
625 /* Messages...used by FormatMessage32* (KERNEL32.something)
627 * They can be specified either directly or using a message ID and
628 * loading them from the resource.
630 * The resourcedata has following format:
631 * start:
632 * 0: DWORD nrofentries
633 * nrofentries * subentry:
634 * 0: DWORD firstentry
635 * 4: DWORD lastentry
636 * 8: DWORD offset from start to the stringentries
638 * (lastentry-firstentry) * stringentry:
639 * 0: WORD len (0 marks end)
640 * 2: WORD unknown (flags?)
641 * 4: CHAR[len-4]
642 * (stringentry i of a subentry refers to the ID 'firstentry+i')
644 * Yes, ANSI strings in win32 resources. Go figure.
647 /**********************************************************************
648 * LoadMessage32A (internal)
650 INT32
651 LoadMessage32A(
652 HINSTANCE32 instance,UINT32 id,WORD lang,LPSTR buffer,int buflen
654 HGLOBAL32 hmem;
655 HRSRC32 hrsrc;
656 BYTE *p;
657 int nrofentries,i,slen;
658 struct _subentry {
659 DWORD firstentry;
660 DWORD lastentry;
661 DWORD offset;
662 } *se;
663 struct _stringentry {
664 WORD len;
665 WORD unknown;
666 CHAR str[1];
667 } *stre;
669 dprintf_resource(stddeb, "LoadMessage: instance = %04x, id = %04x, buffer = %08x, "
670 "length = %d\n", instance, (int)id, (int) buffer, buflen);
672 /*FIXME: I am not sure about the '1' ... But I've only seen those entries*/
673 hrsrc = FindResourceEx32W(instance,(LPWSTR)1,(LPCWSTR)RT_MESSAGELIST,lang);
674 if (!hrsrc) return 0;
675 hmem = LoadResource32( instance, hrsrc );
676 if (!hmem) return 0;
678 p = LockResource32(hmem);
679 nrofentries = *(DWORD*)p;
680 stre = NULL;
681 se = (struct _subentry*)(p+4);
682 for (i=nrofentries;i--;) {
683 if ((id>=se->firstentry) && (id<=se->lastentry)) {
684 stre = (struct _stringentry*)(p+se->offset);
685 id -= se->firstentry;
686 break;
688 se++;
690 if (!stre)
691 return 0;
692 for (i=id;i--;) {
693 if (!(slen=stre->len))
694 return 0;
695 stre = (struct _stringentry*)(((char*)stre)+slen);
697 slen=stre->len;
698 dprintf_resource(stddeb," - strlen=%d\n",slen);
699 i = MIN(buflen - 1, slen);
700 if (buffer == NULL)
701 return slen; /* different to LoadString */
702 if (i>0) {
703 lstrcpyn32A(buffer,stre->str,i);
704 buffer[i]=0;
705 } else {
706 if (buflen>1) {
707 buffer[0]=0;
708 return 0;
711 if (buffer)
712 dprintf_resource(stddeb,"LoadMessage // '%s' copied !\n", buffer);
713 return i;
716 /**********************************************************************
717 * LoadMessage32W (internal)
719 INT32 LoadMessage32W( HINSTANCE32 instance, UINT32 id, WORD lang,
720 LPWSTR buffer, int buflen )
722 INT32 retval;
723 LPSTR buffer2 = NULL;
724 if (buffer) buffer2 = HeapAlloc( GetProcessHeap(), 0, buflen );
725 retval = LoadMessage32A(instance,id,lang,buffer2,buflen);
726 if (buffer)
728 lstrcpynAtoW( buffer, buffer2, buflen );
729 HeapFree( GetProcessHeap(), 0, buffer2 );
731 return retval;