Release 960717
[wine/multimedia.git] / loader / resource.c
blobcea0057dc18764e9a16aa2fdae75b74441e7bd6c
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 "neexe.h"
20 #include "accel.h"
21 #include "module.h"
22 #include "resource.h"
23 #include "stddebug.h"
24 #include "debug.h"
25 #include "libres.h"
26 #include "string32.h"
27 #include "xmalloc.h"
29 #define PrintId(name) \
30 if (HIWORD((DWORD)name)) \
31 dprintf_resource( stddeb, "'%s'", (char *)PTR_SEG_TO_LIN(name)); \
32 else \
33 dprintf_resource( stddeb, "#%04x", LOWORD(name));
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_FindResource( hModule, name, type );
66 #endif
70 /**********************************************************************
71 * FindResource32A (KERNEL32.128)
73 HANDLE32 FindResource32A( HINSTANCE32 hModule, LPCSTR name, LPCSTR type )
75 LPWSTR xname,xtype;
76 HANDLE32 ret;
78 if (HIWORD((DWORD)name)) xname = STRING32_DupAnsiToUni(name);
79 else xname = (LPWSTR)name;
80 if (HIWORD((DWORD)type)) xtype = STRING32_DupAnsiToUni(type);
81 else xtype = (LPWSTR)type;
82 ret = FindResource32W(hModule,xname,xtype);
83 if (HIWORD((DWORD)name)) free(xname);
84 if (HIWORD((DWORD)type)) free(xtype);
85 return ret;
89 /**********************************************************************
90 * FindResource32W (KERNEL32.131)
92 HRSRC32 FindResource32W( HINSTANCE32 hModule, LPCWSTR name, LPCWSTR type )
94 #ifndef WINELIB
95 NE_MODULE *pModule;
97 /* Sometimes we get passed hModule = 0x00000000. FIXME: is GetTaskDS()
98 * ok?
100 if (!hModule) hModule = GetTaskDS();
101 hModule = GetExePtr( hModule ); /* In case we were passed an hInstance */
102 dprintf_resource(stddeb, "FindResource32W: module=%08x type=", hModule );
103 PrintId( type );
104 dprintf_resource( stddeb, " name=" );
105 PrintId( name );
106 dprintf_resource( stddeb, "\n" );
107 if (!(pModule = MODULE_GetPtr( hModule ))) return 0;
108 if (!(pModule->flags & NE_FFLAGS_WIN32)) return 0;
109 return PE_FindResource32W(hModule,name,type);
110 #else
111 return LIBRES_FindResource( hModule, name, type );
112 #endif
116 /**********************************************************************
117 * LoadResource16 (KERNEL.61)
119 HGLOBAL16 LoadResource16( HMODULE16 hModule, HRSRC16 hRsrc )
121 NE_MODULE *pModule;
123 hModule = GetExePtr( hModule ); /* In case we were passed an hInstance */
124 dprintf_resource(stddeb, "LoadResource16: module=%04x res=%04x\n",
125 hModule, hRsrc );
126 if (!hRsrc) return 0;
127 if (!(pModule = MODULE_GetPtr( hModule ))) return 0;
128 #ifndef WINELIB
129 if (pModule->flags & NE_FFLAGS_WIN32)
131 fprintf(stderr,"Don't know how to LoadResource16() for Win32 module\n");
132 return 0;
134 return NE_LoadResource( hModule, hRsrc );
135 #else
136 return LIBRES_LoadResource( hModule, hRsrc );
137 #endif
140 /**********************************************************************
141 * LoadResource32 (KERNEL32.370)
143 HGLOBAL32 LoadResource32( HINSTANCE32 hModule, HRSRC32 hRsrc )
145 #ifndef WINELIB
146 NE_MODULE *pModule;
148 if (!hModule) hModule = GetTaskDS(); /* FIXME: see FindResource32W */
149 hModule = GetExePtr( hModule ); /* In case we were passed an hInstance */
150 dprintf_resource(stddeb, "LoadResource32: module=%04x res=%04x\n",
151 hModule, hRsrc );
152 if (!hRsrc) return 0;
154 if (!(pModule = MODULE_GetPtr( hModule ))) return 0;
155 if (!(pModule->flags & NE_FFLAGS_WIN32))
157 fprintf(stderr,"LoadResource32: tried to load a non win32 resource.\n");
158 return 0; /* FIXME? */
160 return PE_LoadResource32(hModule,hRsrc);
161 #else
162 return LIBRES_LoadResource( hModule, hRsrc );
163 #endif
167 /**********************************************************************
168 * LockResource (KERNEL.62)
170 /* 16-bit version */
171 SEGPTR WIN16_LockResource16(HGLOBAL16 handle)
173 #ifndef WINELIB
174 HMODULE16 hModule;
175 NE_MODULE *pModule;
177 dprintf_resource(stddeb, "LockResource: handle=%04x\n", handle );
178 if (!handle) return (SEGPTR)0;
179 hModule = GetExePtr( handle );
180 if (!(pModule = MODULE_GetPtr( hModule ))) return 0;
181 if (pModule->flags & NE_FFLAGS_WIN32)
183 fprintf(stderr,"Don't know how to LockResource() for Win32 module\n");
184 return 0;
186 return NE_LockResource( hModule, handle );
187 #else
188 return LIBRES_LockResource( handle );
189 #endif
192 /* WINELIB 16-bit version */
193 LPVOID LockResource16( HGLOBAL16 handle )
195 #ifndef WINELIB
196 HMODULE16 hModule;
197 NE_MODULE *pModule;
199 dprintf_resource(stddeb, "LockResource: handle=%04x\n", handle );
200 if (!handle) return NULL;
201 hModule = GetExePtr( handle );
202 if (!(pModule = MODULE_GetPtr( hModule ))) return 0;
203 if (pModule->flags & NE_FFLAGS_WIN32)
205 fprintf(stderr,"Don't know how to LockResource16() for Win32 module\n");
206 return 0;
208 return (LPSTR)PTR_SEG_TO_LIN( NE_LockResource( hModule, handle ) );
209 #else
210 return LIBRES_LockResource( handle );
211 #endif
215 /**********************************************************************
216 * LockResource32 (KERNEL32.384)
218 LPVOID LockResource32( HGLOBAL32 handle )
220 return (LPVOID)handle;
224 /**********************************************************************
225 * FreeResource16 (KERNEL.63)
227 BOOL16 FreeResource16( HGLOBAL16 handle )
229 #ifndef WINELIB
230 HMODULE16 hModule;
231 NE_MODULE *pModule;
233 dprintf_resource(stddeb, "FreeResource16: handle=%04x\n", handle );
234 if (!handle) return FALSE;
235 hModule = GetExePtr( handle );
236 if (!(pModule = MODULE_GetPtr( hModule ))) return 0;
237 if (pModule->flags & NE_FFLAGS_WIN32)
239 fprintf(stderr,"Don't know how to FreeResource16() for Win32 module\n");
240 return 0;
242 return NE_FreeResource( hModule, handle );
243 #else
244 return LIBRES_FreeResource( handle );
245 #endif
248 /**********************************************************************
249 * FreeResource32 (KERNEL32.145)
251 BOOL32 FreeResource32( HGLOBAL32 handle )
253 /* no longer used in Win32 */
254 return TRUE;
258 /**********************************************************************
259 * AccessResource16 (KERNEL.64)
261 INT16 AccessResource16( HINSTANCE16 hModule, HRSRC16 hRsrc )
263 NE_MODULE *pModule;
265 hModule = GetExePtr( hModule ); /* In case we were passed an hInstance */
266 dprintf_resource(stddeb, "AccessResource16: module=%04x res=%04x\n",
267 hModule, hRsrc );
268 if (!hRsrc) return 0;
269 if (!(pModule = MODULE_GetPtr( hModule ))) return 0;
270 #ifndef WINELIB
271 if (pModule->flags & NE_FFLAGS_WIN32)
273 fprintf(stderr,"Don't know how to AccessResource16() for Win32 module\n");
274 return 0;
276 return NE_AccessResource( hModule, hRsrc );
277 #else
278 return LIBRES_AccessResource( hModule, hRsrc );
279 #endif
283 /**********************************************************************
284 * AccessResource32 (KERNEL32.64)
286 INT32 AccessResource32( HINSTANCE32 hModule, HRSRC32 hRsrc )
288 hModule = GetExePtr( hModule ); /* In case we were passed an hInstance */
289 dprintf_resource(stddeb, "AccessResource: module=%04x res=%04x\n",
290 hModule, hRsrc );
291 if (!hRsrc) return 0;
292 fprintf(stderr,"AccessResource32: not implemented\n");
293 return 0;
297 /**********************************************************************
298 * SizeofResource16 (KERNEL.65)
300 DWORD SizeofResource16( HMODULE16 hModule, HRSRC16 hRsrc )
302 NE_MODULE *pModule;
304 hModule = GetExePtr( hModule ); /* In case we were passed an hInstance */
305 dprintf_resource(stddeb, "SizeofResource16: module=%04x res=%04x\n",
306 hModule, hRsrc );
307 if (!(pModule = MODULE_GetPtr( hModule ))) return 0;
308 #ifndef WINELIB
309 if (pModule->flags & NE_FFLAGS_WIN32)
311 fprintf(stderr,"Don't know how to SizeOfResource16() for Win32 module\n");
312 return 0;
314 return NE_SizeofResource( hModule, hRsrc );
315 #else
316 return LIBRES_SizeofResource( hModule, hRsrc );
317 #endif
321 /**********************************************************************
322 * SizeofResource32 (KERNEL32.522)
324 DWORD SizeofResource32( HINSTANCE32 hModule, HRSRC32 hRsrc )
326 hModule = GetExePtr( hModule ); /* In case we were passed an hInstance */
327 dprintf_resource(stddeb, "SizeofResource32: module=%04x res=%04x\n",
328 hModule, hRsrc );
329 fprintf(stderr,"SizeofResource32: not implemented\n");
330 return 0;
334 /**********************************************************************
335 * AllocResource16 (KERNEL.66)
337 HGLOBAL16 AllocResource16( HMODULE16 hModule, HRSRC16 hRsrc, DWORD size )
339 NE_MODULE *pModule;
341 hModule = GetExePtr( hModule ); /* In case we were passed an hInstance */
342 dprintf_resource(stddeb, "AllocResource: module=%04x res=%04x size=%ld\n",
343 hModule, hRsrc, size );
344 if (!hRsrc) return 0;
345 if (!(pModule = MODULE_GetPtr( hModule ))) return 0;
346 #ifndef WINELIB
347 if (pModule->flags & NE_FFLAGS_WIN32)
349 fprintf(stderr,"Don't know how to AllocResource() for Win32 module\n");
350 return 0;
352 return NE_AllocResource( hModule, hRsrc, size );
353 #else
354 return LIBRES_AllocResource( hModule, hRsrc, size );
355 #endif
358 /**********************************************************************
359 * DirectResAlloc (KERNEL.168)
361 * Check Schulman, p. 232 for details
363 HANDLE DirectResAlloc(HANDLE hInstance, WORD wType, WORD wSize)
365 dprintf_resource(stddeb,"DirectResAlloc(%04x,%04x,%04x)\n",
366 hInstance, wType, wSize );
367 hInstance = GetExePtr(hInstance);
368 if(!hInstance)return 0;
369 if(wType != 0x10) /* 0x10 is the only observed value, passed from
370 CreateCursorIndirect. */
371 fprintf(stderr, "DirectResAlloc: wType = %x\n", wType);
372 return GLOBAL_Alloc(GMEM_MOVEABLE, wSize, hInstance, FALSE, FALSE, FALSE);
376 /**********************************************************************
377 * LoadAccelerators16 [USER.177]
379 HACCEL16 LoadAccelerators16(HINSTANCE16 instance, SEGPTR lpTableName)
381 HACCEL16 hAccel;
382 HGLOBAL16 rsc_mem;
383 HRSRC16 hRsrc;
384 BYTE *lp;
385 ACCELHEADER *lpAccelTbl;
386 int i, n;
388 if (HIWORD(lpTableName))
389 dprintf_accel( stddeb, "LoadAccelerators: %04x '%s'\n",
390 instance, (char *)PTR_SEG_TO_LIN( lpTableName ) );
391 else
392 dprintf_accel( stddeb, "LoadAccelerators: %04x %04x\n",
393 instance, LOWORD(lpTableName) );
395 if (!(hRsrc = FindResource16( instance, lpTableName, RT_ACCELERATOR )))
396 return 0;
397 if (!(rsc_mem = LoadResource16( instance, hRsrc ))) return 0;
399 lp = (BYTE *)LockResource16(rsc_mem);
400 n = SizeofResource16(instance,hRsrc)/sizeof(ACCELENTRY);
401 hAccel = GlobalAlloc16(GMEM_MOVEABLE,
402 sizeof(ACCELHEADER) + (n + 1)*sizeof(ACCELENTRY));
403 lpAccelTbl = (LPACCELHEADER)GlobalLock16(hAccel);
404 lpAccelTbl->wCount = 0;
405 for (i = 0; i < n; i++) {
406 lpAccelTbl->tbl[i].type = *(lp++);
407 lpAccelTbl->tbl[i].wEvent = *((WORD *)lp);
408 lp += 2;
409 lpAccelTbl->tbl[i].wIDval = *((WORD *)lp);
410 lp += 2;
411 if (lpAccelTbl->tbl[i].wEvent == 0) break;
412 dprintf_accel(stddeb,
413 "Accelerator #%u / event=%04X id=%04X type=%02X \n",
414 i, lpAccelTbl->tbl[i].wEvent, lpAccelTbl->tbl[i].wIDval,
415 lpAccelTbl->tbl[i].type);
416 lpAccelTbl->wCount++;
418 GlobalUnlock16(hAccel);
419 FreeResource16( rsc_mem );
420 return hAccel;
423 /**********************************************************************
424 * LoadAccelerators32W [USER.177]
426 HACCEL32 LoadAccelerators32W(HINSTANCE32 instance,LPCWSTR lpTableName)
428 #if 0
429 HACCEL32 hAccel;
430 HGLOBAL32 rsc_mem;
431 HRSRC32 hRsrc;
432 BYTE *lp;
433 ACCELHEADER *lpAccelTbl;
434 int i, n;
436 if (HIWORD(lpTableName))
437 dprintf_accel( stddeb, "LoadAccelerators: %04x '%s'\n",
438 instance, (char *)( lpTableName ) );
439 else
440 dprintf_accel( stddeb, "LoadAccelerators: %04x %04x\n",
441 instance, LOWORD(lpTableName) );
443 if (!(hRsrc = FindResource32W( instance, lpTableName,
444 (LPCWSTR)RT_ACCELERATOR )))
445 return 0;
446 if (!(rsc_mem = LoadResource32( instance, hRsrc ))) return 0;
448 lp = (BYTE *)LockResource32(rsc_mem);
449 n = SizeofResource32(instance,hRsrc)/sizeof(ACCELENTRY);
450 hAccel = GlobalAlloc16(GMEM_MOVEABLE,
451 sizeof(ACCELHEADER) + (n + 1)*sizeof(ACCELENTRY));
452 lpAccelTbl = (LPACCELHEADER)GlobalLock16(hAccel);
453 lpAccelTbl->wCount = 0;
454 for (i = 0; i < n; i++) {
455 lpAccelTbl->tbl[i].type = *(lp++);
456 lpAccelTbl->tbl[i].wEvent = *((WORD *)lp);
457 lp += 2;
458 lpAccelTbl->tbl[i].wIDval = *((WORD *)lp);
459 lp += 2;
460 if (lpAccelTbl->tbl[i].wEvent == 0) break;
461 dprintf_accel(stddeb,
462 "Accelerator #%u / event=%04X id=%04X type=%02X \n",
463 i, lpAccelTbl->tbl[i].wEvent, lpAccelTbl->tbl[i].wIDval,
464 lpAccelTbl->tbl[i].type);
465 lpAccelTbl->wCount++;
467 GlobalUnlock16(hAccel);
468 FreeResource32(rsc_mem);
469 return hAccel;
470 #else
471 fprintf(stderr,"LoadAcceleratorsW: not implemented\n");
472 return 0x100; /* Return something anyway */
473 #endif
476 HACCEL32 LoadAccelerators32A(HINSTANCE32 instance,LPCSTR lpTableName)
478 LPWSTR uni;
479 HACCEL32 result;
480 if (HIWORD(lpTableName))
481 uni=STRING32_DupAnsiToUni(lpTableName);
482 else
483 uni=(LPWSTR)lpTableName;
484 result=LoadAccelerators32W(instance,uni);
485 if (HIWORD(uni))
486 free(uni);
487 return result;
491 /**********************************************************************
492 * TranslateAccelerator [USER.178]
494 int TranslateAccelerator(HWND hWnd, HANDLE hAccel, LPMSG16 msg)
496 ACCELHEADER *lpAccelTbl;
497 int i;
499 if (hAccel == 0 || msg == NULL) return 0;
500 if (msg->message != WM_KEYDOWN &&
501 msg->message != WM_KEYUP &&
502 msg->message != WM_SYSKEYDOWN &&
503 msg->message != WM_SYSKEYUP &&
504 msg->message != WM_CHAR) return 0;
506 dprintf_accel(stddeb, "TranslateAccelerators hAccel=%04x !\n", hAccel);
508 lpAccelTbl = (LPACCELHEADER)GlobalLock16(hAccel);
509 for (i = 0; i < lpAccelTbl->wCount; i++) {
510 if(lpAccelTbl->tbl[i].type & VIRTKEY_ACCEL) {
511 if(msg->wParam == lpAccelTbl->tbl[i].wEvent &&
512 (msg->message == WM_KEYDOWN || msg->message == WM_SYSKEYDOWN)) {
513 INT mask = 0;
515 if(GetKeyState(VK_SHIFT) & 0x8000) mask |= SHIFT_ACCEL;
516 if(GetKeyState(VK_CONTROL) & 0x8000) mask |= CONTROL_ACCEL;
517 if(GetKeyState(VK_MENU) & 0x8000) mask |= ALT_ACCEL;
518 if(mask == (lpAccelTbl->tbl[i].type &
519 (SHIFT_ACCEL | CONTROL_ACCEL | ALT_ACCEL))) {
520 SendMessage16(hWnd, WM_COMMAND, lpAccelTbl->tbl[i].wIDval,
521 0x00010000L);
522 GlobalUnlock16(hAccel);
523 return 1;
525 if (msg->message == WM_KEYUP || msg->message == WM_SYSKEYUP)
526 return 1;
529 else {
530 if (msg->wParam == lpAccelTbl->tbl[i].wEvent &&
531 msg->message == WM_CHAR) {
532 SendMessage16(hWnd, WM_COMMAND, lpAccelTbl->tbl[i].wIDval, 0x00010000L);
533 GlobalUnlock16(hAccel);
534 return 1;
538 GlobalUnlock16(hAccel);
539 return 0;
542 /**********************************************************************
543 * LoadString16
545 INT16
546 LoadString16(HINSTANCE16 instance,UINT16 resource_id,LPSTR buffer,INT16 buflen)
548 HGLOBAL16 hmem;
549 HRSRC16 hrsrc;
550 unsigned char *p;
551 int string_num;
552 int i;
554 dprintf_resource(stddeb,"LoadString: inst=%04x id=%04x buff=%08x len=%d\n",
555 instance, resource_id, (int) buffer, buflen);
557 hrsrc = FindResource16( instance, (SEGPTR)((resource_id>>4)+1), RT_STRING );
558 if (!hrsrc) return 0;
559 hmem = LoadResource16( instance, hrsrc );
560 if (!hmem) return 0;
562 p = LockResource16(hmem);
563 string_num = resource_id & 0x000f;
564 for (i = 0; i < string_num; i++)
565 p += *p + 1;
567 dprintf_resource( stddeb, "strlen = %d\n", (int)*p );
569 i = MIN(buflen - 1, *p);
570 if (buffer == NULL)
571 return i;
572 if (i > 0) {
573 memcpy(buffer, p + 1, i);
574 buffer[i] = '\0';
575 } else {
576 if (buflen > 1) {
577 buffer[0] = '\0';
578 return 0;
580 fprintf(stderr,"LoadString // I dont know why , but caller give buflen=%d *p=%d !\n", buflen, *p);
581 fprintf(stderr,"LoadString // and try to obtain string '%s'\n", p + 1);
583 FreeResource16( hmem );
585 dprintf_resource(stddeb,"LoadString // '%s' copied !\n", buffer);
586 return i;
589 /**********************************************************************
590 * LoadString32W (USER32.375)
592 INT32
593 LoadString32W(HINSTANCE32 instance,UINT32 resource_id,LPWSTR buffer,int buflen)
595 HGLOBAL32 hmem;
596 HRSRC32 hrsrc;
597 WCHAR *p;
598 int string_num;
599 int i;
601 dprintf_resource(stddeb, "LoadString: instance = %04x, id = %04x, buffer = %08x, "
602 "length = %d\n", instance, (int)resource_id, (int) buffer, buflen);
604 hrsrc = FindResource32W( instance, (LPCWSTR)((resource_id>>4)+1),
605 (LPCWSTR)RT_STRING );
606 if (!hrsrc) return 0;
607 hmem = LoadResource32( instance, hrsrc );
608 if (!hmem) return 0;
610 p = LockResource32(hmem);
611 string_num = resource_id & 0x000f;
612 for (i = 0; i < string_num; i++)
613 p += *p + 1;
615 dprintf_resource( stddeb, "strlen = %d\n", (int)*p );
617 i = MIN(buflen - 1, *p);
618 if (buffer == NULL)
619 return i;
620 if (i > 0) {
621 memcpy(buffer, p + 1, i * sizeof (WCHAR));
622 buffer[i] = (WCHAR) 0;
623 } else {
624 if (buflen > 1) {
625 buffer[0] = (WCHAR) 0;
626 return 0;
628 #if 0
629 fprintf(stderr,"LoadString // I dont know why , but caller give buflen=%d *p=%d !\n", buflen, *p);
630 fprintf(stderr,"LoadString // and try to obtain string '%s'\n", p + 1);
631 #endif
633 #if 0
634 dprintf_resource(stddeb,"LoadString // '%s' copied !\n", buffer);
635 #endif
636 return i;
639 /**********************************************************************
640 * LoadString32A (USER32.374)
642 INT32
643 LoadString32A(HINSTANCE32 instance,UINT32 resource_id,LPSTR buffer,int buflen)
645 LPWSTR buffer2 = (LPWSTR)xmalloc(buflen*2);
646 INT32 retval = LoadString32W(instance,resource_id,buffer2,buflen);
648 STRING32_UniToAnsi(buffer,buffer2);
649 free(buffer2);
650 return retval;