You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
705 lines
21 KiB
705 lines
21 KiB
/*++
|
|
*
|
|
* WOW v1.0
|
|
*
|
|
* Copyright (c) 1991, Microsoft Corporation
|
|
*
|
|
* WRES16.C
|
|
* WOW32 16-bit resource support
|
|
*
|
|
* History:
|
|
* Created 11-Mar-1991 by Jeff Parsons (jeffpar)
|
|
--*/
|
|
|
|
|
|
#include "precomp.h"
|
|
#pragma hdrstop
|
|
|
|
//
|
|
// BUGBUG: moved macros from mvdm.h and wow32.h
|
|
// as they are not what they appear to be.
|
|
// Watch out these macros increment the pointer arguments!!!!
|
|
// 02-Feb-1994 Jonle
|
|
//
|
|
#define VALIDPUT(p) ((UINT)p>65535)
|
|
#define PUTWORD(p,w) {if (VALIDPUT(p)) *(PWORD)p=w; ((PWORD)p)++; }
|
|
#define PUTDWORD(p,d) {if (VALIDPUT(p)) *(PDWORD)p=d;((PDWORD)p)++;}
|
|
#define PUTUDWORD(p,d) {if (VALIDPUT(p)) *(DWORD UNALIGNED *)p=d;((DWORD UNALIGNED *)p)++;}
|
|
#define GETWORD(pb) (*((UNALIGNED WORD *)pb)++)
|
|
#define GETDWORD(pb) (*((UNALIGNED DWORD *)pb)++)
|
|
|
|
#define ADVGET(p,i) {(UINT)p+=i;}
|
|
#define ADVPUT(p,i) {(UINT)p+=i;}
|
|
#define ALIGNWORD(p) {(UINT)p+=( ((UINT)p)&(sizeof(WORD)-1));}
|
|
#define ALIGNDWORD(p) {(UINT)p+=(-((INT)p)&(sizeof(DWORD)-1));}
|
|
|
|
|
|
MODNAME(wres16.c);
|
|
|
|
PRES presFirst; // pointer to first RES entry
|
|
|
|
#ifdef DEBUG
|
|
|
|
typedef struct _RTINFO { /* rt */
|
|
LPSTR lpType; // predefined resource type
|
|
PSZ pszName; // name of type
|
|
} RTINFO, *PRTINFO;
|
|
|
|
RTINFO artInfo[] = {
|
|
{RT_CURSOR, "CURSOR"},
|
|
{RT_BITMAP, "BITMAP"},
|
|
{RT_ICON, "ICON"},
|
|
{RT_MENU, "MENU"},
|
|
{RT_DIALOG, "DIALOG"},
|
|
{RT_STRING, "STRING"},
|
|
{RT_FONTDIR, "FONTDIR"},
|
|
{RT_FONT, "FONT"},
|
|
{RT_ACCELERATOR, "ACCELERATOR"},
|
|
{RT_RCDATA, "RCDATA"},
|
|
{RT_MESSAGETABLE,"MESSAGETABLE"},
|
|
{RT_GROUP_CURSOR,"CURSOR DIRECTORY"},
|
|
{RT_GROUP_ICON, "ICON DIRECTORY"},
|
|
};
|
|
|
|
PSZ GetResourceType(LPSZ lpszType)
|
|
{
|
|
INT i;
|
|
register PRTINFO prt;
|
|
|
|
if (HIWORD(lpszType) != 0)
|
|
return lpszType;
|
|
|
|
for (prt=artInfo,i=NUMEL(artInfo); i>0; i--,prt++)
|
|
if (prt->lpType == lpszType)
|
|
return prt->pszName;
|
|
|
|
return "UNKNOWN";
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
/* Resource management functions
|
|
*/
|
|
|
|
PRES AddRes16(HMOD16 hmod16, WORD wExeVer, HRESI16 hresinfo16, LPSZ lpszType)
|
|
{
|
|
register PRES pres;
|
|
|
|
if (pres = malloc_w(sizeof(RES))) {
|
|
|
|
// Initialize the structure
|
|
pres->hmod16 = hmod16;
|
|
pres->wExeVer = wExeVer;
|
|
pres->flState = 0;
|
|
pres->hresinfo16 = hresinfo16;
|
|
pres->hresdata16 = 0;
|
|
pres->lpszResType = lpszType;
|
|
pres->pbResData = NULL;
|
|
|
|
// And then link it in
|
|
pres->presNext = presFirst;
|
|
presFirst = pres;
|
|
return pres;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
|
|
VOID FreeRes16(PRES presFree)
|
|
{
|
|
register PRES pres, presPrev;
|
|
|
|
presPrev = (PRES)(&presFirst);
|
|
while (pres = presPrev->presNext) {
|
|
if (pres == presFree)
|
|
break;
|
|
presPrev = pres;
|
|
}
|
|
|
|
// Changed from WOW32ASSERT by cmjones 11/3/97
|
|
// This might be a bogus warning in that USER32!SplFreeResource() calls
|
|
// W32FreeResource() twice on certain types of resources. The Warning
|
|
// might be raised on the 2nd call after the resource was just freed.
|
|
// The only known occurances are at the start of the Winstone '94
|
|
// Quattro Pro test. This can safely be ignored if you see SplFreeResource
|
|
// in the stack dump.
|
|
WOW32WARNMSG((pres),("WOW::FreeRes16:Possible lost resource.\n"));
|
|
|
|
if (pres) {
|
|
presPrev->presNext = pres->presNext;
|
|
if (pres->pbResData)
|
|
UnlockResource16(pres);
|
|
free_w(pres);
|
|
}
|
|
}
|
|
|
|
|
|
VOID DestroyRes16(HMOD16 hmod16)
|
|
{
|
|
register PRES pres, presPrev;
|
|
|
|
presPrev = (PRES)(&presFirst);
|
|
while (pres = presPrev->presNext) {
|
|
if (pres->hmod16 == hmod16) {
|
|
|
|
LOGDEBUG(5,("Freeing resource info for current terminating task\n"));
|
|
|
|
// Now basically do a FreeRes16
|
|
presPrev->presNext = pres->presNext;
|
|
if (pres->pbResData)
|
|
UnlockResource16(pres);
|
|
free_w(pres);
|
|
} else {
|
|
presPrev = pres;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
PRES FindResource16(HMOD16 hmod16, LPSZ lpszName, LPSZ lpszType)
|
|
{
|
|
INT cb;
|
|
PRES pres = NULL;
|
|
VPVOID vp=0;
|
|
PARM16 Parm16;
|
|
VPSZ vpszName = 0, vpszType = 0;
|
|
WORD wExpWinVer;
|
|
|
|
if (HIWORD(lpszName) == 0) {
|
|
vpszName = (VPSZ)lpszName;
|
|
LOGDEBUG(5,(" Finding resource %lx, type %s(%lx)\n",
|
|
lpszName, GetResourceType(lpszType), lpszType));
|
|
} else {
|
|
#ifdef FE_SB
|
|
if (CURRENTPTD()->dwWOWCompatFlagsFE & WOWCF_FE_ARIRANG20_PRNDLG) {
|
|
/*
|
|
* In case of Korean Arirang2.0 word processor, it use wrong dialog ID
|
|
* for Print or Print setup dialog. See dialog box ID on awpfont.dll.
|
|
*/
|
|
if (!WOW32_strcmp(lpszName, "PRINTDLGTEMP"))
|
|
vpszName = (VPSZ) 2;
|
|
else if(!WOW32_strcmp(lpszName, "PRNSETUPDLGTEMP"))
|
|
vpszName = (VPSZ) 1;
|
|
else goto NOT_ARIRANG20;
|
|
} else { // original code
|
|
NOT_ARIRANG20:
|
|
#endif
|
|
cb = strlen(lpszName)+1;
|
|
if (vpszName = GlobalAllocLock16(GMEM_MOVEABLE, cb, NULL))
|
|
putstr16(vpszName, lpszName, cb);
|
|
LOGDEBUG(5,(" Finding resource \"%s\", type %s(%lx)\n",
|
|
lpszName, GetResourceType(lpszType), lpszType));
|
|
#ifdef FE_SB
|
|
}
|
|
#endif
|
|
}
|
|
|
|
if (vpszName) {
|
|
if (HIWORD(lpszType) == 0) { // predefined resource
|
|
vpszType = (VPSZ)lpszType; // no doubt from MAKEINTRESOURCE
|
|
} else {
|
|
cb = strlen(lpszType)+1;
|
|
if (vpszType = GlobalAllocLock16(GMEM_MOVEABLE, cb, NULL)) {
|
|
putstr16(vpszType, lpszType, cb);
|
|
}
|
|
}
|
|
if (vpszType) {
|
|
Parm16.WndProc.wParam = hmod16;
|
|
Parm16.WndProc.lParam = vpszName;
|
|
Parm16.WndProc.wMsg = LOWORD(vpszType);
|
|
Parm16.WndProc.hwnd = HIWORD(vpszType);
|
|
CallBack16(RET_FINDRESOURCE, &Parm16, 0, &vp);
|
|
wExpWinVer = LOWORD(Parm16.WndProc.lParam);
|
|
if (HIWORD(vpszType))
|
|
GlobalUnlockFree16(vpszType);
|
|
}
|
|
if (HIWORD(vpszName))
|
|
GlobalUnlockFree16(vpszName);
|
|
}
|
|
|
|
if ((HRESI16)vp) {
|
|
pres = AddRes16(hmod16,wExpWinVer,(HRESI16)vp, lpszType);
|
|
}
|
|
return pres;
|
|
}
|
|
|
|
|
|
PRES LoadResource16(HMOD16 hmod16, PRES pres)
|
|
{
|
|
VPVOID vp=0;
|
|
PARM16 Parm16;
|
|
|
|
DBG_UNREFERENCED_PARAMETER(hmod16);
|
|
|
|
WOW32ASSERT(pres && hmod16 == pres->hmod16);
|
|
if(pres == NULL) {
|
|
return(NULL);
|
|
}
|
|
|
|
Parm16.WndProc.wParam = pres->hmod16;
|
|
Parm16.WndProc.lParam = pres->hresinfo16;
|
|
|
|
CallBack16(RET_LOADRESOURCE, &Parm16, 0, &vp);
|
|
|
|
if (pres->hresdata16 = (HRESD16)vp)
|
|
return pres;
|
|
|
|
// BUGBUG -- On a LoadResource failure, WIN32 is not required to do a
|
|
// corresponding FreeResource, so our RES structure will hang around until
|
|
// task termination clean-up (which may be OK) -JTP
|
|
return NULL;
|
|
}
|
|
|
|
|
|
BOOL FreeResource16(PRES pres)
|
|
{
|
|
VPVOID vp=0;
|
|
PARM16 Parm16;
|
|
|
|
if(pres == NULL) {
|
|
WOW32ASSERT(pres);
|
|
return(FALSE);
|
|
}
|
|
|
|
Parm16.WndProc.wParam = pres->hresdata16;
|
|
CallBack16(RET_FREERESOURCE, &Parm16, 0, &vp);
|
|
|
|
FreeRes16(pres);
|
|
|
|
return (BOOL)vp;
|
|
}
|
|
|
|
|
|
LPBYTE LockResource16(register PRES pres)
|
|
{
|
|
DWORD cb, cb16;
|
|
VPVOID vp=0;
|
|
PARM16 Parm16;
|
|
WOW32ASSERT(pres);
|
|
|
|
if(pres == NULL) {
|
|
WOW32ASSERT(pres);
|
|
return(NULL);
|
|
}
|
|
|
|
Parm16.WndProc.wParam = pres->hresdata16;
|
|
CallBack16(RET_LOCKRESOURCE, &Parm16, 0, &vp);
|
|
|
|
if (vp) {
|
|
|
|
// Get size of 16-bit resource
|
|
cb16 = Parm16.WndProc.lParam;
|
|
|
|
LOGDEBUG(5,(" Locking/converting resource type %s(%lx)\n",
|
|
GetResourceType(pres->lpszResType), pres->lpszResType));
|
|
|
|
// Handle known resource types here
|
|
if (pres->lpszResType) {
|
|
|
|
switch((INT)pres->lpszResType) {
|
|
|
|
|
|
case (INT)RT_MENU:
|
|
// cb = ConvertMenu16(pres->wExeVer, NULL, vp, cb, cb16);
|
|
cb = cb16 * sizeof(WCHAR); // see SizeofResource16
|
|
if (cb && (pres->pbResData = malloc_w(cb)))
|
|
ConvertMenu16(pres->wExeVer, pres->pbResData, vp, cb, cb16);
|
|
return pres->pbResData;
|
|
|
|
case (INT)RT_DIALOG:
|
|
// cb = ConvertDialog16(NULL, vp, cb, cb16);
|
|
cb = cb16 * sizeof(WCHAR); // see SizeofResource16
|
|
if (cb && (pres->pbResData = malloc_w(cb)))
|
|
ConvertDialog16(pres->pbResData, vp, cb, cb16);
|
|
return pres->pbResData;
|
|
|
|
case (INT)RT_ACCELERATOR:
|
|
WOW32ASSERT(FALSE); // never should we come here.
|
|
return NULL;
|
|
|
|
// case (INT)RT_GROUP_CURSOR:
|
|
// case (INT)RT_GROUP_ICON:
|
|
// GETOPTPTR(vp, 0, lp);
|
|
// return lp;
|
|
}
|
|
}
|
|
|
|
// If we're still here, get desperate and return a simple 32-bit alias
|
|
GETVDMPTR(vp, cb16, pres->pbResData);
|
|
pres->flState |= RES_ALIASPTR;
|
|
return pres->pbResData;
|
|
}
|
|
// If we're still here, nothing worked
|
|
return NULL;
|
|
}
|
|
|
|
|
|
BOOL UnlockResource16(PRES pres)
|
|
{
|
|
VPVOID vp=0;
|
|
PARM16 Parm16;
|
|
|
|
if(pres == NULL) {
|
|
WOW32ASSERT(pres);
|
|
return(FALSE);
|
|
}
|
|
|
|
Parm16.WndProc.wParam = pres->hresdata16;
|
|
CallBack16(RET_UNLOCKRESOURCE, &Parm16, 0, &vp);
|
|
|
|
if (pres->pbResData && !(pres->flState & RES_ALIASPTR))
|
|
free_w(pres->pbResData);
|
|
pres->pbResData = NULL;
|
|
pres->flState &= ~RES_ALIASPTR;
|
|
|
|
return (BOOL)vp;
|
|
}
|
|
|
|
|
|
DWORD SizeofResource16(HMOD16 hmod16, PRES pres)
|
|
{
|
|
VPVOID vp=0;
|
|
DWORD cbData;
|
|
PARM16 Parm16;
|
|
|
|
DBG_UNREFERENCED_PARAMETER(hmod16);
|
|
|
|
WOW32ASSERT(pres && hmod16 == pres->hmod16);
|
|
if(pres == NULL) {
|
|
return(0);
|
|
}
|
|
|
|
Parm16.WndProc.wParam = pres->hmod16;
|
|
Parm16.WndProc.lParam = pres->hresinfo16;
|
|
|
|
CallBack16(RET_SIZEOFRESOURCE, &Parm16, 0, &vp);
|
|
|
|
cbData = (DWORD)vp;
|
|
|
|
/*
|
|
* Adjust the size of the resource if they are different
|
|
* between NT and Windows
|
|
*/
|
|
// Handle known resource types here
|
|
if (pres->lpszResType) {
|
|
|
|
switch((INT)pres->lpszResType) {
|
|
|
|
case (INT)RT_MENU:
|
|
case (INT)RT_DIALOG:
|
|
|
|
// If we need an exact count then we would have to enable this code
|
|
// but currently the count is only used in USER to alloc enough space
|
|
// in the client\server transition windows.
|
|
// WARNING - if this code is re-enabled you must also change LockResource16
|
|
// CallBack16(RET_LOADRESOURCE, &Parm16, 0, &vpResLoad);
|
|
// CallBack16(RET_LOCKRESOURCE, vpResLoad, 0, &vp);
|
|
// if ((INT)pres->lpszResType == RT_MENU)
|
|
// cbData = (DWORD)ConvertMenu16(pres->wExeVer, NULL, vp, cbData);
|
|
// else
|
|
// cbData = (DWORD)ConvertDialog16(NULL, vp, cbData);
|
|
// CallBack16(RET_UNLOCKRESOURCE, &Parm16, 0, &vp);
|
|
|
|
cbData = (DWORD)((DWORD)vp * sizeof(WCHAR));
|
|
break;
|
|
|
|
case (INT)RT_STRING:
|
|
cbData = (DWORD)((DWORD)vp * sizeof(WCHAR));
|
|
break;
|
|
}
|
|
}
|
|
|
|
return cbData;
|
|
}
|
|
|
|
/*
|
|
* ConvertMenu16
|
|
*
|
|
* If pmenu32 is NULL then its just a size query
|
|
*
|
|
* Returns the number of bytes in the CONVERTED menu
|
|
*/
|
|
|
|
DWORD ConvertMenu16(WORD wExeVer, PBYTE pmenu32, VPBYTE vpmenu16, DWORD cb, DWORD cb16)
|
|
{
|
|
WORD wVer, wOffset;
|
|
PBYTE pmenu16, pmenu16Save;
|
|
PBYTE pmenu32T = pmenu32;
|
|
|
|
pmenu16 = GETVDMPTR(vpmenu16, cb16, pmenu16Save);
|
|
wVer = 0;
|
|
if (wExeVer >= 0x300)
|
|
wVer = GETWORD(pmenu16);
|
|
PUTWORD(pmenu32, wVer); // transfer versionNumber
|
|
wOffset = 0;
|
|
if (wExeVer >= 0x300)
|
|
wOffset = GETWORD(pmenu16);
|
|
PUTWORD(pmenu32, wOffset); // transfer offset
|
|
ADVGET(pmenu16, wOffset); // and advance by offset
|
|
ADVPUT(pmenu32, wOffset);
|
|
ALIGNWORD(pmenu32); // this is the DIFFERENCE for WIN32
|
|
cb = pmenu32 - pmenu32T; // pmenu32 will == 4 for size queries
|
|
cb += ConvertMenuItems16(wExeVer, &pmenu32, &pmenu16, vpmenu16+(pmenu16 - pmenu16Save));
|
|
|
|
FREEVDMPTR(pmenu16Save);
|
|
RETURN(cb);
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
* ConvertMenuItems16
|
|
*
|
|
* Returns the number of bytes in the CONVERTED menu
|
|
* Note: This can be called with ppmenu32==4 which means the caller is looking
|
|
* for the size to allocate for the 32-bit menu structure.
|
|
*/
|
|
|
|
DWORD ConvertMenuItems16(WORD wExeVer, PPBYTE ppmenu32, PPBYTE ppmenu16, VPBYTE vpmenu16)
|
|
{
|
|
INT cbAnsi;
|
|
DWORD cbTotal = 0;
|
|
UINT cbUni;
|
|
WORD wOption, wID;
|
|
PBYTE pmenu32 = *ppmenu32;
|
|
PBYTE pmenu16 = *ppmenu16;
|
|
PBYTE pmenu16T = pmenu16;
|
|
PBYTE pmenu32T = pmenu32;
|
|
|
|
do {
|
|
if (wExeVer < 0x300)
|
|
wOption = GETBYTE(pmenu16);
|
|
else
|
|
wOption = GETWORD(pmenu16);
|
|
PUTWORD(pmenu32, wOption); // transfer mtOption
|
|
if (!(wOption & MF_POPUP)) {
|
|
wID = GETWORD(pmenu16);
|
|
PUTWORD(pmenu32, wID); // transfer mtID
|
|
}
|
|
cbAnsi = strlen(pmenu16)+1;
|
|
|
|
// If this is an ownerdraw menu don't copy the ANSI memu string to
|
|
// Unicode. Put a 16:16 pointer into the 32-bit resource which
|
|
// points to menu string instead. User will place this pointer in
|
|
// MEASUREITEMSTRUCT->itemData before sending WM_MEASUREITEM. If it's a
|
|
// NULL string User will place a NULL in MEASUREITEMSTRUCT->itemData.
|
|
// Chess Master and Mavis Beacon Teaches Typing depend on this.
|
|
if ((wOption & MFT_OWNERDRAW) && *pmenu16) {
|
|
if (VALIDPUT(pmenu32)) {
|
|
*(DWORD UNALIGNED *)pmenu32 = vpmenu16 + (pmenu16 - pmenu16T);
|
|
}
|
|
cbUni = sizeof(DWORD);
|
|
}
|
|
else {
|
|
if (VALIDPUT(pmenu32)) {
|
|
RtlMultiByteToUnicodeN((LPWSTR)pmenu32, MAXULONG, (PULONG)&cbUni, pmenu16, cbAnsi);
|
|
|
|
}
|
|
else {
|
|
cbUni = cbAnsi * sizeof(WCHAR);
|
|
}
|
|
}
|
|
|
|
ADVGET(pmenu16, cbAnsi);
|
|
ADVPUT(pmenu32, cbUni);
|
|
ALIGNWORD(pmenu32); // this is the DIFFERENCE for WIN32
|
|
if (wOption & MF_POPUP)
|
|
cbTotal += ConvertMenuItems16(wExeVer, &pmenu32, &pmenu16, vpmenu16+(pmenu16 - pmenu16T));
|
|
|
|
|
|
} while (!(wOption & MF_END));
|
|
|
|
*ppmenu32 = pmenu32;
|
|
*ppmenu16 = pmenu16;
|
|
|
|
return (pmenu32 - pmenu32T);
|
|
}
|
|
|
|
|
|
DWORD ConvertDialog16(PBYTE pdlg32, VPBYTE vpdlg16, DWORD cb, DWORD cb16)
|
|
{
|
|
BYTE b;
|
|
WORD w;
|
|
DWORD dwStyle;
|
|
INT i, cItems;
|
|
UINT cbAnsi;
|
|
UINT cbUni;
|
|
PBYTE pdlg16, pdlg16Save;
|
|
PBYTE pdlg32T = pdlg32;
|
|
|
|
pdlg16 = GETVDMPTR(vpdlg16, cb16, pdlg16Save);
|
|
dwStyle = GETDWORD(pdlg16);
|
|
PUTDWORD(pdlg32, dwStyle); // transfer style
|
|
PUTDWORD(pdlg32, 0); // Add NEW extended style
|
|
|
|
cItems = GETBYTE(pdlg16);
|
|
PUTWORD(pdlg32, (WORD)cItems); // stretch count to WORD for WIN32
|
|
for (i=0; i<4; i++) {
|
|
w = GETWORD(pdlg16);
|
|
PUTWORD(pdlg32, w); // transfer x & y, then cx & cy
|
|
}
|
|
|
|
//
|
|
// the next three fields are all strings (possibly null)
|
|
// menuname, classname, captiontext
|
|
// the Menu string can be encoded as ff nn mm which
|
|
// means that the menu id is ordinal mmnn
|
|
//
|
|
|
|
for (i=0; i<3; i++) {
|
|
if (i==0 && *pdlg16 == 0xFF) { // special encoding of szMenuName
|
|
((PBYTE)pdlg16)++; // advance past the ff byte
|
|
PUTWORD(pdlg32, 0xffff); // copy the f word
|
|
w = GETWORD(pdlg16); // get the menu ordinal
|
|
PUTWORD(pdlg32, w); // transfer it
|
|
} else { // ordinary string
|
|
cbAnsi = strlen(pdlg16)+1;
|
|
if (VALIDPUT(pdlg32)) {
|
|
RtlMultiByteToUnicodeN((LPWSTR)pdlg32, MAXULONG, (PULONG)&cbUni, pdlg16, cbAnsi);
|
|
} else {
|
|
cbUni = cbAnsi * sizeof(WCHAR);
|
|
}
|
|
ADVGET(pdlg16, cbAnsi);
|
|
ADVPUT(pdlg32, cbUni);
|
|
ALIGNWORD(pdlg32); // fix next field alignment for WIN32
|
|
}
|
|
}
|
|
|
|
if (dwStyle & DS_SETFONT) {
|
|
w = GETWORD(pdlg16);
|
|
PUTWORD(pdlg32, w); // transfer cPoints
|
|
cbAnsi = strlen(pdlg16)+1; // then szTypeFace
|
|
if (VALIDPUT(pdlg32)) {
|
|
RtlMultiByteToUnicodeN((LPWSTR)pdlg32, MAXULONG, (PULONG)&cbUni, pdlg16, cbAnsi);
|
|
#ifdef FE_SB
|
|
// orignal source should be fixed.
|
|
// We can't convert right Unicode string from Broken FaceName
|
|
// string.
|
|
// Converted Unicode String should be NULL terminated.
|
|
// 1994.11.12 V-HIDEKK
|
|
if( cbUni && ((LPWSTR)pdlg32)[cbUni/sizeof(WCHAR)-1] ){
|
|
LOGDEBUG(0,(" ConvertDialog16: WARNING: BAD FaceName String\n End of Unicode String (%04x)\n", ((LPWSTR)pdlg32)[cbUni/2-1]));
|
|
((LPWSTR)pdlg32)[cbUni/sizeof(WCHAR)-1] = 0;
|
|
}
|
|
#endif // FE_SB
|
|
} else {
|
|
cbUni = cbAnsi * sizeof(WCHAR);
|
|
}
|
|
ADVGET(pdlg16, cbAnsi);
|
|
ADVPUT(pdlg32, cbUni);
|
|
|
|
}
|
|
while (cItems--) {
|
|
ALIGNDWORD(pdlg32); // items start on DWORD boundaries
|
|
PUTDWORD(pdlg32, FETCHDWORD(*(PDWORD)(pdlg16+sizeof(WORD)*5)));
|
|
PUTDWORD(pdlg32, 0); // Add NEW extended style
|
|
|
|
for (i=0; i<5; i++) {
|
|
w = GETWORD(pdlg16);
|
|
PUTWORD(pdlg32, w); // transfer x & y, then cx & cy, then id
|
|
}
|
|
|
|
ADVGET(pdlg16, sizeof(DWORD)); // skip style, which we already copied
|
|
|
|
//
|
|
// get the class name could be string or encoded value
|
|
// win16 encoding scheme: class is 1 byte with bit 0x80 set,
|
|
// this byte == predefined class
|
|
// win32 encoding: a word of ffff, followed by class (word)
|
|
//
|
|
|
|
if (*pdlg16 & 0x80) {
|
|
PUTWORD(pdlg32, 0xFFFF); // NEW encoding marker 0xFFFF
|
|
b = GETBYTE(pdlg16); // special encoding for predefined class
|
|
PUTWORD(pdlg32, (WORD)b);
|
|
} else {
|
|
cbAnsi = strlen(pdlg16)+1;
|
|
if (VALIDPUT(pdlg32)) { // transfer szClass
|
|
RtlMultiByteToUnicodeN((LPWSTR)pdlg32, MAXULONG, (PULONG)&cbUni, pdlg16, cbAnsi);
|
|
} else {
|
|
cbUni = cbAnsi * sizeof(WCHAR);
|
|
}
|
|
ADVGET(pdlg16, cbAnsi);
|
|
ADVPUT(pdlg32, cbUni);
|
|
}
|
|
ALIGNWORD(pdlg32); // fix next field alignment for WIN32
|
|
|
|
//
|
|
// transfer the item text
|
|
//
|
|
|
|
if (*pdlg16 == 0xFF) { // special encoding
|
|
((PBYTE)pdlg16)++;
|
|
PUTWORD(pdlg32, 0xFFFF);
|
|
w = GETWORD(pdlg16);
|
|
PUTWORD(pdlg32, w);
|
|
} else {
|
|
cbAnsi = strlen(pdlg16)+1;
|
|
if (VALIDPUT(pdlg32)) { // otherwise, just transfer szText
|
|
RtlMultiByteToUnicodeN((LPWSTR)pdlg32, MAXULONG, (PULONG)&cbUni, pdlg16, cbAnsi);
|
|
} else {
|
|
cbUni = cbAnsi * sizeof(WCHAR);
|
|
}
|
|
ADVGET(pdlg16, cbAnsi);
|
|
ADVPUT(pdlg32, cbUni);
|
|
}
|
|
ALIGNWORD(pdlg32); // fix next field alignment for WIN32
|
|
|
|
//
|
|
// transfer the create params
|
|
//
|
|
|
|
b = GETBYTE(pdlg16);
|
|
|
|
//
|
|
// If the template has create params, we're going to get tricky.
|
|
// When USER sends the WM_CREATE message to a control with
|
|
// createparams, lParam points to the CREATESTRUCT, which
|
|
// contains lpCreateParams. lpCreateParams needs to point
|
|
// to the createparams in the DLGTEMPLATE. In order to
|
|
// accomplish this, we store a 16:16 pointer to the 16-bit
|
|
// DLGTEMPLATE's createparams in the 32-bit DLGTEMPLATE's
|
|
// createparams. In other words, whenever the count of
|
|
// bytes of createparams is nonzero (b != 0), we put 4
|
|
// bytes of createparams in the 32-bit DLGTEMPLATE that
|
|
// happen to be a 16:16 pointer to the createparams in
|
|
// the 16-bit DLGTEMPLATE.
|
|
//
|
|
// The other half of this magic is accomplished in USERSRV's
|
|
// xxxServerCreateDialog, which special-cases the creation
|
|
// of controls in a WOW dialog box. USERSRV will pass the
|
|
// DWORD pointed to by lpCreateParams instead of lpCreateParams
|
|
// to CreateWindow. This DWORD is the 16:16 pointer to the
|
|
// 16-bit DLGTEMPLATE's createparams.
|
|
//
|
|
// DaveHart 14-Mar-93
|
|
//
|
|
|
|
if (b != 0) {
|
|
|
|
// store 32-bit createparams size (room for 16:16 ptr)
|
|
|
|
PUTWORD(pdlg32, sizeof(pdlg16));
|
|
//ALIGNDWORD(pdlg32);
|
|
|
|
// store 16:16 pointer in 32-bit createparams
|
|
|
|
PUTUDWORD(pdlg32, (DWORD)vpdlg16 + (DWORD)(pdlg16 - pdlg16Save));
|
|
|
|
// point pdlg16 past createparams
|
|
|
|
ADVGET(pdlg16, b);
|
|
|
|
} else {
|
|
|
|
// there are no createparams, store size of zero.
|
|
|
|
PUTWORD(pdlg32, 0);
|
|
//ALIGNDWORD(pdlg32);
|
|
}
|
|
|
|
}
|
|
FREEVDMPTR(pdlg16Save);
|
|
RETURN(pdlg32 - pdlg32T);
|
|
}
|