Fixes to allow big endian machines to load MSFT typelib files.
[wine/multimedia.git] / loader / ne / convert.c
blobcc5c16fb2ff9c372f976981d427e3dceef4d9070
1 /*
2 * PE->NE resource conversion functions
4 * Copyright 1998 Ulrich Weigand
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 #include <string.h>
22 #include "windef.h"
23 #include "wingdi.h"
24 #include "wine/winuser16.h"
25 #include "wine/unicode.h"
26 #include "module.h"
27 #include "wine/debug.h"
29 WINE_DEFAULT_DEBUG_CHANNEL(resource);
31 /**********************************************************************
32 * ConvertDialog32To16 (KERNEL.615)
33 * ConvertDialog32To16 (KERNEL32.@)
35 VOID WINAPI ConvertDialog32To16( LPVOID dialog32, DWORD size, LPVOID dialog16 )
37 LPVOID p = dialog32;
38 WORD nbItems, data, dialogEx;
39 DWORD style;
41 style = *((DWORD *)dialog16)++ = *((DWORD *)p)++;
42 dialogEx = (style == 0xffff0001); /* DIALOGEX resource */
43 if (dialogEx)
45 *((DWORD *)dialog16)++ = *((DWORD *)p)++; /* helpID */
46 *((DWORD *)dialog16)++ = *((DWORD *)p)++; /* exStyle */
47 style = *((DWORD *)dialog16)++ = *((DWORD *)p)++; /* style */
49 else
50 ((DWORD *)p)++; /* exStyle ignored in 16-bit standard dialog */
52 nbItems = *((BYTE *)dialog16)++ = (BYTE)*((WORD *)p)++;
53 *((WORD *)dialog16)++ = *((WORD *)p)++; /* x */
54 *((WORD *)dialog16)++ = *((WORD *)p)++; /* y */
55 *((WORD *)dialog16)++ = *((WORD *)p)++; /* cx */
56 *((WORD *)dialog16)++ = *((WORD *)p)++; /* cy */
58 /* Transfer menu name */
59 switch (*((WORD *)p))
61 case 0x0000: ((WORD *)p)++; *((BYTE *)dialog16)++ = 0; break;
62 case 0xffff: ((WORD *)p)++; *((BYTE *)dialog16)++ = 0xff;
63 *((WORD *)dialog16)++ = *((WORD *)p)++; break;
64 default: WideCharToMultiByte( CP_ACP, 0, (LPWSTR)p, -1, (LPSTR)dialog16, 0x7fffffff, NULL,NULL );
65 ((LPSTR)dialog16) += strlen( (LPSTR)dialog16 ) + 1;
66 ((LPWSTR)p) += strlenW( (LPWSTR)p ) + 1;
67 break;
70 /* Transfer class name */
71 switch (*((WORD *)p))
73 case 0x0000: ((WORD *)p)++; *((BYTE *)dialog16)++ = 0; break;
74 case 0xffff: ((WORD *)p)++; *((BYTE *)dialog16)++ = 0xff;
75 *((WORD *)dialog16)++ = *((WORD *)p)++; break;
76 default: WideCharToMultiByte( CP_ACP, 0, (LPWSTR)p, -1, (LPSTR)dialog16, 0x7fffffff, NULL,NULL );
77 ((LPSTR)dialog16) += strlen( (LPSTR)dialog16 ) + 1;
78 ((LPWSTR)p) += strlenW( (LPWSTR)p ) + 1;
79 break;
82 /* Transfer window caption */
83 WideCharToMultiByte( CP_ACP, 0, (LPWSTR)p, -1, (LPSTR)dialog16, 0x7fffffff, NULL,NULL );
84 ((LPSTR)dialog16) += strlen( (LPSTR)dialog16 ) + 1;
85 ((LPWSTR)p) += strlenW( (LPWSTR)p ) + 1;
87 /* Transfer font info */
88 if (style & DS_SETFONT)
90 *((WORD *)dialog16)++ = *((WORD *)p)++; /* pointSize */
91 if (dialogEx)
93 *((WORD *)dialog16)++ = *((WORD *)p)++; /* weight */
94 *((WORD *)dialog16)++ = *((WORD *)p)++; /* italic */
96 WideCharToMultiByte( CP_ACP, 0, (LPWSTR)p, -1, (LPSTR)dialog16, 0x7fffffff, NULL,NULL ); /* faceName */
97 ((LPSTR)dialog16) += strlen( (LPSTR)dialog16 ) + 1;
98 ((LPWSTR)p) += strlenW( (LPWSTR)p ) + 1;
101 /* Transfer dialog items */
102 while (nbItems)
104 /* align on DWORD boundary (32-bit only) */
105 p = (LPVOID)((((int)p) + 3) & ~3);
107 if (dialogEx)
109 *((DWORD *)dialog16)++ = *((DWORD *)p)++; /* helpID */
110 *((DWORD *)dialog16)++ = *((DWORD *)p)++; /* exStyle */
111 *((DWORD *)dialog16)++ = *((DWORD *)p)++; /* style */
113 else
115 style = *((DWORD *)p)++; /* save style */
116 ((DWORD *)p)++; /* ignore exStyle */
119 *((WORD *)dialog16)++ = *((WORD *)p)++; /* x */
120 *((WORD *)dialog16)++ = *((WORD *)p)++; /* y */
121 *((WORD *)dialog16)++ = *((WORD *)p)++; /* cx */
122 *((WORD *)dialog16)++ = *((WORD *)p)++; /* cy */
124 if (dialogEx)
125 *((DWORD *)dialog16)++ = *((DWORD *)p)++; /* ID */
126 else
128 *((WORD *)dialog16)++ = *((WORD *)p)++; /* ID */
129 *((DWORD *)dialog16)++ = style; /* style from above */
132 /* Transfer class name */
133 switch (*((WORD *)p))
135 case 0x0000: ((WORD *)p)++; *((BYTE *)dialog16)++ = 0; break;
136 case 0xffff: ((WORD *)p)++;
137 *((BYTE *)dialog16)++ = (BYTE)*((WORD *)p)++; break;
138 default: WideCharToMultiByte( CP_ACP, 0, (LPWSTR)p, -1, (LPSTR)dialog16, 0x7fffffff, NULL,NULL );
139 ((LPSTR)dialog16) += strlen( (LPSTR)dialog16 ) + 1;
140 ((LPWSTR)p) += strlenW( (LPWSTR)p ) + 1;
141 break;
144 /* Transfer window name */
145 switch (*((WORD *)p))
147 case 0x0000: ((WORD *)p)++; *((BYTE *)dialog16)++ = 0; break;
148 case 0xffff: ((WORD *)p)++; *((BYTE *)dialog16)++ = 0xff;
149 *((WORD *)dialog16)++ = *((WORD *)p)++; break;
150 default: WideCharToMultiByte( CP_ACP, 0, (LPWSTR)p, -1, (LPSTR)dialog16, 0x7fffffff, NULL,NULL );
151 ((LPSTR)dialog16) += strlen( (LPSTR)dialog16 ) + 1;
152 ((LPWSTR)p) += strlenW( (LPWSTR)p ) + 1;
153 break;
156 /* Transfer data */
157 data = *((WORD *)p)++;
158 if (dialogEx)
159 *((WORD *)dialog16)++ = data;
160 else
161 *((BYTE *)dialog16)++ = (BYTE)data;
163 if (data)
165 memcpy( dialog16, p, data );
166 (LPSTR)dialog16 += data;
167 (LPSTR)p += data;
170 /* Next item */
171 nbItems--;
175 /**********************************************************************
176 * GetDialog32Size (KERNEL.618)
178 WORD WINAPI GetDialog32Size16( LPVOID dialog32 )
180 LPVOID p = dialog32;
181 WORD nbItems, data, dialogEx;
182 DWORD style;
184 style = *((DWORD *)p)++;
185 dialogEx = (style == 0xffff0001); /* DIALOGEX resource */
186 if (dialogEx)
188 ((DWORD *)p)++; /* helpID */
189 ((DWORD *)p)++; /* exStyle */
190 style = *((DWORD *)p)++; /* style */
192 else
193 ((DWORD *)p)++; /* exStyle */
195 nbItems = *((WORD *)p)++;
196 ((WORD *)p)++; /* x */
197 ((WORD *)p)++; /* y */
198 ((WORD *)p)++; /* cx */
199 ((WORD *)p)++; /* cy */
201 /* Skip menu name */
202 switch (*((WORD *)p))
204 case 0x0000: ((WORD *)p)++; break;
205 case 0xffff: ((WORD *)p) += 2; break;
206 default: ((LPWSTR)p) += strlenW( (LPWSTR)p ) + 1; break;
209 /* Skip class name */
210 switch (*((WORD *)p))
212 case 0x0000: ((WORD *)p)++; break;
213 case 0xffff: ((WORD *)p) += 2; break;
214 default: ((LPWSTR)p) += strlenW( (LPWSTR)p ) + 1; break;
217 /* Skip window caption */
218 ((LPWSTR)p) += strlenW( (LPWSTR)p ) + 1;
220 /* Skip font info */
221 if (style & DS_SETFONT)
223 ((WORD *)p)++; /* pointSize */
224 if (dialogEx)
226 ((WORD *)p)++; /* weight */
227 ((WORD *)p)++; /* italic */
229 ((LPWSTR)p) += strlenW( (LPWSTR)p ) + 1; /* faceName */
232 /* Skip dialog items */
233 while (nbItems)
235 /* align on DWORD boundary */
236 p = (LPVOID)((((int)p) + 3) & ~3);
238 if (dialogEx)
240 ((DWORD *)p)++; /* helpID */
241 ((DWORD *)p)++; /* exStyle */
242 ((DWORD *)p)++; /* style */
244 else
246 ((DWORD *)p)++; /* style */
247 ((DWORD *)p)++; /* exStyle */
250 ((WORD *)p)++; /* x */
251 ((WORD *)p)++; /* y */
252 ((WORD *)p)++; /* cx */
253 ((WORD *)p)++; /* cy */
255 if (dialogEx)
256 ((DWORD *)p)++; /* ID */
257 else
258 ((WORD *)p)++; /* ID */
260 /* Skip class name */
261 switch (*((WORD *)p))
263 case 0x0000: ((WORD *)p)++; break;
264 case 0xffff: ((WORD *)p) += 2; break;
265 default: ((LPWSTR)p) += strlenW( (LPWSTR)p ) + 1; break;
268 /* Skip window name */
269 switch (*((WORD *)p))
271 case 0x0000: ((WORD *)p)++; break;
272 case 0xffff: ((WORD *)p) += 2; break;
273 default: ((LPWSTR)p) += strlenW( (LPWSTR)p ) + 1; break;
276 /* Skip data */
277 data = *((WORD *)p)++;
278 (LPSTR)p += data;
280 /* Next item */
281 nbItems--;
284 return (WORD)((LPSTR)p - (LPSTR)dialog32);
287 /**********************************************************************
288 * ConvertMenu32To16 (KERNEL.616)
290 VOID WINAPI ConvertMenu32To16( LPVOID menu32, DWORD size, LPVOID menu16 )
292 LPVOID p = menu32;
293 WORD version, headersize, flags, level = 1;
295 version = *((WORD *)menu16)++ = *((WORD *)p)++;
296 headersize = *((WORD *)menu16)++ = *((WORD *)p)++;
297 if ( headersize )
299 memcpy( menu16, p, headersize );
300 ((LPSTR)menu16) += headersize;
301 ((LPSTR)p) += headersize;
304 while ( level )
305 if ( version == 0 ) /* standard */
307 flags = *((WORD *)menu16)++ = *((WORD *)p)++;
308 if ( !(flags & MF_POPUP) )
309 *((WORD *)menu16)++ = *((WORD *)p)++; /* ID */
310 else
311 level++;
313 WideCharToMultiByte( CP_ACP, 0, (LPWSTR)p, -1, (LPSTR)menu16, 0x7fffffff, NULL,NULL );
314 ((LPSTR)menu16) += strlen( (LPSTR)menu16 ) + 1;
315 ((LPWSTR)p) += strlenW( (LPWSTR)p ) + 1;
317 if ( flags & MF_END )
318 level--;
320 else /* extended */
322 *((DWORD *)menu16)++ = *((DWORD *)p)++; /* fType */
323 *((DWORD *)menu16)++ = *((DWORD *)p)++; /* fState */
324 *((WORD *)menu16)++ = (WORD)*((DWORD *)p)++; /* ID */
325 flags = *((BYTE *)menu16)++ = (BYTE)*((WORD *)p)++;
327 WideCharToMultiByte( CP_ACP, 0, (LPWSTR)p, -1, (LPSTR)menu16, 0x7fffffff, NULL,NULL );
328 ((LPSTR)menu16) += strlen( (LPSTR)menu16 ) + 1;
329 ((LPWSTR)p) += strlenW( (LPWSTR)p ) + 1;
331 /* align on DWORD boundary (32-bit only) */
332 p = (LPVOID)((((int)p) + 3) & ~3);
334 /* If popup, transfer helpid */
335 if ( flags & 1)
337 *((DWORD *)menu16)++ = *((DWORD *)p)++;
338 level++;
341 if ( flags & MF_END )
342 level--;
346 /**********************************************************************
347 * GetMenu32Size (KERNEL.617)
349 WORD WINAPI GetMenu32Size16( LPVOID menu32 )
351 LPVOID p = menu32;
352 WORD version, headersize, flags, level = 1;
354 version = *((WORD *)p)++;
355 headersize = *((WORD *)p)++;
356 ((LPSTR)p) += headersize;
358 while ( level )
359 if ( version == 0 ) /* standard */
361 flags = *((WORD *)p)++;
362 if ( !(flags & MF_POPUP) )
363 ((WORD *)p)++; /* ID */
364 else
365 level++;
367 ((LPWSTR)p) += strlenW( (LPWSTR)p ) + 1;
369 if ( flags & MF_END )
370 level--;
372 else /* extended */
374 ((DWORD *)p)++; /* fType */
375 ((DWORD *)p)++; /* fState */
376 ((DWORD *)p)++; /* ID */
377 flags = *((WORD *)p)++;
379 ((LPWSTR)p) += strlenW( (LPWSTR)p ) + 1;
381 /* align on DWORD boundary (32-bit only) */
382 p = (LPVOID)((((int)p) + 3) & ~3);
384 /* If popup, skip helpid */
385 if ( flags & 1)
387 ((DWORD *)p)++;
388 level++;
391 if ( flags & MF_END )
392 level--;
395 return (WORD)((LPSTR)p - (LPSTR)menu32);
398 /**********************************************************************
399 * ConvertAccelerator32To16
401 VOID ConvertAccelerator32To16( LPVOID acc32, DWORD size, LPVOID acc16 )
403 int type;
407 /* Copy type */
408 type = *((BYTE *)acc16)++ = *((BYTE *)acc32)++;
409 /* Skip padding */
410 ((BYTE *)acc32)++;
411 /* Copy event and IDval */
412 *((WORD *)acc16)++ = *((WORD *)acc32)++;
413 *((WORD *)acc16)++ = *((WORD *)acc32)++;
414 /* Skip padding */
415 ((WORD *)acc32)++;
417 } while ( !( type & 0x80 ) );
420 /**********************************************************************
421 * NE_LoadPEResource
423 HGLOBAL16 NE_LoadPEResource( NE_MODULE *pModule, WORD type, LPVOID bits, DWORD size )
425 HGLOBAL16 handle;
427 TRACE("module=%04x type=%04x\n", pModule->self, type );
428 if (!pModule || !bits || !size) return 0;
430 handle = GlobalAlloc16( 0, size );
432 switch (type)
434 case RT_MENU16:
435 ConvertMenu32To16( bits, size, GlobalLock16( handle ) );
436 break;
438 case RT_DIALOG16:
439 ConvertDialog32To16( bits, size, GlobalLock16( handle ) );
440 break;
442 case RT_ACCELERATOR16:
443 ConvertAccelerator32To16( bits, size, GlobalLock16( handle ) );
444 break;
446 case RT_STRING16:
447 FIXME("not yet implemented!\n" );
448 /* fall through */
450 default:
451 memcpy( GlobalLock16( handle ), bits, size );
452 break;
455 return handle;