Recovery of release 990110 after disk crash.
[wine/multimedia.git] / loader / ne / convert.c
blob0d201e6602f323b954bc0debc643a17bcdd4c104
1 /*
2 * PE->NE resource conversion functions
4 * Copyright 1998 Ulrich Weigand
5 */
7 #include "module.h"
8 #include "debug.h"
9 #include "debugtools.h"
10 #include "windows.h"
12 /**********************************************************************
13 * ConvertDialog32To16 (KERNEL.615)
15 VOID WINAPI ConvertDialog32To16( LPVOID dialog32, DWORD size, LPVOID dialog16 )
17 LPVOID p = dialog32;
18 WORD nbItems, data, dialogEx;
19 DWORD style;
21 style = *((DWORD *)dialog16)++ = *((DWORD *)p)++;
22 dialogEx = (style == 0xffff0001); /* DIALOGEX resource */
23 if (dialogEx)
25 *((DWORD *)dialog16)++ = *((DWORD *)p)++; /* helpID */
26 *((DWORD *)dialog16)++ = *((DWORD *)p)++; /* exStyle */
27 style = *((DWORD *)dialog16)++ = *((DWORD *)p)++; /* style */
29 else
30 ((DWORD *)p)++; /* exStyle ignored in 16-bit standard dialog */
32 nbItems = *((BYTE *)dialog16)++ = (BYTE)*((WORD *)p)++;
33 *((WORD *)dialog16)++ = *((WORD *)p)++; /* x */
34 *((WORD *)dialog16)++ = *((WORD *)p)++; /* y */
35 *((WORD *)dialog16)++ = *((WORD *)p)++; /* cx */
36 *((WORD *)dialog16)++ = *((WORD *)p)++; /* cy */
38 /* Transfer menu name */
39 switch (*((WORD *)p))
41 case 0x0000: ((WORD *)p)++; *((BYTE *)dialog16)++ = 0; break;
42 case 0xffff: ((WORD *)p)++; *((BYTE *)dialog16)++ = 0xff;
43 *((WORD *)dialog16)++ = *((WORD *)p)++; break;
44 default: lstrcpyWtoA( (LPSTR)dialog16, (LPWSTR)p );
45 ((LPSTR)dialog16) += lstrlen32A( (LPSTR)dialog16 ) + 1;
46 ((LPWSTR)p) += lstrlen32W( (LPWSTR)p ) + 1;
47 break;
50 /* Transfer class name */
51 switch (*((WORD *)p))
53 case 0x0000: ((WORD *)p)++; *((BYTE *)dialog16)++ = 0; break;
54 case 0xffff: ((WORD *)p)++; *((BYTE *)dialog16)++ = 0xff;
55 *((WORD *)dialog16)++ = *((WORD *)p)++; break;
56 default: lstrcpyWtoA( (LPSTR)dialog16, (LPWSTR)p );
57 ((LPSTR)dialog16) += lstrlen32A( (LPSTR)dialog16 ) + 1;
58 ((LPWSTR)p) += lstrlen32W( (LPWSTR)p ) + 1;
59 break;
62 /* Transfer window caption */
63 lstrcpyWtoA( (LPSTR)dialog16, (LPWSTR)p );
64 ((LPSTR)dialog16) += lstrlen32A( (LPSTR)dialog16 ) + 1;
65 ((LPWSTR)p) += lstrlen32W( (LPWSTR)p ) + 1;
67 /* Transfer font info */
68 if (style & DS_SETFONT)
70 *((WORD *)dialog16)++ = *((WORD *)p)++; /* pointSize */
71 if (dialogEx)
73 *((WORD *)dialog16)++ = *((WORD *)p)++; /* weight */
74 *((WORD *)dialog16)++ = *((WORD *)p)++; /* italic */
76 lstrcpyWtoA( (LPSTR)dialog16, (LPWSTR)p ); /* faceName */
77 ((LPSTR)dialog16) += lstrlen32A( (LPSTR)dialog16 ) + 1;
78 ((LPWSTR)p) += lstrlen32W( (LPWSTR)p ) + 1;
81 /* Transfer dialog items */
82 while (nbItems)
84 /* align on DWORD boundary (32-bit only) */
85 p = (LPVOID)((((int)p) + 3) & ~3);
87 if (dialogEx)
89 *((DWORD *)dialog16)++ = *((DWORD *)p)++; /* helpID */
90 *((DWORD *)dialog16)++ = *((DWORD *)p)++; /* exStyle */
91 *((DWORD *)dialog16)++ = *((DWORD *)p)++; /* style */
93 else
95 style = *((DWORD *)p)++; /* save style */
96 ((DWORD *)p)++; /* ignore exStyle */
99 *((WORD *)dialog16)++ = *((WORD *)p)++; /* x */
100 *((WORD *)dialog16)++ = *((WORD *)p)++; /* y */
101 *((WORD *)dialog16)++ = *((WORD *)p)++; /* cx */
102 *((WORD *)dialog16)++ = *((WORD *)p)++; /* cy */
104 if (dialogEx)
105 *((DWORD *)dialog16)++ = *((DWORD *)p)++; /* ID */
106 else
108 *((WORD *)dialog16)++ = *((WORD *)p)++; /* ID */
109 *((DWORD *)dialog16)++ = style; /* style from above */
112 /* Transfer class name */
113 switch (*((WORD *)p))
115 case 0x0000: ((WORD *)p)++; *((BYTE *)dialog16)++ = 0; break;
116 case 0xffff: ((WORD *)p)++;
117 *((BYTE *)dialog16)++ = (BYTE)*((WORD *)p)++; break;
118 default: lstrcpyWtoA( (LPSTR)dialog16, (LPWSTR)p );
119 ((LPSTR)dialog16) += lstrlen32A( (LPSTR)dialog16 ) + 1;
120 ((LPWSTR)p) += lstrlen32W( (LPWSTR)p ) + 1;
121 break;
124 /* Transfer window name */
125 switch (*((WORD *)p))
127 case 0x0000: ((WORD *)p)++; *((BYTE *)dialog16)++ = 0; break;
128 case 0xffff: ((WORD *)p)++; *((BYTE *)dialog16)++ = 0xff;
129 *((WORD *)dialog16)++ = *((WORD *)p)++; break;
130 default: lstrcpyWtoA( (LPSTR)dialog16, (LPWSTR)p );
131 ((LPSTR)dialog16) += lstrlen32A( (LPSTR)dialog16 ) + 1;
132 ((LPWSTR)p) += lstrlen32W( (LPWSTR)p ) + 1;
133 break;
136 /* Transfer data */
137 data = *((WORD *)p)++;
138 if (dialogEx)
139 *((WORD *)dialog16)++ = data;
140 else
141 *((BYTE *)dialog16)++ = (BYTE)data;
143 if (data)
145 memcpy( dialog16, p, data );
146 (LPSTR)dialog16 += data;
147 (LPSTR)p += data;
150 /* Next item */
151 nbItems--;
155 /**********************************************************************
156 * GetDialog32Size (KERNEL.618)
158 WORD WINAPI GetDialog32Size( LPVOID dialog32 )
160 LPVOID p = dialog32;
161 WORD nbItems, data, dialogEx;
162 DWORD style;
164 style = *((DWORD *)p)++;
165 dialogEx = (style == 0xffff0001); /* DIALOGEX resource */
166 if (dialogEx)
168 ((DWORD *)p)++; /* helpID */
169 ((DWORD *)p)++; /* exStyle */
170 style = *((DWORD *)p)++; /* style */
172 else
173 ((DWORD *)p)++; /* exStyle */
175 nbItems = *((WORD *)p)++;
176 ((WORD *)p)++; /* x */
177 ((WORD *)p)++; /* y */
178 ((WORD *)p)++; /* cx */
179 ((WORD *)p)++; /* cy */
181 /* Skip menu name */
182 switch (*((WORD *)p))
184 case 0x0000: ((WORD *)p)++; break;
185 case 0xffff: ((WORD *)p) += 2; break;
186 default: ((LPWSTR)p) += lstrlen32W( (LPWSTR)p ) + 1; break;
189 /* Skip class name */
190 switch (*((WORD *)p))
192 case 0x0000: ((WORD *)p)++; break;
193 case 0xffff: ((WORD *)p) += 2; break;
194 default: ((LPWSTR)p) += lstrlen32W( (LPWSTR)p ) + 1; break;
197 /* Skip window caption */
198 ((LPWSTR)p) += lstrlen32W( (LPWSTR)p ) + 1;
200 /* Skip font info */
201 if (style & DS_SETFONT)
203 ((WORD *)p)++; /* pointSize */
204 if (dialogEx)
206 ((WORD *)p)++; /* weight */
207 ((WORD *)p)++; /* italic */
209 ((LPWSTR)p) += lstrlen32W( (LPWSTR)p ) + 1; /* faceName */
212 /* Skip dialog items */
213 while (nbItems)
215 /* align on DWORD boundary */
216 p = (LPVOID)((((int)p) + 3) & ~3);
218 if (dialogEx)
220 ((DWORD *)p)++; /* helpID */
221 ((DWORD *)p)++; /* exStyle */
222 ((DWORD *)p)++; /* style */
224 else
226 ((DWORD *)p)++; /* style */
227 ((DWORD *)p)++; /* exStyle */
230 ((WORD *)p)++; /* x */
231 ((WORD *)p)++; /* y */
232 ((WORD *)p)++; /* cx */
233 ((WORD *)p)++; /* cy */
235 if (dialogEx)
236 ((DWORD *)p)++; /* ID */
237 else
238 ((WORD *)p)++; /* ID */
240 /* Skip class name */
241 switch (*((WORD *)p))
243 case 0x0000: ((WORD *)p)++; break;
244 case 0xffff: ((WORD *)p) += 2; break;
245 default: ((LPWSTR)p) += lstrlen32W( (LPWSTR)p ) + 1; break;
248 /* Skip window name */
249 switch (*((WORD *)p))
251 case 0x0000: ((WORD *)p)++; break;
252 case 0xffff: ((WORD *)p) += 2; break;
253 default: ((LPWSTR)p) += lstrlen32W( (LPWSTR)p ) + 1; break;
256 /* Skip data */
257 data = *((WORD *)p)++;
258 (LPSTR)p += data;
260 /* Next item */
261 nbItems--;
264 return (WORD)((LPSTR)p - (LPSTR)dialog32);
267 /**********************************************************************
268 * ConvertMenu32To16 (KERNEL.616)
270 VOID WINAPI ConvertMenu32To16( LPVOID menu32, DWORD size, LPVOID menu16 )
272 LPVOID p = menu32;
273 WORD version, headersize, flags, level = 1;
275 version = *((WORD *)menu16)++ = *((WORD *)p)++;
276 headersize = *((WORD *)menu16)++ = *((WORD *)p)++;
277 if ( headersize )
279 memcpy( menu16, p, headersize );
280 ((LPSTR)menu16) += headersize;
281 ((LPSTR)p) += headersize;
284 while ( level )
285 if ( version == 0 ) /* standard */
287 flags = *((WORD *)menu16)++ = *((WORD *)p)++;
288 if ( !(flags & MF_POPUP) )
289 *((WORD *)menu16)++ = *((WORD *)p)++; /* ID */
290 else
291 level++;
293 lstrcpyWtoA( (LPSTR)menu16, (LPWSTR)p );
294 ((LPSTR)menu16) += lstrlen32A( (LPSTR)menu16 ) + 1;
295 ((LPWSTR)p) += lstrlen32W( (LPWSTR)p ) + 1;
297 if ( flags & MF_END )
298 level--;
300 else /* extended */
302 *((DWORD *)menu16)++ = *((DWORD *)p)++; /* fType */
303 *((DWORD *)menu16)++ = *((DWORD *)p)++; /* fState */
304 *((WORD *)menu16)++ = (WORD)*((DWORD *)p)++; /* ID */
305 flags = *((BYTE *)menu16)++ = (BYTE)*((WORD *)p)++;
307 lstrcpyWtoA( (LPSTR)menu16, (LPWSTR)p );
308 ((LPSTR)menu16) += lstrlen32A( (LPSTR)menu16 ) + 1;
309 ((LPWSTR)p) += lstrlen32W( (LPWSTR)p ) + 1;
311 /* align on DWORD boundary (32-bit only) */
312 p = (LPVOID)((((int)p) + 3) & ~3);
314 /* If popup, transfer helpid */
315 if ( flags & 1)
317 *((DWORD *)menu16)++ = *((DWORD *)p)++;
318 level++;
321 if ( flags & MF_END )
322 level--;
326 /**********************************************************************
327 * GetMenu32Size (KERNEL.617)
329 WORD WINAPI GetMenu32Size( LPVOID menu32 )
331 LPVOID p = menu32;
332 WORD version, headersize, flags, level = 1;
334 version = *((WORD *)p)++;
335 headersize = *((WORD *)p)++;
336 ((LPSTR)p) += headersize;
338 while ( level )
339 if ( version == 0 ) /* standard */
341 flags = *((WORD *)p)++;
342 if ( !(flags & MF_POPUP) )
343 ((WORD *)p)++; /* ID */
344 else
345 level++;
347 ((LPWSTR)p) += lstrlen32W( (LPWSTR)p ) + 1;
349 if ( flags & MF_END )
350 level--;
352 else /* extended */
354 ((DWORD *)p)++; /* fType */
355 ((DWORD *)p)++; /* fState */
356 ((DWORD *)p)++; /* ID */
357 flags = *((WORD *)p)++;
359 ((LPWSTR)p) += lstrlen32W( (LPWSTR)p ) + 1;
361 /* align on DWORD boundary (32-bit only) */
362 p = (LPVOID)((((int)p) + 3) & ~3);
364 /* If popup, skip helpid */
365 if ( flags & 1)
367 ((DWORD *)p)++;
368 level++;
371 if ( flags & MF_END )
372 level--;
375 return (WORD)((LPSTR)p - (LPSTR)menu32);
378 /**********************************************************************
379 * ConvertAccelerator32To16
381 VOID ConvertAccelerator32To16( LPVOID acc32, DWORD size, LPVOID acc16 )
383 int type;
387 /* Copy type */
388 type = *((BYTE *)acc16)++ = *((BYTE *)acc32)++;
389 /* Skip padding */
390 ((BYTE *)acc32)++;
391 /* Copy event and IDval */
392 *((WORD *)acc16)++ = *((WORD *)acc32)++;
393 *((WORD *)acc16)++ = *((WORD *)acc32)++;
394 /* Skip padding */
395 ((WORD *)acc32)++;
397 } while ( !( type & 0x80 ) );
400 /**********************************************************************
401 * NE_LoadPEResource
403 HGLOBAL16 NE_LoadPEResource( NE_MODULE *pModule, WORD type, LPVOID bits, DWORD size )
405 HGLOBAL16 handle;
407 TRACE( resource, "module=%04x type=%04x\n", pModule->self, type );
408 if (!pModule || !bits || !size) return 0;
410 handle = GlobalAlloc16( 0, size );
412 switch (type)
414 case RT_MENU16:
415 ConvertMenu32To16( bits, size, GlobalLock16( handle ) );
416 break;
418 case RT_DIALOG16:
419 ConvertDialog32To16( bits, size, GlobalLock16( handle ) );
420 break;
422 case RT_ACCELERATOR16:
423 ConvertAccelerator32To16( bits, size, GlobalLock16( handle ) );
424 break;
426 case RT_STRING16:
427 FIXME( resource, "not yet implemented!\n" );
428 /* fall through */
430 default:
431 memcpy( GlobalLock16( handle ), bits, size );
432 break;
435 return handle;
438 /**********************************************************************
439 * NE_FreePEResource
441 BOOL16 NE_FreePEResource( NE_MODULE *pModule, HGLOBAL16 handle )
443 GlobalFree16( handle );
444 return 0;