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