Added an unknown VxD error code.
[wine] / loader / ne / convert.c
1 /*
2  * PE->NE resource conversion functions
3  *
4  * Copyright 1998 Ulrich Weigand
5  */
6
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"
14
15 DEFAULT_DEBUG_CHANNEL(resource);
16
17 /**********************************************************************
18  *          ConvertDialog32To16   (KERNEL.615)
19  */
20 VOID WINAPI ConvertDialog32To16( LPVOID dialog32, DWORD size, LPVOID dialog16 )
21 {
22     LPVOID p = dialog32;
23     WORD nbItems, data, dialogEx;
24     DWORD style;
25
26     style = *((DWORD *)dialog16)++ = *((DWORD *)p)++;
27     dialogEx = (style == 0xffff0001);  /* DIALOGEX resource */
28     if (dialogEx)
29     {
30         *((DWORD *)dialog16)++ = *((DWORD *)p)++; /* helpID */
31         *((DWORD *)dialog16)++ = *((DWORD *)p)++; /* exStyle */
32         style = *((DWORD *)dialog16)++ = *((DWORD *)p)++; /* style */
33     }
34     else
35         ((DWORD *)p)++; /* exStyle ignored in 16-bit standard dialog */
36
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 */
42
43     /* Transfer menu name */
44     switch (*((WORD *)p))
45     {
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;
53     }
54
55     /* Transfer class name */
56     switch (*((WORD *)p))
57     {
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;
65     }
66
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;
71
72     /* Transfer font info */
73     if (style & DS_SETFONT)
74     {
75         *((WORD *)dialog16)++ = *((WORD *)p)++;  /* pointSize */
76         if (dialogEx)
77         {
78             *((WORD *)dialog16)++ = *((WORD *)p)++; /* weight */
79             *((WORD *)dialog16)++ = *((WORD *)p)++; /* italic */
80         }
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;
84     }
85
86     /* Transfer dialog items */
87     while (nbItems)
88     {
89         /* align on DWORD boundary (32-bit only) */
90         p = (LPVOID)((((int)p) + 3) & ~3);
91
92         if (dialogEx)
93         {
94             *((DWORD *)dialog16)++ = *((DWORD *)p)++; /* helpID */
95             *((DWORD *)dialog16)++ = *((DWORD *)p)++; /* exStyle */
96             *((DWORD *)dialog16)++ = *((DWORD *)p)++; /* style */
97         }
98         else
99         {
100             style = *((DWORD *)p)++; /* save style */
101             ((DWORD *)p)++;          /* ignore exStyle */
102         }
103
104         *((WORD *)dialog16)++ = *((WORD *)p)++; /* x */
105         *((WORD *)dialog16)++ = *((WORD *)p)++; /* y */
106         *((WORD *)dialog16)++ = *((WORD *)p)++; /* cx */
107         *((WORD *)dialog16)++ = *((WORD *)p)++; /* cy */
108
109         if (dialogEx)
110             *((DWORD *)dialog16)++ = *((DWORD *)p)++; /* ID */
111         else
112         {
113             *((WORD *)dialog16)++ = *((WORD *)p)++; /* ID */
114             *((DWORD *)dialog16)++ = style;  /* style from above */
115         }
116
117         /* Transfer class name */
118         switch (*((WORD *)p))
119         {
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;
127         }
128
129         /* Transfer window name */
130         switch (*((WORD *)p))
131         {
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;
139         }
140        
141         /* Transfer data */
142         data = *((WORD *)p)++; 
143         if (dialogEx)
144             *((WORD *)dialog16)++ = data;
145         else
146             *((BYTE *)dialog16)++ = (BYTE)data;
147
148         if (data) 
149         {
150             memcpy( dialog16, p, data );
151             (LPSTR)dialog16 += data;
152             (LPSTR)p += data;
153         }
154
155         /* Next item */
156         nbItems--;
157     }
158 }
159
160 /**********************************************************************
161  *          GetDialog32Size   (KERNEL.618)
162  */
163 WORD WINAPI GetDialog32Size16( LPVOID dialog32 )
164 {
165     LPVOID p = dialog32;
166     WORD nbItems, data, dialogEx;
167     DWORD style;
168
169     style = *((DWORD *)p)++;
170     dialogEx = (style == 0xffff0001);  /* DIALOGEX resource */
171     if (dialogEx)
172     {
173         ((DWORD *)p)++; /* helpID */
174         ((DWORD *)p)++; /* exStyle */
175         style = *((DWORD *)p)++; /* style */
176     }
177     else
178         ((DWORD *)p)++; /* exStyle */
179
180     nbItems = *((WORD *)p)++;
181     ((WORD *)p)++; /* x */
182     ((WORD *)p)++; /* y */
183     ((WORD *)p)++; /* cx */
184     ((WORD *)p)++; /* cy */
185
186     /* Skip menu name */
187     switch (*((WORD *)p))
188     {
189     case 0x0000:  ((WORD *)p)++; break;
190     case 0xffff:  ((WORD *)p) += 2; break;
191     default:      ((LPWSTR)p) += strlenW( (LPWSTR)p ) + 1; break;
192     }
193
194     /* Skip class name */
195     switch (*((WORD *)p))
196     {
197     case 0x0000:  ((WORD *)p)++; break;
198     case 0xffff:  ((WORD *)p) += 2; break;
199     default:      ((LPWSTR)p) += strlenW( (LPWSTR)p ) + 1; break;
200     }
201
202     /* Skip window caption */
203     ((LPWSTR)p) += strlenW( (LPWSTR)p ) + 1; 
204
205     /* Skip font info */
206     if (style & DS_SETFONT)
207     {
208         ((WORD *)p)++;  /* pointSize */
209         if (dialogEx)
210         {
211             ((WORD *)p)++; /* weight */
212             ((WORD *)p)++; /* italic */
213         }
214         ((LPWSTR)p) += strlenW( (LPWSTR)p ) + 1;  /* faceName */
215     }
216
217     /* Skip dialog items */
218     while (nbItems)
219     {
220         /* align on DWORD boundary */
221         p = (LPVOID)((((int)p) + 3) & ~3);
222
223         if (dialogEx)
224         {
225             ((DWORD *)p)++; /* helpID */
226             ((DWORD *)p)++; /* exStyle */
227             ((DWORD *)p)++; /* style */
228         }
229         else
230         {
231             ((DWORD *)p)++; /* style */
232             ((DWORD *)p)++; /* exStyle */
233         }
234
235         ((WORD *)p)++; /* x */
236         ((WORD *)p)++; /* y */
237         ((WORD *)p)++; /* cx */
238         ((WORD *)p)++; /* cy */
239
240         if (dialogEx)
241             ((DWORD *)p)++; /* ID */
242         else
243             ((WORD *)p)++; /* ID */
244
245         /* Skip class name */
246         switch (*((WORD *)p))
247         {
248         case 0x0000:  ((WORD *)p)++; break;
249         case 0xffff:  ((WORD *)p) += 2; break;
250         default:      ((LPWSTR)p) += strlenW( (LPWSTR)p ) + 1; break;
251         }
252
253         /* Skip window name */
254         switch (*((WORD *)p))
255         {
256         case 0x0000:  ((WORD *)p)++; break;
257         case 0xffff:  ((WORD *)p) += 2; break;
258         default:      ((LPWSTR)p) += strlenW( (LPWSTR)p ) + 1; break;
259         }
260        
261         /* Skip data */
262         data = *((WORD *)p)++; 
263         (LPSTR)p += data;
264
265         /* Next item */
266         nbItems--;
267     }
268
269     return (WORD)((LPSTR)p - (LPSTR)dialog32);
270 }
271
272 /**********************************************************************
273  *          ConvertMenu32To16   (KERNEL.616)
274  */
275 VOID WINAPI ConvertMenu32To16( LPVOID menu32, DWORD size, LPVOID menu16 )
276 {
277     LPVOID p = menu32;
278     WORD version, headersize, flags, level = 1;
279
280     version = *((WORD *)menu16)++ = *((WORD *)p)++;
281     headersize = *((WORD *)menu16)++ = *((WORD *)p)++;
282     if ( headersize )
283     {
284         memcpy( menu16, p, headersize );
285         ((LPSTR)menu16) += headersize;
286         ((LPSTR)p) += headersize;
287     }
288
289     while ( level )
290         if ( version == 0 )  /* standard */
291         {
292             flags = *((WORD *)menu16)++ = *((WORD *)p)++;
293             if ( !(flags & MF_POPUP) )
294                 *((WORD *)menu16)++ = *((WORD *)p)++;  /* ID */
295             else
296                 level++;
297        
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;
301
302             if ( flags & MF_END )
303                 level--;
304         }
305         else  /* extended */
306         {
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)++;  
311        
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;
315
316             /* align on DWORD boundary (32-bit only) */
317             p = (LPVOID)((((int)p) + 3) & ~3);
318
319             /* If popup, transfer helpid */
320             if ( flags & 1)
321             {
322                 *((DWORD *)menu16)++ = *((DWORD *)p)++;
323                 level++;
324             }
325
326             if ( flags & MF_END )
327                 level--;
328         }
329 }
330
331 /**********************************************************************
332  *          GetMenu32Size   (KERNEL.617)
333  */
334 WORD WINAPI GetMenu32Size16( LPVOID menu32 )
335 {
336     LPVOID p = menu32;
337     WORD version, headersize, flags, level = 1;
338
339     version = *((WORD *)p)++;
340     headersize = *((WORD *)p)++;
341     ((LPSTR)p) += headersize;
342
343     while ( level )
344         if ( version == 0 )  /* standard */
345         {
346             flags = *((WORD *)p)++;
347             if ( !(flags & MF_POPUP) )
348                 ((WORD *)p)++;  /* ID */
349             else
350                 level++;
351        
352             ((LPWSTR)p) += strlenW( (LPWSTR)p ) + 1;
353
354             if ( flags & MF_END )
355                 level--;
356         }
357         else  /* extended */
358         {
359             ((DWORD *)p)++; /* fType */
360             ((DWORD *)p)++; /* fState */
361             ((DWORD *)p)++; /* ID */
362             flags = *((WORD *)p)++; 
363        
364             ((LPWSTR)p) += strlenW( (LPWSTR)p ) + 1;
365
366             /* align on DWORD boundary (32-bit only) */
367             p = (LPVOID)((((int)p) + 3) & ~3);
368
369             /* If popup, skip helpid */
370             if ( flags & 1)
371             {
372                 ((DWORD *)p)++;
373                 level++;
374             }
375
376             if ( flags & MF_END )
377                 level--;
378         }
379
380     return (WORD)((LPSTR)p - (LPSTR)menu32);
381 }
382
383 /**********************************************************************
384  *          ConvertAccelerator32To16
385  */
386 VOID ConvertAccelerator32To16( LPVOID acc32, DWORD size, LPVOID acc16 )
387 {
388     int type;
389
390     do
391     {
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)++;
401
402     } while ( !( type & 0x80 ) );
403 }
404
405 /**********************************************************************
406  *          NE_LoadPEResource
407  */
408 HGLOBAL16 NE_LoadPEResource( NE_MODULE *pModule, WORD type, LPVOID bits, DWORD size )
409 {
410     HGLOBAL16 handle;
411
412     TRACE("module=%04x type=%04x\n", pModule->self, type );
413     if (!pModule || !bits || !size) return 0;
414
415     handle = GlobalAlloc16( 0, size );
416    
417     switch (type)
418     {
419     case RT_MENU16:
420         ConvertMenu32To16( bits, size, GlobalLock16( handle ) );
421         break;
422
423     case RT_DIALOG16:
424         ConvertDialog32To16( bits, size, GlobalLock16( handle ) );
425         break;
426
427     case RT_ACCELERATOR16:
428         ConvertAccelerator32To16( bits, size, GlobalLock16( handle ) );
429         break;
430
431     case RT_STRING16:
432         FIXME("not yet implemented!\n" );
433         /* fall through */
434
435     default:
436         memcpy( GlobalLock16( handle ), bits, size );
437         break;
438     }
439
440     return handle;
441 }
442