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,name,type,WINE_LanguageId);
40 /**********************************************************************
41 * FindResourceEx32A (KERNEL32.129)
43 HANDLE32 WINAPI FindResourceEx32A( HMODULE32 hModule, LPCSTR name, LPCSTR type,
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, xname, xtype, 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 name,
68 LPCWSTR type, WORD lang )
70 WINE_MODREF *wm = MODULE32_LookupHMODULE(PROCESS_Current(),hModule);
73 TRACE(resource, "module=%08x type=%s name=%s\n",
79 hrsrc = LIBRES_FindResource( hModule, name, type );
86 return PE_FindResourceEx32W(wm,name,type,lang);
88 ERR(module,"unknown module type %d\n",wm->type);
96 /**********************************************************************
97 * FindResource32W (KERNEL32.131)
99 HRSRC32 WINAPI FindResource32W(HINSTANCE32 hModule, LPCWSTR name, LPCWSTR type)
101 return FindResourceEx32W(hModule,name,type,WINE_LanguageId);
105 /**********************************************************************
106 * LoadResource32 (KERNEL32.370)
107 * 'loads' a resource. The current implementation just returns a pointer
108 * into the already mapped image.
110 * pointer into the mapped resource of the passed module
112 HGLOBAL32 WINAPI LoadResource32(
113 HINSTANCE32 hModule, /* [in] module handle */
114 HRSRC32 hRsrc ) /* [in] resource handle */
116 WINE_MODREF *wm = MODULE32_LookupHMODULE(PROCESS_Current(),hModule);
118 TRACE(resource, "module=%04x res=%04x\n",
121 ERR(resource,"hRsrc is 0, return 0.\n");
127 return PE_LoadResource32(wm,hRsrc);
129 ERR(resource,"unknown module type %d\n",wm->type);
133 return LIBRES_LoadResource( hModule, hRsrc );
138 /**********************************************************************
139 * LockResource32 (KERNEL32.384)
141 LPVOID WINAPI LockResource32( HGLOBAL32 handle )
143 return (LPVOID)handle;
147 /**********************************************************************
148 * FreeResource32 (KERNEL32.145)
150 BOOL32 WINAPI FreeResource32( HGLOBAL32 handle )
152 /* no longer used in Win32 */
157 /**********************************************************************
158 * AccessResource32 (KERNEL32.64)
160 INT32 WINAPI AccessResource32( HMODULE32 hModule, HRSRC32 hRsrc )
162 FIXME(resource,"(module=%08x res=%08x),not implemented\n", hModule, hRsrc);
167 /**********************************************************************
168 * SizeofResource32 (KERNEL32.522)
170 DWORD WINAPI SizeofResource32( HINSTANCE32 hModule, HRSRC32 hRsrc )
172 WINE_MODREF *wm = MODULE32_LookupHMODULE(PROCESS_Current(),hModule);
174 TRACE(resource, "module=%08x res=%08x\n", hModule, hRsrc );
181 ret = PE_SizeofResource32(hModule,hRsrc);
187 ERR(module,"unknown module type %d\n",wm->type);
191 FIXME(module,"Not implemented for WINELIB\n");
196 /**********************************************************************
197 * LoadAccelerators16 [USER.177]
199 HACCEL16 WINAPI LoadAccelerators16(HINSTANCE16 instance, SEGPTR lpTableName)
203 if (HIWORD(lpTableName))
204 TRACE(accel, "%04x '%s'\n",
205 instance, (char *)PTR_SEG_TO_LIN( lpTableName ) );
207 TRACE(accel, "%04x %04x\n",
208 instance, LOWORD(lpTableName) );
210 if (!(hRsrc = FindResource16( instance, lpTableName, RT_ACCELERATOR16 ))) {
211 WARN(accel, "couldn't find accelerator table resource\n");
215 TRACE(accel, "returning HACCEL 0x%x\n", hRsrc);
216 return LoadResource16(instance,hRsrc);
219 /**********************************************************************
220 * LoadAccelerators32W [USER.177]
221 * The image layout seems to look like this (not 100% sure):
222 * 00: BYTE type type of accelerator
223 * 01: BYTE pad (to WORD boundary)
226 * 06: WORD pad (to DWORD boundary)
228 HACCEL32 WINAPI LoadAccelerators32W(HINSTANCE32 instance,LPCWSTR lpTableName)
233 if (HIWORD(lpTableName))
234 TRACE(accel, "%p '%s'\n",
235 (LPVOID)instance, (char *)( lpTableName ) );
237 TRACE(accel, "%p 0x%04x\n",
238 (LPVOID)instance, LOWORD(lpTableName) );
240 if (!(hRsrc = FindResource32W( instance, lpTableName, RT_ACCELERATOR32W )))
242 WARN(accel, "couldn't find accelerator table resource\n");
246 hRetval = LoadResource32( instance, hRsrc );
249 TRACE(accel, "returning HACCEL 0x%x\n", hRsrc);
253 HACCEL32 WINAPI LoadAccelerators32A(HINSTANCE32 instance,LPCSTR lpTableName)
257 if (HIWORD(lpTableName))
258 uni = HEAP_strdupAtoW( GetProcessHeap(), 0, lpTableName );
260 uni = (LPWSTR)lpTableName;
261 result = LoadAccelerators32W(instance,uni);
262 if (HIWORD(uni)) HeapFree( GetProcessHeap(), 0, uni);
266 /**********************************************************************
267 * CopyAcceleratorTable32A (USER32.58)
269 INT32 WINAPI CopyAcceleratorTable32A(HACCEL32 src, LPACCEL32 dst, INT32 entries)
271 return CopyAcceleratorTable32W(src, dst, entries);
274 /**********************************************************************
275 * CopyAcceleratorTable32W (USER32.59)
277 * By mortene@pvv.org 980321
279 INT32 WINAPI CopyAcceleratorTable32W(HACCEL32 src, LPACCEL32 dst,
283 LPACCEL32 accel = (LPACCEL32)src;
286 /* Do parameter checking to avoid the explosions and the screaming
287 as far as possible. */
288 if((dst && (entries < 1)) || (src == (HACCEL32)NULL)) {
289 WARN(accel, "Application sent invalid parameters (%p %p %d).\n",
290 (LPVOID)src, (LPVOID)dst, entries);
297 /* Spit out some debugging information. */
298 TRACE(accel, "accel %d: type 0x%02x, event '%c', IDval 0x%04x.\n",
299 i, accel[i].fVirt, accel[i].key, accel[i].cmd);
301 /* Copy data to the destination structure array (if dst == NULL,
302 we're just supposed to count the number of entries). */
304 memcpy(&dst[i], &accel[i], sizeof(ACCEL32));
306 /* Check if we've reached the end of the application supplied
307 accelerator table. */
309 /* Turn off the high order bit, just in case. */
310 dst[i].fVirt &= 0x7f;
315 /* The highest order bit seems to mark the end of the accelerator
316 resource table. (?) */
317 if((accel[i].fVirt & 0x80) != 0) done = TRUE;
325 /*********************************************************************
326 * CreateAcceleratorTable (USER32.64)
328 * By mortene@pvv.org 980321
330 HACCEL32 WINAPI CreateAcceleratorTable32A(LPACCEL32 lpaccel, INT32 cEntries)
334 /* Do parameter checking just in case someone's trying to be
337 WARN(accel, "Application sent invalid parameters (%p %d).\n",
339 SetLastError(ERROR_INVALID_PARAMETER);
340 return (HACCEL32)NULL;
342 FIXME(accel, "should check that the accelerator descriptions are valid,"
343 " return NULL and SetLastError() if not.\n");
346 /* Allocate memory and copy the table. */
347 hAccel = (HACCEL32)HeapAlloc(GetProcessHeap(), 0,
348 cEntries * sizeof(ACCEL32));
349 TRACE(accel, "handle %p\n", (LPVOID)hAccel);
351 ERR(accel, "Out of memory.\n");
352 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
353 return (HACCEL32)NULL;
355 memcpy((LPACCEL32)hAccel, lpaccel, cEntries * sizeof(ACCEL32));
357 /* Set the end-of-table terminator. */
358 ((LPACCEL32)hAccel)[cEntries-1].fVirt |= 0x80;
360 TRACE(accel, "Allocated accelerator handle %x\n", hAccel);
365 /******************************************************************************
366 * DestroyAcceleratorTable [USER32.130]
367 * Destroys an accelerator table
370 * By mortene@pvv.org 980321
373 * handle [I] Handle to accelerator table
377 BOOL32 WINAPI DestroyAcceleratorTable( HACCEL32 handle )
379 FIXME(accel, "(0x%x): stub\n", handle);
382 /* Weird.. I thought this should work. According to the API
383 specification, DestroyAcceleratorTable() should only be called on
384 HACCEL32's made by CreateAcceleratorTable(), but Microsoft Visual
385 Studio 97 calls this function with a series of different handle
386 values without ever calling CreateAcceleratorTable(). Something
387 is very fishy in Denmark... */
388 /* Update: looks like the calls to this function matches the calls
389 to LoadAccelerators() in M$ Visual Studio, except that the handle
390 values are off by some variable size from the HACCEL's returned
391 from LoadAccelerators(). WTH? */
393 /* Parameter checking to avoid any embarassing situations. */
396 WARN(accel, "Application sent NULL ptr.\n");
397 SetLastError(ERROR_INVALID_PARAMETER);
401 HeapFree(GetProcessHeap(), 0, (LPACCEL32)handle);
407 /**********************************************************************
410 INT16 WINAPI LoadString16( HINSTANCE16 instance, UINT16 resource_id,
411 LPSTR buffer, INT16 buflen )
419 TRACE(resource,"inst=%04x id=%04x buff=%08x len=%d\n",
420 instance, resource_id, (int) buffer, buflen);
422 hrsrc = FindResource16( instance, (SEGPTR)((resource_id>>4)+1), RT_STRING16 );
423 if (!hrsrc) return 0;
424 hmem = LoadResource16( instance, hrsrc );
427 p = LockResource16(hmem);
428 string_num = resource_id & 0x000f;
429 for (i = 0; i < string_num; i++)
432 TRACE(resource, "strlen = %d\n", (int)*p );
434 i = MIN(buflen - 1, *p);
438 memcpy(buffer, p + 1, i);
445 WARN(resource,"Dont know why caller give buflen=%d *p=%d trying to obtain string '%s'\n", buflen, *p, p + 1);
447 FreeResource16( hmem );
449 TRACE(resource,"'%s' copied !\n", buffer);
453 /**********************************************************************
454 * LoadString32W (USER32.376)
456 INT32 WINAPI LoadString32W( HINSTANCE32 instance, UINT32 resource_id,
457 LPWSTR buffer, INT32 buflen )
465 if (HIWORD(resource_id)==0xFFFF) /* netscape 3 passes this */
466 resource_id = (UINT32)(-((INT32)resource_id));
467 TRACE(resource, "instance = %04x, id = %04x, buffer = %08x, "
468 "length = %d\n", instance, (int)resource_id, (int) buffer, buflen);
470 hrsrc = FindResource32W( instance, (LPCWSTR)((resource_id>>4)+1),
472 if (!hrsrc) return 0;
473 hmem = LoadResource32( instance, hrsrc );
476 p = LockResource32(hmem);
477 string_num = resource_id & 0x000f;
478 for (i = 0; i < string_num; i++)
481 TRACE(resource, "strlen = %d\n", (int)*p );
483 i = MIN(buflen - 1, *p);
487 memcpy(buffer, p + 1, i * sizeof (WCHAR));
488 buffer[i] = (WCHAR) 0;
491 buffer[0] = (WCHAR) 0;
495 WARN(resource,"Dont know why caller give buflen=%d *p=%d trying to obtain string '%s'\n", buflen, *p, p + 1);
499 TRACE(resource,"'%s' copied !\n", (char *)buffer);
503 /**********************************************************************
504 * LoadString32A (USER32.375)
506 INT32 WINAPI LoadString32A( HINSTANCE32 instance, UINT32 resource_id,
507 LPSTR buffer, INT32 buflen )
510 LPWSTR buffer2 = NULL;
511 if (buffer && buflen)
512 buffer2 = HeapAlloc( GetProcessHeap(), 0, buflen * 2 );
513 retval = LoadString32W(instance,resource_id,buffer2,buflen);
518 lstrcpynWtoA( buffer, buffer2, buflen );
519 retval = lstrlen32A( buffer );
523 HeapFree( GetProcessHeap(), 0, buffer2 );
528 /* Messages...used by FormatMessage32* (KERNEL32.something)
530 * They can be specified either directly or using a message ID and
531 * loading them from the resource.
533 * The resourcedata has following format:
535 * 0: DWORD nrofentries
536 * nrofentries * subentry:
537 * 0: DWORD firstentry
539 * 8: DWORD offset from start to the stringentries
541 * (lastentry-firstentry) * stringentry:
542 * 0: WORD len (0 marks end)
543 * 2: WORD unknown (flags?)
545 * (stringentry i of a subentry refers to the ID 'firstentry+i')
547 * Yes, ANSI strings in win32 resources. Go figure.
550 /**********************************************************************
551 * LoadMessage32A (internal)
553 INT32 LoadMessage32A( HMODULE32 instance, UINT32 id, WORD lang,
554 LPSTR buffer, INT32 buflen )
559 int nrofentries,i,slen;
565 struct _stringentry {
571 TRACE(resource, "instance = %08lx, id = %08lx, buffer = %p, length = %ld\n", (DWORD)instance, (DWORD)id, buffer, (DWORD)buflen);
573 /*FIXME: I am not sure about the '1' ... But I've only seen those entries*/
574 hrsrc = FindResourceEx32W(instance,(LPWSTR)1,RT_MESSAGELIST32W,lang);
575 if (!hrsrc) return 0;
576 hmem = LoadResource32( instance, hrsrc );
579 p = LockResource32(hmem);
580 nrofentries = *(DWORD*)p;
582 se = (struct _subentry*)(p+4);
583 for (i=nrofentries;i--;) {
584 if ((id>=se->firstentry) && (id<=se->lastentry)) {
585 stre = (struct _stringentry*)(p+se->offset);
586 id -= se->firstentry;
594 if (!(slen=stre->len))
596 stre = (struct _stringentry*)(((char*)stre)+slen);
599 TRACE(resource," - strlen=%d\n",slen);
600 i = MIN(buflen - 1, slen);
602 return slen; /* different to LoadString */
604 lstrcpyn32A(buffer,stre->str,i);
613 TRACE(resource,"'%s' copied !\n", buffer);
617 /**********************************************************************
618 * LoadMessage32W (internal)
620 INT32 LoadMessage32W( HMODULE32 instance, UINT32 id, WORD lang,
621 LPWSTR buffer, INT32 buflen )
624 LPSTR buffer2 = NULL;
625 if (buffer && buflen)
626 buffer2 = HeapAlloc( GetProcessHeap(), 0, buflen );
627 retval = LoadMessage32A(instance,id,lang,buffer2,buflen);
631 lstrcpynAtoW( buffer, buffer2, buflen );
632 retval = lstrlen32W( buffer );
634 HeapFree( GetProcessHeap(), 0, buffer2 );
640 /**********************************************************************
641 * EnumResourceTypesA (KERNEL32.90)
643 BOOL32 WINAPI EnumResourceTypes32A( HMODULE32 hmodule,ENUMRESTYPEPROC32A lpfun,
646 /* FIXME: move WINE_MODREF stuff here */
647 return PE_EnumResourceTypes32A(hmodule,lpfun,lParam);
650 /**********************************************************************
651 * EnumResourceTypesW (KERNEL32.91)
653 BOOL32 WINAPI EnumResourceTypes32W( HMODULE32 hmodule,ENUMRESTYPEPROC32W lpfun,
656 /* FIXME: move WINE_MODREF stuff here */
657 return PE_EnumResourceTypes32W(hmodule,lpfun,lParam);
660 /**********************************************************************
661 * EnumResourceNamesA (KERNEL32.88)
663 BOOL32 WINAPI EnumResourceNames32A( HMODULE32 hmodule, LPCSTR type,
664 ENUMRESNAMEPROC32A lpfun, LONG lParam )
666 /* FIXME: move WINE_MODREF stuff here */
667 return PE_EnumResourceNames32A(hmodule,type,lpfun,lParam);
669 /**********************************************************************
670 * EnumResourceNamesW (KERNEL32.89)
672 BOOL32 WINAPI EnumResourceNames32W( HMODULE32 hmodule, LPCWSTR type,
673 ENUMRESNAMEPROC32W lpfun, LONG lParam )
675 /* FIXME: move WINE_MODREF stuff here */
676 return PE_EnumResourceNames32W(hmodule,type,lpfun,lParam);
679 /**********************************************************************
680 * EnumResourceLanguagesA (KERNEL32.86)
682 BOOL32 WINAPI EnumResourceLanguages32A( HMODULE32 hmodule, LPCSTR type,
683 LPCSTR name, ENUMRESLANGPROC32A lpfun,
686 /* FIXME: move WINE_MODREF stuff here */
687 return PE_EnumResourceLanguages32A(hmodule,type,name,lpfun,lParam);
689 /**********************************************************************
690 * EnumResourceLanguagesW (KERNEL32.87)
692 BOOL32 WINAPI EnumResourceLanguages32W( HMODULE32 hmodule, LPCWSTR type,
693 LPCWSTR name, ENUMRESLANGPROC32W lpfun,
696 /* FIXME: move WINE_MODREF stuff here */
697 return PE_EnumResourceLanguages32W(hmodule,type,name,lpfun,lParam);