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

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

PE Resource changes

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