New debug scheme with explicit debug channels declaration.
[wine.git] / loader / ne / convert.c
bloba97af8e3bb76f8728a7ec80c5efc3f70bdb0f62b
1 /*
2 * PE->NE resource conversion functions
4 * Copyright 1998 Ulrich Weigand
5 */
7 #include <string.h>
8 #include "wine/winuser16.h"
9 #include "module.h"
10 #include "debug.h"
11 #include "debugtools.h"
13 DEFAULT_DEBUG_CHANNEL(resource)
15 /**********************************************************************
16 * ConvertDialog32To16 (KERNEL.615)
18 VOID WINAPI ConvertDialog32To16( LPVOID dialog32, DWORD size, LPVOID dialog16 )
20 LPVOID p = dialog32;
21 WORD nbItems, data, dialogEx;
22 DWORD style;
24 style = *((DWORD *)dialog16)++ = *((DWORD *)p)++;
25 dialogEx = (style == 0xffff0001); /* DIALOGEX resource */
26 if (dialogEx)
28 *((DWORD *)dialog16)++ = *((DWORD *)p)++; /* helpID */
29 *((DWORD *)dialog16)++ = *((DWORD *)p)++; /* exStyle */
30 style = *((DWORD *)dialog16)++ = *((DWORD *)p)++; /* style */
32 else
33 ((DWORD *)p)++; /* exStyle ignored in 16-bit standard dialog */
35 nbItems = *((BYTE *)dialog16)++ = (BYTE)*((WORD *)p)++;
36 *((WORD *)dialog16)++ = *((WORD *)p)++; /* x */
37 *((WORD *)dialog16)++ = *((WORD *)p)++; /* y */
38 *((WORD *)dialog16)++ = *((WORD *)p)++; /* cx */
39 *((WORD *)dialog16)++ = *((WORD *)p)++; /* cy */
41 /* Transfer menu name */
42 switch (*((WORD *)p))
44 case 0x0000: ((WORD *)p)++; *((BYTE *)dialog16)++ = 0; break;
45 case 0xffff: ((WORD *)p)++; *((BYTE *)dialog16)++ = 0xff;
46 *((WORD *)dialog16)++ = *((WORD *)p)++; break;
47 default: lstrcpyWtoA( (LPSTR)dialog16, (LPWSTR)p );
48 ((LPSTR)dialog16) += lstrlenA( (LPSTR)dialog16 ) + 1;
49 ((LPWSTR)p) += lstrlenW( (LPWSTR)p ) + 1;
50 break;
53 /* Transfer class name */
54 switch (*((WORD *)p))
56 case 0x0000: ((WORD *)p)++; *((BYTE *)dialog16)++ = 0; break;
57 case 0xffff: ((WORD *)p)++; *((BYTE *)dialog16)++ = 0xff;
58 *((WORD *)dialog16)++ = *((WORD *)p)++; break;
59 default: lstrcpyWtoA( (LPSTR)dialog16, (LPWSTR)p );
60 ((LPSTR)dialog16) += lstrlenA( (LPSTR)dialog16 ) + 1;
61 ((LPWSTR)p) += lstrlenW( (LPWSTR)p ) + 1;
62 break;
65 /* Transfer window caption */
66 lstrcpyWtoA( (LPSTR)dialog16, (LPWSTR)p );
67 ((LPSTR)dialog16) += lstrlenA( (LPSTR)dialog16 ) + 1;
68 ((LPWSTR)p) += lstrlenW( (LPWSTR)p ) + 1;
70 /* Transfer font info */
71 if (style & DS_SETFONT)
73 *((WORD *)dialog16)++ = *((WORD *)p)++; /* pointSize */
74 if (dialogEx)
76 *((WORD *)dialog16)++ = *((WORD *)p)++; /* weight */
77 *((WORD *)dialog16)++ = *((WORD *)p)++; /* italic */
79 lstrcpyWtoA( (LPSTR)dialog16, (LPWSTR)p ); /* faceName */
80 ((LPSTR)dialog16) += lstrlenA( (LPSTR)dialog16 ) + 1;
81 ((LPWSTR)p) += lstrlenW( (LPWSTR)p ) + 1;
84 /* Transfer dialog items */
85 while (nbItems)
87 /* align on DWORD boundary (32-bit only) */
88 p = (LPVOID)((((int)p) + 3) & ~3);
90 if (dialogEx)
92 *((DWORD *)dialog16)++ = *((DWORD *)p)++; /* helpID */
93 *((DWORD *)dialog16)++ = *((DWORD *)p)++; /* exStyle */
94 *((DWORD *)dialog16)++ = *((DWORD *)p)++; /* style */
96 else
98 style = *((DWORD *)p)++; /* save style */
99 ((DWORD *)p)++; /* ignore exStyle */
102 *((WORD *)dialog16)++ = *((WORD *)p)++; /* x */
103 *((WORD *)dialog16)++ = *((WORD *)p)++; /* y */
104 *((WORD *)dialog16)++ = *((WORD *)p)++; /* cx */
105 *((WORD *)dialog16)++ = *((WORD *)p)++; /* cy */
107 if (dialogEx)
108 *((DWORD *)dialog16)++ = *((DWORD *)p)++; /* ID */
109 else
111 *((WORD *)dialog16)++ = *((WORD *)p)++; /* ID */
112 *((DWORD *)dialog16)++ = style; /* style from above */
115 /* Transfer class name */
116 switch (*((WORD *)p))
118 case 0x0000: ((WORD *)p)++; *((BYTE *)dialog16)++ = 0; break;
119 case 0xffff: ((WORD *)p)++;
120 *((BYTE *)dialog16)++ = (BYTE)*((WORD *)p)++; break;
121 default: lstrcpyWtoA( (LPSTR)dialog16, (LPWSTR)p );
122 ((LPSTR)dialog16) += lstrlenA( (LPSTR)dialog16 ) + 1;
123 ((LPWSTR)p) += lstrlenW( (LPWSTR)p ) + 1;
124 break;
127 /* Transfer window name */
128 switch (*((WORD *)p))
130 case 0x0000: ((WORD *)p)++; *((BYTE *)dialog16)++ = 0; break;
131 case 0xffff: ((WORD *)p)++; *((BYTE *)dialog16)++ = 0xff;
132 *((WORD *)dialog16)++ = *((WORD *)p)++; break;
133 default: lstrcpyWtoA( (LPSTR)dialog16, (LPWSTR)p );
134 ((LPSTR)dialog16) += lstrlenA( (LPSTR)dialog16 ) + 1;
135 ((LPWSTR)p) += lstrlenW( (LPWSTR)p ) + 1;
136 break;
139 /* Transfer data */
140 data = *((WORD *)p)++;
141 if (dialogEx)
142 *((WORD *)dialog16)++ = data;
143 else
144 *((BYTE *)dialog16)++ = (BYTE)data;
146 if (data)
148 memcpy( dialog16, p, data );
149 (LPSTR)dialog16 += data;
150 (LPSTR)p += data;
153 /* Next item */
154 nbItems--;
158 /**********************************************************************
159 * GetDialog32Size (KERNEL.618)
161 WORD WINAPI GetDialog32Size16( LPVOID dialog32 )
163 LPVOID p = dialog32;
164 WORD nbItems, data, dialogEx;
165 DWORD style;
167 style = *((DWORD *)p)++;
168 dialogEx = (style == 0xffff0001); /* DIALOGEX resource */
169 if (dialogEx)
171 ((DWORD *)p)++; /* helpID */
172 ((DWORD *)p)++; /* exStyle */
173 style = *((DWORD *)p)++; /* style */
175 else
176 ((DWORD *)p)++; /* exStyle */
178 nbItems = *((WORD *)p)++;
179 ((WORD *)p)++; /* x */
180 ((WORD *)p)++; /* y */
181 ((WORD *)p)++; /* cx */
182 ((WORD *)p)++; /* cy */
184 /* Skip menu name */
185 switch (*((WORD *)p))
187 case 0x0000: ((WORD *)p)++; break;
188 case 0xffff: ((WORD *)p) += 2; break;
189 default: ((LPWSTR)p) += lstrlenW( (LPWSTR)p ) + 1; break;
192 /* Skip class name */
193 switch (*((WORD *)p))
195 case 0x0000: ((WORD *)p)++; break;
196 case 0xffff: ((WORD *)p) += 2; break;
197 default: ((LPWSTR)p) += lstrlenW( (LPWSTR)p ) + 1; break;
200 /* Skip window caption */
201 ((LPWSTR)p) += lstrlenW( (LPWSTR)p ) + 1;
203 /* Skip font info */
204 if (style & DS_SETFONT)
206 ((WORD *)p)++; /* pointSize */
207 if (dialogEx)
209 ((WORD *)p)++; /* weight */
210 ((WORD *)p)++; /* italic */
212 ((LPWSTR)p) += lstrlenW( (LPWSTR)p ) + 1; /* faceName */
215 /* Skip dialog items */
216 while (nbItems)
218 /* align on DWORD boundary */
219 p = (LPVOID)((((int)p) + 3) & ~3);
221 if (dialogEx)
223 ((DWORD *)p)++; /* helpID */
224 ((DWORD *)p)++; /* exStyle */
225 ((DWORD *)p)++; /* style */
227 else
229 ((DWORD *)p)++; /* style */
230 ((DWORD *)p)++; /* exStyle */
233 ((WORD *)p)++; /* x */
234 ((WORD *)p)++; /* y */
235 ((WORD *)p)++; /* cx */
236 ((WORD *)p)++; /* cy */
238 if (dialogEx)
239 ((DWORD *)p)++; /* ID */
240 else
241 ((WORD *)p)++; /* ID */
243 /* Skip class name */
244 switch (*((WORD *)p))
246 case 0x0000: ((WORD *)p)++; break;
247 case 0xffff: ((WORD *)p) += 2; break;
248 default: ((LPWSTR)p) += lstrlenW( (LPWSTR)p ) + 1; break;
251 /* Skip window name */
252 switch (*((WORD *)p))
254 case 0x0000: ((WORD *)p)++; break;
255 case 0xffff: ((WORD *)p) += 2; break;
256 default: ((LPWSTR)p) += lstrlenW( (LPWSTR)p ) + 1; break;
259 /* Skip data */
260 data = *((WORD *)p)++;
261 (LPSTR)p += data;
263 /* Next item */
264 nbItems--;
267 return (WORD)((LPSTR)p - (LPSTR)dialog32);
270 /**********************************************************************
271 * ConvertMenu32To16 (KERNEL.616)
273 VOID WINAPI ConvertMenu32To16( LPVOID menu32, DWORD size, LPVOID menu16 )
275 LPVOID p = menu32;
276 WORD version, headersize, flags, level = 1;
278 version = *((WORD *)menu16)++ = *((WORD *)p)++;
279 headersize = *((WORD *)menu16)++ = *((WORD *)p)++;
280 if ( headersize )
282 memcpy( menu16, p, headersize );
283 ((LPSTR)menu16) += headersize;
284 ((LPSTR)p) += headersize;
287 while ( level )
288 if ( version == 0 ) /* standard */
290 flags = *((WORD *)menu16)++ = *((WORD *)p)++;
291 if ( !(flags & MF_POPUP) )
292 *((WORD *)menu16)++ = *((WORD *)p)++; /* ID */
293 else
294 level++;
296 lstrcpyWtoA( (LPSTR)menu16, (LPWSTR)p );
297 ((LPSTR)menu16) += lstrlenA( (LPSTR)menu16 ) + 1;
298 ((LPWSTR)p) += lstrlenW( (LPWSTR)p ) + 1;
300 if ( flags & MF_END )
301 level--;
303 else /* extended */
305 *((DWORD *)menu16)++ = *((DWORD *)p)++; /* fType */
306 *((DWORD *)menu16)++ = *((DWORD *)p)++; /* fState */
307 *((WORD *)menu16)++ = (WORD)*((DWORD *)p)++; /* ID */
308 flags = *((BYTE *)menu16)++ = (BYTE)*((WORD *)p)++;
310 lstrcpyWtoA( (LPSTR)menu16, (LPWSTR)p );
311 ((LPSTR)menu16) += lstrlenA( (LPSTR)menu16 ) + 1;
312 ((LPWSTR)p) += lstrlenW( (LPWSTR)p ) + 1;
314 /* align on DWORD boundary (32-bit only) */
315 p = (LPVOID)((((int)p) + 3) & ~3);
317 /* If popup, transfer helpid */
318 if ( flags & 1)
320 *((DWORD *)menu16)++ = *((DWORD *)p)++;
321 level++;
324 if ( flags & MF_END )
325 level--;
329 /**********************************************************************
330 * GetMenu32Size (KERNEL.617)
332 WORD WINAPI GetMenu32Size16( LPVOID menu32 )
334 LPVOID p = menu32;
335 WORD version, headersize, flags, level = 1;
337 version = *((WORD *)p)++;
338 headersize = *((WORD *)p)++;
339 ((LPSTR)p) += headersize;
341 while ( level )
342 if ( version == 0 ) /* standard */
344 flags = *((WORD *)p)++;
345 if ( !(flags & MF_POPUP) )
346 ((WORD *)p)++; /* ID */
347 else
348 level++;
350 ((LPWSTR)p) += lstrlenW( (LPWSTR)p ) + 1;
352 if ( flags & MF_END )
353 level--;
355 else /* extended */
357 ((DWORD *)p)++; /* fType */
358 ((DWORD *)p)++; /* fState */
359 ((DWORD *)p)++; /* ID */
360 flags = *((WORD *)p)++;
362 ((LPWSTR)p) += lstrlenW( (LPWSTR)p ) + 1;
364 /* align on DWORD boundary (32-bit only) */
365 p = (LPVOID)((((int)p) + 3) & ~3);
367 /* If popup, skip helpid */
368 if ( flags & 1)
370 ((DWORD *)p)++;
371 level++;
374 if ( flags & MF_END )
375 level--;
378 return (WORD)((LPSTR)p - (LPSTR)menu32);
381 /**********************************************************************
382 * ConvertAccelerator32To16
384 VOID ConvertAccelerator32To16( LPVOID acc32, DWORD size, LPVOID acc16 )
386 int type;
390 /* Copy type */
391 type = *((BYTE *)acc16)++ = *((BYTE *)acc32)++;
392 /* Skip padding */
393 ((BYTE *)acc32)++;
394 /* Copy event and IDval */
395 *((WORD *)acc16)++ = *((WORD *)acc32)++;
396 *((WORD *)acc16)++ = *((WORD *)acc32)++;
397 /* Skip padding */
398 ((WORD *)acc32)++;
400 } while ( !( type & 0x80 ) );
403 /**********************************************************************
404 * NE_LoadPEResource
406 HGLOBAL16 NE_LoadPEResource( NE_MODULE *pModule, WORD type, LPVOID bits, DWORD size )
408 HGLOBAL16 handle;
410 TRACE( resource, "module=%04x type=%04x\n", pModule->self, type );
411 if (!pModule || !bits || !size) return 0;
413 handle = GlobalAlloc16( 0, size );
415 switch (type)
417 case RT_MENU16:
418 ConvertMenu32To16( bits, size, GlobalLock16( handle ) );
419 break;
421 case RT_DIALOG16:
422 ConvertDialog32To16( bits, size, GlobalLock16( handle ) );
423 break;
425 case RT_ACCELERATOR16:
426 ConvertAccelerator32To16( bits, size, GlobalLock16( handle ) );
427 break;
429 case RT_STRING16:
430 FIXME( resource, "not yet implemented!\n" );
431 /* fall through */
433 default:
434 memcpy( GlobalLock16( handle ), bits, size );
435 break;
438 return handle;