source: trunk/src/kernel32/winres.cpp@ 932

Last change on this file since 932 was 932, checked in by sandervl, 26 years ago

* empty log message *

File size: 13.6 KB
Line 
1/* $Id: winres.cpp,v 1.17 1999-09-14 16:55:38 sandervl Exp $ */
2
3/*
4 * Win32 resource class
5 *
6 * Copyright 1998 Sander van Leeuwen (sandervl@xs4all.nl)
7 *
8 *
9 * Project Odin Software License can be found in LICENSE.TXT
10 *
11 *
12 */
13#define INCL_BASE
14#define INCL_WIN
15#define INCL_GPIBITMAPS
16#define INCL_BITMAPFILEFORMAT
17#define INCL_DOSMODULEMGR
18#include <os2wrap.h> //Odin32 OS/2 api wrappers
19#include <stdarg.h>
20#ifdef __IBMCPP__
21#include <builtin.h>
22#endif
23#include <stdio.h>
24#include <stdlib.h>
25#include <string.h>
26#define INCL_WINRES
27#include <win32type.h>
28#include <winres.h>
29#include <misc.h>
30#include <winexebase.h>
31#include <winexepe2lx.h>
32#include "cvtresource.h"
33#include <vmutex.h>
34
35VMutex resmutex;
36
37//******************************************************************************
38//******************************************************************************
39static ULONG CalcBitmapSize(ULONG cBits, LONG cx, LONG cy)
40{
41 ULONG alignment;
42 ULONG factor;
43 BOOL flag = TRUE; //true: '*' false: '/'
44
45 cy = cy < 0 ? -cy : cy;
46
47 switch(cBits)
48 {
49 case 1:
50 factor = 8;
51 flag = FALSE;
52 break;
53
54 case 4:
55 factor = 2;
56 flag = FALSE;
57 break;
58
59 case 8:
60 factor = 1;
61 break;
62
63 case 16:
64 factor = 2;
65 break;
66
67 case 24:
68 factor = 3;
69 break;
70
71 case 32:
72 return cx*cy;
73
74 default:
75 return 0;
76 }
77
78 if (flag)
79 alignment = (cx = (cx*factor)) % 4;
80 else
81 alignment = (cx = ((cx+factor-1)/factor)) % 4;
82
83 if (alignment != 0)
84 cx += 4 - alignment;
85
86 return cx*cy;
87}
88
89//******************************************************************************
90//******************************************************************************
91Win32Resource::Win32Resource() :
92 os2resdata(NULL), winresdata(NULL), resType(RSRC_CUSTOMNODATA)
93{
94 module = NULL;
95 id = -1;
96 type = -1;
97 hres = 0;
98 orgos2type = -1;
99 OS2ResHandle = 0;
100 //resources are in Unicode format by default; indirectly created resources
101 //can also be in ascii format
102 isUnicode = TRUE;
103}
104//******************************************************************************
105//******************************************************************************
106Win32Resource::Win32Resource(Win32ImageBase *module, HRSRC hRes, ULONG id, ULONG type) :
107 os2resdata(NULL), winresdata(NULL), resType(RSRC_PE2LX)
108{
109 APIRET rc;
110
111 resmutex.enter();
112 next = module->winres;
113 module->winres = this;
114 resmutex.leave();
115
116 this->module = module;
117 this->id = id;
118 this->type = type;
119 this->hres = hRes;
120
121 switch(type) {
122 case NTRT_NEWBITMAP:
123 case NTRT_BITMAP:
124 orgos2type = RT_BITMAP;
125 break;
126 case NTRT_CURSOR:
127 case NTRT_GROUP_CURSOR:
128 case NTRT_GROUP_ICON:
129 case NTRT_ICON:
130 orgos2type = RT_POINTER;
131 break;
132 case NTRT_ACCELERATORS:
133 orgos2type = RT_ACCELTABLE;
134 break;
135 case NTRT_NEWMENU:
136 case NTRT_MENU:
137 orgos2type = RT_MENU;
138 break;
139 case NTRT_NEWDIALOG:
140 case NTRT_DIALOG:
141 orgos2type = RT_DIALOG;
142 break;
143 case NTRT_FONTDIR:
144 case NTRT_FONT:
145 case NTRT_MESSAGETABLE:
146 case NTRT_STRING:
147 case NTRT_RCDATA:
148 case NTRT_VERSION:
149 default:
150 orgos2type = RT_RCDATA;
151 break;
152 }
153 OS2ResHandle = 0;
154
155 rc = DosQueryResourceSize(module->hinstance, orgos2type, id, &ressize);
156 if(rc) {
157 dprintf(("Win32Resource ctor: DosQueryResourceSize %x %d %d returned %X\n", module->hinstance, type, id, rc));
158 ressize = 0;
159 }
160 //resources are in Unicode format by default
161 isUnicode = TRUE;
162}
163//******************************************************************************
164//******************************************************************************
165Win32Resource::Win32Resource(Win32ImageBase *module, ULONG id, ULONG type,
166 ULONG size, char *resdata) : hres(NULL),
167 os2resdata(NULL), winresdata(NULL), resType(RSRC_PELOADER)
168{
169 resmutex.enter();
170 next = module->winres;
171 module->winres = this;
172 resmutex.leave();
173
174 this->module = module;
175 this->id = id;
176 this->type = type;
177 orgos2type = -1;
178 this->ressize = size;
179 winresdata = (char *)malloc(size);
180 if(winresdata == NULL) {
181 DebugInt3();
182 return;
183 }
184 OS2ResHandle = 0;
185
186 if(type == NTRT_STRING) {
187 memcpy(winresdata, resdata, size-sizeof(WCHAR));
188 ((USHORT *)winresdata)[size/sizeof(WCHAR)-1] = 0;
189 }
190 else memcpy(winresdata, resdata, size);
191
192 //resources are in Unicode format by default
193 isUnicode = TRUE;
194}
195//******************************************************************************
196//******************************************************************************
197Win32Resource::~Win32Resource()
198{
199 Win32Resource *res = module->winres;
200
201 //returned by DosGetResource, so we don't (and mustn't) free it
202 if(os2resdata && (resType == RSRC_PELOADER || resType == RSRC_CUSTOMINDIRECT))
203 free(os2resdata);
204
205 if(winresdata) free(winresdata);
206
207 resmutex.enter();
208 if(res == this) {
209 module->winres = res->next;
210 }
211 else {
212 while(res->next != this) {
213 res = res->next;
214 }
215 if(res)
216 res->next = next;
217 }
218 resmutex.leave();
219}
220//******************************************************************************
221//******************************************************************************
222PVOID Win32Resource::lockResource()
223{
224 int restype = 0, newid;
225 void *resdata = NULL;
226 APIRET rc;
227 ULONG os2type = RT_RCDATA;
228
229 dprintf(("Win32Resource::lockResource %d\n", id));
230 if(winresdata)
231 return(winresdata);
232
233 switch(type) {
234 case NTRT_BITMAP:
235 rc = DosGetResource((HMODULE)module->hinstance, RT_BITMAP, id, (PPVOID)&resdata);
236 if(rc) return(NULL);
237 winresdata = convertOS2Bitmap((BITMAPFILEHEADER2 *)resdata);
238 break;
239
240 case NTRT_ACCELERATORS:
241 case NTRT_MENU:
242 case NTRT_DIALOG:
243 newid = ((Win32Pe2LxImage *)module)->getWin32ResourceId(id);
244
245 rc = DosGetResource((HMODULE)module->hinstance, RT_RCDATA, (int)newid, (PPVOID)&resdata);
246 if(rc) {
247 dprintf(("Can't find original resource!!!\n"));
248 return(NULL);
249 }
250 winresdata = (char *)malloc(ressize);
251 memcpy(winresdata, resdata, ressize);
252 break;
253
254 //TODO:not yet implemented
255 case NTRT_FONTDIR:
256 case NTRT_FONT:
257 case NTRT_MESSAGETABLE:
258 case NTRT_NEWBITMAP:
259 case NTRT_NEWMENU:
260 case NTRT_NEWDIALOG:
261 os2type = RT_RCDATA;
262 break;
263
264 //Can't do this right now (all group icons stored into a single one)
265 case NTRT_CURSOR:
266 case NTRT_GROUP_CURSOR:
267 case NTRT_GROUP_ICON:
268 case NTRT_ICON:
269 dprintf(("Can't convert this resource!!!!!\n"));
270 os2type = RT_POINTER;
271 break;
272
273 case NTRT_STRING:
274 rc = DosGetResource((HMODULE)module->hinstance, RT_RCDATA, id, (PPVOID)&resdata);
275 if(rc) {
276 dprintf(("Can't find original string!!!\n"));
277 return(NULL);
278 }
279 winresdata = malloc(ressize+sizeof(WCHAR));
280 memcpy(winresdata, resdata, ressize);
281 *(USHORT *)(&((char *)winresdata)[ressize]) = 0;
282 DosFreeResource(resdata);
283 return((PVOID)((ULONG)winresdata+2)); //skip length word
284
285 //no conversion necessary
286 case NTRT_RCDATA:
287 case NTRT_VERSION:
288 default:
289 os2type = RT_RCDATA;
290 break;
291 }
292
293 if(winresdata == NULL) {
294 rc = DosGetResource((HMODULE)module->hinstance, os2type, id, (PPVOID)&resdata);
295 if(rc) {
296 dprintf(("Can't find original resource!!!\n"));
297 return(NULL);
298 }
299 winresdata = (char *)malloc(ressize);
300 memcpy(winresdata, resdata, ressize);
301 }
302 if(resdata)
303 DosFreeResource(resdata);
304
305 return winresdata;
306}
307//******************************************************************************
308//******************************************************************************
309PVOID Win32Resource::lockOS2Resource()
310{
311 APIRET rc;
312 PVOID resdata;
313
314 dprintf(("Win32Resource::lockOS2Resource %d\n", id));
315 if(os2resdata == NULL) {
316 if(resType == RSRC_PELOADER || resType == RSRC_CUSTOMINDIRECT) {
317 os2resdata = convertResource(winresdata);
318 }
319 else {
320 rc = DosGetResource((HMODULE)module->hinstance, orgos2type, id, (PPVOID)&resdata);
321 if(rc) return(NULL);
322 os2resdata = resdata;
323 }
324 }
325 return os2resdata;
326}
327//******************************************************************************
328//return size of converted win32 resource
329//******************************************************************************
330ULONG Win32Resource::getOS2Size()
331{
332 switch(type) {
333 case NTRT_NEWBITMAP:
334 case NTRT_BITMAP:
335 return QueryConvertedBitmapSize((WINBITMAPINFOHEADER *)winresdata, ressize);
336
337 case NTRT_CURSOR:
338 return QueryConvertedCursorSize((CursorComponent *)winresdata, ressize);
339
340 case NTRT_ICON:
341 return QueryConvertedIconSize((WINBITMAPINFOHEADER *)winresdata, ressize);
342
343 case NTRT_GROUP_ICON:
344 case NTRT_GROUP_CURSOR:
345 case NTRT_ACCELERATORS:
346 case NTRT_NEWMENU:
347 case NTRT_MENU:
348 case NTRT_NEWDIALOG:
349 case NTRT_DIALOG:
350 case NTRT_FONTDIR:
351 case NTRT_FONT:
352 case NTRT_MESSAGETABLE:
353 case NTRT_RCDATA:
354 case NTRT_VERSION:
355 case NTRT_STRING:
356 default:
357 dprintf(("Win32Resource::getOS2Size SHOULDN'T BE CALLED for this resource type (%d) (NOT IMPLEMENTED)!!", type));
358 break;
359 }
360 return 0;
361}
362//******************************************************************************
363//******************************************************************************
364PVOID Win32Resource::convertResource(void *win32res)
365{
366 int cvtressize;
367
368 switch(type) {
369 case NTRT_NEWBITMAP:
370 case NTRT_BITMAP:
371 return ConvertBitmap((WINBITMAPINFOHEADER *)win32res, ressize, &ressize);
372
373 case NTRT_CURSOR:
374 return ConvertCursor((CursorComponent *)win32res, ressize, &cvtressize);
375
376 case NTRT_GROUP_CURSOR:
377 return ConvertCursorGroup((CursorHeader *)win32res, ressize, module);
378
379 case NTRT_GROUP_ICON:
380 return ConvertIconGroup((IconHeader *)win32res, ressize, module);
381
382 case NTRT_ICON:
383 return ConvertIcon((WINBITMAPINFOHEADER *)win32res, ressize, &cvtressize);
384
385 case NTRT_ACCELERATORS:
386 return ConvertAccelerator((WINACCEL *)win32res, ressize);
387
388 case NTRT_NEWMENU:
389 case NTRT_MENU:
390 return ConvertMenu((MenuHeader *)win32res, ressize, isUnicode);
391
392 case NTRT_NEWDIALOG:
393 case NTRT_DIALOG:
394 break;
395 case NTRT_FONTDIR:
396 case NTRT_FONT:
397 case NTRT_MESSAGETABLE:
398 case NTRT_RCDATA:
399 case NTRT_VERSION:
400 case NTRT_STRING:
401 break;
402
403 default:
404 break;
405 }
406 dprintf(("Win32Resource::convertResource: Can't convert resource %d (type %d)", id, type));
407 return 0;
408}
409//******************************************************************************
410//NOTE: Will be removed once pe2lx rewrite has been completed
411//******************************************************************************
412PVOID Win32Resource::convertOS2Bitmap(void *bmpdata)
413{
414 BITMAPFILEHEADER2 *bmphdr = (BITMAPFILEHEADER2 *)bmpdata;
415 WINBITMAPINFOHEADER *winbmphdr;
416 RGBQUAD *rgb;
417 RGB2 *os2rgb;
418 int palsize = 0;
419 int imgsize;
420
421 if(bmphdr->cbSize != sizeof(BITMAPFILEHEADER2)) {
422 PVOID bmpdat = malloc(ressize);
423 memcpy(bmpdat, bmpdata, ressize);
424 return(bmpdat); //don't convert OS/2 1.x bitmap
425 }
426
427 if(bmphdr->bmp2.cBitCount < 16) {
428 palsize = (1 << bmphdr->bmp2.cBitCount) * sizeof(RGBQUAD);
429 }
430
431 //SvL: Always recalculate bitmap size (donut.exe has wrong size)
432 imgsize = CalcBitmapSize(bmphdr->bmp2.cBitCount,
433 bmphdr->bmp2.cx,
434 bmphdr->bmp2.cy);
435
436 winbmphdr = (WINBITMAPINFOHEADER *)malloc(sizeof(WINBITMAPINFOHEADER) +
437 imgsize + palsize);
438 memset((char *)winbmphdr, 0, sizeof(WINBITMAPINFOHEADER) + imgsize + palsize);
439
440 winbmphdr->biSize = sizeof(WINBITMAPINFOHEADER);
441 winbmphdr->biWidth = bmphdr->bmp2.cx;
442 winbmphdr->biHeight = bmphdr->bmp2.cy;
443 winbmphdr->biPlanes = bmphdr->bmp2.cPlanes;
444 winbmphdr->biBitCount = bmphdr->bmp2.cBitCount;
445 //TODO: Identical except for BI_BITFIELDS (3L) type!
446 winbmphdr->biCompression = bmphdr->bmp2.ulCompression;
447 winbmphdr->biSizeImage = imgsize;
448 //TODO: Doesn't seem to be completely identical..
449 winbmphdr->biClrUsed = bmphdr->bmp2.cclrUsed;
450 winbmphdr->biClrImportant = bmphdr->bmp2.cclrImportant;
451 winbmphdr->biXPelsPerMeter = bmphdr->bmp2.cxResolution;
452 winbmphdr->biYPelsPerMeter = bmphdr->bmp2.cyResolution;
453
454 os2rgb = (RGB2 *)(bmphdr+1);
455 rgb = (RGBQUAD *)(winbmphdr+1);
456
457 if(palsize) {
458 memcpy((char *)rgb, (char *)os2rgb, palsize);
459 os2rgb = (RGB2 *)((int)os2rgb + palsize);
460 rgb = (RGBQUAD *)((int)rgb + palsize);
461 }
462 memcpy((char *)rgb, (char *)os2rgb, imgsize);
463 return((PVOID)winbmphdr);
464}
465//******************************************************************************
466//******************************************************************************
467void Win32Resource::destroyAll(Win32ImageBase *module)
468{
469 Win32Resource *res = module->winres, *next;
470
471 while(res) {
472 next = res->next;
473 delete(res);
474 res = next;
475 }
476}
477//******************************************************************************
478//******************************************************************************
Note: See TracBrowser for help on using the repository browser.