Use __ASM_GLOBAL_FUNC directly in i386-only code.
[wine/multimedia.git] / loader / ne / convert.c
blob70b7c21918eddcc43726f2df5ce7d8b0555259bd
1 /*
2 * PE->NE resource conversion functions
4 * Copyright 1998 Ulrich Weigand
5 */
7 #include <string.h>
8 #include "windef.h"
9 #include "wingdi.h"
10 #include "wine/winuser16.h"
11 #include "wine/unicode.h"
12 #include "module.h"
13 #include "debugtools.h"
15 DEFAULT_DEBUG_CHANNEL(resource);
17 /**********************************************************************
18 * ConvertDialog32To16 (KERNEL.615)
20 VOID WINAPI ConvertDialog32To16( LPVOID dialog32, DWORD size, LPVOID dialog16 )
22 LPVOID p = dialog32;
23 WORD nbItems, data, dialogEx;
24 DWORD style;
26 style = *((DWORD *)dialog16)++ = *((DWORD *)p)++;
27 dialogEx = (style == 0xffff0001); /* DIALOGEX resource */
28 if (dialogEx)
30 *((DWORD *)dialog16)++ = *((DWORD *)p)++; /* helpID */
31 *((DWORD *)dialog16)++ = *((DWORD *)p)++; /* exStyle */
32 style = *((DWORD *)dialog16)++ = *((DWORD *)p)++; /* style */
34 else
35 ((DWORD *)p)++; /* exStyle ignored in 16-bit standard dialog */
37 nbItems = *((BYTE *)dialog16)++ = (BYTE)*((WORD *)p)++;
38 *((WORD *)dialog16)++ = *((WORD *)p)++; /* x */
39 *((WORD *)dialog16)++ = *((WORD *)p)++; /* y */
40 *((WORD *)dialog16)++ = *((WORD *)p)++; /* cx */
41 *((WORD *)dialog16)++ = *((WORD *)p)++; /* cy */
43 /* Transfer menu name */
44 switch (*((WORD *)p))
46 case 0x0000: ((WORD *)p)++; *((BYTE *)dialog16)++ = 0; break;
47 case 0xffff: ((WORD *)p)++; *((BYTE *)dialog16)++ = 0xff;
48 *((WORD *)dialog16)++ = *((WORD *)p)++; break;
49 default: WideCharToMultiByte( CP_ACP, 0, (LPWSTR)p, -1, (LPSTR)dialog16, 0x7fffffff, NULL,NULL );
50 ((LPSTR)dialog16) += strlen( (LPSTR)dialog16 ) + 1;
51 ((LPWSTR)p) += strlenW( (LPWSTR)p ) + 1;
52 break;
55 /* Transfer class name */
56 switch (*((WORD *)p))
58 case 0x0000: ((WORD *)p)++; *((BYTE *)dialog16)++ = 0; break;
59 case 0xffff: ((WORD *)p)++; *((BYTE *)dialog16)++ = 0xff;
60 *((WORD *)dialog16)++ = *((WORD *)p)++; break;
61 default: WideCharToMultiByte( CP_ACP, 0, (LPWSTR)p, -1, (LPSTR)dialog16, 0x7fffffff, NULL,NULL );
62 ((LPSTR)dialog16) += strlen( (LPSTR)dialog16 ) + 1;
63 ((LPWSTR)p) += strlenW( (LPWSTR)p ) + 1;
64 break;
67 /* Transfer window caption */
68 WideCharToMultiByte( CP_ACP, 0, (LPWSTR)p, -1, (LPSTR)dialog16, 0x7fffffff, NULL,NULL );
69 ((LPSTR)dialog16) += strlen( (LPSTR)dialog16 ) + 1;
70 ((LPWSTR)p) += strlenW( (LPWSTR)p ) + 1;
72 /* Transfer font info */
73 if (style & DS_SETFONT)
75 *((WORD *)dialog16)++ = *((WORD *)p)++; /* pointSize */
76 if (dialogEx)
78 *((WORD *)dialog16)++ = *((WORD *)p)++; /* weight */
79 *((WORD *)dialog16)++ = *((WORD *)p)++; /* italic */
81 WideCharToMultiByte( CP_ACP, 0, (LPWSTR)p, -1, (LPSTR)dialog16, 0x7fffffff, NULL,NULL ); /* faceName */
82 ((LPSTR)dialog16) += strlen( (LPSTR)dialog16 ) + 1;
83 ((LPWSTR)p) += strlenW( (LPWSTR)p ) + 1;
86 /* Transfer dialog items */
87 while (nbItems)
89 /* align on DWORD boundary (32-bit only) */
90 p = (LPVOID)((((int)p) + 3) & ~3);
92 if (dialogEx)
94 *((DWORD *)dialog16)++ = *((DWORD *)p)++; /* helpID */
95 *((DWORD *)dialog16)++ = *((DWORD *)p)++; /* exStyle */
96 *((DWORD *)dialog16)++ = *((DWORD *)p)++; /* style */
98 else
100 style = *((DWORD *)p)++; /* save style */
101 ((DWORD *)p)++; /* ignore exStyle */
104 *((WORD *)dialog16)++ = *((WORD *)p)++; /* x */
105 *((WORD *)dialog16)++ = *((WORD *)p)++; /* y */
106 *((WORD *)dialog16)++ = *((WORD *)p)++; /* cx */
107 *((WORD *)dialog16)++ = *((WORD *)p)++; /* cy */
109 if (dialogEx)
110 *((DWORD *)dialog16)++ = *((DWORD *)p)++; /* ID */
111 else
113 *((WORD *)dialog16)++ = *((WORD *)p)++; /* ID */
114 *((DWORD *)dialog16)++ = style; /* style from above */
117 /* Transfer class name */
118 switch (*((WORD *)p))
120 case 0x0000: ((WORD *)p)++; *((BYTE *)dialog16)++ = 0; break;
121 case 0xffff: ((WORD *)p)++;
122 *((BYTE *)dialog16)++ = (BYTE)*((WORD *)p)++; break;
123 default: WideCharToMultiByte( CP_ACP, 0, (LPWSTR)p, -1, (LPSTR)dialog16, 0x7fffffff, NULL,NULL );
124 ((LPSTR)dialog16) += strlen( (LPSTR)dialog16 ) + 1;
125 ((LPWSTR)p) += strlenW( (LPWSTR)p ) + 1;
126 break;
129 /* Transfer window name */
130 switch (*((WORD *)p))
132 case 0x0000: ((WORD *)p)++; *((BYTE *)dialog16)++ = 0; break;
133 case 0xffff: ((WORD *)p)++; *((BYTE *)dialog16)++ = 0xff;
134 *((WORD *)dialog16)++ = *((WORD *)p)++; break;
135 default: WideCharToMultiByte( CP_ACP, 0, (LPWSTR)p, -1, (LPSTR)dialog16, 0x7fffffff, NULL,NULL );
136 ((LPSTR)dialog16) += strlen( (LPSTR)dialog16 ) + 1;
137 ((LPWSTR)p) += strlenW( (LPWSTR)p ) + 1;
138 break;
141 /* Transfer data */
142 data = *((WORD *)p)++;
143 if (dialogEx)
144 *((WORD *)dialog16)++ = data;
145 else
146 *((BYTE *)dialog16)++ = (BYTE)data;
148 if (data)
150 memcpy( dialog16, p, data );
151 (LPSTR)dialog16 += data;
152 (LPSTR)p += data;
155 /* Next item */
156 nbItems--;
160 /**********************************************************************
161 * GetDialog32Size (KERNEL.618)
163 WORD WINAPI GetDialog32Size16( LPVOID dialog32 )
165 LPVOID p = dialog32;
166 WORD nbItems, data, dialogEx;
167 DWORD style;
169 style = *((DWORD *)p)++;
170 dialogEx = (style == 0xffff0001); /* DIALOGEX resource */
171 if (dialogEx)
173 ((DWORD *)p)++; /* helpID */
174 ((DWORD *)p)++; /* exStyle */
175 style = *((DWORD *)p)++; /* style */
177 else
178 ((DWORD *)p)++; /* exStyle */
180 nbItems = *((WORD *)p)++;
181 ((WORD *)p)++; /* x */
182 ((WORD *)p)++; /* y */
183 ((WORD *)p)++; /* cx */
184 ((WORD *)p)++; /* cy */
186 /* Skip menu name */
187 switch (*((WORD *)p))
189 case 0x0000: ((WORD *)p)++; break;
190 case 0xffff: ((WORD *)p) += 2; break;
191 default: ((LPWSTR)p) += strlenW( (LPWSTR)p ) + 1; break;
194 /* Skip class name */
195 switch (*((WORD *)p))
197 case 0x0000: ((WORD *)p)++; break;
198 case 0xffff: ((WORD *)p) += 2; break;
199 default: ((LPWSTR)p) += strlenW( (LPWSTR)p ) + 1; break;
202 /* Skip window caption */
203 ((LPWSTR)p) += strlenW( (LPWSTR)p ) + 1;
205 /* Skip font info */
206 if (style & DS_SETFONT)
208 ((WORD *)p)++; /* pointSize */
209 if (dialogEx)
211 ((WORD *)p)++; /* weight */
212 ((WORD *)p)++; /* italic */
214 ((LPWSTR)p) += strlenW( (LPWSTR)p ) + 1; /* faceName */
217 /* Skip dialog items */
218 while (nbItems)
220 /* align on DWORD boundary */
221 p = (LPVOID)((((int)p) + 3) & ~3);
223 if (dialogEx)
225 ((DWORD *)p)++; /* helpID */
226 ((DWORD *)p)++; /* exStyle */
227 ((DWORD *)p)++; /* style */
229 else
231 ((DWORD *)p)++; /* style */
232 ((DWORD *)p)++; /* exStyle */
235 ((WORD *)p)++; /* x */
236 ((WORD *)p)++; /* y */
237 ((WORD *)p)++; /* cx */
238 ((WORD *)p)++; /* cy */
240 if (dialogEx)
241 ((DWORD *)p)++; /* ID */
242 else
243 ((WORD *)p)++; /* ID */
245 /* Skip class name */
246 switch (*((WORD *)p))
248 case 0x0000: ((WORD *)p)++; break;
249 case 0xffff: ((WORD *)p) += 2; break;
250 default: ((LPWSTR)p) += strlenW( (LPWSTR)p ) + 1; break;
253 /* Skip window name */
254 switch (*((WORD *)p))
256 case 0x0000: ((WORD *)p)++; break;
257 case 0xffff: ((WORD *)p) += 2; break;
258 default: ((LPWSTR)p) += strlenW( (LPWSTR)p ) + 1; break;
261 /* Skip data */
262 data = *((WORD *)p)++;
263 (LPSTR)p += data;
265 /* Next item */
266 nbItems--;
269 return (WORD)((LPSTR)p - (LPSTR)dialog32);
272 /**********************************************************************
273 * ConvertMenu32To16 (KERNEL.616)
275 VOID WINAPI ConvertMenu32To16( LPVOID menu32, DWORD size, LPVOID menu16 )
277 LPVOID p = menu32;
278 WORD version, headersize, flags, level = 1;
280 version = *((WORD *)menu16)++ = *((WORD *)p)++;
281 headersize = *((WORD *)menu16)++ = *((WORD *)p)++;
282 if ( headersize )
284 memcpy( menu16, p, headersize );
285 ((LPSTR)menu16) += headersize;
286 ((LPSTR)p) += headersize;
289 while ( level )
290 if ( version == 0 ) /* standard */
292 flags = *((WORD *)menu16)++ = *((WORD *)p)++;
293 if ( !(flags & MF_POPUP) )
294 *((WORD *)menu16)++ = *((WORD *)p)++; /* ID */
295 else
296 level++;
298 WideCharToMultiByte( CP_ACP, 0, (LPWSTR)p, -1, (LPSTR)menu16, 0x7fffffff, NULL,NULL );
299 ((LPSTR)menu16) += strlen( (LPSTR)menu16 ) + 1;
300 ((LPWSTR)p) += strlenW( (LPWSTR)p ) + 1;
302 if ( flags & MF_END )
303 level--;
305 else /* extended */
307 *((DWORD *)menu16)++ = *((DWORD *)p)++; /* fType */
308 *((DWORD *)menu16)++ = *((DWORD *)p)++; /* fState */
309 *((WORD *)menu16)++ = (WORD)*((DWORD *)p)++; /* ID */
310 flags = *((BYTE *)menu16)++ = (BYTE)*((WORD *)p)++;
312 WideCharToMultiByte( CP_ACP, 0, (LPWSTR)p, -1, (LPSTR)menu16, 0x7fffffff, NULL,NULL );
313 ((LPSTR)menu16) += strlen( (LPSTR)menu16 ) + 1;
314 ((LPWSTR)p) += strlenW( (LPWSTR)p ) + 1;
316 /* align on DWORD boundary (32-bit only) */
317 p = (LPVOID)((((int)p) + 3) & ~3);
319 /* If popup, transfer helpid */
320 if ( flags & 1)
322 *((DWORD *)menu16)++ = *((DWORD *)p)++;
323 level++;
326 if ( flags & MF_END )
327 level--;
331 /**********************************************************************
332 * GetMenu32Size (KERNEL.617)
334 WORD WINAPI GetMenu32Size16( LPVOID menu32 )
336 LPVOID p = menu32;
337 WORD version, headersize, flags, level = 1;
339 version = *((WORD *)p)++;
340 headersize = *((WORD *)p)++;
341 ((LPSTR)p) += headersize;
343 while ( level )
344 if ( version == 0 ) /* standard */
346 flags = *((WORD *)p)++;
347 if ( !(flags & MF_POPUP) )
348 ((WORD *)p)++; /* ID */
349 else
350 level++;
352 ((LPWSTR)p) += strlenW( (LPWSTR)p ) + 1;
354 if ( flags & MF_END )
355 level--;
357 else /* extended */
359 ((DWORD *)p)++; /* fType */
360 ((DWORD *)p)++; /* fState */
361 ((DWORD *)p)++; /* ID */
362 flags = *((WORD *)p)++;
364 ((LPWSTR)p) += strlenW( (LPWSTR)p ) + 1;
366 /* align on DWORD boundary (32-bit only) */
367 p = (LPVOID)((((int)p) + 3) & ~3);
369 /* If popup, skip helpid */
370 if ( flags & 1)
372 ((DWORD *)p)++;
373 level++;
376 if ( flags & MF_END )
377 level--;
380 return (WORD)((LPSTR)p - (LPSTR)menu32);
383 /**********************************************************************
384 * ConvertAccelerator32To16
386 VOID ConvertAccelerator32To16( LPVOID acc32, DWORD size, LPVOID acc16 )
388 int type;
392 /* Copy type */
393 type = *((BYTE *)acc16)++ = *((BYTE *)acc32)++;
394 /* Skip padding */
395 ((BYTE *)acc32)++;
396 /* Copy event and IDval */
397 *((WORD *)acc16)++ = *((WORD *)acc32)++;
398 *((WORD *)acc16)++ = *((WORD *)acc32)++;
399 /* Skip padding */
400 ((WORD *)acc32)++;
402 } while ( !( type & 0x80 ) );
405 /**********************************************************************
406 * NE_LoadPEResource
408 HGLOBAL16 NE_LoadPEResource( NE_MODULE *pModule, WORD type, LPVOID bits, DWORD size )
410 HGLOBAL16 handle;
412 TRACE("module=%04x type=%04x\n", pModule->self, type );
413 if (!pModule || !bits || !size) return 0;
415 handle = GlobalAlloc16( 0, size );
417 switch (type)
419 case RT_MENU16:
420 ConvertMenu32To16( bits, size, GlobalLock16( handle ) );
421 break;
423 case RT_DIALOG16:
424 ConvertDialog32To16( bits, size, GlobalLock16( handle ) );
425 break;
427 case RT_ACCELERATOR16:
428 ConvertAccelerator32To16( bits, size, GlobalLock16( handle ) );
429 break;
431 case RT_STRING16:
432 FIXME("not yet implemented!\n" );
433 /* fall through */
435 default:
436 memcpy( GlobalLock16( handle ), bits, size );
437 break;
440 return handle;