Made DOSVM_GetTimer survive EAGAIN errors...
[wine/testsucceed.git] / loader / ne / convert.c
blob8091ff9f502a1857497852642d7843b4bfd1032c
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 /**********************************************************************
14 * ConvertDialog32To16 (KERNEL.615)
16 VOID WINAPI ConvertDialog32To16( LPVOID dialog32, DWORD size, LPVOID dialog16 )
18 LPVOID p = dialog32;
19 WORD nbItems, data, dialogEx;
20 DWORD style;
22 style = *((DWORD *)dialog16)++ = *((DWORD *)p)++;
23 dialogEx = (style == 0xffff0001); /* DIALOGEX resource */
24 if (dialogEx)
26 *((DWORD *)dialog16)++ = *((DWORD *)p)++; /* helpID */
27 *((DWORD *)dialog16)++ = *((DWORD *)p)++; /* exStyle */
28 style = *((DWORD *)dialog16)++ = *((DWORD *)p)++; /* style */
30 else
31 ((DWORD *)p)++; /* exStyle ignored in 16-bit standard dialog */
33 nbItems = *((BYTE *)dialog16)++ = (BYTE)*((WORD *)p)++;
34 *((WORD *)dialog16)++ = *((WORD *)p)++; /* x */
35 *((WORD *)dialog16)++ = *((WORD *)p)++; /* y */
36 *((WORD *)dialog16)++ = *((WORD *)p)++; /* cx */
37 *((WORD *)dialog16)++ = *((WORD *)p)++; /* cy */
39 /* Transfer menu name */
40 switch (*((WORD *)p))
42 case 0x0000: ((WORD *)p)++; *((BYTE *)dialog16)++ = 0; break;
43 case 0xffff: ((WORD *)p)++; *((BYTE *)dialog16)++ = 0xff;
44 *((WORD *)dialog16)++ = *((WORD *)p)++; break;
45 default: lstrcpyWtoA( (LPSTR)dialog16, (LPWSTR)p );
46 ((LPSTR)dialog16) += lstrlenA( (LPSTR)dialog16 ) + 1;
47 ((LPWSTR)p) += lstrlenW( (LPWSTR)p ) + 1;
48 break;
51 /* Transfer class name */
52 switch (*((WORD *)p))
54 case 0x0000: ((WORD *)p)++; *((BYTE *)dialog16)++ = 0; break;
55 case 0xffff: ((WORD *)p)++; *((BYTE *)dialog16)++ = 0xff;
56 *((WORD *)dialog16)++ = *((WORD *)p)++; break;
57 default: lstrcpyWtoA( (LPSTR)dialog16, (LPWSTR)p );
58 ((LPSTR)dialog16) += lstrlenA( (LPSTR)dialog16 ) + 1;
59 ((LPWSTR)p) += lstrlenW( (LPWSTR)p ) + 1;
60 break;
63 /* Transfer window caption */
64 lstrcpyWtoA( (LPSTR)dialog16, (LPWSTR)p );
65 ((LPSTR)dialog16) += lstrlenA( (LPSTR)dialog16 ) + 1;
66 ((LPWSTR)p) += lstrlenW( (LPWSTR)p ) + 1;
68 /* Transfer font info */
69 if (style & DS_SETFONT)
71 *((WORD *)dialog16)++ = *((WORD *)p)++; /* pointSize */
72 if (dialogEx)
74 *((WORD *)dialog16)++ = *((WORD *)p)++; /* weight */
75 *((WORD *)dialog16)++ = *((WORD *)p)++; /* italic */
77 lstrcpyWtoA( (LPSTR)dialog16, (LPWSTR)p ); /* faceName */
78 ((LPSTR)dialog16) += lstrlenA( (LPSTR)dialog16 ) + 1;
79 ((LPWSTR)p) += lstrlenW( (LPWSTR)p ) + 1;
82 /* Transfer dialog items */
83 while (nbItems)
85 /* align on DWORD boundary (32-bit only) */
86 p = (LPVOID)((((int)p) + 3) & ~3);
88 if (dialogEx)
90 *((DWORD *)dialog16)++ = *((DWORD *)p)++; /* helpID */
91 *((DWORD *)dialog16)++ = *((DWORD *)p)++; /* exStyle */
92 *((DWORD *)dialog16)++ = *((DWORD *)p)++; /* style */
94 else
96 style = *((DWORD *)p)++; /* save style */
97 ((DWORD *)p)++; /* ignore exStyle */
100 *((WORD *)dialog16)++ = *((WORD *)p)++; /* x */
101 *((WORD *)dialog16)++ = *((WORD *)p)++; /* y */
102 *((WORD *)dialog16)++ = *((WORD *)p)++; /* cx */
103 *((WORD *)dialog16)++ = *((WORD *)p)++; /* cy */
105 if (dialogEx)
106 *((DWORD *)dialog16)++ = *((DWORD *)p)++; /* ID */
107 else
109 *((WORD *)dialog16)++ = *((WORD *)p)++; /* ID */
110 *((DWORD *)dialog16)++ = style; /* style from above */
113 /* Transfer class name */
114 switch (*((WORD *)p))
116 case 0x0000: ((WORD *)p)++; *((BYTE *)dialog16)++ = 0; break;
117 case 0xffff: ((WORD *)p)++;
118 *((BYTE *)dialog16)++ = (BYTE)*((WORD *)p)++; break;
119 default: lstrcpyWtoA( (LPSTR)dialog16, (LPWSTR)p );
120 ((LPSTR)dialog16) += lstrlenA( (LPSTR)dialog16 ) + 1;
121 ((LPWSTR)p) += lstrlenW( (LPWSTR)p ) + 1;
122 break;
125 /* Transfer window name */
126 switch (*((WORD *)p))
128 case 0x0000: ((WORD *)p)++; *((BYTE *)dialog16)++ = 0; break;
129 case 0xffff: ((WORD *)p)++; *((BYTE *)dialog16)++ = 0xff;
130 *((WORD *)dialog16)++ = *((WORD *)p)++; break;
131 default: lstrcpyWtoA( (LPSTR)dialog16, (LPWSTR)p );
132 ((LPSTR)dialog16) += lstrlenA( (LPSTR)dialog16 ) + 1;
133 ((LPWSTR)p) += lstrlenW( (LPWSTR)p ) + 1;
134 break;
137 /* Transfer data */
138 data = *((WORD *)p)++;
139 if (dialogEx)
140 *((WORD *)dialog16)++ = data;
141 else
142 *((BYTE *)dialog16)++ = (BYTE)data;
144 if (data)
146 memcpy( dialog16, p, data );
147 (LPSTR)dialog16 += data;
148 (LPSTR)p += data;
151 /* Next item */
152 nbItems--;
156 /**********************************************************************
157 * GetDialog32Size (KERNEL.618)
159 WORD WINAPI GetDialog32Size16( LPVOID dialog32 )
161 LPVOID p = dialog32;
162 WORD nbItems, data, dialogEx;
163 DWORD style;
165 style = *((DWORD *)p)++;
166 dialogEx = (style == 0xffff0001); /* DIALOGEX resource */
167 if (dialogEx)
169 ((DWORD *)p)++; /* helpID */
170 ((DWORD *)p)++; /* exStyle */
171 style = *((DWORD *)p)++; /* style */
173 else
174 ((DWORD *)p)++; /* exStyle */
176 nbItems = *((WORD *)p)++;
177 ((WORD *)p)++; /* x */
178 ((WORD *)p)++; /* y */
179 ((WORD *)p)++; /* cx */
180 ((WORD *)p)++; /* cy */
182 /* Skip menu name */
183 switch (*((WORD *)p))
185 case 0x0000: ((WORD *)p)++; break;
186 case 0xffff: ((WORD *)p) += 2; break;
187 default: ((LPWSTR)p) += lstrlenW( (LPWSTR)p ) + 1; break;
190 /* Skip class name */
191 switch (*((WORD *)p))
193 case 0x0000: ((WORD *)p)++; break;
194 case 0xffff: ((WORD *)p) += 2; break;
195 default: ((LPWSTR)p) += lstrlenW( (LPWSTR)p ) + 1; break;
198 /* Skip window caption */
199 ((LPWSTR)p) += lstrlenW( (LPWSTR)p ) + 1;
201 /* Skip font info */
202 if (style & DS_SETFONT)
204 ((WORD *)p)++; /* pointSize */
205 if (dialogEx)
207 ((WORD *)p)++; /* weight */
208 ((WORD *)p)++; /* italic */
210 ((LPWSTR)p) += lstrlenW( (LPWSTR)p ) + 1; /* faceName */
213 /* Skip dialog items */
214 while (nbItems)
216 /* align on DWORD boundary */
217 p = (LPVOID)((((int)p) + 3) & ~3);
219 if (dialogEx)
221 ((DWORD *)p)++; /* helpID */
222 ((DWORD *)p)++; /* exStyle */
223 ((DWORD *)p)++; /* style */
225 else
227 ((DWORD *)p)++; /* style */
228 ((DWORD *)p)++; /* exStyle */
231 ((WORD *)p)++; /* x */
232 ((WORD *)p)++; /* y */
233 ((WORD *)p)++; /* cx */
234 ((WORD *)p)++; /* cy */
236 if (dialogEx)
237 ((DWORD *)p)++; /* ID */
238 else
239 ((WORD *)p)++; /* ID */
241 /* Skip class name */
242 switch (*((WORD *)p))
244 case 0x0000: ((WORD *)p)++; break;
245 case 0xffff: ((WORD *)p) += 2; break;
246 default: ((LPWSTR)p) += lstrlenW( (LPWSTR)p ) + 1; break;
249 /* Skip window name */
250 switch (*((WORD *)p))
252 case 0x0000: ((WORD *)p)++; break;
253 case 0xffff: ((WORD *)p) += 2; break;
254 default: ((LPWSTR)p) += lstrlenW( (LPWSTR)p ) + 1; break;
257 /* Skip data */
258 data = *((WORD *)p)++;
259 (LPSTR)p += data;
261 /* Next item */
262 nbItems--;
265 return (WORD)((LPSTR)p - (LPSTR)dialog32);
268 /**********************************************************************
269 * ConvertMenu32To16 (KERNEL.616)
271 VOID WINAPI ConvertMenu32To16( LPVOID menu32, DWORD size, LPVOID menu16 )
273 LPVOID p = menu32;
274 WORD version, headersize, flags, level = 1;
276 version = *((WORD *)menu16)++ = *((WORD *)p)++;
277 headersize = *((WORD *)menu16)++ = *((WORD *)p)++;
278 if ( headersize )
280 memcpy( menu16, p, headersize );
281 ((LPSTR)menu16) += headersize;
282 ((LPSTR)p) += headersize;
285 while ( level )
286 if ( version == 0 ) /* standard */
288 flags = *((WORD *)menu16)++ = *((WORD *)p)++;
289 if ( !(flags & MF_POPUP) )
290 *((WORD *)menu16)++ = *((WORD *)p)++; /* ID */
291 else
292 level++;
294 lstrcpyWtoA( (LPSTR)menu16, (LPWSTR)p );
295 ((LPSTR)menu16) += lstrlenA( (LPSTR)menu16 ) + 1;
296 ((LPWSTR)p) += lstrlenW( (LPWSTR)p ) + 1;
298 if ( flags & MF_END )
299 level--;
301 else /* extended */
303 *((DWORD *)menu16)++ = *((DWORD *)p)++; /* fType */
304 *((DWORD *)menu16)++ = *((DWORD *)p)++; /* fState */
305 *((WORD *)menu16)++ = (WORD)*((DWORD *)p)++; /* ID */
306 flags = *((BYTE *)menu16)++ = (BYTE)*((WORD *)p)++;
308 lstrcpyWtoA( (LPSTR)menu16, (LPWSTR)p );
309 ((LPSTR)menu16) += lstrlenA( (LPSTR)menu16 ) + 1;
310 ((LPWSTR)p) += lstrlenW( (LPWSTR)p ) + 1;
312 /* align on DWORD boundary (32-bit only) */
313 p = (LPVOID)((((int)p) + 3) & ~3);
315 /* If popup, transfer helpid */
316 if ( flags & 1)
318 *((DWORD *)menu16)++ = *((DWORD *)p)++;
319 level++;
322 if ( flags & MF_END )
323 level--;
327 /**********************************************************************
328 * GetMenu32Size (KERNEL.617)
330 WORD WINAPI GetMenu32Size16( LPVOID menu32 )
332 LPVOID p = menu32;
333 WORD version, headersize, flags, level = 1;
335 version = *((WORD *)p)++;
336 headersize = *((WORD *)p)++;
337 ((LPSTR)p) += headersize;
339 while ( level )
340 if ( version == 0 ) /* standard */
342 flags = *((WORD *)p)++;
343 if ( !(flags & MF_POPUP) )
344 ((WORD *)p)++; /* ID */
345 else
346 level++;
348 ((LPWSTR)p) += lstrlenW( (LPWSTR)p ) + 1;
350 if ( flags & MF_END )
351 level--;
353 else /* extended */
355 ((DWORD *)p)++; /* fType */
356 ((DWORD *)p)++; /* fState */
357 ((DWORD *)p)++; /* ID */
358 flags = *((WORD *)p)++;
360 ((LPWSTR)p) += lstrlenW( (LPWSTR)p ) + 1;
362 /* align on DWORD boundary (32-bit only) */
363 p = (LPVOID)((((int)p) + 3) & ~3);
365 /* If popup, skip helpid */
366 if ( flags & 1)
368 ((DWORD *)p)++;
369 level++;
372 if ( flags & MF_END )
373 level--;
376 return (WORD)((LPSTR)p - (LPSTR)menu32);
379 /**********************************************************************
380 * ConvertAccelerator32To16
382 VOID ConvertAccelerator32To16( LPVOID acc32, DWORD size, LPVOID acc16 )
384 int type;
388 /* Copy type */
389 type = *((BYTE *)acc16)++ = *((BYTE *)acc32)++;
390 /* Skip padding */
391 ((BYTE *)acc32)++;
392 /* Copy event and IDval */
393 *((WORD *)acc16)++ = *((WORD *)acc32)++;
394 *((WORD *)acc16)++ = *((WORD *)acc32)++;
395 /* Skip padding */
396 ((WORD *)acc32)++;
398 } while ( !( type & 0x80 ) );
401 /**********************************************************************
402 * NE_LoadPEResource
404 HGLOBAL16 NE_LoadPEResource( NE_MODULE *pModule, WORD type, LPVOID bits, DWORD size )
406 HGLOBAL16 handle;
408 TRACE( resource, "module=%04x type=%04x\n", pModule->self, type );
409 if (!pModule || !bits || !size) return 0;
411 handle = GlobalAlloc16( 0, size );
413 switch (type)
415 case RT_MENU16:
416 ConvertMenu32To16( bits, size, GlobalLock16( handle ) );
417 break;
419 case RT_DIALOG16:
420 ConvertDialog32To16( bits, size, GlobalLock16( handle ) );
421 break;
423 case RT_ACCELERATOR16:
424 ConvertAccelerator32To16( bits, size, GlobalLock16( handle ) );
425 break;
427 case RT_STRING16:
428 FIXME( resource, "not yet implemented!\n" );
429 /* fall through */
431 default:
432 memcpy( GlobalLock16( handle ), bits, size );
433 break;
436 return handle;