2 static char RCSId
[] = "$Id: resource.c,v 1.4 1993/07/04 04:04:21 root Exp root $";
3 static char Copyright
[] = "Copyright Robert J. Amstadt, 1993";
13 #include "prototypes.h"
20 #define MIN(a,b) ((a) < (b) ? (a) : (b))
22 typedef struct resource_s
24 struct resource_s
*next
;
27 struct resource_nameinfo_s nameinfo
;
31 static int ResourceFd
= -1;
32 static HANDLE ResourceInst
= 0;
33 static struct w_files
*ResourceFileInfo
= NULL
;
34 static RESOURCE
*Top
= NULL
;
35 extern HINSTANCE hSysRes
;
37 HANDLE
RSC_LoadResource(int instance
, char *rsc_name
, int type
, int *image_size_ret
);
39 extern char *ProgramName
;
41 /*****************************************************************************
42 * Super Patch, I promise to arrange things as soon as I can.
44 ******************************************************************************/
46 #include "../loader/wine.c"
50 /**********************************************************************
54 OpenResourceFile(HANDLE instance
)
59 if (ResourceInst
== instance
)
62 w
= GetFileInfo(instance
);
66 res_file
= w
->filename
;
71 ResourceInst
= instance
;
73 ResourceFd
= open (res_file
, O_RDONLY
);
76 printf("OpenResourceFile(%04X) // file='%s' hFile=%04X !\n",
77 instance
, w
->filename
, ResourceFd
);
82 /**********************************************************************
86 ConvertCoreBitmap( HDC hdc
, BITMAPCOREHEADER
* image
)
91 int i
, size
, n_colors
;
93 n_colors
= 1 << image
->bcBitCount
;
95 if (image
->bcBitCount
< 24)
97 size
= sizeof(BITMAPINFOHEADER
) + n_colors
* sizeof(RGBQUAD
);
98 bits
= (char *) (image
+ 1) + (n_colors
* sizeof(RGBTRIPLE
));
102 size
= sizeof(BITMAPINFOHEADER
);
103 bits
= (char *) (image
+ 1);
105 bmpInfo
= (BITMAPINFO
*) malloc( size
);
107 bmpInfo
->bmiHeader
.biSize
= sizeof(BITMAPINFOHEADER
);
108 bmpInfo
->bmiHeader
.biWidth
= image
->bcWidth
;
109 bmpInfo
->bmiHeader
.biHeight
= image
->bcHeight
;
110 bmpInfo
->bmiHeader
.biPlanes
= image
->bcPlanes
;
111 bmpInfo
->bmiHeader
.biBitCount
= image
->bcBitCount
;
112 bmpInfo
->bmiHeader
.biCompression
= 0;
113 bmpInfo
->bmiHeader
.biSizeImage
= 0;
114 bmpInfo
->bmiHeader
.biXPelsPerMeter
= 0;
115 bmpInfo
->bmiHeader
.biYPelsPerMeter
= 0;
116 bmpInfo
->bmiHeader
.biClrUsed
= 0;
117 bmpInfo
->bmiHeader
.biClrImportant
= 0;
119 if (image
->bcBitCount
< 24)
121 RGBTRIPLE
* oldMap
= (RGBTRIPLE
*)(image
+ 1);
122 RGBQUAD
* newMap
= bmpInfo
->bmiColors
;
123 for (i
= 0; i
< n_colors
; i
++, oldMap
++, newMap
++)
125 newMap
->rgbRed
= oldMap
->rgbtRed
;
126 newMap
->rgbGreen
= oldMap
->rgbtGreen
;
127 newMap
->rgbBlue
= oldMap
->rgbtBlue
;
128 newMap
->rgbReserved
= 0;
132 hbitmap
= CreateDIBitmap( hdc
, &bmpInfo
->bmiHeader
, CBM_INIT
,
133 bits
, bmpInfo
, DIB_RGB_COLORS
);
138 /**********************************************************************
142 ConvertInfoBitmap( HDC hdc
, BITMAPINFO
* image
)
144 char * bits
= ((char *)image
) + DIB_BitmapInfoSize(image
, DIB_RGB_COLORS
);
145 return CreateDIBitmap( hdc
, &image
->bmiHeader
, CBM_INIT
,
146 bits
, image
, DIB_RGB_COLORS
);
150 load_typeinfo (int fd
, struct resource_typeinfo_s
*typeinfo
)
152 return read (fd
, typeinfo
, sizeof (*typeinfo
)) == sizeof (*typeinfo
);
155 /**********************************************************************
156 * FindResourceByNumber
159 FindResourceByNumber(struct resource_nameinfo_s
*result_p
,
160 int type_id
, int resource_id
)
162 struct resource_typeinfo_s typeinfo
;
163 struct resource_nameinfo_s nameinfo
;
164 unsigned short size_shift
;
169 * Move to beginning of resource table.
171 rtoff
= (ResourceFileInfo
->mz_header
->ne_offset
+
172 ResourceFileInfo
->ne_header
->resource_tab_offset
);
173 lseek(ResourceFd
, rtoff
, SEEK_SET
);
178 if (read(ResourceFd
, &size_shift
, sizeof(size_shift
)) !=
181 printf("FindResourceByNumber (%s) bad block size !\n", resource_id
);
184 size_shift
= CONV_SHORT(size_shift
);
188 typeinfo
.type_id
= 0xffff;
189 while (typeinfo
.type_id
!= 0) {
190 if (!load_typeinfo (ResourceFd
, &typeinfo
)){
191 printf("FindResourceByNumber (%X) bad typeinfo size !\n", resource_id
);
194 #ifdef DEBUG_RESOURCE
195 printf("FindResourceByNumber type=%X count=%d searched=%d \n",
196 typeinfo
.type_id
, typeinfo
.count
, type_id
);
198 if (typeinfo
.type_id
== 0) break;
199 if (typeinfo
.type_id
== type_id
|| type_id
== -1) {
200 for (i
= 0; i
< typeinfo
.count
; i
++) {
202 if (read(ResourceFd
, &nameinfo
, sizeof(nameinfo
)) !=
205 if (!load_nameinfo (ResourceFd
, &nameinfo
))
208 printf("FindResourceByNumber (%X) bad nameinfo size !\n", resource_id
);
211 #ifdef DEBUG_RESOURCE
212 printf("FindResource: search type=%X id=%X // type=%X id=%X\n",
213 type_id
, resource_id
, typeinfo
.type_id
, nameinfo
.id
);
215 if (nameinfo
.id
== resource_id
) {
216 memcpy(result_p
, &nameinfo
, sizeof(nameinfo
));
222 lseek(ResourceFd
, (typeinfo
.count
* sizeof(nameinfo
)), SEEK_CUR
);
228 /**********************************************************************
232 FindResourceByName(struct resource_nameinfo_s
*result_p
,
233 int type_id
, char *resource_name
)
235 struct resource_typeinfo_s typeinfo
;
236 struct resource_nameinfo_s nameinfo
;
237 unsigned short size_shift
;
238 off_t old_pos
, new_pos
;
239 unsigned char nbytes
;
245 * Move to beginning of resource table.
247 rtoff
= (ResourceFileInfo
->mz_header
->ne_offset
+
248 ResourceFileInfo
->ne_header
->resource_tab_offset
);
249 lseek(ResourceFd
, rtoff
, SEEK_SET
);
254 if (read(ResourceFd
, &size_shift
, sizeof(size_shift
)) !=
257 printf("FindResourceByName (%s) bad block size !\n", resource_name
);
260 size_shift
= CONV_SHORT (size_shift
);
265 typeinfo
.type_id
= 0xffff;
266 while (typeinfo
.type_id
!= 0)
268 if (!load_typeinfo (ResourceFd
, &typeinfo
))
270 printf("FindResourceByName (%s) bad typeinfo size !\n", resource_name
);
273 #ifdef DEBUG_RESOURCE
274 printf("FindResourceByName typeinfo.type_id=%X count=%d type_id=%X\n",
275 typeinfo
.type_id
, typeinfo
.count
, type_id
);
277 if (typeinfo
.type_id
== 0) break;
278 if (typeinfo
.type_id
== type_id
|| type_id
== -1)
280 for (i
= 0; i
< typeinfo
.count
; i
++)
283 if (read(ResourceFd
, &nameinfo
, sizeof(nameinfo
)) !=
286 if (!load_nameinfo (ResourceFd
, &nameinfo
))
289 printf("FindResourceByName (%s) bad nameinfo size !\n", resource_name
);
293 if ((nameinfo.id & 0x8000) != 0) continue;
295 #ifdef DEBUG_RESOURCE
296 printf("FindResourceByName // nameinfo.id=%04X !\n", nameinfo
.id
);
298 old_pos
= lseek(ResourceFd
, 0, SEEK_CUR
);
299 new_pos
= rtoff
+ nameinfo
.id
;
300 lseek(ResourceFd
, new_pos
, SEEK_SET
);
301 read(ResourceFd
, &nbytes
, 1);
302 #ifdef DEBUG_RESOURCE
303 printf("FindResourceByName // namesize=%d !\n", nbytes
);
305 nbytes
= CONV_CHAR_TO_LONG (nbytes
);
306 read(ResourceFd
, name
, nbytes
);
307 lseek(ResourceFd
, old_pos
, SEEK_SET
);
309 #ifdef DEBUG_RESOURCE
310 printf("FindResourceByName type_id=%X (%d of %d) name='%s' resource_name='%s'\n",
311 typeinfo
.type_id
, i
+ 1, typeinfo
.count
,
312 name
, resource_name
);
314 /* if (strcasecmp(name, resource_name) == 0) */
315 if (strcasecmp(name
, resource_name
) == 0 ||
316 (nameinfo
.id
== 0x8001 && type_id
== NE_RSCTYPE_MENU
))
318 memcpy(result_p
, &nameinfo
, sizeof(nameinfo
));
324 lseek(ResourceFd
, (typeinfo
.count
* sizeof(nameinfo
)), SEEK_CUR
);
331 /**********************************************************************
332 * LoadIcon [USER.174]
334 HICON
LoadIcon(HANDLE instance
, LPSTR icon_name
)
339 ICONDESCRIP
*lpicodesc
;
343 BITMAPINFOHEADER
*bih
;
349 int i
, j
, image_size
;
350 #ifdef DEBUG_RESOURCE
351 printf("LoadIcon: instance = %04x, name = %08x\n",
352 instance
, icon_name
);
355 if (!(hdc
= GetDC(GetDesktopWindow()))) return 0;
356 if (instance
== (HANDLE
)NULL
) instance
= hSysRes
;
357 rsc_mem
= RSC_LoadResource(instance
, icon_name
, NE_RSCTYPE_GROUP_ICON
,
359 if (rsc_mem
== (HANDLE
)NULL
) {
360 printf("LoadIcon / Icon %04X not Found !\n", icon_name
);
361 ReleaseDC(GetDesktopWindow(), hdc
);
364 lp
= (WORD
*)GlobalLock(rsc_mem
);
367 ReleaseDC(GetDesktopWindow(), hdc
);
370 lpicodesc
= (ICONDESCRIP
*)(lp
+ 3);
371 hIcon
= GlobalAlloc(GMEM_MOVEABLE
, sizeof(ICONALLOC
) + 1024);
372 if (hIcon
== (HICON
)NULL
) {
374 ReleaseDC(GetDesktopWindow(), hdc
);
377 lpico
= (ICONALLOC
*)GlobalLock(hIcon
);
378 lpico
->descriptor
= *lpicodesc
;
379 width
= lpicodesc
->Width
;
380 height
= lpicodesc
->Height
;
381 GlobalUnlock(rsc_mem
);
383 rsc_mem
= RSC_LoadResource(instance
,
384 MAKEINTRESOURCE(lpicodesc
->icoDIBOffset
),
385 NE_RSCTYPE_ICON
, &image_size
);
386 if (rsc_mem
== (HANDLE
)NULL
) {
387 printf("LoadIcon / Icon %04X Bitmaps not Found !\n", icon_name
);
388 ReleaseDC(GetDesktopWindow(), hdc
);
391 lp
= (WORD
*)GlobalLock(rsc_mem
);
394 ReleaseDC(GetDesktopWindow(), hdc
);
397 bmi
= (BITMAPINFO
*)lp
;
398 bih
= (BITMAPINFOHEADER
*)lp
;
399 rgbq
= &bmi
->bmiColors
[0];
400 bih
->biHeight
= bih
->biHeight
/ 2;
402 printf("LoadIcon / image_size=%d width=%d height=%d bih->biBitCount=%d bih->biSizeImage=%ld\n",
403 image_size, width, height, bih->biBitCount, bih->biSizeImage);
405 if (bih
->biSize
== sizeof(BITMAPINFOHEADER
))
406 lpico
->hBitmap
= ConvertInfoBitmap(hdc
, (BITMAPINFO
*)bih
);
410 bih
->biClrUsed
= bih
->biClrImportant
= 2;
411 rgbq
[0].rgbBlue
= 0xFF;
412 rgbq
[0].rgbGreen
= 0xFF;
413 rgbq
[0].rgbRed
= 0xFF;
414 rgbq
[0].rgbReserved
= 0x00;
415 rgbq
[1].rgbBlue
= 0x00;
416 rgbq
[1].rgbGreen
= 0x00;
417 rgbq
[1].rgbRed
= 0x00;
418 rgbq
[1].rgbReserved
= 0x00;
419 lpico
->hBitMask
= CreateDIBitmap(hdc
, bih
, CBM_INIT
,
420 (LPSTR
)lp
+ bih
->biSizeImage
- sizeof(BITMAPINFOHEADER
) / 2 - 4,
421 (BITMAPINFO
*)bih
, DIB_RGB_COLORS
);
422 GlobalUnlock(rsc_mem
);
424 hMemDC
= CreateCompatibleDC(hdc
);
425 hMemDC2
= CreateCompatibleDC(hdc
);
426 SelectObject(hMemDC
, lpico
->hBitmap
);
427 SelectObject(hMemDC2
, lpico
->hBitMask
);
428 BitBlt(hMemDC
, 0, 0, bih
->biWidth
, bih
->biHeight
, hMemDC2
, 0, 0, SRCINVERT
);
431 ReleaseDC(GetDesktopWindow(), hdc
);
433 #ifdef DEBUG_RESOURCE
434 printf("LoadIcon Alloc hIcon=%X\n", hIcon
);
440 /**********************************************************************
441 * DestroyIcon [USER.457]
443 BOOL
DestroyIcon(HICON hIcon
)
446 if (hIcon
== (HICON
)NULL
) return FALSE
;
447 lpico
= (ICONALLOC
*)GlobalLock(hIcon
);
448 if (lpico
->hBitmap
!= (HBITMAP
)NULL
) DeleteObject(lpico
->hBitmap
);
454 /**********************************************************************
455 * LoadAccelerators [USER.177]
457 HANDLE
LoadAccelerators(HANDLE instance
, LPSTR lpTableName
)
462 ACCELHEADER
*lpAccelTbl
;
465 if (((LONG
)lpTableName
& 0xFFFF0000L
) == 0L)
466 printf("LoadAccelerators: instance = %04X, name = %08X\n",
467 instance
, lpTableName
);
469 printf("LoadAccelerators: instance = %04X, name = '%s'\n",
470 instance
, lpTableName
);
472 if (instance
== (HANDLE
)NULL
) instance
= hSysRes
;
473 rsc_mem
= RSC_LoadResource(instance
, lpTableName
, NE_RSCTYPE_ACCELERATOR
,
475 if (rsc_mem
== (HANDLE
)NULL
) {
476 printf("LoadAccelerators / AccelTable %04X not Found !\n", lpTableName
);
479 lp
= (BYTE
*)GlobalLock(rsc_mem
);
485 printf("LoadAccelerators / image_size=%d\n", image_size
);
487 hAccel
= GlobalAlloc(GMEM_MOVEABLE
,
488 sizeof(ACCELHEADER
) + sizeof(ACCELENTRY
) + image_size
);
489 lpAccelTbl
= (LPACCELHEADER
)GlobalLock(hAccel
);
490 lpAccelTbl
->wCount
= 0;
492 lpAccelTbl
->tbl
[i
].type
= *(lp
++);
493 lpAccelTbl
->tbl
[i
].wEvent
= *((WORD
*)lp
);
495 lpAccelTbl
->tbl
[i
].wIDval
= *((WORD
*)lp
);
497 if (lpAccelTbl
->tbl
[i
].wEvent
== 0) break;
499 printf("Accelerator #%u / event=%04X id=%04X type=%02X \n",
500 i
, lpAccelTbl
->tbl
[i
].wEvent
, lpAccelTbl
->tbl
[i
].wIDval
,
501 lpAccelTbl
->tbl
[i
].type
);
503 lpAccelTbl
->wCount
++;
505 GlobalUnlock(hAccel
);
506 GlobalUnlock(rsc_mem
);
511 /**********************************************************************
512 * TranslateAccelerator [USER.178]
514 int TranslateAccelerator(HWND hWnd
, HANDLE hAccel
, LPMSG msg
)
516 ACCELHEADER
*lpAccelTbl
;
518 if (hAccel
== 0 || msg
== NULL
) return 0;
519 if (msg
->message
!= WM_KEYDOWN
&&
520 msg
->message
!= WM_KEYUP
&&
521 msg
->message
!= WM_CHAR
) return 0;
523 printf("TranslateAccelerators hAccel=%04X !\n", hAccel
);
525 lpAccelTbl
= (LPACCELHEADER
)GlobalLock(hAccel
);
526 for (i
= 0; i
< lpAccelTbl
->wCount
; i
++) {
527 /* if (lpAccelTbl->tbl[i].type & SHIFT_ACCEL) { */
528 /* if (lpAccelTbl->tbl[i].type & CONTROL_ACCEL) { */
529 if (lpAccelTbl
->tbl
[i
].type
& VIRTKEY_ACCEL
) {
530 if (msg
->wParam
== lpAccelTbl
->tbl
[i
].wEvent
&&
531 msg
->message
== WM_KEYDOWN
) {
532 SendMessage(hWnd
, WM_COMMAND
, lpAccelTbl
->tbl
[i
].wIDval
, 0x00010000L
);
535 if (msg
->message
== WM_KEYUP
) return 1;
538 if (msg
->wParam
== lpAccelTbl
->tbl
[i
].wEvent
&&
539 msg
->message
== WM_CHAR
) {
540 SendMessage(hWnd
, WM_COMMAND
, lpAccelTbl
->tbl
[i
].wIDval
, 0x00010000L
);
545 GlobalUnlock(hAccel
);
549 /**********************************************************************
550 * FindResource [KERNEL.60]
552 HANDLE
FindResource(HANDLE instance
, LPSTR resource_name
, LPSTR type_name
)
560 #ifdef DEBUG_RESOURCE
561 printf("FindResource hInst=%04X typename=%08X resname=%08X\n",
562 instance
, type_name
, resource_name
);
564 if (OpenResourceFile(instance
) < 0)
567 rh
= GlobalAlloc(GMEM_MOVEABLE
, sizeof(*r
));
570 r
= (RESOURCE
*)GlobalLock(rh
);
577 if (((int) resource_name
& 0xffff0000) == 0)
579 r
->size_shift
= FindResourceByNumber(&r
->nameinfo
, (int)type_name
,
580 (int) resource_name
| 0x8000);
584 r
->size_shift
= FindResourceByName(&r
->nameinfo
, (int)type_name
,
588 if (r
->size_shift
== -1)
597 /**********************************************************************
598 * LoadResource [KERNEL.61]
600 HANDLE
LoadResource(HANDLE instance
, HANDLE hResInfo
)
610 if (OpenResourceFile(instance
) < 0)
613 r
= (RESOURCE
*)GlobalLock(hResInfo
);
617 image_size
= r
->nameinfo
.length
<< r
->size_shift
;
619 h
= r
->rsc_mem
= GlobalAlloc(GMEM_MOVEABLE
, image_size
);
620 image
= GlobalLock(h
);
622 lseek(ResourceFd
, ((int) r
->nameinfo
.offset
<< r
->size_shift
), SEEK_SET
);
624 if (image
== NULL
|| read(ResourceFd
, image
, image_size
) != image_size
)
627 GlobalUnlock(hResInfo
);
632 GlobalUnlock(hResInfo
);
636 /**********************************************************************
637 * LockResource [KERNEL.62]
639 LPSTR
LockResource(HANDLE hResData
)
641 return GlobalLock(hResData
);
644 /**********************************************************************
645 * FreeResource [KERNEL.63]
647 HANDLE
FreeResource(HANDLE hResData
)
651 for (r
= rp
= Top
; r
!= NULL
; r
= r
->next
)
653 if (r
->info_mem
== hResData
)
660 GlobalFree(r
->rsc_mem
);
661 GlobalFree(r
->info_mem
);
669 /**********************************************************************
670 * AccessResource [KERNEL.64]
672 int AccessResource(HANDLE instance
, HANDLE hResInfo
)
675 #ifdef DEBUG_RESOURCE
676 printf("AccessResource(%04X, %04X);\n", instance
, hResInfo
);
679 resfile = OpenResourceFile(instance);
687 /**********************************************************************
691 RSC_LoadResource(int instance
, char *rsc_name
, int type
, int *image_size_ret
)
693 struct resource_nameinfo_s nameinfo
;
706 else if (OpenResourceFile(instance
) < 0)
710 * Get resource by ordinal
712 if (((int) rsc_name
& 0xffff0000) == 0)
714 size_shift
= FindResourceByNumber(&nameinfo
, type
,
715 (int) rsc_name
| 0x8000);
718 * Get resource by name
722 size_shift
= FindResourceByName(&nameinfo
, type
, rsc_name
);
724 if (size_shift
== -1) {
725 if ((LONG
)rsc_name
>= 0x00010000L
)
726 printf("RSC_LoadResource / Resource '%s' not Found !\n", rsc_name
);
728 printf("RSC_LoadResource / Resource '%X' not Found !\n", rsc_name
);
734 lseek(ResourceFd
, ((int) nameinfo
.offset
<< size_shift
), SEEK_SET
);
736 image_size
= nameinfo
.length
<< size_shift
;
737 if (image_size_ret
!= NULL
)
738 *image_size_ret
= image_size
;
739 hmem
= GlobalAlloc(GMEM_MOVEABLE
, image_size
);
740 image
= GlobalLock(hmem
);
741 if (image
== NULL
|| read(ResourceFd
, image
, image_size
) != image_size
)
751 /**********************************************************************
755 LoadString(HANDLE instance
, WORD resource_id
, LPSTR buffer
, int buflen
)
763 #ifdef DEBUG_RESOURCE
764 printf("LoadString: instance = %04x, id = %d, "
765 "buffer = %08x, length = %d\n",
766 instance
, resource_id
, buffer
, buflen
);
769 hmem
= RSC_LoadResource(instance
, (char *) ((resource_id
>> 4) + 1),
770 NE_RSCTYPE_STRING
, &rsc_size
);
774 p
= GlobalLock(hmem
);
775 string_num
= resource_id
& 0x000f;
776 for (i
= 0; i
< string_num
; i
++)
779 i
= MIN(buflen
- 1, *p
);
780 memcpy(buffer
, p
+ 1, i
);
785 #ifdef DEBUG_RESOURCE
786 printf(" '%s'\n", buffer
);
791 /**********************************************************************
795 RSC_LoadMenu(HANDLE instance
, LPSTR menu_name
)
797 return RSC_LoadResource(instance
, menu_name
, NE_RSCTYPE_MENU
, NULL
);
800 /**********************************************************************
804 LoadBitmap(HANDLE instance
, LPSTR bmp_name
)
812 #ifdef DEBUG_RESOURCE
813 printf("LoadBitmap: instance = %04x, name = %08x\n",
816 if (instance
== (HANDLE
)NULL
) instance
= hSysRes
;
817 if (!(hdc
= GetDC(GetDesktopWindow()))) return 0;
819 rsc_mem
= RSC_LoadResource(instance
, bmp_name
, NE_RSCTYPE_BITMAP
,
821 if (rsc_mem
== (HANDLE
)NULL
) {
822 printf("LoadBitmap / BitMap %04X not Found !\n", bmp_name
);
825 lp
= (long *) GlobalLock(rsc_mem
);
831 if (*lp
== sizeof(BITMAPCOREHEADER
))
832 hbitmap
= ConvertCoreBitmap( hdc
, (BITMAPCOREHEADER
*) lp
);
833 else if (*lp
== sizeof(BITMAPINFOHEADER
))
834 hbitmap
= ConvertInfoBitmap( hdc
, (BITMAPINFO
*) lp
);