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

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

Win32Resource ctor bugfix

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