summaryrefslogtreecommitdiffstats
path: root/private/mvdm/wow32/wres16.c
diff options
context:
space:
mode:
Diffstat (limited to 'private/mvdm/wow32/wres16.c')
-rw-r--r--private/mvdm/wow32/wres16.c654
1 files changed, 654 insertions, 0 deletions
diff --git a/private/mvdm/wow32/wres16.c b/private/mvdm/wow32/wres16.c
new file mode 100644
index 000000000..206d9b984
--- /dev/null
+++ b/private/mvdm/wow32/wres16.c
@@ -0,0 +1,654 @@
+/*++
+ *
+ * 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 wo32.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;
+ }
+ WOW32ASSERT(pres); // not finding a pres would be rather distressing
+ 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 {
+ 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));
+ }
+
+ 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) {
+ PCBVDMFRAME pCBFrame;
+
+ Parm16.WndProc.wParam = hmod16;
+ Parm16.WndProc.lParam = vpszName;
+ Parm16.WndProc.wMsg = LOWORD(vpszType);
+ Parm16.WndProc.hwnd = HIWORD(vpszType);
+ CallBack16(RET_FINDRESOURCE, &Parm16, 0, &vp);
+ pCBFrame = CBFRAMEPTR(CURRENTPTD()->vpCBStack);
+ wExpWinVer = pCBFrame->wGenUse1;
+ FREEVDMPTR(pCBFrame);
+ 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);
+
+ 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;
+
+ WOW32ASSERT(pres);
+
+ 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);
+
+ Parm16.WndProc.wParam = pres->hresdata16;
+ CallBack16(RET_LOCKRESOURCE, &Parm16, 0, &vp);
+
+ if (vp) {
+ PCBVDMFRAME pCBFrame;
+
+ // Get size of 16-bit resource
+ pCBFrame = CBFRAMEPTR(CURRENTPTD()->vpCBStack);
+ cb16 = pCBFrame->wGenUse2 | (LONG)pCBFrame->wGenUse1 << 16;
+
+ 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;
+
+ WOW32ASSERT(pres);
+
+ 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);
+
+ 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
+ GETBYTE(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);
+ } 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
+ GETBYTE(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);
+}