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