//////////////////////////////////////////////
//
// This file has the helper function used in the win32 r/w
// I copied them in this file to share them with the res32 r/w
//
#include <afxwin.h>
#include ".\rwdll.h"
#include ".\rw32hlpr.h"

/////////////////////////////////////////////////////////////////////////////
// Global variables
BYTE sizeofByte = sizeof(BYTE);
BYTE sizeofWord = sizeof(WORD);
BYTE sizeofDWord = sizeof(DWORD);
BYTE sizeofDWordPtr = sizeof(DWORD_PTR);

char szCaption[MAXSTR];
char szUpdCaption[MAXSTR];
WCHAR wszUpdCaption[MAXSTR];
CWordArray wIDArray;

#define DIALOGEX_VERION 1

/////////////////////////////////////////////////////////////////////////////
// Global settings, like code page and append options
UINT g_cp = CP_ACP;     // Default to CP_ACP
BOOL g_bAppend = FALSE; // Default to FALSE
BOOL g_bUpdOtherResLang = TRUE; // Default to FALSE
char g_char[] = " ";    // Default char for WideChartoMultiByte

VOID InitGlobals()
{
    // Make sure we are using the right code page and global settings
    // Get the pointer to the function
    HINSTANCE hDllInst = LoadLibrary("iodll.dll");
    if (hDllInst)
    {
        UINT (FAR PASCAL * lpfnGetSettings)(LPSETTINGS);
        // Get the pointer to the function to get the settings
        lpfnGetSettings = (UINT (FAR PASCAL *)(LPSETTINGS))
                     GetProcAddress( hDllInst, "RSGetGlobals" );
        if (lpfnGetSettings!=NULL) {
            SETTINGS settings;
            (*lpfnGetSettings)(&settings);

            g_cp      = settings.cp;
            g_bAppend = settings.bAppend;
            strcpy( g_char, settings.szDefChar );
        }
        FreeLibrary(hDllInst);
    }
}

#define _A_RLT_NULL_ "_RLT32_NULL_"
WCHAR _W_RLT_NULL_[] = L"_RLT32_NULL_";
int   _NULL_TAG_LEN_ = wcslen(_W_RLT_NULL_);
////////////////////////////////////////////////////////////////////////////
// Helper Function Implementation
UINT GetNameOrOrdU( PUCHAR pRes,
            ULONG ulId,
            LPWSTR lpwszStrId,
            DWORD* pdwId )
{

    if (ulId & IMAGE_RESOURCE_NAME_IS_STRING) {
        PIMAGE_RESOURCE_DIR_STRING_U pStrU = (PIMAGE_RESOURCE_DIR_STRING_U)((BYTE *)pRes
            + (ulId & (~IMAGE_RESOURCE_NAME_IS_STRING)));

        for (USHORT usCount=0; usCount < pStrU->Length ; usCount++) {
            *(lpwszStrId++) = LOBYTE(pStrU->NameString[usCount]);
        }
        *(lpwszStrId++) = 0x0000;
        *pdwId = 0;
    } else {
        *lpwszStrId = 0x0000;
        *pdwId = ulId;
    }

    return ERROR_NO_ERROR;
}

UINT _MBSTOWCS( WCHAR * pwszOut, CHAR * pszIn, UINT nLength)
{
    //
    // Check if we have a pointer to the function
    //

    int rc = MultiByteToWideChar(
        g_cp,           // UINT CodePage,
        0,              // DWORD dwFlags,
        pszIn,          // LPCSTR lpMultiByteStr,
        -1,             // int cchMultiByte,
        pwszOut,        // unsigned int far * lpWideCharStr,           // LPWSTR
        nLength );      // int cchWideChar

    return rc;
}

UINT _WCSTOMBS( CHAR* pszOut, WCHAR* pwszIn, UINT nLength)
{
    BOOL Bool = FALSE;

    int rc = WideCharToMultiByte(
        g_cp,           // UINT CodePage,
        0,              // DWORD dwFlags,
        pwszIn,         // const unsigned int far * lpWideCharStr,     // LPCWSTR
        -1,             // int cchWideChar,
        pszOut,         // LPSTR lpMultiByteStr,
        nLength,        // int cchMultiByte,
        g_char,        // LPCSTR lpDefaultChar,
        &Bool);         // BOOL far * lpUsedDefaultChar);              // LPBOOL

    return  rc;
}

UINT _WCSLEN( WCHAR * pwszIn )
{
    UINT n = 0;

    while( *(pwszIn+n)!=0x0000 ) n++;
    return( n + 1 );
}


BYTE
PutByte( BYTE far * far* lplpBuf, BYTE bValue, LONG* pdwSize )
{
    if (*pdwSize>=sizeofByte){
        memcpy(*lplpBuf, &bValue, sizeofByte);
        *lplpBuf += sizeofByte;
        *pdwSize -= sizeofByte;
    } else *pdwSize = -1;
    return sizeofByte;
}


UINT
PutNameOrOrd( BYTE far * far* lplpBuf,  WORD wOrd, LPSTR lpszText, LONG* pdwSize )
{
    UINT uiSize = 0;

    if (wOrd) {
        uiSize += PutWord(lplpBuf, 0xFFFF, pdwSize);
        uiSize += PutWord(lplpBuf, wOrd, pdwSize);
    } else {
        uiSize += PutStringW(lplpBuf, lpszText, pdwSize);
    }
    return uiSize;
}


UINT
PutCaptionOrOrd( BYTE far * far* lplpBuf,  WORD wOrd, LPSTR lpszText, LONG* pdwSize,
	WORD wClass, DWORD dwStyle )
{
    UINT uiSize = 0;

    // If this is an ICON then can just be an ID
    // Fix bug in the RC compiler
    /*
    if( (wClass==0x0082) && ((dwStyle & 0xF)==SS_ICON) ) {
    	if (wOrd) {
	    	uiSize += PutWord(lplpBuf, 0xFFFF, pdwSize);
	        uiSize += PutWord(lplpBuf, wOrd, pdwSize);
	        return uiSize;
    	} else {
    		// put nothing
    		return 0;
    	}
    }
    */
    if (wOrd) {
        uiSize += PutWord(lplpBuf, 0xFFFF, pdwSize);
        uiSize += PutWord(lplpBuf, wOrd, pdwSize);
    } else {
        uiSize += PutStringW(lplpBuf, lpszText, pdwSize);
    }
    return uiSize;
}


UINT
PutStringA( BYTE far * far* lplpBuf, LPSTR lpszText, LONG* pdwSize )
{
    int iSize = strlen(lpszText)+1;
    if (*pdwSize>=iSize){
        memcpy(*lplpBuf, lpszText, iSize);
        *lplpBuf += iSize;
        *pdwSize -= iSize;
    } else *pdwSize = -1;
    return iSize;
}


UINT
PutStringW( BYTE far * far* lplpBuf, LPSTR lpszText, LONG* pdwSize )
{
    int iSize = strlen(lpszText)+1;
    if (*pdwSize>=(iSize*2)){
        WCHAR* lpwszStr = new WCHAR[(iSize*2)];
        if (!lpwszStr) *pdwSize =0;
        else {
            SetLastError(0);
            iSize = _MBSTOWCS( lpwszStr, lpszText, iSize*2 );
            // Check for error
            if(GetLastError())
                return ERROR_DLL_LOAD;
            memcpy(*lplpBuf, lpwszStr, (iSize*2));
            *lplpBuf += (iSize*2);
            *pdwSize -= (iSize*2);
            delete lpwszStr;
        }
    } else *pdwSize = -1;
    return (iSize*2);
}



BYTE
PutWord( BYTE far * far* lplpBuf, WORD wValue, LONG* pdwSize )
{
    if (*pdwSize>=sizeofWord){
        memcpy(*lplpBuf, &wValue, sizeofWord);
        *lplpBuf += sizeofWord;
        *pdwSize -= sizeofWord;
    } else *pdwSize = -1;
    return sizeofWord;
}


BYTE
PutDWord( BYTE far * far* lplpBuf, DWORD dwValue, LONG* pdwSize )
{
    if (*pdwSize>=sizeofDWord){
        memcpy(*lplpBuf, &dwValue, sizeofDWord);
        *lplpBuf += sizeofDWord;
        *pdwSize -= sizeofDWord;
    } else *pdwSize = -1;
    return sizeofDWord;
}

BYTE
PutDWordPtr( BYTE far * far* lplpBuf, DWORD_PTR dwValue, LONG* pdwSize )
{
    if (*pdwSize>=sizeofDWordPtr){
        memcpy(*lplpBuf, &dwValue, sizeofDWordPtr);
        *lplpBuf += sizeofDWordPtr;
        *pdwSize -= sizeofDWordPtr;
    } else *pdwSize = -1;
    return sizeofDWordPtr;
}

 DWORD CalcID( WORD wId, BOOL bFlag )
{
    // We want to calculate the ID Relative to the WORD wId
    // If we have any other ID with the same value then we return
    // the incremental number + the value.
    // If no other Item have been found then the incremental number will be 0.
    // If bFlag = TRUE then the id get added to the present list.
    // If bFlag = FALSE then the list is reseted and the function return

    // Clean the array if needed
    if(!bFlag) {
        wIDArray.RemoveAll();
		wIDArray.SetSize(30, 1);
        return 0;
    }

    // Add the value to the array
    wIDArray.Add(wId);

    // Walk the array to get the number of duplicated ID
    int c = -1; // will be 0 based
    for(INT_PTR i=wIDArray.GetUpperBound(); i>=0 ; i-- ) {
        if (wIDArray.GetAt(i)==wId)
            c++;
    }
    TRACE3("CalcID: ID: %d\tPos: %d\tFinal: %u\n", wId, c, MAKELONG( wId, c ));


    return MAKELONG( wId, c );
}


UINT
ParseAccel( LPVOID lpImageBuf, DWORD dwISize,  LPVOID lpBuffer, DWORD dwSize )
{
    BYTE far * lpImage = (BYTE far *)lpImageBuf;
    LONG dwImageSize = dwISize;

    BYTE far * lpBuf = (BYTE far *)lpBuffer;
    LONG dwBufSize = dwSize;

    BYTE far * lpItem = (BYTE far *)lpBuffer;
    UINT uiOffset = 0;
    LONG lDummy;

    LONG dwOverAllSize = 0L;

    typedef struct accelerator {
        WORD fFlags;
        WORD wAscii;
        WORD wId;
        WORD padding;
    } ACCEL, *PACCEL;

    PACCEL pAcc = (PACCEL)lpImage;

    // Reset the IDArray
    CalcID(0, FALSE);
    // get the number of entry in the table
    for( int cNumEntry =(int)(dwImageSize/sizeof(ACCEL)), c=1; c<=cNumEntry ; c++)
    {
        // Fixed field
        dwOverAllSize += PutDWord( &lpBuf, 0, &dwBufSize);
        // We don't have the size and pos in a menu
        dwOverAllSize += PutWord( &lpBuf, (WORD)-1, &dwBufSize);
        dwOverAllSize += PutWord( &lpBuf, (WORD)-1, &dwBufSize);
        dwOverAllSize += PutWord( &lpBuf, (WORD)-1, &dwBufSize);
        dwOverAllSize += PutWord( &lpBuf, (WORD)-1, &dwBufSize);

        // we don't have checksum and style
        dwOverAllSize += PutDWord( &lpBuf, (DWORD)-1, &dwBufSize);
        dwOverAllSize += PutDWord( &lpBuf, (DWORD)pAcc->wAscii, &dwBufSize);
        dwOverAllSize += PutDWord( &lpBuf, (DWORD)-1, &dwBufSize);

        //Put the Flag
        dwOverAllSize += PutDWord( &lpBuf, (DWORD)pAcc->fFlags, &dwBufSize);
        //Put the MenuId
        dwOverAllSize += PutDWord( &lpBuf, CalcID(pAcc->wId, TRUE), &dwBufSize);


        // we don't have the resID, and the Type Id
        dwOverAllSize += PutDWord( &lpBuf, (DWORD)-1, &dwBufSize);
        dwOverAllSize += PutDWord( &lpBuf, (DWORD)-1, &dwBufSize);

        // we don't have the language
        dwOverAllSize += PutDWord( &lpBuf, (DWORD)-1, &dwBufSize);

        // we don't have the codepage or the font name
        dwOverAllSize += PutDWord( &lpBuf, (DWORD)-1, &dwBufSize);
        dwOverAllSize += PutWord( &lpBuf, (WORD)-1, &dwBufSize);
        dwOverAllSize += PutWord( &lpBuf, (WORD)-1, &dwBufSize);
        dwOverAllSize += PutWord( &lpBuf, (WORD)-1, &dwBufSize);
        dwOverAllSize += PutByte( &lpBuf, (BYTE)-1, &dwBufSize);
        dwOverAllSize += PutByte( &lpBuf, (BYTE)-1, &dwBufSize);

        // Let's put null were we don;t have the strings
        uiOffset = sizeof(RESITEM);
        dwOverAllSize += PutDWordPtr( &lpBuf, 0, &dwBufSize);
        dwOverAllSize += PutDWordPtr( &lpBuf, 0, &dwBufSize);
        dwOverAllSize += PutDWordPtr( &lpBuf, 0, &dwBufSize);
        dwOverAllSize += PutDWordPtr( &lpBuf, 0, &dwBufSize);
        dwOverAllSize += PutDWordPtr( &lpBuf, 0, &dwBufSize);

        // Put the size of the resource
        if (dwBufSize>=0) {
            lDummy = 8;
            PutDWord( &lpItem, (DWORD)uiOffset, &lDummy);
        }

        // Move to the next position
        if (dwBufSize>0)
            lpItem = lpBuf;
        pAcc++;
    }

    return (UINT)(dwOverAllSize);
}

UINT GenerateAccel( LPVOID lpNewBuf, LONG dwNewSize,
                    LPVOID lpNewI, DWORD* pdwNewImageSize )
{
    UINT uiError = ERROR_NO_ERROR;

    BYTE * lpNewImage = (BYTE *) lpNewI;
    LONG dwNewImageSize = *pdwNewImageSize;

    BYTE * lpBuf = (BYTE *) lpNewBuf;

    LPRESITEM lpResItem = LPNULL;

    typedef struct accelerator {
        WORD fFlags;
        WORD wAscii;
        WORD wId;
        WORD padding;
    } ACCEL, *PACCEL;

    ACCEL acc;
    BYTE bAccSize = sizeof(ACCEL);

    LONG  dwOverAllSize = 0l;

    while(dwNewSize>0) {
        if (dwNewSize ) {
            lpResItem = (LPRESITEM) lpBuf;

            acc.wId = LOWORD(lpResItem->dwItemID);
            acc.fFlags = (WORD)lpResItem->dwFlags;
            acc.wAscii = (WORD)lpResItem->dwStyle;
            acc.padding = 0;
            lpBuf += lpResItem->dwSize;
            dwNewSize -= lpResItem->dwSize;
        }

        if (dwNewSize<=0) {
            // Last Item in the accel table, mark it
            acc.fFlags = acc.fFlags | 0x80;
        }
        TRACE3("Accel: wID: %hd\t wAscii: %hd\t wFlag: %hd\n", acc.wId, acc.wAscii, acc.fFlags);

        if(bAccSize<=dwNewImageSize)
        {
            memcpy(lpNewImage, &acc, bAccSize);
            dwNewImageSize -= bAccSize;
            lpNewImage = lpNewImage+bAccSize;
            dwOverAllSize += bAccSize;
        }
        else dwOverAllSize += bAccSize;

    }

    if (dwOverAllSize>(LONG)*pdwNewImageSize) {
        // calc the padding as well
        dwOverAllSize += (BYTE)Pad16((DWORD)(dwOverAllSize));
        *pdwNewImageSize = dwOverAllSize;
        return uiError;
    }

    *pdwNewImageSize = *pdwNewImageSize-dwNewImageSize;

    if(*pdwNewImageSize>0) {
        // calculate padding
        BYTE bPad = (BYTE)Pad16((DWORD)(*pdwNewImageSize));
        if (bPad>dwNewImageSize) {
            *pdwNewImageSize += bPad;
            return uiError;
        }
        memset(lpNewImage, 0x00, bPad);
        *pdwNewImageSize += bPad;
    }

    return uiError;
}


UINT
UpdateAccel( LPVOID lpNewBuf, LONG dwNewSize,
            LPVOID lpOldI, LONG dwOldImageSize,
            LPVOID lpNewI, DWORD* pdwNewImageSize )
{
    UINT uiError = ERROR_NO_ERROR;
    TRACE("Update Accelerators:\n");
    BYTE far * lpNewImage = (BYTE far *) lpNewI;
    LONG dwNewImageSize = *pdwNewImageSize;

    BYTE far * lpOldImage = (BYTE far *) lpOldI;
    DWORD dwOriginalOldSize = dwOldImageSize;

    BYTE far * lpBuf = (BYTE far *) lpNewBuf;

    LPRESITEM lpResItem = LPNULL;

    WORD wDummy;
    //Old Items
    WORD fFlags = 0;
    WORD wEvent = 0;
    WORD wId = 0;
    WORD wPos = 0;

    // Updated items
    WORD fUpdFlags = 0;
    WORD wUpdEvent = 0;
    WORD wUpdId = 0;
    WORD wUpdPos = 0;

    LONG  dwOverAllSize = 0l;


    while(dwOldImageSize>0) {
        wPos++;
        // Get the information from the old image
        GetWord( &lpOldImage, &fFlags, &dwOldImageSize );
        GetWord( &lpOldImage, &wEvent, &dwOldImageSize );
        GetWord( &lpOldImage, &wId, &dwOldImageSize );
        GetWord( &lpOldImage, &wDummy, &dwOldImageSize );
        TRACE3("Old: fFlags: %d\t wEvent: %d\t wId: %d\n",fFlags, wEvent, wId);
        if ((!wUpdPos) && dwNewSize ) {
            lpResItem = (LPRESITEM) lpBuf;

            wUpdId = LOWORD(lpResItem->dwItemID);
            wUpdPos = HIWORD(lpResItem->dwItemID);
            fUpdFlags = (WORD)lpResItem->dwFlags;
            wUpdEvent = (WORD)lpResItem->dwStyle;
            lpBuf += lpResItem->dwSize;
            dwNewSize -= lpResItem->dwSize;
        }


        if ((wUpdId==wId)) {
            fFlags = fUpdFlags;
            wEvent = wUpdEvent;
            wUpdPos = 0;
        }

        TRACE3("New: fFlags: %d\t wEvent: %d\t wId: %d\n",fFlags, wEvent, wId);
        dwOverAllSize += PutWord( &lpNewImage, fFlags, &dwNewImageSize);
        dwOverAllSize += PutWord( &lpNewImage, wEvent, &dwNewImageSize);
        dwOverAllSize += PutWord( &lpNewImage, wId, &dwNewImageSize);
        dwOverAllSize += PutWord( &lpNewImage, 0, &dwNewImageSize);
    }

    if (dwOverAllSize>(LONG)*pdwNewImageSize) {
        // calc the padding as well
        BYTE bPad = (BYTE)Pad4((DWORD)(dwOverAllSize));
        dwOverAllSize += bPad;
        *pdwNewImageSize = dwOverAllSize;
        return uiError;
    }

    *pdwNewImageSize = *pdwNewImageSize-dwNewImageSize;

    if(*pdwNewImageSize>0) {
        // calculate padding
        BYTE bPad = (BYTE)Pad4((DWORD)(*pdwNewImageSize));
        if (bPad>dwNewImageSize) {
            *pdwNewImageSize += bPad;
            return uiError;
        }
        memset(lpNewImage, 0x00, bPad);
        *pdwNewImageSize += bPad;
    }

    return uiError;
}



UINT
ParseMenu( LPVOID lpImageBuf, DWORD dwISize,  LPVOID lpBuffer, DWORD dwSize )
{
    BYTE far * lpImage = (BYTE far *)lpImageBuf;
    LONG dwImageSize = dwISize;

    BYTE far * lpBuf = (BYTE far *)lpBuffer;
    LONG dwBufSize = dwSize;

    BYTE far * lpItem = (BYTE far *)lpBuffer;
    UINT uiOffset = 0;
    LONG lDummy;

    LONG dwOverAllSize = 0L;
    BOOL bExt = FALSE;
    WORD wlen = 0;

    // Menu Template
    WORD wMenuVer = 0;
    WORD wHdrSize = 0;

    // get the menu header
    GetWord( &lpImage, &wMenuVer, &dwImageSize );
	GetWord( &lpImage, &wHdrSize, &dwImageSize );
	
	// Check if is one of the new extended resource
	if(wMenuVer == 1) {
		bExt = TRUE;
		SkipByte( &lpImage, wHdrSize, &dwImageSize );
	}
		
    // Menu Items
    WORD fItemFlags = 0;
    WORD wMenuId = 0;

    // Extended Menu Items
    DWORD dwType = 0L;
    DWORD dwState = 0L;
    DWORD dwID = 0L;
    DWORD dwHelpID = 0;

    while(dwImageSize>0) {
        // Fixed field
        dwOverAllSize += PutDWord( &lpBuf, 0, &dwBufSize);
        // We don't have the size and pos in a menu
        dwOverAllSize += PutWord( &lpBuf, (WORD)-1, &dwBufSize);
        dwOverAllSize += PutWord( &lpBuf, (WORD)-1, &dwBufSize);
        dwOverAllSize += PutWord( &lpBuf, (WORD)-1, &dwBufSize);
        dwOverAllSize += PutWord( &lpBuf, (WORD)-1, &dwBufSize);

        // we don't have checksum and style
        dwOverAllSize += PutDWord( &lpBuf, (WORD)-1, &dwBufSize);
        dwOverAllSize += PutDWord( &lpBuf, (WORD)-1, &dwBufSize);
        dwOverAllSize += PutDWord( &lpBuf, (WORD)-1, &dwBufSize);

        if(bExt) {
        	GetDWord( &lpImage, &dwType, &dwImageSize );
        	GetDWord( &lpImage, &dwState, &dwImageSize );
        	GetDWord( &lpImage, &dwID, &dwImageSize );
        	// Let's get the Menu flags
	        GetWord( &lpImage, &fItemFlags, &dwImageSize );
	
	        // Check if it is a MFR_POPUP 0x0001
	        if (fItemFlags & MFR_POPUP) {
                // convert to the standard value
	        	fItemFlags &= ~(WORD)MFR_POPUP;
	        	fItemFlags |= MF_POPUP;
	        }
	
	        //Put the Flag
	        dwOverAllSize += PutDWord( &lpBuf, (DWORD)fItemFlags, &dwBufSize);
	        //Put the MenuId
	        dwOverAllSize += PutDWord( &lpBuf, dwID, &dwBufSize);
        } else {
	        // Let's get the Menu flags
	        GetWord( &lpImage, &fItemFlags, &dwImageSize );
	        if ( !(fItemFlags & MF_POPUP) )
	            // Get the menu Id
	            GetWord( &lpImage, &wMenuId, &dwImageSize );
	        else wMenuId = (WORD)-1;

	        //Put the Flag
	        dwOverAllSize += PutDWord( &lpBuf, (DWORD)fItemFlags, &dwBufSize);
	        //Put the MenuId
	        dwOverAllSize += PutDWord( &lpBuf, (DWORD)wMenuId, &dwBufSize);
        }

        // we don't have the resID, and the Type Id
        dwOverAllSize += PutDWord( &lpBuf, (DWORD)-1, &dwBufSize);
        dwOverAllSize += PutDWord( &lpBuf, (DWORD)-1, &dwBufSize);

        // we don't have the language
        dwOverAllSize += PutDWord( &lpBuf, (DWORD)-1, &dwBufSize);

        // we don't have the codepage or the font name
        dwOverAllSize += PutDWord( &lpBuf, (DWORD)-1, &dwBufSize);
        dwOverAllSize += PutWord( &lpBuf, (WORD)-1, &dwBufSize);
        dwOverAllSize += PutWord( &lpBuf, (WORD)-1, &dwBufSize);
        dwOverAllSize += PutWord( &lpBuf, (WORD)-1, &dwBufSize);
        dwOverAllSize += PutByte( &lpBuf, (BYTE)-1, &dwBufSize);
        dwOverAllSize += PutByte( &lpBuf, (BYTE)-1, &dwBufSize);

        // Let's put null were we don;t have the strings
        uiOffset = sizeof(RESITEM);
        dwOverAllSize += PutDWordPtr( &lpBuf, 0, &dwBufSize);
        dwOverAllSize += PutDWordPtr( &lpBuf, 0, &dwBufSize);
        dwOverAllSize += PutDWordPtr( &lpBuf, (DWORD_PTR)(lpItem+uiOffset), &dwBufSize);
        dwOverAllSize += PutDWordPtr( &lpBuf, 0, &dwBufSize);
        dwOverAllSize += PutDWordPtr( &lpBuf, 0, &dwBufSize);

        // Get the text
        // calculate were the string is going to be
        // Will be the fixed header+the pointer
        wlen = (WORD)GetStringW( &lpImage, &szCaption[0], &dwImageSize, MAXSTR );

		dwOverAllSize += PutStringA( &lpBuf, &szCaption[0], &dwBufSize);
		
		if(bExt) {
			// Do we need padding
			BYTE bPad = (BYTE)Pad4((WORD)(wlen+sizeofWord));
			SkipByte( &lpImage, bPad, &dwImageSize );
			
			if ( (fItemFlags & MF_POPUP) )
	            // Get the Help Id
	            GetDWord( &lpImage, &dwHelpID, &dwImageSize );
		}

        // Put the size of the resource
        uiOffset += strlen(szCaption)+1;
        // Check if we are alligned
        lDummy = Allign( &lpBuf, &dwBufSize, (LONG)uiOffset);
        dwOverAllSize += lDummy;
        uiOffset += lDummy;
        lDummy = 4;
        if(dwBufSize>=0)
            PutDWord( &lpItem, (DWORD)uiOffset, &lDummy);
        /*
        if (dwBufSize>=0) {
            uiOffset += strlen((LPSTR)(lpItem+uiOffset))+1;
            // Check if we are alligned
            lDummy = Allign( &lpBuf, &dwBufSize, (LONG)uiOffset);
            dwOverAllSize += lDummy;
            uiOffset += lDummy;
            lDummy = 8;
            PutDWord( &lpItem, (DWORD)uiOffset, &lDummy);
        }
        */

        // Move to the next position
        lpItem = lpBuf;
        if (dwImageSize<=16) {
            // Check if we are at the end and this is just padding
            BYTE bPad = (BYTE)Pad16((DWORD)(dwISize-dwImageSize));
	        if (bPad==dwImageSize) {
					BYTE far * lpBuf = lpImage;
					while (bPad){
						if(*lpBuf++!=0x00)
							break;
						bPad--;
					}
					if (bPad==0)
						dwImageSize = -1;
		    }
		}
    }
    return (UINT)(dwOverAllSize);
}


UINT
UpdateMenu( LPVOID lpNewBuf, LONG dwNewSize,
            LPVOID lpOldI, LONG dwOldImageSize,
            LPVOID lpNewI, DWORD* pdwNewImageSize )
{
    UINT uiError = ERROR_NO_ERROR;

    BYTE far * lpNewImage = (BYTE far *) lpNewI;
    LONG dwNewImageSize = *pdwNewImageSize;

    BYTE far * lpOldImage = (BYTE far *) lpOldI;
    DWORD dwOriginalOldSize = dwOldImageSize;

    BYTE far * lpBuf = (BYTE far *) lpNewBuf;

    LPRESITEM lpResItem = LPNULL;

    // We have to read the information from the lpNewBuf
    // Menu Items
    WORD fItemFlags;
    WORD wMenuId;
    WORD wPos = 0;

    // Updated items
    WORD wUpdPos = 0;
    WORD fUpdItemFlags;
    WORD wUpdMenuId;

	// Extended Menu Items
    DWORD dwType = 0L;
    DWORD dwState = 0L;
    DWORD dwID = 0L;
    DWORD dwHelpID = 0;

    LONG dwOverAllSize = 0l;
    WORD wlen = 0;
    BOOL bExt = FALSE;
    BYTE bPad = 0;

    // Menu Template
    WORD wMenuVer = 0;
    WORD wHdrSize = 0;

    // get the menu header
    GetWord( &lpOldImage, &wMenuVer, &dwOldImageSize );
	GetWord( &lpOldImage, &wHdrSize, &dwOldImageSize );
	
	// Check if is one of the new extended resource
	if(wMenuVer == 1) {
		bExt = TRUE;
		// Put the header informations
		dwOverAllSize += PutWord( &lpNewImage, wMenuVer, &dwNewImageSize);
		dwOverAllSize += PutWord( &lpNewImage, wHdrSize, &dwNewImageSize);
		
		if(wHdrSize) {
			while(wHdrSize) {
				dwOldImageSize -= PutByte( &lpNewImage, *((BYTE*)lpOldImage), &dwNewImageSize);
			    lpOldImage += sizeofByte;
			    dwOverAllSize += sizeofByte;
				wHdrSize--;
			}
		}
	}
	else {
		// Put the header informations
		dwOverAllSize += PutWord( &lpNewImage, wMenuVer, &dwNewImageSize);
		dwOverAllSize += PutWord( &lpNewImage, wHdrSize, &dwNewImageSize);
	}
	
    while(dwOldImageSize>0) {
        wPos++;
        // Get the information from the old image
        // Get the menu flag
        if(bExt) {
        	GetDWord( &lpOldImage, &dwType, &dwOldImageSize );
        	GetDWord( &lpOldImage, &dwState, &dwOldImageSize );
        	GetDWord( &lpOldImage, &dwID, &dwOldImageSize );
        	wMenuId = LOWORD(dwID);	// we need to do this since we had no idea the ID could be DWORD
        	// Let's get the Menu flags
	        GetWord( &lpOldImage, &fItemFlags, &dwOldImageSize );
	        // Get the text
        	wlen = (WORD)GetStringW( &lpOldImage, &szCaption[0], &dwOldImageSize, MAXSTR );
        	
	        // Do we need padding
			bPad = (BYTE)Pad4((WORD)(wlen+sizeofWord));
			SkipByte( &lpOldImage, bPad, &dwOldImageSize );
			
			if ( (fItemFlags & MFR_POPUP) )
	            // Get the Help Id
	            GetDWord( &lpOldImage, &dwHelpID, &dwOldImageSize );
        } else {
	        // Let's get the Menu flags
	        GetWord( &lpOldImage, &fItemFlags, &dwOldImageSize );
	        if ( !(fItemFlags & MF_POPUP) )
	            // Get the menu Id
	            GetWord( &lpOldImage, &wMenuId, &dwOldImageSize );
	        else wMenuId = (WORD)-1;
	
        	// Get the text
        	GetStringW( &lpOldImage, &szCaption[0], &dwOldImageSize, MAXSTR );
        }

        if ((!wUpdPos) && dwNewSize ) {
            lpResItem = (LPRESITEM) lpBuf;

            wUpdPos = HIWORD(lpResItem->dwItemID);
            wUpdMenuId = LOWORD(lpResItem->dwItemID);
            fUpdItemFlags = (WORD)lpResItem->dwFlags;
            strcpy( szUpdCaption, lpResItem->lpszCaption );
            lpBuf += lpResItem->dwSize;
            dwNewSize -= lpResItem->dwSize;
        }

        if ((wPos==wUpdPos) && (wUpdMenuId==wMenuId)) {
        	if ((fItemFlags & MFR_POPUP) && bExt) {
	        	fUpdItemFlags &= ~MF_POPUP;
	        	fUpdItemFlags |= MFR_POPUP;
	        }
	        	
            // check if it is not the last item in the menu
	        if(fItemFlags & MF_END)
	                fItemFlags = fUpdItemFlags | (WORD)MF_END;
	        else fItemFlags = fUpdItemFlags;
	
	        // check it is not a separator
            if((fItemFlags==0) && (wMenuId==0) && !(*szCaption))
                strcpy(szCaption, "");
            else strcpy(szCaption, szUpdCaption);
            wUpdPos = 0;
        }
        if(bExt) {
        	dwOverAllSize += PutDWord( &lpNewImage, dwType, &dwNewImageSize);
        	dwOverAllSize += PutDWord( &lpNewImage, dwState, &dwNewImageSize);
        	dwOverAllSize += PutDWord( &lpNewImage, dwID, &dwNewImageSize);
        	
        	dwOverAllSize += PutWord( &lpNewImage, fItemFlags, &dwNewImageSize);
        	wlen = (WORD)PutStringW( &lpNewImage, &szCaption[0], &dwNewImageSize);
        	dwOverAllSize += wlen;
        	
        	// Do we need padding
			bPad = (BYTE)Pad4((WORD)(wlen+sizeofWord));
			while(bPad) {
				dwOverAllSize += PutByte( &lpNewImage, 0, &dwNewImageSize);
				bPad--;
			}
			
			if ( (fItemFlags & MFR_POPUP) )
	            // write the Help Id
	            dwOverAllSize += PutDWord( &lpNewImage, dwHelpID, &dwNewImageSize);
        }
        else {
	        dwOverAllSize += PutWord( &lpNewImage, fItemFlags, &dwNewImageSize);
	
	        if ( !(fItemFlags & MF_POPUP) ) {
	            dwOverAllSize += PutWord( &lpNewImage, wMenuId, &dwNewImageSize);
	        }
	
	        // Write the text in UNICODE
	        dwOverAllSize += PutStringW( &lpNewImage, &szCaption[0], &dwNewImageSize);
        }

        if (dwOldImageSize<=16) {
            // Check if we are at the end and this is just padding
            BYTE bPad = (BYTE)Pad16((DWORD)(dwOriginalOldSize-dwOldImageSize));
	        if (bPad==dwOldImageSize) {
				BYTE far * lpBuf = lpOldImage;
				while (bPad){
					if(*lpBuf++!=0x00)
						break;
					bPad--;
				}
				if (bPad==0)
					dwOldImageSize = -1;
			}
		}
    }

    if (dwOverAllSize>(LONG)*pdwNewImageSize) {
        // calc the padding as well
        BYTE bPad = (BYTE)Pad16((DWORD)(dwOverAllSize));
        dwOverAllSize += bPad;
        *pdwNewImageSize = dwOverAllSize;
        return uiError;
    }

    *pdwNewImageSize = *pdwNewImageSize-dwNewImageSize;

    if(*pdwNewImageSize>0) {
        // calculate padding
        BYTE bPad = (BYTE)Pad16((DWORD)(*pdwNewImageSize));
        if (bPad>dwNewImageSize) {
            *pdwNewImageSize += bPad;
            return uiError;
        }
        memset(lpNewImage, 0x00, bPad);
        *pdwNewImageSize += bPad;
    }
    return uiError;
}


UINT
ParseString( LPVOID lpImageBuf, DWORD dwISize,  LPVOID lpBuffer, DWORD dwSize )
{
    // Should be almost impossible for a String to be Huge
    BYTE far * lpImage = (BYTE far *)lpImageBuf;
    LONG dwImageSize = dwISize;

    BYTE far * lpBuf = (BYTE far *)lpBuffer;
    LONG dwBufSize = dwSize;

    BYTE far * lpItem = (BYTE far *)lpBuffer;
    UINT uiOffset = 0;
    LONG lDummy;

    LONG dwOverAllSize = 0L;

    LONG dwRead = 0L;

    BYTE bIdCount = 0;

    while( (dwImageSize>0) && (bIdCount<16)  ) {
        // Fixed field
        dwOverAllSize += PutDWord( &lpBuf, 0, &dwBufSize);
        // We don't have the size and pos in a string
        dwOverAllSize += PutWord( &lpBuf, (WORD)-1, &dwBufSize);
        dwOverAllSize += PutWord( &lpBuf, (WORD)-1, &dwBufSize);
        dwOverAllSize += PutWord( &lpBuf, (WORD)-1, &dwBufSize);
        dwOverAllSize += PutWord( &lpBuf, (WORD)-1, &dwBufSize);

        // we don't have checksum and style
        dwOverAllSize += PutDWord( &lpBuf, (DWORD)-1, &dwBufSize);
        dwOverAllSize += PutDWord( &lpBuf, (DWORD)-1, &dwBufSize);
        dwOverAllSize += PutDWord( &lpBuf, (DWORD)-1, &dwBufSize);
        dwOverAllSize += PutDWord( &lpBuf, (DWORD)-1, &dwBufSize);

        //Put the StringId
        dwOverAllSize += PutDWord( &lpBuf, bIdCount++, &dwBufSize);

        // we don't have the resID, and the Type Id
        dwOverAllSize += PutDWord( &lpBuf, (DWORD)-1, &dwBufSize);
        dwOverAllSize += PutDWord( &lpBuf, (DWORD)-1, &dwBufSize);

        // we don't have the language
        dwOverAllSize += PutDWord( &lpBuf, (DWORD)-1, &dwBufSize);

        // we don't have the codepage or the font name
        dwOverAllSize += PutDWord( &lpBuf, (DWORD)-1, &dwBufSize);
        dwOverAllSize += PutWord( &lpBuf, (WORD)-1, &dwBufSize);
        dwOverAllSize += PutWord( &lpBuf, (WORD)-1, &dwBufSize);
        dwOverAllSize += PutWord( &lpBuf, (WORD)-1, &dwBufSize);
        dwOverAllSize += PutByte( &lpBuf, (BYTE)-1, &dwBufSize);
        dwOverAllSize += PutByte( &lpBuf, (BYTE)-1, &dwBufSize);

        // Let's put null were we don;t have the strings
        uiOffset = sizeof(RESITEM);
        dwOverAllSize += PutDWordPtr( &lpBuf, 0, &dwBufSize);  // ClassName
        dwOverAllSize += PutDWordPtr( &lpBuf, 0, &dwBufSize);  // FaceName
        dwOverAllSize += PutDWordPtr( &lpBuf, (DWORD_PTR)(lpItem+uiOffset), &dwBufSize);   // Caption
        dwOverAllSize += PutDWordPtr( &lpBuf, 0, &dwBufSize);  // ResItem
        dwOverAllSize += PutDWordPtr( &lpBuf, 0, &dwBufSize);  // TypeItem

        // Get the text
        GetPascalString( &lpImage, &szCaption[0], MAXSTR, &dwImageSize );
        dwOverAllSize += PutStringA( &lpBuf, &szCaption[0], &dwBufSize);

        // Put the size of the resource
        uiOffset += strlen(szCaption)+1;
        // Check if we are alligned
        lDummy = Allign( &lpBuf, &dwBufSize, (LONG)uiOffset);
        dwOverAllSize += lDummy;
        uiOffset += lDummy;
        lDummy = 4;
        if(dwBufSize>=0)
            PutDWord( &lpItem, (DWORD)uiOffset, &lDummy);

        /*
        if ((LONG)(dwSize-dwOverAllSize)>=0) {
            uiOffset += strlen(szCaption)+1;
            // Check if we are alligned
            lDummy = Allign( &lpBuf, &dwBufSize, (LONG)uiOffset);
            dwOverAllSize += lDummy;
            uiOffset += lDummy;
            lDummy = 8;
            PutDWord( &lpItem, (DWORD)uiOffset, &lDummy);
        }
        */

        // Move to the next position
        lpItem = lpBuf;

        // Check if we are at the end and this is just padding
        if (dwImageSize<=16 && (bIdCount==16)) {
            // Check if we are at the end and this is just padding
            BYTE bPad = (BYTE)Pad16((DWORD)(dwISize-dwImageSize));
            if (bPad==dwImageSize) {
				BYTE far * lpBuf = lpImage;
				while (bPad){
					if(*lpBuf++!=0x00)
						break;
					bPad--;
				}
				if (bPad==0)
					dwImageSize = -1;
			}
		}
    }
    return (UINT)(dwOverAllSize);
}



UINT
UpdateString( LPVOID lpNewBuf, LONG dwNewSize,
            LPVOID lpOldI, LONG dwOldImageSize,
            LPVOID lpNewI, DWORD* pdwNewImageSize )
{
    UINT uiError = ERROR_NO_ERROR;

    LONG dwNewImageSize = *pdwNewImageSize;
    BYTE far * lpNewImage = (BYTE far *) lpNewI;

    BYTE far * lpOldImage = (BYTE far *) lpOldI;

    BYTE far * lpBuf = (BYTE far *) lpNewBuf;
    LPRESITEM lpResItem = LPNULL;

    // We have to read the information from the lpNewBuf
    WORD wLen;
    WORD wPos = 0;

    // Updated info
    WORD wUpdPos = 0;

    DWORD dwOriginalOldSize = dwOldImageSize;
    LONG dwOverAllSize = 0l;

    while(dwOldImageSize>0) {
        wPos++;
        // Get the information from the old image
        GetPascalString( &lpOldImage, &szCaption[0], MAXSTR, &dwOldImageSize );

        if ((!wUpdPos) && dwNewSize ) {
            lpResItem = (LPRESITEM) lpBuf;

            wUpdPos = HIWORD(lpResItem->dwItemID);
            strcpy( szUpdCaption, lpResItem->lpszCaption );
            lpBuf += lpResItem->dwSize;
            dwNewSize -= lpResItem->dwSize;
        }

        if ((wPos==wUpdPos)) {
            strcpy(szCaption, szUpdCaption);
            wUpdPos = 0;
        }

        wLen = strlen(szCaption);

        // Write the text
        dwOverAllSize += PutPascalStringW( &lpNewImage, &szCaption[0], wLen, &dwNewImageSize );

    }

    if (dwOverAllSize>(LONG)*pdwNewImageSize) {
        // calc the padding as well
        BYTE bPad = (BYTE)Pad4((DWORD)(dwOverAllSize));
        dwOverAllSize += bPad;
        *pdwNewImageSize = dwOverAllSize;
        return uiError;
    }

    *pdwNewImageSize = *pdwNewImageSize-dwNewImageSize;

    if(*pdwNewImageSize>0) {
        // calculate padding
        BYTE bPad = (BYTE)Pad4((DWORD)(*pdwNewImageSize));
        if (bPad>dwNewImageSize) {
            *pdwNewImageSize += bPad;
            return uiError;
        }
        memset(lpNewImage, 0x00, bPad);
        *pdwNewImageSize += bPad;
    }

    return uiError;
}


UINT
UpdateMsgTbl( LPVOID lpNewBuf, LONG dwNewSize,
              LPVOID lpOldI, LONG dwOldImageSize,
              LPVOID lpNewI, DWORD* pdwNewImageSize )
{
    UINT uiError = ERROR_NO_ERROR;

    LONG dwNewImageSize = *pdwNewImageSize;
    BYTE far * lpNewImage = (BYTE far *) lpNewI;
    BYTE far * lpStartImage = (BYTE far *) lpNewI;

    BYTE far * lpOldImage = (BYTE far *) lpOldI;

    BYTE far * lpBuf = (BYTE far *) lpNewBuf;
    LPRESITEM lpResItem = LPNULL;

    // We have to read the information from the lpNewBuf
    WORD wPos = 0;

    // Updated info
    WORD wUpdPos = 0;
    WORD wUpdId = 0;

    DWORD dwOriginalOldSize = dwOldImageSize;
    LONG dwOverAllSize = 0l;

    ULONG ulNumofBlock = 0;

    ULONG ulLowId =  0l;
    ULONG ulHighId = 0l;
    ULONG ulOffsetToEntry = 0l;

    USHORT usLength = 0l;
    USHORT usFlags = 0l;

    // we have to calculate the position of the first Entry block in the immage
    // Get number of blocks in the old image
    GetDWord( &lpOldImage, &ulNumofBlock, &dwOldImageSize );

    BYTE far * lpEntryBlock = lpNewImage+(ulNumofBlock*sizeof(ULONG)*3+sizeof(ULONG));

    // Write the number of block in the new image
    dwOverAllSize = PutDWord( &lpNewImage, ulNumofBlock, &dwNewImageSize );
    wPos = 1;
    for( ULONG c = 0; c<ulNumofBlock ; c++) {
        // Get ID of the block
        GetDWord( &lpOldImage, &ulLowId, &dwOldImageSize );
        GetDWord( &lpOldImage, &ulHighId, &dwOldImageSize );

        // Write the Id of the block
        dwOverAllSize += PutDWord( &lpNewImage, ulLowId, &dwNewImageSize );
        dwOverAllSize += PutDWord( &lpNewImage, ulHighId, &dwNewImageSize );

        // Get the offset to the data in the old image
        GetDWord( &lpOldImage, &ulOffsetToEntry, &dwOldImageSize );

        // Write the offset to the data in the new Image
        dwOverAllSize += PutDWord( &lpNewImage, (DWORD)(lpEntryBlock-lpStartImage), &dwNewImageSize );

        BYTE far * lpData = (BYTE far *)lpOldI;
        lpData += ulOffsetToEntry;
        while( ulHighId>=ulLowId ) {

            GetMsgStr( &lpData,
                       &szCaption[0],
                       MAXSTR,
                       &usLength,
                       &usFlags,
                       &dwOldImageSize );


            if ( dwNewSize ) {
                lpResItem = (LPRESITEM) lpBuf;

                wUpdId = LOWORD(lpResItem->dwItemID);
                strcpy( szUpdCaption, lpResItem->lpszCaption );
                lpBuf += lpResItem->dwSize;
                dwNewSize -= lpResItem->dwSize;
            }

            // Check if the item has been updated
            if (wUpdId==wPos++) {
                strcpy(szCaption, szUpdCaption);
            }

            dwOverAllSize += PutMsgStr( &lpEntryBlock,
                                        &szCaption[0],
                                        usFlags,
                                        &dwNewImageSize );

            ulLowId++;
        }
    }

    if (dwOverAllSize>(LONG)*pdwNewImageSize) {
        // calc the padding as well
        BYTE bPad = (BYTE)Pad4((DWORD)(dwOverAllSize));
        dwOverAllSize += bPad;
        *pdwNewImageSize = dwOverAllSize;
        return uiError;
    }

    *pdwNewImageSize = *pdwNewImageSize-dwNewImageSize;

    if(*pdwNewImageSize>0) {
        // calculate padding
        BYTE bPad = (BYTE)Pad4((DWORD)(*pdwNewImageSize));
        if (bPad>dwNewImageSize) {
            *pdwNewImageSize += bPad;
            return uiError;
        }
        memset(lpNewImage, 0x00, bPad);
        *pdwNewImageSize += bPad;
    }

    return uiError;
}



UINT
ParseDialog( LPVOID lpImageBuf, DWORD dwISize,  LPVOID lpBuffer, DWORD dwSize )
{
    BYTE far * lpImage = (BYTE far *)lpImageBuf;
    LONG dwImageSize = dwISize;

    BYTE far * lpBuf = (BYTE far *)lpBuffer;
    LONG dwBufSize = dwSize;

    LPRESITEM lpResItem = (LPRESITEM)lpBuffer;
    UINT uiOffset = 0;

    char far * lpStrBuf = (char far *)(lpBuf+sizeof(RESITEM));

    LONG dwOverAllSize = 0L;

    WORD wIdCount = 0;
    BOOL bExt = FALSE;		// Extended dialog flag

    // Dialog Elements
    WORD wDlgVer = 0;
    WORD wSign	= 0;
    DWORD dwHelpID = 0L;
    DWORD dwStyle = 0L;
    DWORD dwExtStyle = 0L;
    WORD wNumOfElem = 0;
    WORD wX = 0;
    WORD wY = 0;
    WORD wcX = 0;
    WORD wcY = 0;
    WORD wId = 0;
    DWORD dwId = 0L;
    char szMenuName[128];
    WORD wMenuName;
    char szClassName[128];
    WORD wClassName;
    WORD wOrd = 0;
    WORD wPointSize = 0;
    WORD wWeight = -1;
    BYTE bItalic = -1;
    BYTE bCharSet = DEFAULT_CHARSET;
    char szFaceName[128];
    WORD wRawData = 0;
    WORD wDataSize = 0;
    szCaption[0] = '\0';


    // read the dialog header
    wDataSize = GetDWord( &lpImage, &dwStyle, &dwImageSize );

    // Check for extended dialog style
    if(HIWORD(dwStyle)==0xFFFF)	{
    	bExt = TRUE;
    	wDlgVer = HIWORD(dwStyle);
    	wSign = LOWORD(dwStyle);
		wDataSize += GetDWord( &lpImage, &dwHelpID, &dwImageSize );
	}
    wDataSize += GetDWord( &lpImage, &dwExtStyle, &dwImageSize );
    if(bExt)
    	wDataSize += GetDWord( &lpImage, &dwStyle, &dwImageSize );
    wDataSize += GetWord( &lpImage, &wNumOfElem, &dwImageSize );
    wDataSize += GetWord( &lpImage, &wX, &dwImageSize );
    wDataSize += GetWord( &lpImage, &wY, &dwImageSize );
    wDataSize += GetWord( &lpImage, &wcX, &dwImageSize );
    wDataSize += GetWord( &lpImage, &wcY, &dwImageSize );
    wDataSize += (WORD)GetNameOrOrd( &lpImage, &wMenuName, &szMenuName[0], &dwImageSize );
    wDataSize += (WORD)GetClassName( &lpImage, &wClassName, &szClassName[0], &dwImageSize );
    wDataSize += (WORD)GetCaptionOrOrd( &lpImage, &wOrd, &szCaption[0], &dwImageSize, wClassName, dwStyle );
    if( dwStyle & DS_SETFONT ) {
        wDataSize += GetWord( &lpImage, &wPointSize, &dwImageSize );
        if(bExt) {
        	wDataSize += GetWord( &lpImage, &wWeight, &dwImageSize );
        	wDataSize += GetByte( &lpImage, &bItalic, &dwImageSize );
        	wDataSize += GetByte( &lpImage, &bCharSet, &dwImageSize );
        }
        wDataSize += (WORD)GetStringW( &lpImage, &szFaceName[0], &dwImageSize, 128 );
    }


    // calculate the padding
    BYTE bPad = (BYTE)Pad4((WORD)wDataSize);
    if (bPad)
        SkipByte( &lpImage, bPad, &dwImageSize );

    TRACE("WIN32.DLL ParseDialog\t");
    if(bExt)
    	TRACE("Extended style Dialog - Chicago win32 dialog format\n");
    else TRACE("Standart style Dialog - NT win32 dialog format\n");
    if (bExt){
    	TRACE1("DlgVer: %d\t", wDlgVer);
    	TRACE1("Signature: %d\t", wSign);
    	TRACE1("HelpID: %lu\n", dwHelpID);
    }
    TRACE1("NumElem: %d\t", wNumOfElem);
    TRACE1("X %d\t", wX);
    TRACE1("Y: %d\t", wY);
    TRACE1("CX: %d\t", wcX);
    TRACE1("CY: %d\t", wcY);
    TRACE1("Id: %d\t", wId);
    TRACE1("Style: %lu\t", dwStyle);
    TRACE1("ExtStyle: %lu\n", dwExtStyle);
    TRACE1("Caption: %s\n", szCaption);
    TRACE2("ClassName: %s\tClassId: %d\n", szClassName, wClassName );
    TRACE2("MenuName: %s\tMenuId: %d\n", szMenuName, wMenuName );
    TRACE2("FontName: %s\tPoint: %d\n", szFaceName, wPointSize );
#ifdef _DEBUG
    if(bExt)
    	TRACE2("Weight: %d\tItalic: %d\n", wWeight, bItalic );
#endif

    // Fixed field
    dwOverAllSize += PutDWord( &lpBuf, 0, &dwBufSize);

    dwOverAllSize += PutWord( &lpBuf, wX, &dwBufSize);
    dwOverAllSize += PutWord( &lpBuf, wY, &dwBufSize);
    dwOverAllSize += PutWord( &lpBuf, wcX, &dwBufSize);
    dwOverAllSize += PutWord( &lpBuf, wcY, &dwBufSize);

    // we don't have checksum
    dwOverAllSize += PutDWord( &lpBuf, (DWORD)-1, &dwBufSize);
    dwOverAllSize += PutDWord( &lpBuf, dwStyle, &dwBufSize);
    dwOverAllSize += PutDWord( &lpBuf, dwExtStyle, &dwBufSize);
    dwOverAllSize += PutDWord( &lpBuf, (DWORD)-1, &dwBufSize);

    //Put the Id 0 for the main dialog
    dwOverAllSize += PutDWord( &lpBuf, wIdCount++, &dwBufSize);

    // we don't have the resID, and the Type Id
    dwOverAllSize += PutDWord( &lpBuf, (DWORD)-1, &dwBufSize);
    dwOverAllSize += PutDWord( &lpBuf, (DWORD)-1, &dwBufSize);

    // we don't have the language
    dwOverAllSize += PutDWord( &lpBuf, (DWORD)-1, &dwBufSize);

    // we don't have the codepage
    dwOverAllSize += PutDWord( &lpBuf, (DWORD)-1, &dwBufSize);

    dwOverAllSize += PutWord( &lpBuf, wClassName, &dwBufSize);
    dwOverAllSize += PutWord( &lpBuf, wPointSize, &dwBufSize);
    dwOverAllSize += PutWord( &lpBuf, wWeight, &dwBufSize);
    dwOverAllSize += PutByte( &lpBuf, bItalic, &dwBufSize);
    dwOverAllSize += PutByte( &lpBuf, bCharSet, &dwBufSize);

    // Let's put null were we don't have the strings
    uiOffset = sizeof(RESITEM);
    dwOverAllSize += PutDWordPtr( &lpBuf, 0, &dwBufSize);  // ClassName
    dwOverAllSize += PutDWordPtr( &lpBuf, 0, &dwBufSize);  // FaceName
    dwOverAllSize += PutDWordPtr( &lpBuf, 0, &dwBufSize);  // Caption
    dwOverAllSize += PutDWordPtr( &lpBuf, 0, &dwBufSize);  // ResItem
    dwOverAllSize += PutDWordPtr( &lpBuf, 0, &dwBufSize);  // TypeItem

    lpResItem->lpszClassName = strcpy( lpStrBuf, szClassName );
    lpStrBuf += strlen(lpResItem->lpszClassName)+1;

    lpResItem->lpszFaceName = strcpy( lpStrBuf, szFaceName );
    lpStrBuf += strlen(lpResItem->lpszFaceName)+1;

    lpResItem->lpszCaption = strcpy( lpStrBuf, szCaption );
    lpStrBuf += strlen(lpResItem->lpszCaption)+1;

    // Put the size of the resource
    if (dwBufSize>0) {
        uiOffset += strlen((LPSTR)(lpResItem->lpszClassName))+1;
        uiOffset += strlen((LPSTR)(lpResItem->lpszFaceName))+1;
        uiOffset += strlen((LPSTR)(lpResItem->lpszCaption))+1;
    }

    // Check if we are alligned
    uiOffset += Allign( (LPLPBYTE)&lpStrBuf, &dwBufSize, (LONG)uiOffset);

    dwOverAllSize += uiOffset-sizeof(RESITEM);
    lpResItem->dwSize = (DWORD)uiOffset;

    // Move to the next position
    lpResItem = (LPRESITEM) lpStrBuf;
    lpBuf = (BYTE far *)lpStrBuf;
    lpStrBuf = (char far *)(lpBuf+sizeof(RESITEM));

    while( (dwImageSize>0) && (wNumOfElem>0) ) {
        // Read the Controls
        if(bExt) {
        	wDataSize = GetDWord( &lpImage, &dwHelpID, &dwImageSize );
        	wDataSize += GetDWord( &lpImage, &dwExtStyle, &dwImageSize );
        	wDataSize += GetDWord( &lpImage, &dwStyle, &dwImageSize );
        }
        else {
	        wDataSize = GetDWord( &lpImage, &dwStyle, &dwImageSize );
	        wDataSize += GetDWord( &lpImage, &dwExtStyle, &dwImageSize );
	    }
	    wDataSize += GetWord( &lpImage, &wX, &dwImageSize );
        wDataSize += GetWord( &lpImage, &wY, &dwImageSize );
        wDataSize += GetWord( &lpImage, &wcX, &dwImageSize );
        wDataSize += GetWord( &lpImage, &wcY, &dwImageSize );
        if(bExt) {
        	wDataSize += GetDWord( &lpImage, &dwId, &dwImageSize );
        	wId = LOWORD(dwId);
        }
        else wDataSize += GetWord( &lpImage, &wId, &dwImageSize );
        wDataSize += (WORD)GetClassName( &lpImage, &wClassName, &szClassName[0], &dwImageSize );
        wDataSize += (WORD)GetCaptionOrOrd( &lpImage, &wOrd, &szCaption[0], &dwImageSize, wClassName, dwStyle );
        if (bExt) {
        	wDataSize += GetWord( &lpImage, &wRawData, &dwImageSize );
        	wDataSize += (WORD)SkipByte( &lpImage, wRawData, &dwImageSize );
        } else
        	wDataSize += (WORD)SkipByte( &lpImage, 2, &dwImageSize );

        // Calculate padding
        bPad = (BYTE)Pad4((WORD)wDataSize);
        if (bPad)
            SkipByte( &lpImage, bPad, &dwImageSize );

        wNumOfElem--;

        // Fixed field
        dwOverAllSize += PutDWord( &lpBuf, 0, &dwBufSize);

        dwOverAllSize += PutWord( &lpBuf, wX, &dwBufSize);
        dwOverAllSize += PutWord( &lpBuf, wY, &dwBufSize);
        dwOverAllSize += PutWord( &lpBuf, wcX, &dwBufSize);
        dwOverAllSize += PutWord( &lpBuf, wcY, &dwBufSize);

        // we don't have checksum and extended style
        dwOverAllSize += PutDWord( &lpBuf, (DWORD)-1, &dwBufSize);
        dwOverAllSize += PutDWord( &lpBuf, dwStyle, &dwBufSize);
        dwOverAllSize += PutDWord( &lpBuf, dwExtStyle, &dwBufSize);
        dwOverAllSize += PutDWord( &lpBuf, (DWORD)-1, &dwBufSize);

        //Put the Id
        dwOverAllSize += PutDWord( &lpBuf, wId, &dwBufSize);

        // we don't have the resID, and the Type Id
        dwOverAllSize += PutDWord( &lpBuf, (DWORD)-1, &dwBufSize);
        dwOverAllSize += PutDWord( &lpBuf, (DWORD)-1, &dwBufSize);

        // we don't have the language
        dwOverAllSize += PutDWord( &lpBuf, (DWORD)-1, &dwBufSize);

        // we don't have the codepage
        dwOverAllSize += PutDWord( &lpBuf, (DWORD)-1, &dwBufSize);

        dwOverAllSize += PutWord( &lpBuf, wClassName, &dwBufSize);
        dwOverAllSize += PutWord( &lpBuf, wPointSize, &dwBufSize);
        dwOverAllSize += PutWord( &lpBuf, wWeight, &dwBufSize);
        dwOverAllSize += PutByte( &lpBuf, bItalic, &dwBufSize);
        dwOverAllSize += PutByte( &lpBuf, bCharSet, &dwBufSize);

        // Let's put null were we don't have the strings
        uiOffset = sizeof(RESITEM);
        dwOverAllSize += PutDWordPtr( &lpBuf, 0, &dwBufSize);  // ClassName
        dwOverAllSize += PutDWordPtr( &lpBuf, 0, &dwBufSize);  // FaceName
        dwOverAllSize += PutDWordPtr( &lpBuf, 0, &dwBufSize);  // Caption
        dwOverAllSize += PutDWordPtr( &lpBuf, 0, &dwBufSize);  // ResItem
        dwOverAllSize += PutDWordPtr( &lpBuf, 0, &dwBufSize);  // TypeItem

        lpResItem->lpszClassName = strcpy( lpStrBuf, szClassName );
        lpStrBuf += strlen(lpResItem->lpszClassName)+1;

        lpResItem->lpszFaceName = strcpy( lpStrBuf, szFaceName );
        lpStrBuf += strlen(lpResItem->lpszFaceName)+1;

        lpResItem->lpszCaption = strcpy( lpStrBuf, szCaption );
        lpStrBuf += strlen(lpResItem->lpszCaption)+1;

        // Put the size of the resource
        if (dwBufSize>0) {
            uiOffset += strlen((LPSTR)(lpResItem->lpszClassName))+1;
            uiOffset += strlen((LPSTR)(lpResItem->lpszFaceName))+1;
            uiOffset += strlen((LPSTR)(lpResItem->lpszCaption))+1;
        }

        // Check if we are alligned
        uiOffset += Allign( (LPLPBYTE)&lpStrBuf, &dwBufSize, (LONG)uiOffset);

        dwOverAllSize += uiOffset-sizeof(RESITEM);
        lpResItem->dwSize = (DWORD)uiOffset;

        // Move to the next position
        lpResItem = (LPRESITEM) lpStrBuf;
        lpBuf = (BYTE far *)lpStrBuf;
        lpStrBuf = (char far *)(lpBuf+sizeof(RESITEM));

        TRACE1("\tControl: X: %d\t", wX);
        TRACE1("Y: %d\t", wY);
        TRACE1("CX: %d\t", wcX);
        TRACE1("CY: %d\t", wcY);
        if (bExt) TRACE1("Id: %lu\t", dwId);
        else TRACE1("Id: %d\t", wId);
        TRACE1("Style: %lu\t", dwStyle);
        TRACE1("ExtStyle: %lu\n", dwExtStyle);
        TRACE1("HelpID: %lu\t", dwHelpID);
        TRACE1("RawData: %d\n", wRawData);
        TRACE1("Caption: %s\n", szCaption);

        if (dwImageSize<=16) {
            // Check if we are at the end and this is just padding
            BYTE bPad = (BYTE)Pad16((DWORD)(dwISize-dwImageSize));
            if (bPad==dwImageSize) {
				BYTE far * lpBuf = lpImage;
				while (bPad){
					if(*lpBuf++!=0x00)
						break;
					bPad--;
				}
				if (bPad==0)
					dwImageSize = -1;
			}
        }
    }

    return (UINT)(dwOverAllSize);
}



UINT
UpdateDialog( LPVOID lpNewBuf, LONG dwNewSize,
            LPVOID lpOldI, LONG dwOldImageSize,
            LPVOID lpNewI, DWORD* pdwNewImageSize )
{
    UINT uiError = ERROR_NO_ERROR;
    BYTE far * lpNewImage = (BYTE far *) lpNewI;
    LONG dwNewImageSize = *pdwNewImageSize;

    BYTE far * lpOldImage = (BYTE far *) lpOldI;
    LONG dwOriginalOldSize = dwOldImageSize;

    BYTE far * lpBuf = (BYTE far *) lpNewBuf;
    LPRESITEM lpResItem = LPNULL;

    LONG dwOverAllSize = 0L;

    //WORD    wIdCount = 0;
    BOOL bExt = FALSE;		// Extended dialog flag
    BOOL bUpdExt = FALSE;	// Updated DIALOGEX flag

    // Updated elements
    WORD wUpdX = 0;
    WORD wUpdY = 0;
    WORD wUpdcX = 0;
    WORD wUpdcY = 0;
    DWORD dwUpdStyle = 0l;
    DWORD dwUpdExtStyle = 0L;
    DWORD dwPosId = 0l;
     char szUpdFaceName[128];
    WORD wUpdPointSize = 0;
    BYTE bUpdCharSet = DEFAULT_CHARSET;
    WORD wUpdPos = 0;

    // Dialog Elements
    WORD	wDlgVer = 0;
    WORD	wSign	= 0;
    DWORD	dwHelpID = 0L;
    DWORD	dwID = 0L;
    DWORD   dwStyle = 0L;
    DWORD   dwExtStyle = 0L;
    WORD    wNumOfElem = 0;
    WORD    wX = 0;
    WORD    wY = 0;
    WORD    wcX = 0;
    WORD    wcY = 0;
    WORD    wId = 0;
     char     szMenuName[128];
    WORD    wMenuName;
     char     szClassName[128];
    WORD    wClassName;
    WORD    wPointSize = 0;
    WORD	wWeight = FW_NORMAL;
    BYTE    bItalic = 0;
    BYTE    bCharSet = DEFAULT_CHARSET;
     char    szFaceName[128];
    WORD	wRawData = 0;
    BYTE *	lpRawData = NULL;
    WORD    wDataSize = 0;

    WORD    wPos = 1;
    WORD    wOrd = 0;

    // read the dialog header
    wDataSize = GetDWord( &lpOldImage, &dwStyle, &dwOriginalOldSize );

    // Check for extended dialog style
    if(HIWORD(dwStyle)==0xFFFF)	{
    	bExt = TRUE;
    	wDlgVer = HIWORD(dwStyle);
    	wSign = LOWORD(dwStyle);
		wDataSize += GetDWord( &lpOldImage, &dwHelpID, &dwOriginalOldSize );
	}
    wDataSize += GetDWord( &lpOldImage, &dwExtStyle, &dwOriginalOldSize );
    if(bExt)
    	wDataSize += GetDWord( &lpOldImage, &dwStyle, &dwOriginalOldSize );
    wDataSize += GetWord( &lpOldImage, &wNumOfElem, &dwOriginalOldSize );
    wDataSize += GetWord( &lpOldImage, &wX, &dwOriginalOldSize );
    wDataSize += GetWord( &lpOldImage, &wY, &dwOriginalOldSize );
    wDataSize += GetWord( &lpOldImage, &wcX, &dwOriginalOldSize );
    wDataSize += GetWord( &lpOldImage, &wcY, &dwOriginalOldSize );
    wDataSize += (WORD)GetNameOrOrd( &lpOldImage, &wMenuName, &szMenuName[0], &dwOriginalOldSize );
    wDataSize += (WORD)GetClassName( &lpOldImage, &wClassName, &szClassName[0], &dwOriginalOldSize );
    wDataSize += (WORD)GetCaptionOrOrd( &lpOldImage , &wOrd, &szCaption[0], &dwOriginalOldSize, wClassName, dwStyle  );
    if( dwStyle & DS_SETFONT ) {
        wDataSize += GetWord( &lpOldImage, &wPointSize, &dwOriginalOldSize );
        if(bExt) {
        	wDataSize += GetWord( &lpOldImage, &wWeight, &dwOriginalOldSize );
        	wDataSize += GetByte( &lpOldImage, &bItalic, &dwOriginalOldSize );
        	wDataSize += GetByte( &lpOldImage, &bCharSet, &dwOriginalOldSize );
        }
        wDataSize += (WORD)GetStringW( &lpOldImage, &szFaceName[0], &dwOriginalOldSize, 128 );
    }

    // calculate the padding
    BYTE bPad = (BYTE)Pad4((WORD)wDataSize);
    if (bPad)
        SkipByte( &lpOldImage, bPad, &dwOriginalOldSize );

    TRACE("WIN32.DLL UpdateDialog\n");
    if(bExt)
    	TRACE("Extended style Dialog - Chicago win32 dialog format\n");
    else TRACE("Standart style Dialog - NT win32 dialog format\n");
    if (bExt){
    	TRACE1("DlgVer: %d\t", wDlgVer);
    	TRACE1("Signature: %d\t", wSign);
    	TRACE1("HelpID: %lu\n", dwHelpID);
    }

    TRACE1("NumElem: %d\t", wNumOfElem);
    TRACE1("X %d\t", wX);
    TRACE1("Y: %d\t", wY);
    TRACE1("CX: %d\t", wcX);
    TRACE1("CY: %d\t", wcY);
    TRACE1("Id: %d\t", wId);
    TRACE1("Style: %lu\t", dwStyle);
    TRACE1("ExtStyle: %lu\n", dwExtStyle);
    TRACE1("Caption: %s\n", szCaption);
    TRACE2("ClassName: %s\tClassId: %d\n", szClassName, wClassName );
    TRACE2("MenuName: %s\tMenuId: %d\n", szMenuName, wMenuName );
    TRACE2("FontName: %s\tPoint: %d\n", szFaceName, wPointSize );
#ifdef _DEBUG
    if(bExt)
    	TRACE2("Weight: %d\tItalic: %d\n", wWeight, bItalic );
#endif

    // Get the infrmation from the updated resource
    if ((!wUpdPos) && dwNewSize ) {
        lpResItem = (LPRESITEM) lpBuf;
        wUpdX = lpResItem->wX;
        wUpdY = lpResItem->wY;
        wUpdcX = lpResItem->wcX;
        wUpdcY = lpResItem->wcY;
        wUpdPointSize = lpResItem->wPointSize;
        bUpdCharSet = lpResItem->bCharSet;
        dwUpdStyle = lpResItem->dwStyle;
        dwUpdExtStyle = lpResItem->dwExtStyle;
        dwPosId = lpResItem->dwItemID;
        strcpy( szUpdCaption, lpResItem->lpszCaption );
        strcpy( szUpdFaceName, lpResItem->lpszFaceName );
        lpBuf += lpResItem->dwSize;
        dwNewSize -= lpResItem->dwSize;
    }

    // check if we have to update the header
    if ((HIWORD(dwPosId)==wPos) && (LOWORD(dwPosId)==wId)) {
        wX = wUpdX;
        wY = wUpdY;
        wcX = wUpdcX;
        wcY = wUpdcY;
        wPointSize = wUpdPointSize;
        bCharSet = bUpdCharSet;
        dwStyle = dwUpdStyle;
        dwExtStyle = dwUpdExtStyle;
        strcpy(szCaption, szUpdCaption);
        strcpy(szFaceName, szUpdFaceName);
    }

    // User changed DIALOG to DIALOGEX by adding charset information.
    if (!bExt && bCharSet != DEFAULT_CHARSET){
        bUpdExt = TRUE;
        wSign = DIALOGEX_VERION;
        wDlgVer = 0xFFFF;
        dwHelpID = 0;
        wWeight = FW_NORMAL;
        bItalic = 0;
    }
    DWORD dwPadCalc = dwOverAllSize;
    // Write the header informations
    if(bExt || bUpdExt) {
    	dwOverAllSize += PutWord( &lpNewImage, wSign, &dwNewImageSize );
    	dwOverAllSize += PutWord( &lpNewImage, wDlgVer, &dwNewImageSize );
    	dwOverAllSize += PutDWord( &lpNewImage, dwHelpID, &dwNewImageSize );
        dwOverAllSize += PutDWord( &lpNewImage, dwExtStyle, &dwNewImageSize );
	    dwOverAllSize += PutDWord( &lpNewImage, dwStyle, &dwNewImageSize );
    }
    else {
	    dwOverAllSize += PutDWord( &lpNewImage, dwStyle, &dwNewImageSize );
	    dwOverAllSize += PutDWord( &lpNewImage, dwExtStyle, &dwNewImageSize );
	}
    dwOverAllSize += PutWord( &lpNewImage, wNumOfElem, &dwNewImageSize );
    dwOverAllSize += PutWord( &lpNewImage, wX, &dwNewImageSize );
    dwOverAllSize += PutWord( &lpNewImage, wY, &dwNewImageSize );
    dwOverAllSize += PutWord( &lpNewImage, wcX, &dwNewImageSize );
    dwOverAllSize += PutWord( &lpNewImage, wcY, &dwNewImageSize );
    dwOverAllSize += PutNameOrOrd( &lpNewImage, wMenuName, &szMenuName[0], &dwNewImageSize );
    dwOverAllSize += PutClassName( &lpNewImage, wClassName, &szClassName[0], &dwNewImageSize );
    dwOverAllSize += PutCaptionOrOrd( &lpNewImage, wOrd, &szCaption[0], &dwNewImageSize,
    	wClassName, dwStyle );
    if( dwStyle & DS_SETFONT ) {
    	dwOverAllSize += PutWord( &lpNewImage, wPointSize, &dwNewImageSize );
    	if(bExt || bUpdExt) {
    		dwOverAllSize += PutWord( &lpNewImage, wWeight, &dwNewImageSize );
    		dwOverAllSize += PutByte( &lpNewImage, bItalic, &dwNewImageSize );
    		dwOverAllSize += PutByte( &lpNewImage, bCharSet, &dwNewImageSize );
    	}
        dwOverAllSize += PutStringW( &lpNewImage, &szFaceName[0], &dwNewImageSize );
    }

    // Check if padding is needed
    bPad = (BYTE)Pad4((WORD)(dwOverAllSize-dwPadCalc));
    if (bPad) {
        if( (bPad)<=dwNewImageSize )
            memset( lpNewImage, 0x00, bPad );
        dwNewImageSize -= (bPad);
        dwOverAllSize += (bPad);
        lpNewImage += (bPad);
    }

    while( (dwOriginalOldSize>0) && (wNumOfElem>0) ) {
        wPos++;
        // Get the info for the control
        // Read the Controls
        if(bExt) {
        	wDataSize = GetDWord( &lpOldImage, &dwHelpID, &dwOriginalOldSize );
        	wDataSize += GetDWord( &lpOldImage, &dwExtStyle, &dwOriginalOldSize );
        	wDataSize += GetDWord( &lpOldImage, &dwStyle, &dwOriginalOldSize );
        }
        else {
	        wDataSize = GetDWord( &lpOldImage, &dwStyle, &dwOriginalOldSize );
	        wDataSize += GetDWord( &lpOldImage, &dwExtStyle, &dwOriginalOldSize );
	    }
	    wDataSize += GetWord( &lpOldImage, &wX, &dwOriginalOldSize );
        wDataSize += GetWord( &lpOldImage, &wY, &dwOriginalOldSize );
        wDataSize += GetWord( &lpOldImage, &wcX, &dwOriginalOldSize );
        wDataSize += GetWord( &lpOldImage, &wcY, &dwOriginalOldSize );
        if(bExt) {
        	wDataSize += GetDWord( &lpOldImage, &dwID, &dwOriginalOldSize );
        	wId = LOWORD(dwID);
        } else {
            wDataSize += GetWord( &lpOldImage, &wId, &dwOriginalOldSize );
        }

        wDataSize += (WORD)GetClassName( &lpOldImage, &wClassName, &szClassName[0], &dwOriginalOldSize );
        wDataSize += (WORD)GetCaptionOrOrd( &lpOldImage, &wOrd, &szCaption[0], &dwOriginalOldSize, wClassName, dwStyle );
        if (bExt) {
        	wDataSize += GetWord( &lpOldImage, &wRawData, &dwOriginalOldSize );
        	if(wRawData) {
        		lpRawData = (BYTE*)lpOldImage;
        		wDataSize += (WORD)SkipByte( &lpOldImage, wRawData, &dwOriginalOldSize );
        	} else lpRawData = NULL;
        } else
        	wDataSize += (WORD)SkipByte( &lpOldImage, 2, &dwOriginalOldSize );

        // Calculate padding
        bPad = (BYTE)Pad4((WORD)wDataSize);
        if (bPad)
            SkipByte( &lpOldImage, bPad, &dwOriginalOldSize );

        wNumOfElem--;

        if ((!wUpdPos) && dwNewSize ) {
        TRACE1("\t\tUpdateDialog:\tdwNewSize=%ld\n",(LONG)dwNewSize);
            TRACE1("\t\t\t\tlpszCaption=%Fs\n",lpResItem->lpszCaption);
            lpResItem = (LPRESITEM) lpBuf;
            wUpdX = lpResItem->wX;
            wUpdY = lpResItem->wY;
            wUpdcX = lpResItem->wcX;
            wUpdcY = lpResItem->wcY;
            dwUpdStyle = lpResItem->dwStyle;
            dwUpdExtStyle = lpResItem->dwExtStyle;
            dwPosId = lpResItem->dwItemID;
            strcpy( szUpdCaption, lpResItem->lpszCaption );
            lpBuf += lpResItem->dwSize;
            dwNewSize -= lpResItem->dwSize;
        }
        // check if we have to update the header
        if ((HIWORD(dwPosId)==wPos) && (LOWORD(dwPosId)==wId)) {
            wX = wUpdX;
            wY = wUpdY;
            wcX = wUpdcX;
            wcY = wUpdcY;
            dwStyle = dwUpdStyle;
            dwExtStyle = dwUpdExtStyle;
            strcpy(szCaption, szUpdCaption);
        }

        dwPadCalc = dwOverAllSize;
        //write the control
        if(bExt || bUpdExt) {
        	dwOverAllSize += PutDWord( &lpNewImage, dwHelpID, &dwNewImageSize );
        	dwOverAllSize += PutDWord( &lpNewImage, dwExtStyle, &dwNewImageSize );
        	dwOverAllSize += PutDWord( &lpNewImage, dwStyle, &dwNewImageSize );
        }
        else {
        	dwOverAllSize += PutDWord( &lpNewImage, dwStyle, &dwNewImageSize );
        	dwOverAllSize += PutDWord( &lpNewImage, dwExtStyle, &dwNewImageSize );
        }
        dwOverAllSize += PutWord( &lpNewImage, wX, &dwNewImageSize );
        dwOverAllSize += PutWord( &lpNewImage, wY, &dwNewImageSize );
        dwOverAllSize += PutWord( &lpNewImage, wcX, &dwNewImageSize );
        dwOverAllSize += PutWord( &lpNewImage, wcY, &dwNewImageSize );
        if (bUpdExt){
            dwID = MAKELONG(wId, 0);
        }
        if(bExt || bUpdExt)
        	 dwOverAllSize += PutDWord( &lpNewImage, dwID, &dwNewImageSize );
        else dwOverAllSize += PutWord( &lpNewImage, wId, &dwNewImageSize );
        dwOverAllSize += PutClassName( &lpNewImage, wClassName, &szClassName[0], &dwNewImageSize );
        dwOverAllSize += PutCaptionOrOrd( &lpNewImage, wOrd, &szCaption[0], &dwNewImageSize,
        	wClassName, dwStyle );
        if (bExt) {
        	dwOverAllSize += PutWord( &lpNewImage, wRawData, &dwNewImageSize );
        	while(wRawData) {
        		dwOverAllSize += PutByte( &lpNewImage, *((BYTE*)lpRawData++), &dwNewImageSize );
        		wRawData--;
        	}
        } else
        	dwOverAllSize += PutWord( &lpNewImage, 0, &dwNewImageSize );

        // Check if padding is needed
        bPad = (BYTE)Pad4((WORD)(dwOverAllSize-dwPadCalc));
        if (bPad) {
            if( (bPad)<=dwNewImageSize )
                memset( lpNewImage, 0x00, bPad );
            dwNewImageSize -= (bPad);
            dwOverAllSize += (bPad);
            lpNewImage += (bPad);
        }
    }

    if (dwOverAllSize>(LONG)*pdwNewImageSize) {
        // calc the padding as well
        BYTE bPad = (BYTE)Pad4((DWORD)(dwOverAllSize));
        dwOverAllSize += bPad;
        *pdwNewImageSize = dwOverAllSize;
        return uiError;
    }

    *pdwNewImageSize = *pdwNewImageSize-dwNewImageSize;

    if(*pdwNewImageSize>0) {
        // calculate padding
        BYTE bPad = (BYTE)Pad4((DWORD)(*pdwNewImageSize));
        if (bPad>dwNewImageSize) {
            *pdwNewImageSize += bPad;
            return uiError;
        }
        memset(lpNewImage, 0x00, bPad);
        *pdwNewImageSize += bPad;
    }


    return uiError;
}


UINT
ParseMsgTbl( LPVOID lpImageBuf, DWORD dwISize,  LPVOID lpBuffer, DWORD dwSize )
{
    LONG dwOverAllSize = 0L;

    // Should be almost impossible for a Message table to be Huge
    BYTE far * lpImage = (BYTE far *)lpImageBuf;
    LONG dwImageSize = dwISize;

    BYTE far * lpBuf = (BYTE far *)lpBuffer;
    LONG dwBufSize = dwSize;

    BYTE far * lpItem = (BYTE far *)lpBuffer;
    UINT uiOffset = 0;
    LONG lDummy;

    LONG dwRead = 0L;

    ULONG ulNumofBlock = 0l;

    ULONG ulLowId =  0l;
    ULONG ulHighId = 0l;
    ULONG ulOffsetToEntry = 0l;

    USHORT usLength = 0l;
    USHORT usFlags = 0l;

    WORD wPos = 0;
    // Get number of blocks
    GetDWord( &lpImage, &ulNumofBlock, &dwImageSize );
    wPos = 1;
    for( ULONG c = 0; c<ulNumofBlock ; c++) {
        // Get ID of the block
        GetDWord( &lpImage, &ulLowId, &dwImageSize );
        GetDWord( &lpImage, &ulHighId, &dwImageSize );

        // Get the offset to the data
        GetDWord( &lpImage, &ulOffsetToEntry, &dwImageSize );

        BYTE far * lpData = (BYTE far *)lpImageBuf;
        lpData += ulOffsetToEntry;
        while( ulHighId>=ulLowId ) {

            GetMsgStr( &lpData,
                          &szCaption[0],
                          MAXSTR,
                          &usLength,
                          &usFlags,
                          &dwImageSize );
            // Fixed field
            dwOverAllSize += PutDWord( &lpBuf, 0, &dwBufSize);
            // We don't have the size and pos in a string
            dwOverAllSize += PutWord( &lpBuf, (WORD)-1, &dwBufSize);
            dwOverAllSize += PutWord( &lpBuf, (WORD)-1, &dwBufSize);
            dwOverAllSize += PutWord( &lpBuf, (WORD)-1, &dwBufSize);
            dwOverAllSize += PutWord( &lpBuf, (WORD)-1, &dwBufSize);

            // we don't have checksum and style
            dwOverAllSize += PutDWord( &lpBuf, (DWORD)-1, &dwBufSize);
            dwOverAllSize += PutDWord( &lpBuf, (DWORD)-1, &dwBufSize);
            dwOverAllSize += PutDWord( &lpBuf, (DWORD)-1, &dwBufSize);
            dwOverAllSize += PutDWord( &lpBuf, (DWORD)-1, &dwBufSize);

            //Put the lowStringId
            //dwOverAllSize += PutDWord( &lpBuf, MAKELONG(ulLowId++, wPos++), &dwBufSize);

            ulLowId++;
            dwOverAllSize += PutDWord( &lpBuf, MAKELONG(wPos, wPos), &dwBufSize);
            wPos++;


            dwOverAllSize += PutDWord( &lpBuf, (DWORD)-1, &dwBufSize);
            dwOverAllSize += PutDWord( &lpBuf, (DWORD)-1, &dwBufSize);

            // we don't have the language
            dwOverAllSize += PutDWord( &lpBuf, (DWORD)-1, &dwBufSize);

            // Put the flags: if 1 = ANSI if 0 = ASCII(OEM)
            dwOverAllSize += PutDWord( &lpBuf, usFlags , &dwBufSize);

            // we don't have the font name
            dwOverAllSize += PutWord( &lpBuf, (WORD)-1, &dwBufSize);
            dwOverAllSize += PutWord( &lpBuf, (WORD)-1, &dwBufSize);
            dwOverAllSize += PutWord( &lpBuf, (WORD)-1, &dwBufSize);
            dwOverAllSize += PutByte( &lpBuf, (BYTE)-1, &dwBufSize);
            dwOverAllSize += PutByte( &lpBuf, (BYTE)-1, &dwBufSize);

            // Let's put null were we don;t have the strings
            uiOffset = sizeof(RESITEM);
            dwOverAllSize += PutDWordPtr( &lpBuf, 0, &dwBufSize);  // ClassName
            dwOverAllSize += PutDWordPtr( &lpBuf, 0, &dwBufSize);  // FaceName
            dwOverAllSize += PutDWordPtr( &lpBuf, (DWORD_PTR)(lpItem+uiOffset), &dwBufSize);   // Caption
            dwOverAllSize += PutDWordPtr( &lpBuf, 0, &dwBufSize);  // ResItem
            dwOverAllSize += PutDWordPtr( &lpBuf, 0, &dwBufSize);  // TypeItem

            dwOverAllSize += PutStringA( &lpBuf, &szCaption[0], &dwBufSize);

            // Put the size of the resource
            if ((LONG)(dwSize-dwOverAllSize)>=0) {
                uiOffset += strlen((LPSTR)(lpItem+uiOffset))+1;
                // Check if we are alligned
            	lDummy = Allign( &lpBuf, &dwBufSize, (LONG)uiOffset);
            	dwOverAllSize += lDummy;
            	uiOffset += lDummy;
            	lDummy = 8;
                PutDWord( &lpItem, (DWORD)uiOffset, &lDummy);
            }

            // Move to the next position
            lpItem = lpBuf;

            // Check if we are at the end and this is just padding
            if (dwImageSize<=16) {
                BYTE bPad = (BYTE)Pad16((DWORD)(dwISize-dwImageSize));
    	        if (bPad==dwImageSize) {
    				BYTE far * lpBuf = lpImage;
    				while (bPad){
    					if(*lpBuf++!=0x00)
    						break;
    					bPad--;
    				}
    				if (bPad==0)
    					dwImageSize = -1;
    			}
    		}
        }
    }

    return (UINT)(dwOverAllSize);
}


UINT
ParseVerst( LPVOID lpImageBuf, DWORD dwISize,  LPVOID lpBuffer, DWORD dwSize )
{
    BYTE far * lpImage = (BYTE far *)lpImageBuf;
    LONG dwImageSize = dwISize;

    BYTE far * lpBuf = (BYTE far *)lpBuffer;
    LONG dwBufSize = dwSize;

    BYTE far * lpItem = (BYTE far *)lpBuffer;
    UINT uiOffset = 0;

    LPRESITEM lpResItem = (LPRESITEM)lpBuffer;
    char far * lpStrBuf = (char far *)(lpBuf+sizeof(RESITEM));

    LONG dwOverAllSize = 0L;

     VER_BLOCK VSBlock;
    WORD wPad = 0;
    WORD wPos = 0;

    while(dwImageSize>0) {

        GetVSBlock( &lpImage, &dwImageSize, &VSBlock );

        TRACE1("Key: %s\t", VSBlock.szKey);
        TRACE1("Value: %s\n", VSBlock.szValue);
        TRACE3("Len: %d\tSkip: %d\tType: %d\n", VSBlock.wBlockLen, VSBlock.wValueLen, VSBlock.wType );
        // check if this is the translation block
        if (!strcmp(VSBlock.szKey, "Translation" )){
            // This is the translation block let the localizer have it for now
            DWORD dwCodeLang = 0;
            LONG lDummy = 4;
            GetDWord( &VSBlock.pValue, &dwCodeLang, &lDummy);

            // Put the value in the string value
            wsprintf( &VSBlock.szValue[0], "%#08lX", dwCodeLang );
        }

        // Fixed field
        dwOverAllSize += PutDWord( &lpBuf, 0, &dwBufSize);
        // We don't have the size and pos in an accelerator
        dwOverAllSize += PutWord( &lpBuf, (WORD)-1, &dwBufSize);
        dwOverAllSize += PutWord( &lpBuf, (WORD)-1, &dwBufSize);
        dwOverAllSize += PutWord( &lpBuf, (WORD)-1, &dwBufSize);
        dwOverAllSize += PutWord( &lpBuf, (WORD)-1, &dwBufSize);

        // we don't have checksum and style
        dwOverAllSize += PutDWord( &lpBuf, (DWORD)-1, &dwBufSize);
        dwOverAllSize += PutDWord( &lpBuf, (DWORD)-1, &dwBufSize);
        dwOverAllSize += PutDWord( &lpBuf, (DWORD)-1, &dwBufSize);

        //Put the Flag
        dwOverAllSize += PutDWord( &lpBuf, (DWORD)-1, &dwBufSize);
        // we will need to calculate the correct ID for mike
        //Put the Id
        dwOverAllSize += PutDWord( &lpBuf, wPos++, &dwBufSize);


        // we don't have the resID, and the Type Id
        dwOverAllSize += PutDWord( &lpBuf, (DWORD)-1, &dwBufSize);
        dwOverAllSize += PutDWord( &lpBuf, (DWORD)-1, &dwBufSize);

        // we don't have the language
        dwOverAllSize += PutDWord( &lpBuf, (DWORD)-1, &dwBufSize);

        // we don't have the codepage or the font name
        dwOverAllSize += PutDWord( &lpBuf, (DWORD)-1, &dwBufSize);
        dwOverAllSize += PutWord( &lpBuf, (WORD)-1, &dwBufSize);
        dwOverAllSize += PutWord( &lpBuf, (WORD)-1, &dwBufSize);
        dwOverAllSize += PutWord( &lpBuf, (WORD)-1, &dwBufSize);
        dwOverAllSize += PutByte( &lpBuf, (BYTE)-1, &dwBufSize);
        dwOverAllSize += PutByte( &lpBuf, (BYTE)-1, &dwBufSize);

        // Let's put null were we don;t have the strings
        uiOffset = sizeof(RESITEM);
        dwOverAllSize += PutDWordPtr( &lpBuf, 0, &dwBufSize);
        dwOverAllSize += PutDWordPtr( &lpBuf, 0, &dwBufSize);
        dwOverAllSize += PutDWordPtr( &lpBuf, 0, &dwBufSize);
        dwOverAllSize += PutDWordPtr( &lpBuf, 0, &dwBufSize);
        dwOverAllSize += PutDWordPtr( &lpBuf, 0, &dwBufSize);

        lpResItem->lpszClassName = strcpy( lpStrBuf, VSBlock.szKey );
        lpStrBuf += strlen(lpResItem->lpszClassName)+1;

        lpResItem->lpszCaption = strcpy( lpStrBuf, VSBlock.szValue );
        lpStrBuf += strlen(lpResItem->lpszCaption)+1;


        // Put the size of the resource
        if (dwBufSize>0) {
            uiOffset += strlen((LPSTR)(lpResItem->lpszClassName))+1;
            uiOffset += strlen((LPSTR)(lpResItem->lpszCaption))+1;
        }

        // Check if we are alligned
        uiOffset += Allign( (LPLPBYTE)&lpStrBuf, &dwBufSize, (LONG)uiOffset);
        dwOverAllSize += uiOffset-sizeof(RESITEM);
        lpResItem->dwSize = (DWORD)uiOffset;


        // Move to the next position
        lpResItem = (LPRESITEM) lpStrBuf;
        lpBuf = (BYTE far *)lpStrBuf;
        lpStrBuf = (char far *)(lpBuf+sizeof(RESITEM));
    }

    return (UINT)(dwOverAllSize);
}

 UINT GetVSBlock( BYTE far * far* lplpBuf, LONG* pdwSize, VER_BLOCK* pBlock )
{
    WORD wPad = 0;
    int  iToRead = 0;
    WORD wLen = 0;
    WORD wHead = 0;

    if(*lplpBuf==NULL)
        return 0;

    pBlock->pValue = *lplpBuf;
    wHead = GetWord( lplpBuf, &pBlock->wBlockLen, pdwSize );
    wHead += GetWord( lplpBuf, &pBlock->wValueLen, pdwSize );
    wHead += GetWord( lplpBuf, &pBlock->wType, pdwSize );

    // Get the Key name
    wHead += (WORD)GetStringW( lplpBuf, &pBlock->szKey[0], pdwSize, 100 );
    if(Pad4(wHead))
        wPad += (WORD)SkipByte( lplpBuf, 2, pdwSize );

    iToRead = pBlock->wValueLen;
    pBlock->wHead = wHead;

    // Check if we are going over the image len
    if (iToRead>*pdwSize) {
        // There is an error
        wPad += (WORD)SkipByte( lplpBuf, (UINT)*pdwSize, pdwSize );
        return wHead+wPad;
    }

    // Save the pointer to the Value field
    pBlock->pValue = (pBlock->pValue+wHead+wPad);

    if(pBlock->wType && iToRead){
        iToRead -= wPad>>1;
        // Get the string
        if (iToRead>MAXSTR) {
            *pdwSize -= iToRead*sizeofWord;
            *lplpBuf += iToRead*sizeofWord;
        } else {
                int n = 0;
                int iBytesRead = 0;
                if ((iToRead*sizeofWord)+wHead+wPad>pBlock->wBlockLen)
                    // Need to fix this up. Bug in the RC compiler?
                    iToRead -= ((iToRead*sizeofWord)+wHead+wPad - pBlock->wBlockLen)>>1;
                iBytesRead = GetStringW(lplpBuf, &pBlock->szValue[0], pdwSize, 256);
                //
                //  Some old version stamp has a NULL char in between
                //  Microsoft Corp. and the year of copyright.  GetString
                //  will return the number of byte read up to the NULL char.
                //  We need to skip the rest.
                //
                if (iBytesRead < iToRead*sizeofWord)
                {
                    iBytesRead += SkipByte(lplpBuf,
                                           iToRead*sizeofWord-iBytesRead,
                                           pdwSize);
                }
                iToRead = iBytesRead;
        }
    } else {
        SkipByte( lplpBuf, iToRead, pdwSize );
        *pBlock->szValue = '\0';
    }

    if (*pdwSize)
    {
        WORD far * lpw = (WORD far *)*lplpBuf;
        while((WORD)*(lpw)==0x0000)
        {
            wPad += (WORD)SkipByte( (BYTE far * far *)&lpw, 2, pdwSize );
            if ((*pdwSize)<=0)
            {
                break;
            }
        }
        *lplpBuf = (BYTE far *)lpw;
    }

    return (wHead+iToRead+wPad);
}

 UINT
PutVSBlock( BYTE far * far * lplpImage, LONG* pdwSize, VER_BLOCK ver,
            LPSTR lpStr, BYTE far * far * lplpBlockSize, WORD* pwTrash)

{
    // We have to write the info in the VER_BLOCK in the new image
    // We want to remember were the block size field is so we can update it later

    WORD wHead = 0;
    WORD wValue = 0;
    WORD wPad = Pad4(ver.wHead);
    *pwTrash = 0;

    // Get the pointer to the header of the block
    BYTE far * pHead = ver.pValue-ver.wHead-wPad;
    BYTE far * lpNewImage = *lplpImage;
    // Copy the header of the block to the new image
    wHead = ver.wHead;
    if (*pdwSize>=(int)ver.wHead) {
        memcpy( *lplpImage, pHead, ver.wHead );
        *pdwSize -= ver.wHead;
        lpNewImage += ver.wHead;
    }

    // Check if padding is needed
    if ((wPad) && (*pdwSize>=(int)wPad)) {
        memset( *lplpImage+ver.wHead, 0, wPad );
        *pdwSize -= wPad;
        lpNewImage += wPad;
    }

    // Store the pointer to the block size WORD
    BYTE far * pBlockSize = *lplpImage;

    // Check if the value is a string or a BYTE array
    if(ver.wType) {
        // it is a string, copy the updated item
        // Check if we had a string in this field
        if(ver.wValueLen) {
            BYTE far * lpImageStr = *lplpImage+wHead+wPad;
            wValue = (WORD)PutStringW(&lpImageStr, lpStr, pdwSize);
            lpNewImage += wValue;

            // Check if padding is needed
            if ((Pad4(wValue)) && (*pdwSize>=(int)Pad4(wValue))) {
                memset( *lplpImage+ver.wHead+wValue+wPad, 0, Pad4(wValue) );
                *pdwSize -= Pad4(wValue);
                lpNewImage += Pad4(wValue);
            }

            WORD wPad1 = Pad4(wValue);
            WORD wFixUp = wValue/sizeofWord;
            *pwTrash = Pad4(ver.wValueLen);
            wValue += wPad1;
            // Fix to the strange behaviour of the ver.dll
            if((wPad1) && (wPad1>=*pwTrash)) {
                wValue -= *pwTrash;
            } else *pwTrash = 0;
            // Fix up the Value len field. We will put the len of the value without padding
            // The len will be in char so since the string is unicode will be twice the size
            memcpy( pBlockSize+2, &wFixUp, 2);
        }
    } else {
        // it is an array, just copy it in the new image buffer
        wValue = ver.wValueLen;
        if (*pdwSize>=(int)ver.wValueLen) {
            memcpy(*lplpImage+wHead+wPad, ver.pValue, ver.wValueLen);
            *pdwSize -= ver.wValueLen;
            lpNewImage += ver.wValueLen;
        }

        // Check if padding is needed
        if ((Pad4(ver.wValueLen)) && (*pdwSize>=(int)Pad4(ver.wValueLen))) {
            memset( *lplpImage+ver.wHead+ver.wValueLen+wPad, 0, Pad4(ver.wValueLen) );
            *pdwSize -= Pad4(ver.wValueLen);
            lpNewImage += Pad4(ver.wValueLen);
        }
        wPad += Pad4(ver.wValueLen);
    }

    *lplpBlockSize = pBlockSize;
    *lplpImage = lpNewImage;
    return wPad+wValue+wHead;
}


/*
 * Will return the matching LPRESITEM
 */
 LPRESITEM
GetItem( BYTE far * lpBuf, LONG dwNewSize, LPSTR lpStr )
{
    LPRESITEM lpResItem = (LPRESITEM) lpBuf;

    while(strcmp(lpResItem->lpszClassName, lpStr)) {
        lpBuf += lpResItem->dwSize;
        dwNewSize -= lpResItem->dwSize;
        if (dwNewSize<=0)
            return LPNULL;
        lpResItem = (LPRESITEM) lpBuf;
    }
    return lpResItem;
}


UINT
UpdateVerst( LPVOID lpNewBuf, LONG dwNewSize,
             LPVOID lpOldI, LONG dwOldImageSize,
             LPVOID lpNewI, DWORD* pdwNewImageSize )
{
    /*
     * This Function is a big mess. It is like this because the RC compiler generate
     * some inconsistent code so we have to do a lot of hacking to get the VS working
     * In future, if ever ver.dll and the RC compiler will be fixed will be possible
     * fix some of the bad thing we have to do to get the updated VS as consistent as
     * possible with the old one
     */

    UINT uiError = ERROR_NO_ERROR;

    LONG dwNewImageSize = *pdwNewImageSize;
    BYTE far * lpNewImage = (BYTE far *) lpNewI;

    BYTE far * lpOldImage = (BYTE far *) lpOldI;

    BYTE far * lpBuf = (BYTE far *) lpNewBuf;
    LPRESITEM lpResItem = LPNULL;

    WORD wPos = 0;

    // Updated info
    WORD wUpdPos = 0;
    char szCaption[300];
    char szUpdCaption[300];
    char szUpdKey[100];

    DWORD dwOriginalOldSize = dwOldImageSize;
    LONG dwOverAllSize = 0l;

    WORD wPad = 0;

    // Pointer to the block size to fix up later
    BYTE far * lpVerBlockSize = LPNULL;
    BYTE far * lpSFIBlockSize = LPNULL;
    BYTE far * lpTrnBlockSize = LPNULL;
    BYTE far * lpStrBlockSize = LPNULL;
    BYTE far * lpTrnBlockName = LPNULL;
    BYTE far * lpDummy = LPNULL;

    LONG dwDummySize;

    WORD wVerBlockSize = 0;
    WORD wSFIBlockSize = 0;
    WORD wTrnBlockSize = 0;
    WORD wStrBlockSize = 0;
    WORD wTrash = 0;        // we need this to fix a bug in the RC compiler
    WORD wDefaultLang = 0x0409;

    // StringFileInfo
    VER_BLOCK SFI;   // StringFileInfo
    LONG lSFILen = 0;

    // Translation blocks
    VER_BLOCK Trn;
    LONG lTrnLen = 0;
    BOOL bHasTranslation=(NULL != GetItem( lpBuf, dwNewSize, "Translation"));
    BOOL bTrnBlockFilled=FALSE;

    VER_BLOCK Str;   // Strings

    // we read first of all the information from the VS_VERSION_INFO block
    VER_BLOCK VS_INFO; // VS_VERSION_INFO

    int iHeadLen = GetVSBlock( &lpOldImage, &dwOldImageSize, &VS_INFO );

    // Write the block in the new image
    wVerBlockSize = (WORD)PutVSBlock( &lpNewImage, &dwNewImageSize, VS_INFO,
                                &VS_INFO.szValue[0], &lpVerBlockSize, &wTrash );

    dwOverAllSize = wVerBlockSize+wTrash;

    LONG lVS_INFOLen = VS_INFO.wBlockLen - iHeadLen;

    while(dwOldImageSize>0) {
        //Get the StringFileInfo
        iHeadLen = GetVSBlock( &lpOldImage, &dwOldImageSize, &SFI );

        // Check if this is the StringFileInfo field
        if (!strcmp(SFI.szKey, "StringFileInfo")) {
            bTrnBlockFilled=TRUE;
            // Read all the translation blocks
            lSFILen = SFI.wBlockLen-iHeadLen;
            // Write the block in the new image
            wSFIBlockSize = (WORD)PutVSBlock( &lpNewImage, &dwNewImageSize, SFI,
                                         &SFI.szValue[0], &lpSFIBlockSize, &wTrash );
            dwOverAllSize += wSFIBlockSize+wTrash;

            while(lSFILen>0) {
                // Read the Translation block
                iHeadLen = GetVSBlock( &lpOldImage, &dwOldImageSize, &Trn );
                // Calculate the right key name
                if ((lpResItem = GetItem( lpBuf, dwNewSize, Trn.szKey)) && bHasTranslation)  {
                	// We default to UNICODE for the 32 bit files
                    WORD wLang;
                    if(lpResItem)
                    {
                        if (lpResItem->dwLanguage != 0xffffffff)
                        {
                            wLang = LOWORD(lpResItem->dwLanguage);
                        }
                        else
                        {
                            wLang = wDefaultLang;
                        }
                    }
                    GenerateTransField( wLang, &Trn );

                    // Save the position for later Fixup
                    lpTrnBlockName = lpNewImage;
                }
                // Write the block in the new image
                wTrnBlockSize = (WORD)PutVSBlock( &lpNewImage, &dwNewImageSize, Trn,
                                             &Trn.szValue[0], &lpTrnBlockSize, &wTrash );
                dwOverAllSize += wTrnBlockSize+wTrash;
                lTrnLen = Trn.wBlockLen-iHeadLen;
                while(lTrnLen>0) {
                    // Read the Strings in the block
                    iHeadLen = GetVSBlock( &lpOldImage, &dwOldImageSize, &Str );
                    lTrnLen -= iHeadLen;
                    TRACE2("Key: %s\tValue: %s\n", Str.szKey, Str.szValue );
                    TRACE3("Len: %d\tValLen: %d\tType: %d\n", Str.wBlockLen, Str.wValueLen, Str.wType );

                    strcpy(szCaption, Str.szValue);
                    // Check if this Item has been updated
                    if ((lpResItem = GetItem( lpBuf, dwNewSize, Str.szKey)))  {
                        strcpy( szUpdCaption, lpResItem->lpszCaption );
                        strcpy( szUpdKey, lpResItem->lpszClassName );
                    }
                    if (!strcmp( szUpdKey, Str.szKey)) {
                        strcpy( szCaption, szUpdCaption );
                        wUpdPos = 0;
                    }

                    // Write the block in the new image
                    wStrBlockSize = (WORD)PutVSBlock( &lpNewImage, &dwNewImageSize, Str,
                                                 szCaption, &lpStrBlockSize, &wTrash );
                    dwOverAllSize += wStrBlockSize+wTrash;

                    // Fix up the size of the block
                    if (dwNewImageSize>=0)
                        memcpy( lpStrBlockSize, &wStrBlockSize, 2);

                    wTrnBlockSize += wStrBlockSize + wTrash;
                }
                lSFILen -= Trn.wBlockLen;
                // Fix up the size of the block
                if (dwNewImageSize>=0)
                    memcpy( lpTrnBlockSize, &wTrnBlockSize, 2);

                wSFIBlockSize += wTrnBlockSize;
            }
            lVS_INFOLen -= SFI.wBlockLen;
            // Fix up the size of the block
            if (dwNewImageSize>=0)
                memcpy( lpSFIBlockSize, &wSFIBlockSize, 2);
            wVerBlockSize += wSFIBlockSize;

        } else {
            // this is another block skip it all
            lVS_INFOLen -= SFI.wValueLen+iHeadLen;


            // Check if this block is the translation field
            if (!strcmp(SFI.szKey, "Translation")) {
                // it is calculate the right value to place in the value field
                // We calculate automatically the value to have the correct
                // localized language in the translation field
                //wVerBlockSize += PutTranslation( &lpNewImage, &dwNewImageSize, SFI );
                // check if this is the translation block
                // This is the translation block let the localizer have it for now

                //
                // We do generate the Tranlsation filed from the language
                // We will have to update the block name as well
                //

                DWORD dwCodeLang = 0;
                if ((lpResItem = GetItem( lpBuf, dwNewSize, SFI.szKey)))
                {
                    WORD wLang = 0x0409;
                    if(lpResItem)
                        wLang = (LOWORD(lpResItem->dwLanguage)!=0xffff ? LOWORD(lpResItem->dwLanguage) : 0x0409);
                    dwCodeLang = GenerateTransField(wLang, FALSE);

                    if (bTrnBlockFilled)
                    {
                        // fix up the block name
                        GenerateTransField( wLang, &Trn );

                        // Write the block in the new image
                        dwDummySize = dwNewImageSize;
                        PutVSBlock( &lpTrnBlockName, &dwDummySize, Trn,
                                             &Trn.szValue[0], &lpDummy, &wTrash );

                        // Fix up the block size
                        memcpy( lpTrnBlockSize, &wTrnBlockSize, 2);
                    }
                    else
                    {
                        wDefaultLang = LOWORD(dwCodeLang);
                    }
                } else {
                    // Place the original value here
                    dwCodeLang =(DWORD)*(SFI.pValue);
                }
                LONG lDummy = 4;
                SFI.pValue -= PutDWord( &SFI.pValue, dwCodeLang, &lDummy );
            }

            // Write the block in the new image
            wVerBlockSize += (WORD)PutVSBlock( &lpNewImage, &dwNewImageSize, SFI,
                                         &SFI.szValue[0], &lpDummy, &wTrash );
            if (dwNewImageSize>=0)
                memcpy( lpVerBlockSize, &wVerBlockSize, 2);

            dwOverAllSize = wVerBlockSize+wTrash;
        }
    }

    // fix up the block size
    if (dwNewImageSize>=0)
        memcpy( lpVerBlockSize, &wVerBlockSize, 2);

    if (dwOverAllSize>(LONG)*pdwNewImageSize) {
        // calc the padding as well
        BYTE bPad = (BYTE)Pad16((DWORD)(dwOverAllSize));
        dwOverAllSize += bPad;
        *pdwNewImageSize = dwOverAllSize;
        return uiError;
    }

    *pdwNewImageSize = *pdwNewImageSize-dwNewImageSize;

    if(*pdwNewImageSize>0) {
        // calculate padding
        BYTE bPad = (BYTE)Pad16((DWORD)(*pdwNewImageSize));
        if (bPad>dwNewImageSize) {
            *pdwNewImageSize += bPad;
            return uiError;
        }
        memset(lpNewImage, 0x00, bPad);
        *pdwNewImageSize += bPad;
    }

    return uiError;
}

UINT GetStringU( PWCHAR pwStr, LPSTR pszStr )
{
    PWCHAR pwStart = pwStr;
    while (*pwStr!=0x0000) {
        *(pszStr++) = LOBYTE(*(pwStr++));
    }
    *(pszStr++) = LOBYTE(*(pwStr++));
    return (UINT)(pwStr-pwStart);
}


UINT
SkipByte( BYTE far * far * lplpBuf, UINT uiSkip, LONG* pdwSize )
{
    if(*pdwSize>=(int)uiSkip) {
        *lplpBuf += uiSkip;;
        *pdwSize -= uiSkip;
    }
    return uiSkip;
}


BYTE
GetDWord( BYTE far * far* lplpBuf, DWORD* dwValue, LONG* pdwSize )
{
    if (*pdwSize>=sizeofDWord){
        memcpy( dwValue, *lplpBuf, sizeofDWord);
        *lplpBuf += sizeofDWord;
        *pdwSize -= sizeofDWord;
    } else *dwValue = 0;
    return sizeofDWord;
}


BYTE
GetWord( BYTE far * far* lplpBuf, WORD* wValue, LONG* pdwSize )
{
    if (*pdwSize>=sizeofWord){
        memcpy( wValue, *lplpBuf, sizeofWord);
        *lplpBuf += sizeofWord;
        *pdwSize -= sizeofWord;
    } else *wValue = 0;
    return sizeofWord;
}


BYTE
GetByte( BYTE far * far* lplpBuf, BYTE* bValue, LONG* pdwSize )
{
    if (*pdwSize>=sizeofByte){
        memcpy(bValue, *lplpBuf, sizeofByte);
        *lplpBuf += sizeofByte;
        *pdwSize -= sizeofByte;
    } else *bValue = 0;
    return sizeofByte;
}


UINT
GetStringW( BYTE far * far* lplpBuf, LPSTR lpszText, LONG* pdwSize, WORD cLen )
{
    if(*lplpBuf==NULL)
        return 0;

    int cch = _WCSLEN((WCHAR*)*lplpBuf);
    if (*pdwSize>=cch){
    _WCSTOMBS( lpszText, (WCHAR*)*lplpBuf, cLen );
    *lplpBuf += (cch*sizeofWord);
        *pdwSize -= (cch*sizeofWord);
    } else *lplpBuf = '\0';
    return(cch*2);
}


UINT
GetStringA( BYTE far * far* lplpBuf, LPSTR lpszText, LONG* pdwSize )
{
    if(*lplpBuf==NULL)
        return 0;

    int iSize = strlen((char*)*lplpBuf)+1;
    if (*pdwSize>=iSize){
        memcpy( lpszText, *lplpBuf, iSize);
        *lplpBuf += iSize;
        *pdwSize -= iSize;
    } else *lplpBuf = '\0';
    return iSize;
}


UINT
GetPascalString( BYTE far * far* lplpBuf, LPSTR lpszText, WORD wMaxLen, LONG* pdwSize )
{
    // Get the length of the string
    WORD wstrlen = 0;
    WORD wMBLen = 0;
    GetWord( lplpBuf, &wstrlen, pdwSize );

    if ((wstrlen+1)>wMaxLen) {
        *pdwSize -= wstrlen*2;
        *lplpBuf += wstrlen*2;
    } else {
        if (wstrlen) {
	        WCHAR* lpwszStr = new WCHAR[wstrlen+1];
	        if (!lpwszStr)
	            *pdwSize =-1;
	        else {
	        	memcpy(lpwszStr, *lplpBuf, (wstrlen*2));
	        	*(lpwszStr+wstrlen) = 0;
	        	
                if(lstrlenW(lpwszStr) < wstrlen)
                {
                    // We have at least one \0 in the string.
                    // This is done to convert \0 in the string in to \\0
                    // First pass check how many \0 we have
                    int c = wstrlen;
                    int czero = 0;
                    while(c)
                    {
                        c--;
                        if((WORD)*(lpwszStr+c)==0)
                        {
                            czero++;
                        }
                    }

                    // Now that we have the size reallocate the buffer
                    delete lpwszStr;
                    if ((wstrlen+czero*_NULL_TAG_LEN_+1)>wMaxLen) {
                        *pdwSize -= wstrlen*2;
                        *lplpBuf += wstrlen*2;
                    }
                    else {
                        WCHAR* lpwszStr = new WCHAR[wstrlen+czero*_NULL_TAG_LEN_+1];
                        if (!lpwszStr)
	                        *pdwSize =-1;
	                    else {
                            int clen = 0;
                            c = 0;
                            WCHAR* lpwStr = (WCHAR*)*lplpBuf;
                            WCHAR* lpwStrW = lpwszStr;
                            while(c<wstrlen)
                            {
                                if((WORD)*(lpwStr+c)==0)
                                {
                                    memcpy(lpwStrW, _W_RLT_NULL_, (_NULL_TAG_LEN_*2));
                                    lpwStrW += _NULL_TAG_LEN_;
                                    clen += _NULL_TAG_LEN_-1;
                                }
                                else
                                    *lpwStrW++ = *(lpwStr+c);

                                clen++;
                                c++;
                            }

                            *(lpwszStr+clen) = 0;
                            wMBLen = (WORD)_WCSTOMBS( lpszText, (WCHAR*)lpwszStr, wMaxLen);
                            delete lpwszStr;
                        }
                    }
                }
                else
                {
	            	wMBLen = (WORD)_WCSTOMBS( lpszText, (WCHAR*)lpwszStr, wMaxLen);
                    delete lpwszStr;
                }

	        }
        }
        *(lpszText+wMBLen) = 0;
        *lplpBuf += wstrlen*2;
        *pdwSize -= wstrlen*2;
    }
    return(wstrlen+1);
}


UINT
PutMsgStr( BYTE far * far* lplpBuf, LPSTR lpszText, WORD wFlags, LONG* pdwSize )
{
    // Put the length of the entry
    UINT uiLen = strlen(lpszText)+1;

    //for unicode string;
    WCHAR* lpwszStr = new WCHAR[uiLen*2];

    if(wFlags && uiLen)
         uiLen = _MBSTOWCS(lpwszStr, lpszText, uiLen*sizeofWord)*sizeofWord;

    UINT uiPad = Pad4(uiLen);
    UINT uiWrite = PutWord(lplpBuf, (WORD) uiLen+4+uiPad, pdwSize);

    // Write the flag
    uiWrite += PutWord(lplpBuf, wFlags, pdwSize);

    // Write the string
    if (*pdwSize>=(int) uiLen)
        if (uiLen){
            if (wFlags)
                memcpy(*lplpBuf, lpwszStr, uiLen);
            else
                memcpy(*lplpBuf, lpszText, uiLen);

            *lplpBuf += uiLen;
            *pdwSize -= uiLen;
            uiWrite += uiLen;
        }
     else
        *pdwSize = -1;

    // Padding
    while(uiPad) {
        uiWrite += PutByte(lplpBuf, 0, pdwSize);
        uiPad--;
    }

    delete lpwszStr;
    return uiWrite;
}


UINT
GetMsgStr( BYTE far * far* lplpBuf, LPSTR lpszText, WORD wMaxLen, WORD* pwLen, WORD* pwFlags, LONG* pdwSize )
{

    // Get the length of the entry
    UINT uiRead = GetWord( lplpBuf, pwLen, pdwSize );

    // Get the flag
    uiRead += GetWord( lplpBuf, pwFlags, pdwSize );

    if (!*pwLen)
        return 0;

    // If flags=1 then the string is a unicode str else is ASCII
    // Bug #354 We cannot assume the string is NULL terminated.
    // There is no specification if the string is a NULL terminated string but since
    // the doc say that the format is similar to the stringtable then
    // we have to assume the string is not NULL terminated

    WORD wstrlen = *pwLen-4; // Get the len of the entry and subtract 4 (len + flag)
    WORD wMBLen = 0;
    if ((wstrlen+1)>wMaxLen) {
    } else {
        if (wstrlen && *pwFlags) {
            wMBLen = (WORD)_WCSTOMBS( lpszText, (WCHAR*)*lplpBuf, wMaxLen );
        } else memcpy( lpszText, (char*)*lplpBuf, wstrlen );

        *(lpszText+(wstrlen)) = 0;
        TRACE1("Caption: %Fs\n", (wstrlen<256 ? lpszText : "\n"));
    }
    *lplpBuf += *pwLen-uiRead;
    *pdwSize -= *pwLen-uiRead;

    return(wstrlen);
}



UINT
GetNameOrOrd( BYTE far * far* lplpBuf,  WORD* wOrd, LPSTR lpszText, LONG* pdwSize )
{
    UINT uiSize = 0;

    if(*lplpBuf==NULL)
        return 0;

    *wOrd = (WORD)(((**lplpBuf)<<8)+(*(*lplpBuf+1)));
    if((*wOrd)==0xFFFF) {
        // This is an Ordinal
        uiSize += GetWord( lplpBuf, wOrd, pdwSize );
        uiSize += GetWord( lplpBuf, wOrd, pdwSize );
        *lpszText = '\0';
    } else {
        uiSize += GetStringW( lplpBuf, lpszText, pdwSize, 128 );
        *wOrd = 0;
    }
    return uiSize;
}


UINT
GetCaptionOrOrd( BYTE far * far* lplpBuf,  WORD* wOrd, LPSTR lpszText, LONG* pdwSize,
	WORD wClass, DWORD dwStyle )
{
    UINT uiSize = 0;

    if(*lplpBuf==NULL)
        return 0;

    *wOrd = (WORD)(((**lplpBuf)<<8)+(*(*lplpBuf+1)));
    if((*wOrd)==0xFFFF) {
        // This is an Ordinal
        uiSize += GetWord( lplpBuf, wOrd, pdwSize );
        uiSize += GetWord( lplpBuf, wOrd, pdwSize );
        *lpszText = '\0';
    } else {
        uiSize += GetStringW( lplpBuf, lpszText, pdwSize, MAXSTR );
        *wOrd = 0;
    }
    return uiSize;
}


UINT
GetClassName( BYTE far * far* lplpBuf,  WORD* wClass, LPSTR lpszText, LONG* pdwSize )
{
    UINT uiSize = 0;

    if(*lplpBuf==NULL)
        return 0;

    *wClass = (WORD)(((**lplpBuf)<<8)+(*(*lplpBuf+1)));
    if( *wClass==0xFFFF ) {
        // This is an Ordinal
        uiSize += GetWord( lplpBuf, wClass, pdwSize );
        uiSize += GetWord( lplpBuf, wClass, pdwSize );
        *lpszText = '\0';
    } else {
        uiSize += GetStringW( lplpBuf, lpszText, pdwSize, 128 );
        *wClass = 0;
    }
    return uiSize;
}

 LONG ReadFile(CFile* pFile, UCHAR * pBuf, LONG lRead)
{
    LONG lLeft = lRead;
    WORD wRead = 0;
    DWORD dwOffset = 0;

    while(lLeft>0){
        wRead =(WORD) (32738ul < lLeft ? 32738: lLeft);
        if (wRead!=_lread( (HFILE)pFile->m_hFile, (UCHAR *)pBuf+dwOffset, wRead))
            return 0l;
        lLeft -= wRead;
        dwOffset += wRead;
    }
    return dwOffset;

}

 UINT CopyFile( CFile* pfilein, CFile* pfileout )
{
    LONG lLeft = pfilein->GetLength();
    WORD wRead = 0;
    DWORD dwOffset = 0;
    BYTE far * pBuf = (BYTE far *) new BYTE[32739];

    if(!pBuf)
        return ERROR_NEW_FAILED;

    while(lLeft>0){
        wRead =(WORD) (32738ul < lLeft ? 32738: lLeft);
        if (wRead!= pfilein->Read( pBuf, wRead))
            return ERROR_FILE_READ;
        pfileout->Write( pBuf, wRead );
        lLeft -= wRead;
        dwOffset += wRead;
    }

    delete []pBuf;
    return ERROR_NO_ERROR;
}

 UINT GetRes(
                 BYTE far * far* lplpBuffer,
                 UINT* puiBufSize,
                 WORD* wTypeId, LPSTR lplpszTypeId,
                 WORD* wNameId, LPSTR lplpszNameId,
                 DWORD* dwLang, DWORD* dwSize, DWORD* dwFileOffset )
{
    UINT uiSize = 0l;
	LONG lSize = *puiBufSize;

    uiSize = GetWord( lplpBuffer, wTypeId, (LONG*)&lSize );
    uiSize += GetStringA( lplpBuffer, lplpszTypeId, (LONG*)&lSize );
	uiSize += SkipByte( lplpBuffer, Pad4(uiSize), (LONG*)&lSize );

    uiSize += GetWord( lplpBuffer, wNameId, (LONG*)&lSize );
    uiSize += GetStringA( lplpBuffer, lplpszNameId, (LONG*)&lSize );
	uiSize += SkipByte( lplpBuffer, Pad4(uiSize), (LONG*)&lSize );

    uiSize += GetDWord( lplpBuffer, dwLang, (LONG*)&lSize );

    uiSize += GetDWord( lplpBuffer, dwSize, (LONG*)&lSize );

    uiSize += GetDWord( lplpBuffer, dwFileOffset, (LONG*)&lSize );

	*puiBufSize = lSize;
    return uiSize;
}

 UINT GetUpdatedRes(
                 BYTE far * far* lplpBuffer,
                 UINT* puiBufSize,
                 WORD* wTypeId, LPSTR lplpszTypeId,
                 WORD* wNameId, LPSTR lplpszNameId,
                 DWORD* dwLang, DWORD* dwSize )
{
    UINT uiSize = 0l;
	LONG lSize = *puiBufSize;

    uiSize = GetWord( lplpBuffer, wTypeId, (LONG*)&lSize );
    uiSize += GetStringA( lplpBuffer, lplpszTypeId, (LONG*)&lSize );
	uiSize += SkipByte( lplpBuffer, Pad4(uiSize), (LONG*)&lSize );

    uiSize += GetWord( lplpBuffer, wNameId, (LONG*)&lSize );
    uiSize += GetStringA( lplpBuffer, lplpszNameId, (LONG*)&lSize );
	uiSize += SkipByte( lplpBuffer, Pad4(uiSize), (LONG*)&lSize );

    uiSize += GetDWord( lplpBuffer, dwLang, (LONG*)&lSize );

    uiSize += GetDWord( lplpBuffer, dwSize, (LONG*)&lSize );

	*puiBufSize = lSize;

    return 0;
}


UINT
PutClassName( BYTE far * far* lplpBuf,  WORD wClass, LPSTR lpszText, LONG* pdwSize )
{
    UINT uiSize = 0;

    if( (wClass==0x0080) ||
        (wClass==0x0081) ||
        (wClass==0x0082) ||
        (wClass==0x0083) ||
        (wClass==0x0084) ||
        (wClass==0x0085)
        ) {
        // This is an Ordinal
        uiSize += PutWord(lplpBuf, 0xFFFF, pdwSize);
        uiSize += PutWord(lplpBuf, wClass, pdwSize);
    } else {
        uiSize += PutStringW(lplpBuf, lpszText, pdwSize);
    }
    return uiSize;
}


UINT
PutPascalStringW( BYTE far * far* lplpBuf, LPSTR lpszText, WORD wLen, LONG* pdwSize )
{
	UINT uiSize = 0;
    WCHAR * pWStrBuf = (WCHAR*)&wszUpdCaption;
  	// calculate the necessary lenght
	WORD wWCLen = (WORD)_MBSTOWCS( pWStrBuf, lpszText, 0 );
	
    if(wWCLen>MAXSTR)
    {
        // Allocate a new buffer
        pWStrBuf = new WCHAR[wWCLen+1];
    }

    WCHAR * pWStr = pWStrBuf;

    // convert the string for good
    wLen = _MBSTOWCS( pWStr, lpszText, wWCLen )-1;

    WCHAR * wlpRltNull = pWStr;
    WCHAR * wlpStrEnd = pWStr+wLen;

    // First of all check for _RLT32_NULL_ tag
    while((wlpRltNull = wcsstr(wlpRltNull, _W_RLT_NULL_)) && (wlpStrEnd>=wlpRltNull))
    {
        // remove the null tag and place \0
        *wlpRltNull++ = 0x0000;
        wlpRltNull = (WCHAR*)memmove(wlpRltNull, wlpRltNull+_NULL_TAG_LEN_-1, (short)(wlpStrEnd-(wlpRltNull+_NULL_TAG_LEN_-1))*2 );
        wlpStrEnd -= (_NULL_TAG_LEN_-1);
    }

    wLen = (WORD)(wlpStrEnd-pWStr);

	// We will use the buffer provided by the szUpdCaption string to calculate
	// the necessary lenght
	//wWCLen = _MBSTOWCS( (WCHAR*)&szUpdCaption, lpszText, 0 ) - 1;
	//if (wWCLen>1)
	//	wLen = wWCLen;
	uiSize = PutWord( lplpBuf, wLen, pdwSize );
	
    if (*pdwSize>=(int)(wLen*2)){
        if(wLen) {
        	//wLen = _MBSTOWCS( (WCHAR*)*lplpBuf, lpszText, wWCLen );
            memcpy(*lplpBuf, pWStr, wLen*2);
        }
        *lplpBuf += wLen*2;
        *pdwSize -= wLen*2;
    } else *pdwSize = -1;

    if(pWStrBuf!=(WCHAR*)&wszUpdCaption)
        delete pWStrBuf;

    return uiSize+(wWCLen*2);
}

 void GenerateTransField( WORD wLang, VER_BLOCK * pVer )
{
    // Get the DWORD value
    DWORD dwValue = GenerateTransField( wLang, TRUE );
    char buf[9];


    // Put the value in the string value
    wsprintf( &buf[0], "%08lX", dwValue );

    TRACE3("\t\tGenerateTransField: Old: %s\tNew : %s\t dwValue: %lX\n", pVer->szKey, buf, dwValue );
    // Just check if we are in the right place. Should never have problem
    if(strlen(pVer->szKey)==8) {
        // We have to change the header in the image, not just the szKey field
        // Get the pointer to he begin of the field
        WORD wPad = Pad4(pVer->wHead);
        LONG cbDummy =18;
        BYTE far * pHead = pVer->pValue-pVer->wHead-wPad;
        pHead += 6; // Move at the begin of the string
        PutStringW(&pHead, buf, &cbDummy);
    }
}

 DWORD GenerateTransField(WORD wLang, BOOL bMode)
{
    // we have to generate a table to connect
    // the language with the correct code page

    WORD wCP = 1200;        // Unicode

    if (bMode)
    	return MAKELONG( wCP, wLang );
    else return MAKELONG( wLang, wCP );
}

 LONG Allign( LPLPBYTE lplpBuf, LONG* plBufSize, LONG lSize )
{
   LONG lRet = 0;
   BYTE bPad =(BYTE)PadPtr(lSize);
   lRet = bPad;
   if (bPad && *plBufSize>=bPad) {
      while(bPad && *plBufSize)  {
         **lplpBuf = 0x00;
         *lplpBuf += 1;
         *plBufSize -= 1;
         bPad--;
      }
   }
   return lRet;
}

UINT
ParseEmbeddedFile( LPVOID lpImageBuf, DWORD dwISize,  LPVOID lpBuffer, DWORD dwSize )
{
	// we will return just one item so the iodll will handle this resource as
	// something valid. We will not bother doing anything else. The only thing
	// we are interesed is the raw data in the immage, but if we don't return at
	// least one item IODLL will consider the resource empty.
	BYTE far * lpBuf = (BYTE far *)lpBuffer;
    LONG dwBufSize = dwSize;
    LONG dwOverAllSize = 0;

	TRACE1("ParseEmbeddedFile: dwISize=%ld\n", dwISize);

	dwOverAllSize += PutDWord( &lpBuf, sizeof(RESITEM), &dwBufSize);

    // We have the size and pos in a cursor but we are not interested now
    dwOverAllSize += PutWord( &lpBuf, (WORD)-1, &dwBufSize);
    dwOverAllSize += PutWord( &lpBuf, (WORD)-1, &dwBufSize);
    dwOverAllSize += PutWord( &lpBuf, (WORD)-1, &dwBufSize);
    dwOverAllSize += PutWord( &lpBuf, (WORD)-1, &dwBufSize);

    // we don't have checksum and style
    dwOverAllSize += PutDWord( &lpBuf, (DWORD)-1, &dwBufSize);
    dwOverAllSize += PutDWord( &lpBuf, (DWORD)-1, &dwBufSize);
    dwOverAllSize += PutDWord( &lpBuf, (DWORD)-1, &dwBufSize);

    //Put the Flag
    dwOverAllSize += PutDWord( &lpBuf, (DWORD)-1, &dwBufSize);

    // The ID will be just 1
    dwOverAllSize += PutDWord( &lpBuf, 1, &dwBufSize);

    // we don't have the resID, and the Type Id
    dwOverAllSize += PutDWord( &lpBuf, (DWORD)-1, &dwBufSize);
    dwOverAllSize += PutDWord( &lpBuf, (DWORD)-1, &dwBufSize);

    // we don't have the language
    dwOverAllSize += PutDWord( &lpBuf, (DWORD)-1, &dwBufSize);

    // we don't have the codepage or the font name
    dwOverAllSize += PutDWord( &lpBuf, (DWORD)-1, &dwBufSize);
    dwOverAllSize += PutWord( &lpBuf, (WORD)-1, &dwBufSize);
    dwOverAllSize += PutWord( &lpBuf, (WORD)-1, &dwBufSize);
    dwOverAllSize += PutWord( &lpBuf, (WORD)-1, &dwBufSize);
    dwOverAllSize += PutByte( &lpBuf, (BYTE)-1, &dwBufSize);
    dwOverAllSize += PutByte( &lpBuf, (BYTE)-1, &dwBufSize);

    // Let's put null were we don;t have the strings
    dwOverAllSize += PutDWordPtr( &lpBuf, 0, &dwBufSize);
    dwOverAllSize += PutDWordPtr( &lpBuf, 0, &dwBufSize);
    dwOverAllSize += PutDWordPtr( &lpBuf, 0, &dwBufSize);
    dwOverAllSize += PutDWordPtr( &lpBuf, 0, &dwBufSize);
    dwOverAllSize += PutDWordPtr( &lpBuf, 0, &dwBufSize);

    // we just return. This is enough for IODLL
    return (UINT)(dwOverAllSize);
}