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

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

More PE resource changes

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