Implementation of PE->NE resource conversion routines (KERNEL.615-618).

This commit is contained in:
Ulrich Weigand 1998-11-25 17:57:26 +00:00 committed by Alexandre Julliard
parent f1779ed51d
commit 5443a7e658
3 changed files with 427 additions and 6 deletions

View File

@ -480,12 +480,12 @@ file krnl386.exe
610 pascal FindSLThunkletCallback(long long) FindSLThunkletCallback
611 return FreeThunklet 8 0
612 pascal16 IsSLThunklet(ptr) IsSLThunklet
613 stub KERNEL_613 # (cbclient)
614 stub KERNEL_614 # (cbclient)
615 stub KERNEL_615 # (cbclient)
616 stub KERNEL_616 # (cbclient)
617 stub KERNEL_617 # (cbclient)
618 stub KERNEL_618 # (cbclient)
613 stub KERNEL_613
614 stub KERNEL_614
615 pascal16 ConvertDialog32To16(long long long) ConvertDialog32To16
616 pascal16 ConvertMenu32To16(long long long) ConvertMenu32To16
617 pascal16 GetMenu32Size(ptr) GetMenu32Size
618 pascal16 GetDialog32Size(ptr) GetDialog32Size
619 pascal16 RegisterCBClient(word ptr long) RegisterCBClient
620 register CBClientThunkSL() CBClientThunkSL
621 stub KERNEL_621 # (cbclient)

View File

@ -6,6 +6,7 @@ VPATH = @srcdir@
MODULE = ne
C_SRCS = \
convert.c \
module.c \
resource.c \
segment.c

420
loader/ne/convert.c Normal file
View File

@ -0,0 +1,420 @@
/*
* PE->NE resource conversion functions
*
* Copyright 1998 Ulrich Weigand
*/
#include "module.h"
#include "debug.h"
#include "debugtools.h"
#include "windows.h"
/**********************************************************************
* ConvertDialog32To16 (KERNEL.615)
*/
VOID WINAPI ConvertDialog32To16( LPVOID dialog32, DWORD size, LPVOID dialog16 )
{
LPVOID p = dialog32;
WORD nbItems, data, dialogEx;
DWORD style;
style = *((DWORD *)dialog16)++ = *((DWORD *)p)++;
dialogEx = (style == 0xffff0001); /* DIALOGEX resource */
if (dialogEx)
{
*((DWORD *)dialog16)++ = *((DWORD *)p)++; /* helpID */
*((DWORD *)dialog16)++ = *((DWORD *)p)++; /* exStyle */
style = *((DWORD *)dialog16)++ = *((DWORD *)p)++; /* style */
}
else
((DWORD *)p)++; /* exStyle ignored in 16-bit standard dialog */
nbItems = *((BYTE *)dialog16)++ = (BYTE)*((WORD *)p)++;
*((WORD *)dialog16)++ = *((WORD *)p)++; /* x */
*((WORD *)dialog16)++ = *((WORD *)p)++; /* y */
*((WORD *)dialog16)++ = *((WORD *)p)++; /* cx */
*((WORD *)dialog16)++ = *((WORD *)p)++; /* cy */
/* Transfer menu name */
switch (*((WORD *)p))
{
case 0x0000: ((WORD *)p)++; *((BYTE *)dialog16)++ = 0; break;
case 0xffff: ((WORD *)p)++; *((BYTE *)dialog16)++ = 0xff;
*((WORD *)dialog16)++ = *((WORD *)p)++; break;
default: lstrcpyWtoA( (LPSTR)dialog16, (LPWSTR)p );
((LPSTR)dialog16) += lstrlen32A( (LPSTR)dialog16 ) + 1;
((LPWSTR)p) += lstrlen32W( (LPWSTR)p ) + 1;
break;
}
/* Transfer class name */
switch (*((WORD *)p))
{
case 0x0000: ((WORD *)p)++; *((BYTE *)dialog16)++ = 0; break;
case 0xffff: ((WORD *)p)++; *((BYTE *)dialog16)++ = 0xff;
*((WORD *)dialog16)++ = *((WORD *)p)++; break;
default: lstrcpyWtoA( (LPSTR)dialog16, (LPWSTR)p );
((LPSTR)dialog16) += lstrlen32A( (LPSTR)dialog16 ) + 1;
((LPWSTR)p) += lstrlen32W( (LPWSTR)p ) + 1;
break;
}
/* Transfer window caption */
lstrcpyWtoA( (LPSTR)dialog16, (LPWSTR)p );
((LPSTR)dialog16) += lstrlen32A( (LPSTR)dialog16 ) + 1;
((LPWSTR)p) += lstrlen32W( (LPWSTR)p ) + 1;
/* Transfer font info */
if (style & DS_SETFONT)
{
*((WORD *)dialog16)++ = *((WORD *)p)++; /* pointSize */
if (dialogEx)
{
*((WORD *)dialog16)++ = *((WORD *)p)++; /* weight */
*((WORD *)dialog16)++ = *((WORD *)p)++; /* italic */
}
lstrcpyWtoA( (LPSTR)dialog16, (LPWSTR)p ); /* faceName */
((LPSTR)dialog16) += lstrlen32A( (LPSTR)dialog16 ) + 1;
((LPWSTR)p) += lstrlen32W( (LPWSTR)p ) + 1;
}
/* Transfer dialog items */
while (nbItems)
{
/* align on DWORD boundary (32-bit only) */
p = (LPVOID)((((int)p) + 3) & ~3);
if (dialogEx)
{
*((DWORD *)dialog16)++ = *((DWORD *)p)++; /* helpID */
*((DWORD *)dialog16)++ = *((DWORD *)p)++; /* exStyle */
*((DWORD *)dialog16)++ = *((DWORD *)p)++; /* style */
}
else
{
style = *((DWORD *)p)++; /* save style */
((DWORD *)p)++; /* ignore exStyle */
}
*((WORD *)dialog16)++ = *((WORD *)p)++; /* x */
*((WORD *)dialog16)++ = *((WORD *)p)++; /* y */
*((WORD *)dialog16)++ = *((WORD *)p)++; /* cx */
*((WORD *)dialog16)++ = *((WORD *)p)++; /* cy */
if (dialogEx)
*((DWORD *)dialog16)++ = *((DWORD *)p)++; /* ID */
else
{
*((WORD *)dialog16)++ = *((WORD *)p)++; /* ID */
*((DWORD *)dialog16)++ = style; /* style from above */
}
/* Transfer class name */
switch (*((WORD *)p))
{
case 0x0000: ((WORD *)p)++; *((BYTE *)dialog16)++ = 0; break;
case 0xffff: ((WORD *)p)++;
*((BYTE *)dialog16)++ = (BYTE)*((WORD *)p)++; break;
default: lstrcpyWtoA( (LPSTR)dialog16, (LPWSTR)p );
((LPSTR)dialog16) += lstrlen32A( (LPSTR)dialog16 ) + 1;
((LPWSTR)p) += lstrlen32W( (LPWSTR)p ) + 1;
break;
}
/* Transfer window name */
switch (*((WORD *)p))
{
case 0x0000: ((WORD *)p)++; *((BYTE *)dialog16)++ = 0; break;
case 0xffff: ((WORD *)p)++; *((BYTE *)dialog16)++ = 0xff;
*((WORD *)dialog16)++ = *((WORD *)p)++; break;
default: lstrcpyWtoA( (LPSTR)dialog16, (LPWSTR)p );
((LPSTR)dialog16) += lstrlen32A( (LPSTR)dialog16 ) + 1;
((LPWSTR)p) += lstrlen32W( (LPWSTR)p ) + 1;
break;
}
/* Transfer data */
data = *((WORD *)p)++;
if (dialogEx)
*((WORD *)dialog16)++ = data;
else
*((BYTE *)dialog16)++ = (BYTE)data;
if (data)
{
memcpy( dialog16, p, data );
(LPSTR)dialog16 += data;
(LPSTR)p += data;
}
/* Next item */
nbItems--;
}
}
/**********************************************************************
* GetDialog32Size (KERNEL.618)
*/
WORD WINAPI GetDialog32Size( LPVOID dialog32 )
{
LPVOID p = dialog32;
WORD nbItems, data, dialogEx;
DWORD style;
style = *((DWORD *)p)++;
dialogEx = (style == 0xffff0001); /* DIALOGEX resource */
if (dialogEx)
{
((DWORD *)p)++; /* helpID */
((DWORD *)p)++; /* exStyle */
style = *((DWORD *)p)++; /* style */
}
else
((DWORD *)p)++; /* exStyle */
nbItems = *((WORD *)p)++;
((WORD *)p)++; /* x */
((WORD *)p)++; /* y */
((WORD *)p)++; /* cx */
((WORD *)p)++; /* cy */
/* Skip menu name */
switch (*((WORD *)p))
{
case 0x0000: ((WORD *)p)++; break;
case 0xffff: ((WORD *)p) += 2; break;
default: ((LPWSTR)p) += lstrlen32W( (LPWSTR)p ) + 1; break;
}
/* Skip class name */
switch (*((WORD *)p))
{
case 0x0000: ((WORD *)p)++; break;
case 0xffff: ((WORD *)p) += 2; break;
default: ((LPWSTR)p) += lstrlen32W( (LPWSTR)p ) + 1; break;
}
/* Skip window caption */
((LPWSTR)p) += lstrlen32W( (LPWSTR)p ) + 1;
/* Skip font info */
if (style & DS_SETFONT)
{
((WORD *)p)++; /* pointSize */
if (dialogEx)
{
((WORD *)p)++; /* weight */
((WORD *)p)++; /* italic */
}
((LPWSTR)p) += lstrlen32W( (LPWSTR)p ) + 1; /* faceName */
}
/* Skip dialog items */
while (nbItems)
{
/* align on DWORD boundary */
p = (LPVOID)((((int)p) + 3) & ~3);
if (dialogEx)
{
((DWORD *)p)++; /* helpID */
((DWORD *)p)++; /* exStyle */
((DWORD *)p)++; /* style */
}
else
{
((DWORD *)p)++; /* style */
((DWORD *)p)++; /* exStyle */
}
((WORD *)p)++; /* x */
((WORD *)p)++; /* y */
((WORD *)p)++; /* cx */
((WORD *)p)++; /* cy */
if (dialogEx)
((DWORD *)p)++; /* ID */
else
((WORD *)p)++; /* ID */
/* Skip class name */
switch (*((WORD *)p))
{
case 0x0000: ((WORD *)p)++; break;
case 0xffff: ((WORD *)p) += 2; break;
default: ((LPWSTR)p) += lstrlen32W( (LPWSTR)p ) + 1; break;
}
/* Skip window name */
switch (*((WORD *)p))
{
case 0x0000: ((WORD *)p)++; break;
case 0xffff: ((WORD *)p) += 2; break;
default: ((LPWSTR)p) += lstrlen32W( (LPWSTR)p ) + 1; break;
}
/* Skip data */
data = *((WORD *)p)++;
(LPSTR)p += data;
/* Next item */
nbItems--;
}
return (WORD)((LPSTR)p - (LPSTR)dialog32);
}
/**********************************************************************
* ConvertMenu32To16 (KERNEL.616)
*/
VOID WINAPI ConvertMenu32To16( LPVOID menu32, DWORD size, LPVOID menu16 )
{
LPVOID p = menu32;
WORD version, headersize, flags, level = 1;
version = *((WORD *)menu16)++ = *((WORD *)p)++;
headersize = *((WORD *)menu16)++ = *((WORD *)p)++;
if ( headersize )
{
memcpy( menu16, p, headersize );
((LPSTR)menu16) += headersize;
((LPSTR)p) += headersize;
}
while ( level )
if ( version == 0 ) /* standard */
{
flags = *((WORD *)menu16)++ = *((WORD *)p)++;
if ( !(flags & MF_POPUP) )
*((WORD *)menu16)++ = *((WORD *)p)++; /* ID */
else
level++;
lstrcpyWtoA( (LPSTR)menu16, (LPWSTR)p );
((LPSTR)menu16) += lstrlen32A( (LPSTR)menu16 ) + 1;
((LPWSTR)p) += lstrlen32W( (LPWSTR)p ) + 1;
if ( flags & MF_END )
level--;
}
else /* extended */
{
*((DWORD *)menu16)++ = *((DWORD *)p)++; /* fType */
*((DWORD *)menu16)++ = *((DWORD *)p)++; /* fState */
*((WORD *)menu16)++ = (WORD)*((DWORD *)p)++; /* ID */
flags = *((BYTE *)menu16)++ = (BYTE)*((WORD *)p)++;
lstrcpyWtoA( (LPSTR)menu16, (LPWSTR)p );
((LPSTR)menu16) += lstrlen32A( (LPSTR)menu16 ) + 1;
((LPWSTR)p) += lstrlen32W( (LPWSTR)p ) + 1;
/* align on DWORD boundary (32-bit only) */
p = (LPVOID)((((int)p) + 3) & ~3);
/* If popup, transfer helpid */
if ( flags & 1)
{
*((DWORD *)menu16)++ = *((DWORD *)p)++;
level++;
}
if ( flags & MF_END )
level--;
}
}
/**********************************************************************
* GetMenu32Size (KERNEL.617)
*/
WORD WINAPI GetMenu32Size( LPVOID menu32 )
{
LPVOID p = menu32;
WORD version, headersize, flags, level = 1;
version = *((WORD *)p)++;
headersize = *((WORD *)p)++;
((LPSTR)p) += headersize;
while ( level )
if ( version == 0 ) /* standard */
{
flags = *((WORD *)p)++;
if ( !(flags & MF_POPUP) )
((WORD *)p)++; /* ID */
else
level++;
((LPWSTR)p) += lstrlen32W( (LPWSTR)p ) + 1;
if ( flags & MF_END )
level--;
}
else /* extended */
{
((DWORD *)p)++; /* fType */
((DWORD *)p)++; /* fState */
((DWORD *)p)++; /* ID */
flags = *((WORD *)p)++;
((LPWSTR)p) += lstrlen32W( (LPWSTR)p ) + 1;
/* align on DWORD boundary (32-bit only) */
p = (LPVOID)((((int)p) + 3) & ~3);
/* If popup, skip helpid */
if ( flags & 1)
{
((DWORD *)p)++;
level++;
}
if ( flags & MF_END )
level--;
}
return (WORD)((LPSTR)p - (LPSTR)menu32);
}
/**********************************************************************
* NE_LoadPEResource
*/
HGLOBAL16 NE_LoadPEResource( NE_MODULE *pModule, WORD type, LPVOID bits, DWORD size )
{
HGLOBAL16 handle;
TRACE( resource, "module=%04x type=%04x\n", pModule->self, type );
if (!pModule || !bits || !size) return 0;
handle = GlobalAlloc16( 0, size );
switch (type)
{
case RT_MENU16:
ConvertMenu32To16( bits, size, GlobalLock16( handle ) );
break;
case RT_DIALOG16:
ConvertDialog32To16( bits, size, GlobalLock16( handle ) );
break;
case RT_STRING16:
FIXME( resource, "not yet implemented!\n" );
/* fall through */
default:
memcpy( GlobalLock16( handle ), bits, size );
break;
}
return handle;
}
/**********************************************************************
* NE_FreePEResource
*/
BOOL16 NE_FreePEResource( NE_MODULE *pModule, HGLOBAL16 handle )
{
GlobalFree16( handle );
return 0;
}