4 * Copyright 1993 Robert J. Amstadt
5 * Copyright 1995 Alexandre Julliard
11 #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,type,name,WINE_LanguageId);
40 /**********************************************************************
41 * FindResourceEx32A (KERNEL32.129)
43 HANDLE32 WINAPI FindResourceEx32A( HMODULE32 hModule, LPCSTR type, LPCSTR name,
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, xtype, xname, 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 type,
68 LPCWSTR name, WORD lang )
70 WINE_MODREF *wm = MODULE32_LookupHMODULE(PROCESS_Current(),hModule);
73 TRACE(resource, "module=%08x(%s) type=%s name=%s\n",
78 if (!wm) return (HRSRC32)0;
83 hrsrc = PE_FindResourceEx32W(wm,name,type,lang);
87 hrsrc = LIBRES_FindResource( hModule, name, type );
91 ERR(module,"unknown module type %d\n",wm->type);
96 ERR(resource,"0x%08x(%s) %s(%s) not found!\n", hModule,wm->modname, debugres_w (name), debugres_w (type));
102 /**********************************************************************
103 * FindResource32W (KERNEL32.131)
105 HRSRC32 WINAPI FindResource32W(HINSTANCE32 hModule, LPCWSTR name, LPCWSTR type)
107 return FindResourceEx32W(hModule,type,name,WINE_LanguageId);
111 /**********************************************************************
112 * LoadResource32 (KERNEL32.370)
113 * 'loads' a resource. The current implementation just returns a pointer
114 * into the already mapped image.
116 * pointer into the mapped resource of the passed module
118 HGLOBAL32 WINAPI LoadResource32(
119 HINSTANCE32 hModule, /* [in] module handle */
120 HRSRC32 hRsrc ) /* [in] resource handle */
122 WINE_MODREF *wm = MODULE32_LookupHMODULE(PROCESS_Current(),hModule);
124 TRACE(resource, "module=%04x res=%04x\n",
127 ERR(resource,"hRsrc is 0, return 0.\n");
135 return PE_LoadResource32(wm,hRsrc);
138 return LIBRES_LoadResource( hModule, hRsrc );
141 ERR(resource,"unknown module type %d\n",wm->type);
148 /**********************************************************************
149 * LockResource32 (KERNEL32.384)
151 LPVOID WINAPI LockResource32( HGLOBAL32 handle )
153 return (LPVOID)handle;
157 /**********************************************************************
158 * FreeResource32 (KERNEL32.145)
160 BOOL32 WINAPI FreeResource32( HGLOBAL32 handle )
162 /* no longer used in Win32 */
167 /**********************************************************************
168 * AccessResource32 (KERNEL32.64)
170 INT32 WINAPI AccessResource32( HMODULE32 hModule, HRSRC32 hRsrc )
172 FIXME(resource,"(module=%08x res=%08x),not implemented\n", hModule, hRsrc);
177 /**********************************************************************
178 * SizeofResource32 (KERNEL32.522)
180 DWORD WINAPI SizeofResource32( HINSTANCE32 hModule, HRSRC32 hRsrc )
182 WINE_MODREF *wm = MODULE32_LookupHMODULE(PROCESS_Current(),hModule);
184 TRACE(resource, "module=%08x res=%08x\n", hModule, hRsrc );
190 return PE_SizeofResource32(hModule,hRsrc);
193 FIXME(module,"Not implemented for ELF modules\n");
197 ERR(module,"unknown module type %d\n",wm->type);
204 /**********************************************************************
205 * LoadAccelerators16 [USER.177]
207 HACCEL16 WINAPI LoadAccelerators16(HINSTANCE16 instance, SEGPTR lpTableName)
211 if (HIWORD(lpTableName))
212 TRACE(accel, "%04x '%s'\n",
213 instance, (char *)PTR_SEG_TO_LIN( lpTableName ) );
215 TRACE(accel, "%04x %04x\n",
216 instance, LOWORD(lpTableName) );
218 if (!(hRsrc = FindResource16( instance, lpTableName, RT_ACCELERATOR16 ))) {
219 WARN(accel, "couldn't find accelerator table resource\n");
223 TRACE(accel, "returning HACCEL 0x%x\n", hRsrc);
224 return LoadResource16(instance,hRsrc);
227 /**********************************************************************
228 * LoadAccelerators32W [USER.177]
229 * The image layout seems to look like this (not 100% sure):
230 * 00: BYTE type type of accelerator
231 * 01: BYTE pad (to WORD boundary)
234 * 06: WORD pad (to DWORD boundary)
236 HACCEL32 WINAPI LoadAccelerators32W(HINSTANCE32 instance,LPCWSTR lpTableName)
242 if (HIWORD(lpTableName))
243 TRACE(accel, "%p '%s'\n",
244 (LPVOID)instance, (char *)( lpTableName ) );
246 TRACE(accel, "%p 0x%04x\n",
247 (LPVOID)instance, LOWORD(lpTableName) );
249 if (!(hRsrc = FindResource32W( instance, lpTableName, RT_ACCELERATOR32W )))
251 WARN(accel, "couldn't find accelerator table resource\n");
255 hRetval = LoadResource32( instance, hRsrc );
256 size = SizeofResource32( instance, hRsrc );
257 if(size>=sizeof(ACCEL32))
259 LPACCEL32 accel_table = (LPACCEL32) hRetval;
260 /* mark last element as such - sometimes it is not marked in image */
261 accel_table[size/sizeof(ACCEL32)-1].fVirt |= 0x80;
265 TRACE(accel, "returning HACCEL 0x%x\n", hRsrc);
269 HACCEL32 WINAPI LoadAccelerators32A(HINSTANCE32 instance,LPCSTR lpTableName)
273 if (HIWORD(lpTableName))
274 uni = HEAP_strdupAtoW( GetProcessHeap(), 0, lpTableName );
276 uni = (LPWSTR)lpTableName;
277 result = LoadAccelerators32W(instance,uni);
278 if (HIWORD(uni)) HeapFree( GetProcessHeap(), 0, uni);
282 /**********************************************************************
283 * CopyAcceleratorTable32A (USER32.58)
285 INT32 WINAPI CopyAcceleratorTable32A(HACCEL32 src, LPACCEL32 dst, INT32 entries)
287 return CopyAcceleratorTable32W(src, dst, entries);
290 /**********************************************************************
291 * CopyAcceleratorTable32W (USER32.59)
293 * By mortene@pvv.org 980321
295 INT32 WINAPI CopyAcceleratorTable32W(HACCEL32 src, LPACCEL32 dst,
299 LPACCEL32 accel = (LPACCEL32)src;
302 /* Do parameter checking to avoid the explosions and the screaming
303 as far as possible. */
304 if((dst && (entries < 1)) || (src == (HACCEL32)NULL)) {
305 WARN(accel, "Application sent invalid parameters (%p %p %d).\n",
306 (LPVOID)src, (LPVOID)dst, entries);
313 /* Spit out some debugging information. */
314 TRACE(accel, "accel %d: type 0x%02x, event '%c', IDval 0x%04x.\n",
315 i, accel[i].fVirt, accel[i].key, accel[i].cmd);
317 /* Copy data to the destination structure array (if dst == NULL,
318 we're just supposed to count the number of entries). */
320 memcpy(&dst[i], &accel[i], sizeof(ACCEL32));
322 /* Check if we've reached the end of the application supplied
323 accelerator table. */
325 /* Turn off the high order bit, just in case. */
326 dst[i].fVirt &= 0x7f;
331 /* The highest order bit seems to mark the end of the accelerator
332 resource table. (?) */
333 if((accel[i].fVirt & 0x80) != 0) done = TRUE;
341 /*********************************************************************
342 * CreateAcceleratorTable (USER32.64)
344 * By mortene@pvv.org 980321
346 HACCEL32 WINAPI CreateAcceleratorTable32A(LPACCEL32 lpaccel, INT32 cEntries)
350 /* Do parameter checking just in case someone's trying to be
353 WARN(accel, "Application sent invalid parameters (%p %d).\n",
355 SetLastError(ERROR_INVALID_PARAMETER);
356 return (HACCEL32)NULL;
358 FIXME(accel, "should check that the accelerator descriptions are valid,"
359 " return NULL and SetLastError() if not.\n");
362 /* Allocate memory and copy the table. */
363 hAccel = (HACCEL32)HeapAlloc(GetProcessHeap(), 0,
364 cEntries * sizeof(ACCEL32));
365 TRACE(accel, "handle %p\n", (LPVOID)hAccel);
367 ERR(accel, "Out of memory.\n");
368 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
369 return (HACCEL32)NULL;
371 memcpy((LPACCEL32)hAccel, lpaccel, cEntries * sizeof(ACCEL32));
373 /* Set the end-of-table terminator. */
374 ((LPACCEL32)hAccel)[cEntries-1].fVirt |= 0x80;
376 TRACE(accel, "Allocated accelerator handle %x\n", hAccel);
381 /******************************************************************************
382 * DestroyAcceleratorTable [USER32.130]
383 * Destroys an accelerator table
386 * By mortene@pvv.org 980321
389 * handle [I] Handle to accelerator table
393 BOOL32 WINAPI DestroyAcceleratorTable( HACCEL32 handle )
395 FIXME(accel, "(0x%x): stub\n", handle);
398 /* Weird.. I thought this should work. According to the API
399 specification, DestroyAcceleratorTable() should only be called on
400 HACCEL32's made by CreateAcceleratorTable(), but Microsoft Visual
401 Studio 97 calls this function with a series of different handle
402 values without ever calling CreateAcceleratorTable(). Something
403 is very fishy in Denmark... */
404 /* Update: looks like the calls to this function matches the calls
405 to LoadAccelerators() in M$ Visual Studio, except that the handle
406 values are off by some variable size from the HACCEL's returned
407 from LoadAccelerators(). WTH? */
409 /* Parameter checking to avoid any embarassing situations. */
412 WARN(accel, "Application sent NULL ptr.\n");
413 SetLastError(ERROR_INVALID_PARAMETER);
417 HeapFree(GetProcessHeap(), 0, (LPACCEL32)handle);
423 /**********************************************************************
426 INT16 WINAPI LoadString16( HINSTANCE16 instance, UINT16 resource_id,
427 LPSTR buffer, INT16 buflen )
435 TRACE(resource,"inst=%04x id=%04x buff=%08x len=%d\n",
436 instance, resource_id, (int) buffer, buflen);
438 hrsrc = FindResource16( instance, (SEGPTR)((resource_id>>4)+1), RT_STRING16 );
439 if (!hrsrc) return 0;
440 hmem = LoadResource16( instance, hrsrc );
443 p = LockResource16(hmem);
444 string_num = resource_id & 0x000f;
445 for (i = 0; i < string_num; i++)
448 TRACE(resource, "strlen = %d\n", (int)*p );
450 i = MIN(buflen - 1, *p);
454 memcpy(buffer, p + 1, i);
461 WARN(resource,"Dont know why caller give buflen=%d *p=%d trying to obtain string '%s'\n", buflen, *p, p + 1);
463 FreeResource16( hmem );
465 TRACE(resource,"'%s' loaded !\n", buffer);
469 /**********************************************************************
470 * LoadString32W (USER32.376)
472 INT32 WINAPI LoadString32W( HINSTANCE32 instance, UINT32 resource_id,
473 LPWSTR buffer, INT32 buflen )
481 if (HIWORD(resource_id)==0xFFFF) /* netscape 3 passes this */
482 resource_id = (UINT32)(-((INT32)resource_id));
483 TRACE(resource, "instance = %04x, id = %04x, buffer = %08x, "
484 "length = %d\n", instance, (int)resource_id, (int) buffer, buflen);
486 hrsrc = FindResource32W( instance, (LPCWSTR)((resource_id>>4)+1),
488 if (!hrsrc) return 0;
489 hmem = LoadResource32( instance, hrsrc );
492 p = LockResource32(hmem);
493 string_num = resource_id & 0x000f;
494 for (i = 0; i < string_num; i++)
497 TRACE(resource, "strlen = %d\n", (int)*p );
499 i = MIN(buflen - 1, *p);
503 memcpy(buffer, p + 1, i * sizeof (WCHAR));
504 buffer[i] = (WCHAR) 0;
507 buffer[0] = (WCHAR) 0;
511 WARN(resource,"Dont know why caller give buflen=%d *p=%d trying to obtain string '%s'\n", buflen, *p, p + 1);
515 TRACE(resource,"%s loaded !\n", debugstr_w(buffer));
519 /**********************************************************************
520 * LoadString32A (USER32.375)
522 INT32 WINAPI LoadString32A( HINSTANCE32 instance, UINT32 resource_id,
523 LPSTR buffer, INT32 buflen )
526 LPWSTR buffer2 = NULL;
527 if (buffer && buflen)
528 buffer2 = HeapAlloc( GetProcessHeap(), 0, buflen * 2 );
529 retval = LoadString32W(instance,resource_id,buffer2,buflen);
534 lstrcpynWtoA( buffer, buffer2, buflen );
535 retval = lstrlen32A( buffer );
539 HeapFree( GetProcessHeap(), 0, buffer2 );
544 /* Messages...used by FormatMessage32* (KERNEL32.something)
546 * They can be specified either directly or using a message ID and
547 * loading them from the resource.
549 * The resourcedata has following format:
551 * 0: DWORD nrofentries
552 * nrofentries * subentry:
553 * 0: DWORD firstentry
555 * 8: DWORD offset from start to the stringentries
557 * (lastentry-firstentry) * stringentry:
558 * 0: WORD len (0 marks end)
559 * 2: WORD unknown (flags?)
561 * (stringentry i of a subentry refers to the ID 'firstentry+i')
563 * Yes, ANSI strings in win32 resources. Go figure.
566 /**********************************************************************
567 * LoadMessage32A (internal)
569 INT32 WINAPI LoadMessage32A( HMODULE32 instance, UINT32 id, WORD lang,
570 LPSTR buffer, INT32 buflen )
575 int nrofentries,i,slen;
581 struct _stringentry {
587 TRACE(resource, "instance = %08lx, id = %08lx, buffer = %p, length = %ld\n", (DWORD)instance, (DWORD)id, buffer, (DWORD)buflen);
589 /*FIXME: I am not sure about the '1' ... But I've only seen those entries*/
590 hrsrc = FindResourceEx32W(instance,RT_MESSAGELIST32W,(LPWSTR)1,lang);
591 if (!hrsrc) return 0;
592 hmem = LoadResource32( instance, hrsrc );
595 p = LockResource32(hmem);
596 nrofentries = *(DWORD*)p;
598 se = (struct _subentry*)(p+4);
599 for (i=nrofentries;i--;) {
600 if ((id>=se->firstentry) && (id<=se->lastentry)) {
601 stre = (struct _stringentry*)(p+se->offset);
602 id -= se->firstentry;
610 if (!(slen=stre->len))
612 stre = (struct _stringentry*)(((char*)stre)+slen);
615 TRACE(resource," - strlen=%d\n",slen);
616 i = MIN(buflen - 1, slen);
618 return slen; /* different to LoadString */
620 lstrcpyn32A(buffer,stre->str,i);
629 TRACE(resource,"'%s' copied !\n", buffer);
633 /**********************************************************************
634 * LoadMessage32W (internal)
636 INT32 WINAPI LoadMessage32W( HMODULE32 instance, UINT32 id, WORD lang,
637 LPWSTR buffer, INT32 buflen )
640 LPSTR buffer2 = NULL;
641 if (buffer && buflen)
642 buffer2 = HeapAlloc( GetProcessHeap(), 0, buflen );
643 retval = LoadMessage32A(instance,id,lang,buffer2,buflen);
647 lstrcpynAtoW( buffer, buffer2, buflen );
648 retval = lstrlen32W( buffer );
650 HeapFree( GetProcessHeap(), 0, buffer2 );
656 /**********************************************************************
657 * EnumResourceTypesA (KERNEL32.90)
659 BOOL32 WINAPI EnumResourceTypes32A( HMODULE32 hmodule,ENUMRESTYPEPROC32A lpfun,
662 /* FIXME: move WINE_MODREF stuff here */
663 return PE_EnumResourceTypes32A(hmodule,lpfun,lParam);
666 /**********************************************************************
667 * EnumResourceTypesW (KERNEL32.91)
669 BOOL32 WINAPI EnumResourceTypes32W( HMODULE32 hmodule,ENUMRESTYPEPROC32W lpfun,
672 /* FIXME: move WINE_MODREF stuff here */
673 return PE_EnumResourceTypes32W(hmodule,lpfun,lParam);
676 /**********************************************************************
677 * EnumResourceNamesA (KERNEL32.88)
679 BOOL32 WINAPI EnumResourceNames32A( HMODULE32 hmodule, LPCSTR type,
680 ENUMRESNAMEPROC32A lpfun, LONG lParam )
682 /* FIXME: move WINE_MODREF stuff here */
683 return PE_EnumResourceNames32A(hmodule,type,lpfun,lParam);
685 /**********************************************************************
686 * EnumResourceNamesW (KERNEL32.89)
688 BOOL32 WINAPI EnumResourceNames32W( HMODULE32 hmodule, LPCWSTR type,
689 ENUMRESNAMEPROC32W lpfun, LONG lParam )
691 /* FIXME: move WINE_MODREF stuff here */
692 return PE_EnumResourceNames32W(hmodule,type,lpfun,lParam);
695 /**********************************************************************
696 * EnumResourceLanguagesA (KERNEL32.86)
698 BOOL32 WINAPI EnumResourceLanguages32A( HMODULE32 hmodule, LPCSTR type,
699 LPCSTR name, ENUMRESLANGPROC32A lpfun,
702 /* FIXME: move WINE_MODREF stuff here */
703 return PE_EnumResourceLanguages32A(hmodule,type,name,lpfun,lParam);
705 /**********************************************************************
706 * EnumResourceLanguagesW (KERNEL32.87)
708 BOOL32 WINAPI EnumResourceLanguages32W( HMODULE32 hmodule, LPCWSTR type,
709 LPCWSTR name, ENUMRESLANGPROC32W lpfun,
712 /* FIXME: move WINE_MODREF stuff here */
713 return PE_EnumResourceLanguages32W(hmodule,type,name,lpfun,lParam);