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