Added Interlocked*Pointer functions.
[wine/testsucceed.git] / loader / ne / convert.c
blob3a27eff68cea6500e308bc5ef012d6e4e484ba55
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)
19 * ConvertDialog32To16 (KERNEL32.@)
21 VOID WINAPI ConvertDialog32To16( LPVOID dialog32, DWORD size, LPVOID dialog16 )
23 LPVOID p = dialog32;
24 WORD nbItems, data, dialogEx;
25 DWORD style;
27 style = *((DWORD *)dialog16)++ = *((DWORD *)p)++;
28 dialogEx = (style == 0xffff0001); /* DIALOGEX resource */
29 if (dialogEx)
31 *((DWORD *)dialog16)++ = *((DWORD *)p)++; /* helpID */
32 *((DWORD *)dialog16)++ = *((DWORD *)p)++; /* exStyle */
33 style = *((DWORD *)dialog16)++ = *((DWORD *)p)++; /* style */
35 else
36 ((DWORD *)p)++; /* exStyle ignored in 16-bit standard dialog */
38 nbItems = *((BYTE *)dialog16)++ = (BYTE)*((WORD *)p)++;
39 *((WORD *)dialog16)++ = *((WORD *)p)++; /* x */
40 *((WORD *)dialog16)++ = *((WORD *)p)++; /* y */
41 *((WORD *)dialog16)++ = *((WORD *)p)++; /* cx */
42 *((WORD *)dialog16)++ = *((WORD *)p)++; /* cy */
44 /* Transfer menu name */
45 switch (*((WORD *)p))
47 case 0x0000: ((WORD *)p)++; *((BYTE *)dialog16)++ = 0; break;
48 case 0xffff: ((WORD *)p)++; *((BYTE *)dialog16)++ = 0xff;
49 *((WORD *)dialog16)++ = *((WORD *)p)++; break;
50 default: WideCharToMultiByte( CP_ACP, 0, (LPWSTR)p, -1, (LPSTR)dialog16, 0x7fffffff, NULL,NULL );
51 ((LPSTR)dialog16) += strlen( (LPSTR)dialog16 ) + 1;
52 ((LPWSTR)p) += strlenW( (LPWSTR)p ) + 1;
53 break;
56 /* Transfer class name */
57 switch (*((WORD *)p))
59 case 0x0000: ((WORD *)p)++; *((BYTE *)dialog16)++ = 0; break;
60 case 0xffff: ((WORD *)p)++; *((BYTE *)dialog16)++ = 0xff;
61 *((WORD *)dialog16)++ = *((WORD *)p)++; break;
62 default: WideCharToMultiByte( CP_ACP, 0, (LPWSTR)p, -1, (LPSTR)dialog16, 0x7fffffff, NULL,NULL );
63 ((LPSTR)dialog16) += strlen( (LPSTR)dialog16 ) + 1;
64 ((LPWSTR)p) += strlenW( (LPWSTR)p ) + 1;
65 break;
68 /* Transfer window caption */
69 WideCharToMultiByte( CP_ACP, 0, (LPWSTR)p, -1, (LPSTR)dialog16, 0x7fffffff, NULL,NULL );
70 ((LPSTR)dialog16) += strlen( (LPSTR)dialog16 ) + 1;
71 ((LPWSTR)p) += strlenW( (LPWSTR)p ) + 1;
73 /* Transfer font info */
74 if (style & DS_SETFONT)
76 *((WORD *)dialog16)++ = *((WORD *)p)++; /* pointSize */
77 if (dialogEx)
79 *((WORD *)dialog16)++ = *((WORD *)p)++; /* weight */
80 *((WORD *)dialog16)++ = *((WORD *)p)++; /* italic */
82 WideCharToMultiByte( CP_ACP, 0, (LPWSTR)p, -1, (LPSTR)dialog16, 0x7fffffff, NULL,NULL ); /* faceName */
83 ((LPSTR)dialog16) += strlen( (LPSTR)dialog16 ) + 1;
84 ((LPWSTR)p) += strlenW( (LPWSTR)p ) + 1;
87 /* Transfer dialog items */
88 while (nbItems)
90 /* align on DWORD boundary (32-bit only) */
91 p = (LPVOID)((((int)p) + 3) & ~3);
93 if (dialogEx)
95 *((DWORD *)dialog16)++ = *((DWORD *)p)++; /* helpID */
96 *((DWORD *)dialog16)++ = *((DWORD *)p)++; /* exStyle */
97 *((DWORD *)dialog16)++ = *((DWORD *)p)++; /* style */
99 else
101 style = *((DWORD *)p)++; /* save style */
102 ((DWORD *)p)++; /* ignore exStyle */
105 *((WORD *)dialog16)++ = *((WORD *)p)++; /* x */
106 *((WORD *)dialog16)++ = *((WORD *)p)++; /* y */
107 *((WORD *)dialog16)++ = *((WORD *)p)++; /* cx */
108 *((WORD *)dialog16)++ = *((WORD *)p)++; /* cy */
110 if (dialogEx)
111 *((DWORD *)dialog16)++ = *((DWORD *)p)++; /* ID */
112 else
114 *((WORD *)dialog16)++ = *((WORD *)p)++; /* ID */
115 *((DWORD *)dialog16)++ = style; /* style from above */
118 /* Transfer class name */
119 switch (*((WORD *)p))
121 case 0x0000: ((WORD *)p)++; *((BYTE *)dialog16)++ = 0; break;
122 case 0xffff: ((WORD *)p)++;
123 *((BYTE *)dialog16)++ = (BYTE)*((WORD *)p)++; break;
124 default: WideCharToMultiByte( CP_ACP, 0, (LPWSTR)p, -1, (LPSTR)dialog16, 0x7fffffff, NULL,NULL );
125 ((LPSTR)dialog16) += strlen( (LPSTR)dialog16 ) + 1;
126 ((LPWSTR)p) += strlenW( (LPWSTR)p ) + 1;
127 break;
130 /* Transfer window name */
131 switch (*((WORD *)p))
133 case 0x0000: ((WORD *)p)++; *((BYTE *)dialog16)++ = 0; break;
134 case 0xffff: ((WORD *)p)++; *((BYTE *)dialog16)++ = 0xff;
135 *((WORD *)dialog16)++ = *((WORD *)p)++; break;
136 default: WideCharToMultiByte( CP_ACP, 0, (LPWSTR)p, -1, (LPSTR)dialog16, 0x7fffffff, NULL,NULL );
137 ((LPSTR)dialog16) += strlen( (LPSTR)dialog16 ) + 1;
138 ((LPWSTR)p) += strlenW( (LPWSTR)p ) + 1;
139 break;
142 /* Transfer data */
143 data = *((WORD *)p)++;
144 if (dialogEx)
145 *((WORD *)dialog16)++ = data;
146 else
147 *((BYTE *)dialog16)++ = (BYTE)data;
149 if (data)
151 memcpy( dialog16, p, data );
152 (LPSTR)dialog16 += data;
153 (LPSTR)p += data;
156 /* Next item */
157 nbItems--;
161 /**********************************************************************
162 * GetDialog32Size (KERNEL.618)
164 WORD WINAPI GetDialog32Size16( LPVOID dialog32 )
166 LPVOID p = dialog32;
167 WORD nbItems, data, dialogEx;
168 DWORD style;
170 style = *((DWORD *)p)++;
171 dialogEx = (style == 0xffff0001); /* DIALOGEX resource */
172 if (dialogEx)
174 ((DWORD *)p)++; /* helpID */
175 ((DWORD *)p)++; /* exStyle */
176 style = *((DWORD *)p)++; /* style */
178 else
179 ((DWORD *)p)++; /* exStyle */
181 nbItems = *((WORD *)p)++;
182 ((WORD *)p)++; /* x */
183 ((WORD *)p)++; /* y */
184 ((WORD *)p)++; /* cx */
185 ((WORD *)p)++; /* cy */
187 /* Skip menu name */
188 switch (*((WORD *)p))
190 case 0x0000: ((WORD *)p)++; break;
191 case 0xffff: ((WORD *)p) += 2; break;
192 default: ((LPWSTR)p) += strlenW( (LPWSTR)p ) + 1; break;
195 /* Skip class name */
196 switch (*((WORD *)p))
198 case 0x0000: ((WORD *)p)++; break;
199 case 0xffff: ((WORD *)p) += 2; break;
200 default: ((LPWSTR)p) += strlenW( (LPWSTR)p ) + 1; break;
203 /* Skip window caption */
204 ((LPWSTR)p) += strlenW( (LPWSTR)p ) + 1;
206 /* Skip font info */
207 if (style & DS_SETFONT)
209 ((WORD *)p)++; /* pointSize */
210 if (dialogEx)
212 ((WORD *)p)++; /* weight */
213 ((WORD *)p)++; /* italic */
215 ((LPWSTR)p) += strlenW( (LPWSTR)p ) + 1; /* faceName */
218 /* Skip dialog items */
219 while (nbItems)
221 /* align on DWORD boundary */
222 p = (LPVOID)((((int)p) + 3) & ~3);
224 if (dialogEx)
226 ((DWORD *)p)++; /* helpID */
227 ((DWORD *)p)++; /* exStyle */
228 ((DWORD *)p)++; /* style */
230 else
232 ((DWORD *)p)++; /* style */
233 ((DWORD *)p)++; /* exStyle */
236 ((WORD *)p)++; /* x */
237 ((WORD *)p)++; /* y */
238 ((WORD *)p)++; /* cx */
239 ((WORD *)p)++; /* cy */
241 if (dialogEx)
242 ((DWORD *)p)++; /* ID */
243 else
244 ((WORD *)p)++; /* ID */
246 /* Skip class name */
247 switch (*((WORD *)p))
249 case 0x0000: ((WORD *)p)++; break;
250 case 0xffff: ((WORD *)p) += 2; break;
251 default: ((LPWSTR)p) += strlenW( (LPWSTR)p ) + 1; break;
254 /* Skip window name */
255 switch (*((WORD *)p))
257 case 0x0000: ((WORD *)p)++; break;
258 case 0xffff: ((WORD *)p) += 2; break;
259 default: ((LPWSTR)p) += strlenW( (LPWSTR)p ) + 1; break;
262 /* Skip data */
263 data = *((WORD *)p)++;
264 (LPSTR)p += data;
266 /* Next item */
267 nbItems--;
270 return (WORD)((LPSTR)p - (LPSTR)dialog32);
273 /**********************************************************************
274 * ConvertMenu32To16 (KERNEL.616)
276 VOID WINAPI ConvertMenu32To16( LPVOID menu32, DWORD size, LPVOID menu16 )
278 LPVOID p = menu32;
279 WORD version, headersize, flags, level = 1;
281 version = *((WORD *)menu16)++ = *((WORD *)p)++;
282 headersize = *((WORD *)menu16)++ = *((WORD *)p)++;
283 if ( headersize )
285 memcpy( menu16, p, headersize );
286 ((LPSTR)menu16) += headersize;
287 ((LPSTR)p) += headersize;
290 while ( level )
291 if ( version == 0 ) /* standard */
293 flags = *((WORD *)menu16)++ = *((WORD *)p)++;
294 if ( !(flags & MF_POPUP) )
295 *((WORD *)menu16)++ = *((WORD *)p)++; /* ID */
296 else
297 level++;
299 WideCharToMultiByte( CP_ACP, 0, (LPWSTR)p, -1, (LPSTR)menu16, 0x7fffffff, NULL,NULL );
300 ((LPSTR)menu16) += strlen( (LPSTR)menu16 ) + 1;
301 ((LPWSTR)p) += strlenW( (LPWSTR)p ) + 1;
303 if ( flags & MF_END )
304 level--;
306 else /* extended */
308 *((DWORD *)menu16)++ = *((DWORD *)p)++; /* fType */
309 *((DWORD *)menu16)++ = *((DWORD *)p)++; /* fState */
310 *((WORD *)menu16)++ = (WORD)*((DWORD *)p)++; /* ID */
311 flags = *((BYTE *)menu16)++ = (BYTE)*((WORD *)p)++;
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 /* align on DWORD boundary (32-bit only) */
318 p = (LPVOID)((((int)p) + 3) & ~3);
320 /* If popup, transfer helpid */
321 if ( flags & 1)
323 *((DWORD *)menu16)++ = *((DWORD *)p)++;
324 level++;
327 if ( flags & MF_END )
328 level--;
332 /**********************************************************************
333 * GetMenu32Size (KERNEL.617)
335 WORD WINAPI GetMenu32Size16( LPVOID menu32 )
337 LPVOID p = menu32;
338 WORD version, headersize, flags, level = 1;
340 version = *((WORD *)p)++;
341 headersize = *((WORD *)p)++;
342 ((LPSTR)p) += headersize;
344 while ( level )
345 if ( version == 0 ) /* standard */
347 flags = *((WORD *)p)++;
348 if ( !(flags & MF_POPUP) )
349 ((WORD *)p)++; /* ID */
350 else
351 level++;
353 ((LPWSTR)p) += strlenW( (LPWSTR)p ) + 1;
355 if ( flags & MF_END )
356 level--;
358 else /* extended */
360 ((DWORD *)p)++; /* fType */
361 ((DWORD *)p)++; /* fState */
362 ((DWORD *)p)++; /* ID */
363 flags = *((WORD *)p)++;
365 ((LPWSTR)p) += strlenW( (LPWSTR)p ) + 1;
367 /* align on DWORD boundary (32-bit only) */
368 p = (LPVOID)((((int)p) + 3) & ~3);
370 /* If popup, skip helpid */
371 if ( flags & 1)
373 ((DWORD *)p)++;
374 level++;
377 if ( flags & MF_END )
378 level--;
381 return (WORD)((LPSTR)p - (LPSTR)menu32);
384 /**********************************************************************
385 * ConvertAccelerator32To16
387 VOID ConvertAccelerator32To16( LPVOID acc32, DWORD size, LPVOID acc16 )
389 int type;
393 /* Copy type */
394 type = *((BYTE *)acc16)++ = *((BYTE *)acc32)++;
395 /* Skip padding */
396 ((BYTE *)acc32)++;
397 /* Copy event and IDval */
398 *((WORD *)acc16)++ = *((WORD *)acc32)++;
399 *((WORD *)acc16)++ = *((WORD *)acc32)++;
400 /* Skip padding */
401 ((WORD *)acc32)++;
403 } while ( !( type & 0x80 ) );
406 /**********************************************************************
407 * NE_LoadPEResource
409 HGLOBAL16 NE_LoadPEResource( NE_MODULE *pModule, WORD type, LPVOID bits, DWORD size )
411 HGLOBAL16 handle;
413 TRACE("module=%04x type=%04x\n", pModule->self, type );
414 if (!pModule || !bits || !size) return 0;
416 handle = GlobalAlloc16( 0, size );
418 switch (type)
420 case RT_MENU16:
421 ConvertMenu32To16( bits, size, GlobalLock16( handle ) );
422 break;
424 case RT_DIALOG16:
425 ConvertDialog32To16( bits, size, GlobalLock16( handle ) );
426 break;
428 case RT_ACCELERATOR16:
429 ConvertAccelerator32To16( bits, size, GlobalLock16( handle ) );
430 break;
432 case RT_STRING16:
433 FIXME("not yet implemented!\n" );
434 /* fall through */
436 default:
437 memcpy( GlobalLock16( handle ), bits, size );
438 break;
441 return handle;