4 * Copyright 1993 Robert J. Amstadt
5 * Copyright 1995 Alexandre Julliard
11 #include <sys/types.h>
19 #include "wine/winbase16.h"
20 #include "wine/winuser16.h"
21 #include "wine/exception.h"
26 #include "cursoricon.h"
32 #include "debugtools.h"
36 DEFAULT_DEBUG_CHANNEL(resource
);
37 DECLARE_DEBUG_CHANNEL(accel
);
39 #define HRSRC_MAP_BLOCKSIZE 16
41 typedef struct _HRSRC_ELEM
47 typedef struct _HRSRC_MAP
54 /**********************************************************************
57 static HRSRC16
MapHRsrc32To16( NE_MODULE
*pModule
, HANDLE hRsrc32
, WORD type
)
59 HRSRC_MAP
*map
= (HRSRC_MAP
*)pModule
->hRsrcMap
;
63 /* On first call, initialize HRSRC map */
66 if ( !(map
= (HRSRC_MAP
*)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY
,
67 sizeof(HRSRC_MAP
) ) ) )
69 ERR("Cannot allocate HRSRC map\n" );
72 pModule
->hRsrcMap
= (LPVOID
)map
;
75 /* Check whether HRSRC32 already in map */
76 for ( i
= 0; i
< map
->nUsed
; i
++ )
77 if ( map
->elem
[i
].hRsrc
== hRsrc32
)
78 return (HRSRC16
)(i
+ 1);
80 /* If no space left, grow table */
81 if ( map
->nUsed
== map
->nAlloc
)
83 if ( !(newElem
= (HRSRC_ELEM
*)HeapReAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY
,
85 (map
->nAlloc
+ HRSRC_MAP_BLOCKSIZE
)
86 * sizeof(HRSRC_ELEM
) ) ))
88 ERR("Cannot grow HRSRC map\n" );
92 map
->nAlloc
+= HRSRC_MAP_BLOCKSIZE
;
95 /* Add HRSRC32 to table */
96 map
->elem
[map
->nUsed
].hRsrc
= hRsrc32
;
97 map
->elem
[map
->nUsed
].type
= type
;
100 return (HRSRC16
)map
->nUsed
;
103 /**********************************************************************
106 static HANDLE
MapHRsrc16To32( NE_MODULE
*pModule
, HRSRC16 hRsrc16
)
108 HRSRC_MAP
*map
= (HRSRC_MAP
*)pModule
->hRsrcMap
;
109 if ( !map
|| !hRsrc16
|| (int)hRsrc16
> map
->nUsed
) return 0;
111 return map
->elem
[(int)hRsrc16
-1].hRsrc
;
114 /**********************************************************************
117 static WORD
MapHRsrc16ToType( NE_MODULE
*pModule
, HRSRC16 hRsrc16
)
119 HRSRC_MAP
*map
= (HRSRC_MAP
*)pModule
->hRsrcMap
;
120 if ( !map
|| !hRsrc16
|| (int)hRsrc16
> map
->nUsed
) return 0;
122 return map
->elem
[(int)hRsrc16
-1].type
;
126 /* filter for page-fault exceptions */
127 static WINE_EXCEPTION_FILTER(page_fault
)
129 if (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION
)
130 return EXCEPTION_EXECUTE_HANDLER
;
131 return EXCEPTION_CONTINUE_SEARCH
;
134 static HRSRC
RES_FindResource2( HMODULE hModule
, LPCSTR type
,
135 LPCSTR name
, WORD lang
,
136 BOOL bUnicode
, BOOL bRet16
)
139 HMODULE16 hMod16
= MapHModuleLS( hModule
);
140 NE_MODULE
*pModule
= NE_GetPtr( hMod16
);
141 WINE_MODREF
*wm
= pModule
&& pModule
->module32
?
142 MODULE32_LookupHMODULE( pModule
->module32
) : NULL
;
144 TRACE("(%08x %s, %08x%s, %08x%s, %04x, %s, %s)\n",
146 pModule
? (char *)NE_MODULE_NAME(pModule
) : "NULL dereference",
147 (UINT
)type
, HIWORD(type
)? (bUnicode
? debugstr_w((LPWSTR
)type
) : debugstr_a(type
)) : "",
148 (UINT
)name
, HIWORD(name
)? (bUnicode
? debugstr_w((LPWSTR
)name
) : debugstr_a(name
)) : "",
151 bRet16
? "NE" : "PE" );
157 /* 32-bit PE module */
158 LPWSTR typeStr
, nameStr
;
160 if ( HIWORD( type
) && !bUnicode
)
161 typeStr
= HEAP_strdupAtoW( GetProcessHeap(), 0, type
);
163 typeStr
= (LPWSTR
)type
;
164 if ( HIWORD( name
) && !bUnicode
)
165 nameStr
= HEAP_strdupAtoW( GetProcessHeap(), 0, name
);
167 nameStr
= (LPWSTR
)name
;
169 hRsrc
= PE_FindResourceExW( wm
, nameStr
, typeStr
, lang
);
171 if ( HIWORD( type
) && !bUnicode
)
172 HeapFree( GetProcessHeap(), 0, typeStr
);
173 if ( HIWORD( name
) && !bUnicode
)
174 HeapFree( GetProcessHeap(), 0, nameStr
);
177 /* If we need to return 16-bit HRSRC, perform conversion */
179 hRsrc
= MapHRsrc32To16( pModule
, hRsrc
,
180 HIWORD( type
)? 0 : LOWORD( type
) );
184 /* 16-bit NE module */
185 LPSTR typeStr
, nameStr
;
187 if ( HIWORD( type
) && bUnicode
)
188 typeStr
= HEAP_strdupWtoA( GetProcessHeap(), 0, (LPCWSTR
)type
);
190 typeStr
= (LPSTR
)type
;
191 if ( HIWORD( name
) && bUnicode
)
192 nameStr
= HEAP_strdupWtoA( GetProcessHeap(), 0, (LPCWSTR
)name
);
194 nameStr
= (LPSTR
)name
;
196 hRsrc
= NE_FindResource( pModule
, nameStr
, typeStr
);
198 if ( HIWORD( type
) && bUnicode
)
199 HeapFree( GetProcessHeap(), 0, typeStr
);
200 if ( HIWORD( name
) && bUnicode
)
201 HeapFree( GetProcessHeap(), 0, nameStr
);
204 /* If we need to return 32-bit HRSRC, no conversion is necessary,
205 we simply use the 16-bit HRSRC as 32-bit HRSRC */
211 /**********************************************************************
215 static HRSRC
RES_FindResource( HMODULE hModule
, LPCSTR type
,
216 LPCSTR name
, WORD lang
,
217 BOOL bUnicode
, BOOL bRet16
)
222 hRsrc
= RES_FindResource2(hModule
, type
, name
, lang
, bUnicode
, bRet16
);
226 WARN("page fault\n");
227 SetLastError(ERROR_INVALID_PARAMETER
);
234 /**********************************************************************
237 static DWORD
RES_SizeofResource( HMODULE hModule
, HRSRC hRsrc
, BOOL bRet16
)
241 HMODULE16 hMod16
= MapHModuleLS( hModule
);
242 NE_MODULE
*pModule
= NE_GetPtr( hMod16
);
243 WINE_MODREF
*wm
= pModule
&& pModule
->module32
?
244 MODULE32_LookupHMODULE( pModule
->module32
) : NULL
;
246 TRACE("(%08x %s, %08x, %s)\n",
247 hModule
, NE_MODULE_NAME(pModule
), hRsrc
, bRet16
? "NE" : "PE" );
249 if ( !pModule
|| !hRsrc
) return 0;
253 /* 32-bit PE module */
255 /* If we got a 16-bit hRsrc, convert it */
256 HRSRC hRsrc32
= HIWORD(hRsrc
)? hRsrc
: MapHRsrc16To32( pModule
, hRsrc
);
258 size
= PE_SizeofResource( hModule
, hRsrc32
);
262 /* 16-bit NE module */
264 /* If we got a 32-bit hRsrc, we don't need to convert it */
266 size
= NE_SizeofResource( pModule
, hRsrc
);
272 /**********************************************************************
275 static HFILE
RES_AccessResource( HMODULE hModule
, HRSRC hRsrc
, BOOL bRet16
)
277 HFILE hFile
= HFILE_ERROR
;
279 HMODULE16 hMod16
= MapHModuleLS( hModule
);
280 NE_MODULE
*pModule
= NE_GetPtr( hMod16
);
281 WINE_MODREF
*wm
= pModule
&& pModule
->module32
?
282 MODULE32_LookupHMODULE( pModule
->module32
) : NULL
;
284 TRACE("(%08x %s, %08x, %s)\n",
285 hModule
, NE_MODULE_NAME(pModule
), hRsrc
, bRet16
? "NE" : "PE" );
287 if ( !pModule
|| !hRsrc
) return HFILE_ERROR
;
291 /* 32-bit PE module */
293 /* If we got a 16-bit hRsrc, convert it */
294 HRSRC hRsrc32
= HIWORD(hRsrc
)? hRsrc
: MapHRsrc16To32( pModule
, hRsrc
);
297 FIXME("32-bit modules not yet supported.\n" );
300 /* If we need to return a 16-bit file handle, convert it */
302 hFile
= FILE_AllocDosHandle( hFile
);
306 /* 16-bit NE module */
308 /* If we got a 32-bit hRsrc, we don't need to convert it */
310 hFile
= NE_AccessResource( pModule
, hRsrc
);
312 /* If we are to return a 32-bit file handle, convert it */
314 hFile
= FILE_GetHandle( hFile
);
320 /**********************************************************************
323 static HGLOBAL
RES_LoadResource( HMODULE hModule
, HRSRC hRsrc
, BOOL bRet16
)
327 HMODULE16 hMod16
= MapHModuleLS( hModule
);
328 NE_MODULE
*pModule
= NE_GetPtr( hMod16
);
329 WINE_MODREF
*wm
= pModule
&& pModule
->module32
?
330 MODULE32_LookupHMODULE( pModule
->module32
) : NULL
;
332 TRACE("(%08x %s, %08x, %s)\n",
333 hModule
, NE_MODULE_NAME(pModule
), hRsrc
, bRet16
? "NE" : "PE" );
335 if ( !pModule
|| !hRsrc
) return 0;
339 /* 32-bit PE module */
341 /* If we got a 16-bit hRsrc, convert it */
342 HRSRC hRsrc32
= HIWORD(hRsrc
)? hRsrc
: MapHRsrc16To32( pModule
, hRsrc
);
344 hMem
= PE_LoadResource( wm
, hRsrc32
);
346 /* If we need to return a 16-bit resource, convert it */
349 WORD type
= MapHRsrc16ToType( pModule
, hRsrc
);
350 DWORD size
= SizeofResource( hModule
, hRsrc
);
351 LPVOID bits
= LockResource( hMem
);
353 hMem
= NE_LoadPEResource( pModule
, type
, bits
, size
);
358 /* 16-bit NE module */
360 /* If we got a 32-bit hRsrc, we don't need to convert it */
362 hMem
= NE_LoadResource( pModule
, hRsrc
);
364 /* If we are to return a 32-bit resource, we should probably
365 convert it but we don't for now. FIXME !!! */
371 /**********************************************************************
374 static LPVOID
RES_LockResource( HGLOBAL handle
, BOOL bRet16
)
378 TRACE("(%08x, %s)\n", handle
, bRet16
? "NE" : "PE" );
380 if ( HIWORD( handle
) )
382 /* 32-bit memory handle */
385 FIXME("can't return SEGPTR to 32-bit resource %08x.\n", handle
);
387 bits
= (LPVOID
)handle
;
391 /* 16-bit memory handle */
393 /* May need to reload the resource if discarded */
394 SEGPTR segPtr
= WIN16_GlobalLock16( handle
);
397 bits
= (LPVOID
)segPtr
;
399 bits
= PTR_SEG_TO_LIN( segPtr
);
405 /**********************************************************************
408 static BOOL
RES_FreeResource( HGLOBAL handle
)
410 HGLOBAL retv
= handle
;
412 TRACE("(%08x)\n", handle
);
414 if ( HIWORD( handle
) )
416 /* 32-bit memory handle: nothing to do */
420 /* 16-bit memory handle */
421 NE_MODULE
*pModule
= NE_GetPtr( FarGetOwner16( handle
) );
423 /* Try NE resource first */
424 retv
= NE_FreeResource( pModule
, handle
);
426 /* If this failed, call USER.DestroyIcon32; this will check
427 whether it is a shared cursor/icon; if not it will call
430 if ( Callout
.DestroyIcon32
)
431 retv
= Callout
.DestroyIcon32( handle
, CID_RESOURCE
);
433 retv
= GlobalFree16( handle
);
441 /**********************************************************************
442 * FindResource16 (KERNEL.60)
444 HRSRC16 WINAPI
FindResource16( HMODULE16 hModule
, SEGPTR name
, SEGPTR type
)
446 LPCSTR nameStr
= HIWORD(name
)? PTR_SEG_TO_LIN(name
) : (LPCSTR
)name
;
447 LPCSTR typeStr
= HIWORD(type
)? PTR_SEG_TO_LIN(type
) : (LPCSTR
)type
;
449 return RES_FindResource( hModule
, typeStr
, nameStr
,
450 GetSystemDefaultLangID(), FALSE
, TRUE
);
453 /**********************************************************************
454 * FindResourceA (KERNEL32.128)
456 HANDLE WINAPI
FindResourceA( HMODULE hModule
, LPCSTR name
, LPCSTR type
)
458 return RES_FindResource( hModule
, type
, name
,
459 GetSystemDefaultLangID(), FALSE
, FALSE
);
462 /**********************************************************************
463 * FindResourceExA (KERNEL32.129)
465 HANDLE WINAPI
FindResourceExA( HMODULE hModule
,
466 LPCSTR type
, LPCSTR name
, WORD lang
)
468 return RES_FindResource( hModule
, type
, name
,
469 lang
, FALSE
, FALSE
);
472 /**********************************************************************
473 * FindResourceExW (KERNEL32.130)
475 HRSRC WINAPI
FindResourceExW( HMODULE hModule
,
476 LPCWSTR type
, LPCWSTR name
, WORD lang
)
478 return RES_FindResource( hModule
, (LPCSTR
)type
, (LPCSTR
)name
,
482 /**********************************************************************
483 * FindResourceW (KERNEL32.131)
485 HRSRC WINAPI
FindResourceW(HINSTANCE hModule
, LPCWSTR name
, LPCWSTR type
)
487 return RES_FindResource( hModule
, (LPCSTR
)type
, (LPCSTR
)name
,
488 GetSystemDefaultLangID(), TRUE
, FALSE
);
491 /**********************************************************************
492 * LoadResource16 (KERNEL.61)
494 HGLOBAL16 WINAPI
LoadResource16( HMODULE16 hModule
, HRSRC16 hRsrc
)
496 return RES_LoadResource( hModule
, hRsrc
, TRUE
);
499 /**********************************************************************
500 * LoadResource (KERNEL32.370)
502 HGLOBAL WINAPI
LoadResource( HINSTANCE hModule
, HRSRC hRsrc
)
504 return RES_LoadResource( hModule
, hRsrc
, FALSE
);
507 /**********************************************************************
508 * LockResource16 (KERNEL.62)
510 SEGPTR WINAPI
WIN16_LockResource16( HGLOBAL16 handle
)
512 return (SEGPTR
)RES_LockResource( handle
, TRUE
);
514 LPVOID WINAPI
LockResource16( HGLOBAL16 handle
)
516 return RES_LockResource( handle
, FALSE
);
519 /**********************************************************************
520 * LockResource (KERNEL32.384)
522 LPVOID WINAPI
LockResource( HGLOBAL handle
)
524 return RES_LockResource( handle
, FALSE
);
527 /**********************************************************************
528 * FreeResource16 (KERNEL.63)
530 BOOL16 WINAPI
FreeResource16( HGLOBAL16 handle
)
532 return RES_FreeResource( handle
);
535 /**********************************************************************
536 * FreeResource (KERNEL32.145)
538 BOOL WINAPI
FreeResource( HGLOBAL handle
)
540 return RES_FreeResource( handle
);
543 /**********************************************************************
544 * AccessResource16 (KERNEL.64)
546 INT16 WINAPI
AccessResource16( HINSTANCE16 hModule
, HRSRC16 hRsrc
)
548 return RES_AccessResource( hModule
, hRsrc
, TRUE
);
551 /**********************************************************************
552 * AccessResource (KERNEL32.64)
554 INT WINAPI
AccessResource( HMODULE hModule
, HRSRC hRsrc
)
556 return RES_AccessResource( hModule
, hRsrc
, FALSE
);
559 /**********************************************************************
560 * SizeofResource16 (KERNEL.65)
562 DWORD WINAPI
SizeofResource16( HMODULE16 hModule
, HRSRC16 hRsrc
)
564 return RES_SizeofResource( hModule
, hRsrc
, TRUE
);
567 /**********************************************************************
568 * SizeofResource (KERNEL32.522)
570 DWORD WINAPI
SizeofResource( HINSTANCE hModule
, HRSRC hRsrc
)
572 return RES_SizeofResource( hModule
, hRsrc
, FALSE
);
577 /**********************************************************************
578 * LoadAccelerators16 [USER.177]
580 HACCEL16 WINAPI
LoadAccelerators16(HINSTANCE16 instance
, SEGPTR lpTableName
)
584 if (HIWORD(lpTableName
))
585 TRACE_(accel
)("%04x '%s'\n",
586 instance
, (char *)PTR_SEG_TO_LIN( lpTableName
) );
588 TRACE_(accel
)("%04x %04x\n",
589 instance
, LOWORD(lpTableName
) );
591 if (!(hRsrc
= FindResource16( instance
, lpTableName
, RT_ACCELERATOR16
))) {
592 WARN_(accel
)("couldn't find accelerator table resource\n");
596 TRACE_(accel
)("returning HACCEL 0x%x\n", hRsrc
);
597 return LoadResource16(instance
,hRsrc
);
600 /**********************************************************************
601 * LoadAcceleratorsW [USER.177]
602 * The image layout seems to look like this (not 100% sure):
603 * 00: BYTE type type of accelerator
604 * 01: BYTE pad (to WORD boundary)
607 * 06: WORD pad (to DWORD boundary)
609 HACCEL WINAPI
LoadAcceleratorsW(HINSTANCE instance
,LPCWSTR lpTableName
)
612 HACCEL hMem
,hRetval
=0;
615 if (HIWORD(lpTableName
))
616 TRACE_(accel
)("%p '%s'\n",
617 (LPVOID
)instance
, (char *)( lpTableName
) );
619 TRACE_(accel
)("%p 0x%04x\n",
620 (LPVOID
)instance
, LOWORD(lpTableName
) );
622 if (!(hRsrc
= FindResourceW( instance
, lpTableName
, RT_ACCELERATORW
)))
624 WARN_(accel
)("couldn't find accelerator table resource\n");
626 hMem
= LoadResource( instance
, hRsrc
);
627 size
= SizeofResource( instance
, hRsrc
);
628 if(size
>=sizeof(PE_ACCEL
))
630 LPPE_ACCEL accel_table
= (LPPE_ACCEL
) hMem
;
632 int i
,nrofaccells
= size
/sizeof(PE_ACCEL
);
634 hRetval
= GlobalAlloc16(0,sizeof(ACCEL16
)*nrofaccells
);
635 accel16
= (LPACCEL16
)GlobalLock16(hRetval
);
636 for (i
=0;i
<nrofaccells
;i
++) {
637 accel16
[i
].fVirt
= accel_table
[i
].fVirt
;
638 accel16
[i
].key
= accel_table
[i
].key
;
639 accel16
[i
].cmd
= accel_table
[i
].cmd
;
641 accel16
[i
-1].fVirt
|= 0x80;
644 TRACE_(accel
)("returning HACCEL 0x%x\n", hRsrc
);
648 /***********************************************************************
651 HACCEL WINAPI
LoadAcceleratorsA(HINSTANCE instance
,LPCSTR lpTableName
)
655 if (HIWORD(lpTableName
))
656 uni
= HEAP_strdupAtoW( GetProcessHeap(), 0, lpTableName
);
658 uni
= (LPWSTR
)lpTableName
;
659 result
= LoadAcceleratorsW(instance
,uni
);
660 if (HIWORD(uni
)) HeapFree( GetProcessHeap(), 0, uni
);
664 /**********************************************************************
665 * CopyAcceleratorTableA (USER32.58)
667 INT WINAPI
CopyAcceleratorTableA(HACCEL src
, LPACCEL dst
, INT entries
)
669 return CopyAcceleratorTableW(src
, dst
, entries
);
672 /**********************************************************************
673 * CopyAcceleratorTableW (USER32.59)
675 * By mortene@pvv.org 980321
677 INT WINAPI
CopyAcceleratorTableW(HACCEL src
, LPACCEL dst
,
681 LPACCEL16 accel
= (LPACCEL16
)GlobalLock16(src
);
684 /* Do parameter checking to avoid the explosions and the screaming
685 as far as possible. */
686 if((dst
&& (entries
< 1)) || (src
== (HACCEL
)NULL
) || !accel
) {
687 WARN_(accel
)("Application sent invalid parameters (%p %p %d).\n",
688 (LPVOID
)src
, (LPVOID
)dst
, entries
);
691 xsize
= GlobalSize16(src
)/sizeof(ACCEL16
);
692 if (xsize
>entries
) entries
=xsize
;
696 /* Spit out some debugging information. */
697 TRACE_(accel
)("accel %d: type 0x%02x, event '%c', IDval 0x%04x.\n",
698 i
, accel
[i
].fVirt
, accel
[i
].key
, accel
[i
].cmd
);
700 /* Copy data to the destination structure array (if dst == NULL,
701 we're just supposed to count the number of entries). */
703 dst
[i
].fVirt
= accel
[i
].fVirt
;
704 dst
[i
].key
= accel
[i
].key
;
705 dst
[i
].cmd
= accel
[i
].cmd
;
707 /* Check if we've reached the end of the application supplied
708 accelerator table. */
710 /* Turn off the high order bit, just in case. */
711 dst
[i
].fVirt
&= 0x7f;
716 /* The highest order bit seems to mark the end of the accelerator
717 resource table, but not always. Use GlobalSize() check too. */
718 if((accel
[i
].fVirt
& 0x80) != 0) done
= TRUE
;
726 /*********************************************************************
727 * CreateAcceleratorTableA (USER32.64)
729 * By mortene@pvv.org 980321
731 HACCEL WINAPI
CreateAcceleratorTableA(LPACCEL lpaccel
, INT cEntries
)
737 /* Do parameter checking just in case someone's trying to be
740 WARN_(accel
)("Application sent invalid parameters (%p %d).\n",
742 SetLastError(ERROR_INVALID_PARAMETER
);
745 FIXME_(accel
)("should check that the accelerator descriptions are valid,"
746 " return NULL and SetLastError() if not.\n");
749 /* Allocate memory and copy the table. */
750 hAccel
= GlobalAlloc16(0,cEntries
*sizeof(ACCEL16
));
752 TRACE_(accel
)("handle %x\n", hAccel
);
754 ERR_(accel
)("Out of memory.\n");
755 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
758 accel
= GlobalLock16(hAccel
);
759 for (i
=0;i
<cEntries
;i
++) {
760 accel
[i
].fVirt
= lpaccel
[i
].fVirt
;
761 accel
[i
].key
= lpaccel
[i
].key
;
762 accel
[i
].cmd
= lpaccel
[i
].cmd
;
764 /* Set the end-of-table terminator. */
765 accel
[cEntries
-1].fVirt
|= 0x80;
767 TRACE_(accel
)("Allocated accelerator handle %x\n", hAccel
);
771 /*********************************************************************
772 * CreateAcceleratorTableW (USER32.64)
776 HACCEL WINAPI
CreateAcceleratorTableW(LPACCEL lpaccel
, INT cEntries
)
783 /* Do parameter checking just in case someone's trying to be
786 WARN_(accel
)("Application sent invalid parameters (%p %d).\n",
788 SetLastError(ERROR_INVALID_PARAMETER
);
791 FIXME_(accel
)("should check that the accelerator descriptions are valid,"
792 " return NULL and SetLastError() if not.\n");
795 /* Allocate memory and copy the table. */
796 hAccel
= GlobalAlloc16(0,cEntries
*sizeof(ACCEL16
));
798 TRACE_(accel
)("handle %x\n", hAccel
);
800 ERR_(accel
)("Out of memory.\n");
801 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
804 accel
= GlobalLock16(hAccel
);
807 for (i
=0;i
<cEntries
;i
++) {
808 accel
[i
].fVirt
= lpaccel
[i
].fVirt
;
809 if( !(accel
[i
].fVirt
& FVIRTKEY
) ) {
810 ckey
= (char) lpaccel
[i
].key
;
811 if(!MultiByteToWideChar(CP_ACP
, MB_PRECOMPOSED
, &ckey
, 1, &accel
[i
].key
, 1))
812 WARN_(accel
)("Error converting ASCII accelerator table to Unicode");
815 accel
[i
].key
= lpaccel
[i
].key
;
816 accel
[i
].cmd
= lpaccel
[i
].cmd
;
819 /* Set the end-of-table terminator. */
820 accel
[cEntries
-1].fVirt
|= 0x80;
822 TRACE_(accel
)("Allocated accelerator handle %x\n", hAccel
);
826 /******************************************************************************
827 * DestroyAcceleratorTable [USER32.130]
828 * Destroys an accelerator table
831 * By mortene@pvv.org 980321
834 * handle [I] Handle to accelerator table
838 BOOL WINAPI
DestroyAcceleratorTable( HACCEL handle
)
840 return !GlobalFree16(handle
);
843 /**********************************************************************
846 INT16 WINAPI
LoadString16( HINSTANCE16 instance
, UINT16 resource_id
,
847 LPSTR buffer
, INT16 buflen
)
855 TRACE("inst=%04x id=%04x buff=%08x len=%d\n",
856 instance
, resource_id
, (int) buffer
, buflen
);
858 hrsrc
= FindResource16( instance
, (SEGPTR
)((resource_id
>>4)+1), RT_STRING16
);
859 if (!hrsrc
) return 0;
860 hmem
= LoadResource16( instance
, hrsrc
);
863 p
= LockResource16(hmem
);
864 string_num
= resource_id
& 0x000f;
865 for (i
= 0; i
< string_num
; i
++)
868 TRACE("strlen = %d\n", (int)*p
);
870 if (buffer
== NULL
) return *p
;
871 i
= min(buflen
- 1, *p
);
873 memcpy(buffer
, p
+ 1, i
);
880 WARN("Dont know why caller give buflen=%d *p=%d trying to obtain string '%s'\n", buflen
, *p
, p
+ 1);
882 FreeResource16( hmem
);
884 TRACE("'%s' loaded !\n", buffer
);
888 /**********************************************************************
889 * LoadStringW (USER32.376)
891 INT WINAPI
LoadStringW( HINSTANCE instance
, UINT resource_id
,
892 LPWSTR buffer
, INT buflen
)
900 if (HIWORD(resource_id
)==0xFFFF) /* netscape 3 passes this */
901 resource_id
= (UINT
)(-((INT
)resource_id
));
902 TRACE("instance = %04x, id = %04x, buffer = %08x, "
903 "length = %d\n", instance
, (int)resource_id
, (int) buffer
, buflen
);
905 /* Use bits 4 - 19 (incremented by 1) as resourceid, mask out
907 hrsrc
= FindResourceW( instance
, (LPCWSTR
)(((resource_id
>>4)&0xffff)+1),
909 if (!hrsrc
) return 0;
910 hmem
= LoadResource( instance
, hrsrc
);
913 p
= LockResource(hmem
);
914 string_num
= resource_id
& 0x000f;
915 for (i
= 0; i
< string_num
; i
++)
918 TRACE("strlen = %d\n", (int)*p
);
920 if (buffer
== NULL
) return *p
;
921 i
= min(buflen
- 1, *p
);
923 memcpy(buffer
, p
+ 1, i
* sizeof (WCHAR
));
924 buffer
[i
] = (WCHAR
) 0;
927 buffer
[0] = (WCHAR
) 0;
931 WARN("Dont know why caller give buflen=%d *p=%d trying to obtain string '%s'\n", buflen
, *p
, p
+ 1);
935 TRACE("%s loaded !\n", debugstr_w(buffer
));
939 /**********************************************************************
940 * LoadStringA (USER32.375)
942 INT WINAPI
LoadStringA( HINSTANCE instance
, UINT resource_id
,
943 LPSTR buffer
, INT buflen
)
948 TRACE("instance = %04x, id = %04x, buffer = %08x, "
949 "length = %d\n", instance
, (int)resource_id
, (int) buffer
, buflen
);
951 if(buffer
== NULL
) /* asked size of string */
952 return LoadStringW(instance
, resource_id
, NULL
, 0);
954 wbuf
= HeapAlloc(GetProcessHeap(), 0, buflen
* sizeof(WCHAR
));
958 retval
= LoadStringW(instance
, resource_id
, wbuf
, buflen
);
961 retval
= WideCharToMultiByte(CP_ACP
, 0, wbuf
, retval
, buffer
, buflen
- 1, NULL
, NULL
);
963 TRACE("%s loaded !\n", debugstr_a(buffer
));
965 HeapFree( GetProcessHeap(), 0, wbuf
);
970 /* Messages...used by FormatMessage32* (KERNEL32.something)
972 * They can be specified either directly or using a message ID and
973 * loading them from the resource.
975 * The resourcedata has following format:
977 * 0: DWORD nrofentries
978 * nrofentries * subentry:
979 * 0: DWORD firstentry
981 * 8: DWORD offset from start to the stringentries
983 * (lastentry-firstentry) * stringentry:
984 * 0: WORD len (0 marks end)
987 * (stringentry i of a subentry refers to the ID 'firstentry+i')
989 * Yes, ANSI strings in win32 resources. Go figure.
992 /**********************************************************************
993 * LoadMessageA (internal)
995 INT WINAPI
LoadMessageA( HMODULE instance
, UINT id
, WORD lang
,
996 LPSTR buffer
, INT buflen
)
1000 PMESSAGE_RESOURCE_DATA mrd
;
1001 PMESSAGE_RESOURCE_BLOCK mrb
;
1002 PMESSAGE_RESOURCE_ENTRY mre
;
1005 TRACE("instance = %08lx, id = %08lx, buffer = %p, length = %ld\n", (DWORD
)instance
, (DWORD
)id
, buffer
, (DWORD
)buflen
);
1007 /*FIXME: I am not sure about the '1' ... But I've only seen those entries*/
1008 hrsrc
= FindResourceExW(instance
,RT_MESSAGELISTW
,(LPWSTR
)1,lang
);
1009 if (!hrsrc
) return 0;
1010 hmem
= LoadResource( instance
, hrsrc
);
1011 if (!hmem
) return 0;
1013 mrd
= (PMESSAGE_RESOURCE_DATA
)LockResource(hmem
);
1015 mrb
= &(mrd
->Blocks
[0]);
1016 for (i
=mrd
->NumberOfBlocks
;i
--;) {
1017 if ((id
>=mrb
->LowId
) && (id
<=mrb
->HighId
)) {
1018 mre
= (PMESSAGE_RESOURCE_ENTRY
)(((char*)mrd
)+mrb
->OffsetToEntries
);
1029 mre
= (PMESSAGE_RESOURCE_ENTRY
)(((char*)mre
)+(mre
->Length
));
1032 TRACE(" - strlen=%d\n",slen
);
1033 i
= min(buflen
- 1, slen
);
1037 lstrcpynA(buffer
,(char*)mre
->Text
,i
);
1046 TRACE("'%s' copied !\n", buffer
);
1050 /**********************************************************************
1051 * LoadMessageW (internal)
1053 INT WINAPI
LoadMessageW( HMODULE instance
, UINT id
, WORD lang
,
1054 LPWSTR buffer
, INT buflen
)
1057 LPSTR buffer2
= NULL
;
1058 if (buffer
&& buflen
)
1059 buffer2
= HeapAlloc( GetProcessHeap(), 0, buflen
);
1060 retval
= LoadMessageA(instance
,id
,lang
,buffer2
,buflen
);
1064 lstrcpynAtoW( buffer
, buffer2
, buflen
);
1065 retval
= lstrlenW( buffer
);
1067 HeapFree( GetProcessHeap(), 0, buffer2
);
1073 /**********************************************************************
1074 * EnumResourceTypesA (KERNEL32.90)
1076 BOOL WINAPI
EnumResourceTypesA( HMODULE hmodule
,ENUMRESTYPEPROCA lpfun
,
1079 /* FIXME: move WINE_MODREF stuff here */
1080 return PE_EnumResourceTypesA(hmodule
,lpfun
,lParam
);
1083 /**********************************************************************
1084 * EnumResourceTypesW (KERNEL32.91)
1086 BOOL WINAPI
EnumResourceTypesW( HMODULE hmodule
,ENUMRESTYPEPROCW lpfun
,
1089 /* FIXME: move WINE_MODREF stuff here */
1090 return PE_EnumResourceTypesW(hmodule
,lpfun
,lParam
);
1093 /**********************************************************************
1094 * EnumResourceNamesA (KERNEL32.88)
1096 BOOL WINAPI
EnumResourceNamesA( HMODULE hmodule
, LPCSTR type
,
1097 ENUMRESNAMEPROCA lpfun
, LONG lParam
)
1099 /* FIXME: move WINE_MODREF stuff here */
1100 return PE_EnumResourceNamesA(hmodule
,type
,lpfun
,lParam
);
1102 /**********************************************************************
1103 * EnumResourceNamesW (KERNEL32.89)
1105 BOOL WINAPI
EnumResourceNamesW( HMODULE hmodule
, LPCWSTR type
,
1106 ENUMRESNAMEPROCW lpfun
, LONG lParam
)
1108 /* FIXME: move WINE_MODREF stuff here */
1109 return PE_EnumResourceNamesW(hmodule
,type
,lpfun
,lParam
);
1112 /**********************************************************************
1113 * EnumResourceLanguagesA (KERNEL32.86)
1115 BOOL WINAPI
EnumResourceLanguagesA( HMODULE hmodule
, LPCSTR type
,
1116 LPCSTR name
, ENUMRESLANGPROCA lpfun
,
1119 /* FIXME: move WINE_MODREF stuff here */
1120 return PE_EnumResourceLanguagesA(hmodule
,type
,name
,lpfun
,lParam
);
1122 /**********************************************************************
1123 * EnumResourceLanguagesW (KERNEL32.87)
1125 BOOL WINAPI
EnumResourceLanguagesW( HMODULE hmodule
, LPCWSTR type
,
1126 LPCWSTR name
, ENUMRESLANGPROCW lpfun
,
1129 /* FIXME: move WINE_MODREF stuff here */
1130 return PE_EnumResourceLanguagesW(hmodule
,type
,name
,lpfun
,lParam
);