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 ret = PE_FindResourceEx32W(wm,name,type,lang);
88 ERR(resource,"%s not found!\n",debugres_w (name));
91 ERR(module,"unknown module type %d\n",wm->type);
99 /**********************************************************************
100 * FindResource32W (KERNEL32.131)
102 HRSRC32 WINAPI FindResource32W(HINSTANCE32 hModule, LPCWSTR name, LPCWSTR type)
104 return FindResourceEx32W(hModule,name,type,WINE_LanguageId);
108 /**********************************************************************
109 * LoadResource32 (KERNEL32.370)
110 * 'loads' a resource. The current implementation just returns a pointer
111 * into the already mapped image.
113 * pointer into the mapped resource of the passed module
115 HGLOBAL32 WINAPI LoadResource32(
116 HINSTANCE32 hModule, /* [in] module handle */
117 HRSRC32 hRsrc ) /* [in] resource handle */
119 WINE_MODREF *wm = MODULE32_LookupHMODULE(PROCESS_Current(),hModule);
121 TRACE(resource, "module=%04x res=%04x\n",
124 ERR(resource,"hRsrc is 0, return 0.\n");
130 return PE_LoadResource32(wm,hRsrc);
132 ERR(resource,"unknown module type %d\n",wm->type);
136 return LIBRES_LoadResource( hModule, hRsrc );
141 /**********************************************************************
142 * LockResource32 (KERNEL32.384)
144 LPVOID WINAPI LockResource32( HGLOBAL32 handle )
146 return (LPVOID)handle;
150 /**********************************************************************
151 * FreeResource32 (KERNEL32.145)
153 BOOL32 WINAPI FreeResource32( HGLOBAL32 handle )
155 /* no longer used in Win32 */
160 /**********************************************************************
161 * AccessResource32 (KERNEL32.64)
163 INT32 WINAPI AccessResource32( HMODULE32 hModule, HRSRC32 hRsrc )
165 FIXME(resource,"(module=%08x res=%08x),not implemented\n", hModule, hRsrc);
170 /**********************************************************************
171 * SizeofResource32 (KERNEL32.522)
173 DWORD WINAPI SizeofResource32( HINSTANCE32 hModule, HRSRC32 hRsrc )
175 WINE_MODREF *wm = MODULE32_LookupHMODULE(PROCESS_Current(),hModule);
177 TRACE(resource, "module=%08x res=%08x\n", hModule, hRsrc );
184 ret = PE_SizeofResource32(hModule,hRsrc);
190 ERR(module,"unknown module type %d\n",wm->type);
194 FIXME(module,"Not implemented for WINELIB\n");
199 /**********************************************************************
200 * LoadAccelerators16 [USER.177]
202 HACCEL16 WINAPI LoadAccelerators16(HINSTANCE16 instance, SEGPTR lpTableName)
206 if (HIWORD(lpTableName))
207 TRACE(accel, "%04x '%s'\n",
208 instance, (char *)PTR_SEG_TO_LIN( lpTableName ) );
210 TRACE(accel, "%04x %04x\n",
211 instance, LOWORD(lpTableName) );
213 if (!(hRsrc = FindResource16( instance, lpTableName, RT_ACCELERATOR16 ))) {
214 WARN(accel, "couldn't find accelerator table resource\n");
218 TRACE(accel, "returning HACCEL 0x%x\n", hRsrc);
219 return LoadResource16(instance,hRsrc);
222 /**********************************************************************
223 * LoadAccelerators32W [USER.177]
224 * The image layout seems to look like this (not 100% sure):
225 * 00: BYTE type type of accelerator
226 * 01: BYTE pad (to WORD boundary)
229 * 06: WORD pad (to DWORD boundary)
231 HACCEL32 WINAPI LoadAccelerators32W(HINSTANCE32 instance,LPCWSTR lpTableName)
237 if (HIWORD(lpTableName))
238 TRACE(accel, "%p '%s'\n",
239 (LPVOID)instance, (char *)( lpTableName ) );
241 TRACE(accel, "%p 0x%04x\n",
242 (LPVOID)instance, LOWORD(lpTableName) );
244 if (!(hRsrc = FindResource32W( instance, lpTableName, RT_ACCELERATOR32W )))
246 WARN(accel, "couldn't find accelerator table resource\n");
250 hRetval = LoadResource32( instance, hRsrc );
251 size = SizeofResource32( instance, hRsrc );
252 if(size>=sizeof(ACCEL32))
254 LPACCEL32 accel_table = (LPACCEL32) hRetval;
255 /* mark last element as such - sometimes it is not marked in image */
256 accel_table[size/sizeof(ACCEL32)-1].fVirt |= 0x80;
260 TRACE(accel, "returning HACCEL 0x%x\n", hRsrc);
264 HACCEL32 WINAPI LoadAccelerators32A(HINSTANCE32 instance,LPCSTR lpTableName)
268 if (HIWORD(lpTableName))
269 uni = HEAP_strdupAtoW( GetProcessHeap(), 0, lpTableName );
271 uni = (LPWSTR)lpTableName;
272 result = LoadAccelerators32W(instance,uni);
273 if (HIWORD(uni)) HeapFree( GetProcessHeap(), 0, uni);
277 /**********************************************************************
278 * CopyAcceleratorTable32A (USER32.58)
280 INT32 WINAPI CopyAcceleratorTable32A(HACCEL32 src, LPACCEL32 dst, INT32 entries)
282 return CopyAcceleratorTable32W(src, dst, entries);
285 /**********************************************************************
286 * CopyAcceleratorTable32W (USER32.59)
288 * By mortene@pvv.org 980321
290 INT32 WINAPI CopyAcceleratorTable32W(HACCEL32 src, LPACCEL32 dst,
294 LPACCEL32 accel = (LPACCEL32)src;
297 /* Do parameter checking to avoid the explosions and the screaming
298 as far as possible. */
299 if((dst && (entries < 1)) || (src == (HACCEL32)NULL)) {
300 WARN(accel, "Application sent invalid parameters (%p %p %d).\n",
301 (LPVOID)src, (LPVOID)dst, entries);
308 /* Spit out some debugging information. */
309 TRACE(accel, "accel %d: type 0x%02x, event '%c', IDval 0x%04x.\n",
310 i, accel[i].fVirt, accel[i].key, accel[i].cmd);
312 /* Copy data to the destination structure array (if dst == NULL,
313 we're just supposed to count the number of entries). */
315 memcpy(&dst[i], &accel[i], sizeof(ACCEL32));
317 /* Check if we've reached the end of the application supplied
318 accelerator table. */
320 /* Turn off the high order bit, just in case. */
321 dst[i].fVirt &= 0x7f;
326 /* The highest order bit seems to mark the end of the accelerator
327 resource table. (?) */
328 if((accel[i].fVirt & 0x80) != 0) done = TRUE;
336 /*********************************************************************
337 * CreateAcceleratorTable (USER32.64)
339 * By mortene@pvv.org 980321
341 HACCEL32 WINAPI CreateAcceleratorTable32A(LPACCEL32 lpaccel, INT32 cEntries)
345 /* Do parameter checking just in case someone's trying to be
348 WARN(accel, "Application sent invalid parameters (%p %d).\n",
350 SetLastError(ERROR_INVALID_PARAMETER);
351 return (HACCEL32)NULL;
353 FIXME(accel, "should check that the accelerator descriptions are valid,"
354 " return NULL and SetLastError() if not.\n");
357 /* Allocate memory and copy the table. */
358 hAccel = (HACCEL32)HeapAlloc(GetProcessHeap(), 0,
359 cEntries * sizeof(ACCEL32));
360 TRACE(accel, "handle %p\n", (LPVOID)hAccel);
362 ERR(accel, "Out of memory.\n");
363 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
364 return (HACCEL32)NULL;
366 memcpy((LPACCEL32)hAccel, lpaccel, cEntries * sizeof(ACCEL32));
368 /* Set the end-of-table terminator. */
369 ((LPACCEL32)hAccel)[cEntries-1].fVirt |= 0x80;
371 TRACE(accel, "Allocated accelerator handle %x\n", hAccel);
376 /******************************************************************************
377 * DestroyAcceleratorTable [USER32.130]
378 * Destroys an accelerator table
381 * By mortene@pvv.org 980321
384 * handle [I] Handle to accelerator table
388 BOOL32 WINAPI DestroyAcceleratorTable( HACCEL32 handle )
390 FIXME(accel, "(0x%x): stub\n", handle);
393 /* Weird.. I thought this should work. According to the API
394 specification, DestroyAcceleratorTable() should only be called on
395 HACCEL32's made by CreateAcceleratorTable(), but Microsoft Visual
396 Studio 97 calls this function with a series of different handle
397 values without ever calling CreateAcceleratorTable(). Something
398 is very fishy in Denmark... */
399 /* Update: looks like the calls to this function matches the calls
400 to LoadAccelerators() in M$ Visual Studio, except that the handle
401 values are off by some variable size from the HACCEL's returned
402 from LoadAccelerators(). WTH? */
404 /* Parameter checking to avoid any embarassing situations. */
407 WARN(accel, "Application sent NULL ptr.\n");
408 SetLastError(ERROR_INVALID_PARAMETER);
412 HeapFree(GetProcessHeap(), 0, (LPACCEL32)handle);
418 /**********************************************************************
421 INT16 WINAPI LoadString16( HINSTANCE16 instance, UINT16 resource_id,
422 LPSTR buffer, INT16 buflen )
430 TRACE(resource,"inst=%04x id=%04x buff=%08x len=%d\n",
431 instance, resource_id, (int) buffer, buflen);
433 hrsrc = FindResource16( instance, (SEGPTR)((resource_id>>4)+1), RT_STRING16 );
434 if (!hrsrc) return 0;
435 hmem = LoadResource16( instance, hrsrc );
438 p = LockResource16(hmem);
439 string_num = resource_id & 0x000f;
440 for (i = 0; i < string_num; i++)
443 TRACE(resource, "strlen = %d\n", (int)*p );
445 i = MIN(buflen - 1, *p);
449 memcpy(buffer, p + 1, i);
456 WARN(resource,"Dont know why caller give buflen=%d *p=%d trying to obtain string '%s'\n", buflen, *p, p + 1);
458 FreeResource16( hmem );
460 TRACE(resource,"'%s' copied !\n", buffer);
464 /**********************************************************************
465 * LoadString32W (USER32.376)
467 INT32 WINAPI LoadString32W( HINSTANCE32 instance, UINT32 resource_id,
468 LPWSTR buffer, INT32 buflen )
476 if (HIWORD(resource_id)==0xFFFF) /* netscape 3 passes this */
477 resource_id = (UINT32)(-((INT32)resource_id));
478 TRACE(resource, "instance = %04x, id = %04x, buffer = %08x, "
479 "length = %d\n", instance, (int)resource_id, (int) buffer, buflen);
481 hrsrc = FindResource32W( instance, (LPCWSTR)((resource_id>>4)+1),
483 if (!hrsrc) return 0;
484 hmem = LoadResource32( instance, hrsrc );
487 p = LockResource32(hmem);
488 string_num = resource_id & 0x000f;
489 for (i = 0; i < string_num; i++)
492 TRACE(resource, "strlen = %d\n", (int)*p );
494 i = MIN(buflen - 1, *p);
498 memcpy(buffer, p + 1, i * sizeof (WCHAR));
499 buffer[i] = (WCHAR) 0;
502 buffer[0] = (WCHAR) 0;
506 WARN(resource,"Dont know why caller give buflen=%d *p=%d trying to obtain string '%s'\n", buflen, *p, p + 1);
510 TRACE(resource,"'%s' copied !\n", (char *)buffer);
514 /**********************************************************************
515 * LoadString32A (USER32.375)
517 INT32 WINAPI LoadString32A( HINSTANCE32 instance, UINT32 resource_id,
518 LPSTR buffer, INT32 buflen )
521 LPWSTR buffer2 = NULL;
522 if (buffer && buflen)
523 buffer2 = HeapAlloc( GetProcessHeap(), 0, buflen * 2 );
524 retval = LoadString32W(instance,resource_id,buffer2,buflen);
529 lstrcpynWtoA( buffer, buffer2, buflen );
530 retval = lstrlen32A( buffer );
534 HeapFree( GetProcessHeap(), 0, buffer2 );
539 /* Messages...used by FormatMessage32* (KERNEL32.something)
541 * They can be specified either directly or using a message ID and
542 * loading them from the resource.
544 * The resourcedata has following format:
546 * 0: DWORD nrofentries
547 * nrofentries * subentry:
548 * 0: DWORD firstentry
550 * 8: DWORD offset from start to the stringentries
552 * (lastentry-firstentry) * stringentry:
553 * 0: WORD len (0 marks end)
554 * 2: WORD unknown (flags?)
556 * (stringentry i of a subentry refers to the ID 'firstentry+i')
558 * Yes, ANSI strings in win32 resources. Go figure.
561 /**********************************************************************
562 * LoadMessage32A (internal)
564 INT32 WINAPI LoadMessage32A( HMODULE32 instance, UINT32 id, WORD lang,
565 LPSTR buffer, INT32 buflen )
570 int nrofentries,i,slen;
576 struct _stringentry {
582 TRACE(resource, "instance = %08lx, id = %08lx, buffer = %p, length = %ld\n", (DWORD)instance, (DWORD)id, buffer, (DWORD)buflen);
584 /*FIXME: I am not sure about the '1' ... But I've only seen those entries*/
585 hrsrc = FindResourceEx32W(instance,(LPWSTR)1,RT_MESSAGELIST32W,lang);
586 if (!hrsrc) return 0;
587 hmem = LoadResource32( instance, hrsrc );
590 p = LockResource32(hmem);
591 nrofentries = *(DWORD*)p;
593 se = (struct _subentry*)(p+4);
594 for (i=nrofentries;i--;) {
595 if ((id>=se->firstentry) && (id<=se->lastentry)) {
596 stre = (struct _stringentry*)(p+se->offset);
597 id -= se->firstentry;
605 if (!(slen=stre->len))
607 stre = (struct _stringentry*)(((char*)stre)+slen);
610 TRACE(resource," - strlen=%d\n",slen);
611 i = MIN(buflen - 1, slen);
613 return slen; /* different to LoadString */
615 lstrcpyn32A(buffer,stre->str,i);
624 TRACE(resource,"'%s' copied !\n", buffer);
628 /**********************************************************************
629 * LoadMessage32W (internal)
631 INT32 WINAPI LoadMessage32W( HMODULE32 instance, UINT32 id, WORD lang,
632 LPWSTR buffer, INT32 buflen )
635 LPSTR buffer2 = NULL;
636 if (buffer && buflen)
637 buffer2 = HeapAlloc( GetProcessHeap(), 0, buflen );
638 retval = LoadMessage32A(instance,id,lang,buffer2,buflen);
642 lstrcpynAtoW( buffer, buffer2, buflen );
643 retval = lstrlen32W( buffer );
645 HeapFree( GetProcessHeap(), 0, buffer2 );
651 /**********************************************************************
652 * EnumResourceTypesA (KERNEL32.90)
654 BOOL32 WINAPI EnumResourceTypes32A( HMODULE32 hmodule,ENUMRESTYPEPROC32A lpfun,
657 /* FIXME: move WINE_MODREF stuff here */
658 return PE_EnumResourceTypes32A(hmodule,lpfun,lParam);
661 /**********************************************************************
662 * EnumResourceTypesW (KERNEL32.91)
664 BOOL32 WINAPI EnumResourceTypes32W( HMODULE32 hmodule,ENUMRESTYPEPROC32W lpfun,
667 /* FIXME: move WINE_MODREF stuff here */
668 return PE_EnumResourceTypes32W(hmodule,lpfun,lParam);
671 /**********************************************************************
672 * EnumResourceNamesA (KERNEL32.88)
674 BOOL32 WINAPI EnumResourceNames32A( HMODULE32 hmodule, LPCSTR type,
675 ENUMRESNAMEPROC32A lpfun, LONG lParam )
677 /* FIXME: move WINE_MODREF stuff here */
678 return PE_EnumResourceNames32A(hmodule,type,lpfun,lParam);
680 /**********************************************************************
681 * EnumResourceNamesW (KERNEL32.89)
683 BOOL32 WINAPI EnumResourceNames32W( HMODULE32 hmodule, LPCWSTR type,
684 ENUMRESNAMEPROC32W lpfun, LONG lParam )
686 /* FIXME: move WINE_MODREF stuff here */
687 return PE_EnumResourceNames32W(hmodule,type,lpfun,lParam);
690 /**********************************************************************
691 * EnumResourceLanguagesA (KERNEL32.86)
693 BOOL32 WINAPI EnumResourceLanguages32A( HMODULE32 hmodule, LPCSTR type,
694 LPCSTR name, ENUMRESLANGPROC32A lpfun,
697 /* FIXME: move WINE_MODREF stuff here */
698 return PE_EnumResourceLanguages32A(hmodule,type,name,lpfun,lParam);
700 /**********************************************************************
701 * EnumResourceLanguagesW (KERNEL32.87)
703 BOOL32 WINAPI EnumResourceLanguages32W( HMODULE32 hmodule, LPCWSTR type,
704 LPCWSTR name, ENUMRESLANGPROC32W lpfun,
707 /* FIXME: move WINE_MODREF stuff here */
708 return PE_EnumResourceLanguages32W(hmodule,type,name,lpfun,lParam);