mirror of https://github.com/tongzx/nt5src
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
749 lines
23 KiB
749 lines
23 KiB
//+---------------------------------------------------------------------------
|
|
//
|
|
// File: mac.cpp
|
|
//
|
|
// Contents: Implementation for the Macintosh Read/Write module
|
|
//
|
|
// History: 23-Aug-94 alessanm created
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
#include <afxwin.h>
|
|
#include <limits.h>
|
|
#include <malloc.h>
|
|
#include "..\common\rwdll.h"
|
|
#include "..\common\m68k.h"
|
|
#include "..\common\helper.h"
|
|
#include "mac.h"
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// Initialization of MFC Extension DLL
|
|
|
|
#include "afxdllx.h" // standard MFC Extension DLL routines
|
|
|
|
static AFX_EXTENSION_MODULE NEAR extensionDLL = { NULL, NULL };
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// General Declarations
|
|
#define RWTAG "MAC"
|
|
|
|
static ULONG gType;
|
|
static ULONG gLng;
|
|
static ULONG gResId;
|
|
static WCHAR gwszResId[256];
|
|
|
|
HINSTANCE g_IODLLInst = 0;
|
|
DWORD (PASCAL * g_lpfnGetImage)(HANDLE, LPCSTR, LPCSTR, DWORD, LPVOID, DWORD);
|
|
DWORD (PASCAL * g_lpfnUpdateResImage)(HANDLE, LPSTR, LPSTR, DWORD, DWORD, LPVOID, DWORD);
|
|
HANDLE (PASCAL * g_lpfnHandleFromName)(LPCSTR);
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// Public C interface implementation
|
|
|
|
//[registration]
|
|
extern "C"
|
|
BOOL FAR PASCAL RWGetTypeString(LPSTR lpszTypeName)
|
|
{
|
|
strcpy( lpszTypeName, RWTAG );
|
|
return FALSE;
|
|
}
|
|
|
|
//=============================================================================
|
|
//
|
|
// To validate a mac res binary file we will walk the resource header and see
|
|
// if it matches with what we have.
|
|
//
|
|
//=============================================================================
|
|
|
|
extern "C"
|
|
BOOL FAR PASCAL RWValidateFileType (LPCSTR lpszFilename)
|
|
{
|
|
BOOL bRet = FALSE;
|
|
TRACE("MAC.DLL: RWValidateFileType()\n");
|
|
|
|
CFile file;
|
|
|
|
// we Open the file to see if it is a file we can handle
|
|
if (!file.Open( lpszFilename, CFile::typeBinary | CFile::modeRead | CFile::shareDenyNone ))
|
|
return bRet;
|
|
|
|
// Check if this is a MAC Resource file ...
|
|
if(IsMacResFile( &file ))
|
|
bRet = TRUE;
|
|
|
|
file.Close();
|
|
return bRet;
|
|
}
|
|
|
|
//=============================================================================
|
|
//
|
|
// We will walk the resource header, walk the resource map and then normalize
|
|
// the Mac it to Windows id and pass this info to the RW.
|
|
//
|
|
//=============================================================================
|
|
|
|
extern "C"
|
|
DllExport
|
|
UINT
|
|
APIENTRY
|
|
RWReadTypeInfo(
|
|
LPCSTR lpszFilename,
|
|
LPVOID lpBuffer,
|
|
UINT* puiSize
|
|
|
|
)
|
|
{
|
|
TRACE("MAC.DLL: RWReadTypeInfo()\n");
|
|
UINT uiError = ERROR_NO_ERROR;
|
|
BYTE far * lpBuf = (BYTE far *)lpBuffer;
|
|
UINT uiBufSize = *puiSize;
|
|
CFile file;
|
|
int iFileNameLen = strlen(lpszFilename)+1;
|
|
|
|
if (!file.Open(lpszFilename, CFile::modeRead | CFile::typeBinary | CFile::shareDenyNone))
|
|
return ERROR_FILE_OPEN;
|
|
|
|
UINT uiBufStartSize = uiBufSize;
|
|
|
|
////////////////////////////////////
|
|
// Check if it is a valid mac file
|
|
|
|
// Is a Mac Resource file ...
|
|
if(IsMacResFile( &file )) {
|
|
// load the file in memory
|
|
// NOTE: WIN16 This might be to expensive in memory allocation
|
|
// on a 16 bit platform
|
|
BYTE * pResources = (BYTE*)malloc(file.GetLength());
|
|
if(!pResources) {
|
|
file.Close();
|
|
return ERROR_NEW_FAILED;
|
|
}
|
|
|
|
file.Seek(0, CFile::begin);
|
|
file.ReadHuge(pResources, file.GetLength());
|
|
|
|
IMAGE_SECTION_HEADER Sect;
|
|
memset(&Sect, 0, sizeof(IMAGE_SECTION_HEADER));
|
|
|
|
ParseResourceFile(pResources, &Sect, (BYTE**)&lpBuffer, (LONG*)puiSize, iFileNameLen);
|
|
free(pResources);
|
|
|
|
*puiSize = uiBufSize - *puiSize;
|
|
file.Close();
|
|
return uiError;
|
|
}
|
|
|
|
file.Close();
|
|
return uiError;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// We will prepend to the image the file name. This will be usefull later on
|
|
// to retrive the dialog item list
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
extern "C"
|
|
DllExport
|
|
DWORD
|
|
APIENTRY
|
|
RWGetImage(
|
|
LPCSTR lpszFilename,
|
|
DWORD dwImageOffset,
|
|
LPVOID lpBuffer,
|
|
DWORD dwSize
|
|
)
|
|
{
|
|
UINT uiError = ERROR_NO_ERROR;
|
|
BYTE far * lpBuf = (BYTE far *)lpBuffer;
|
|
int iNameLen = strlen(lpszFilename)+1;
|
|
DWORD dwBufSize = dwSize - iNameLen;
|
|
// we can consider the use of a CMemFile so we get the same speed as memory access.
|
|
CFile file;
|
|
|
|
// Open the file and try to read the information on the resource in it.
|
|
if (!file.Open(lpszFilename, CFile::modeRead | CFile::typeBinary | CFile::shareDenyNone))
|
|
return (DWORD)ERROR_FILE_OPEN;
|
|
|
|
if ( dwImageOffset!=(DWORD)file.Seek( dwImageOffset, CFile::begin) )
|
|
return (DWORD)ERROR_FILE_INVALID_OFFSET;
|
|
|
|
// copy the file name at the beginning of the buffer
|
|
memcpy((BYTE*)lpBuf, lpszFilename, iNameLen);
|
|
lpBuf = ((BYTE*)lpBuf+iNameLen);
|
|
|
|
if (dwBufSize>UINT_MAX) {
|
|
// we have to read the image in different steps
|
|
return (DWORD)0L;
|
|
} else uiError = file.Read( lpBuf, (UINT)dwBufSize)+iNameLen;
|
|
file.Close();
|
|
|
|
return (DWORD)uiError;
|
|
}
|
|
|
|
extern "C"
|
|
DllExport
|
|
UINT
|
|
APIENTRY
|
|
RWParseImage(
|
|
LPCSTR lpszType,
|
|
LPVOID lpImageBuf,
|
|
DWORD dwImageSize,
|
|
LPVOID lpBuffer,
|
|
DWORD dwSize
|
|
)
|
|
{
|
|
UINT uiError = ERROR_NO_ERROR;
|
|
BYTE * lpBuf = (BYTE *)lpBuffer;
|
|
DWORD dwBufSize = dwSize;
|
|
|
|
|
|
// Remove the filename...
|
|
if( !strcmp(lpszType, "MENU") ||
|
|
!strcmp(lpszType, "STR ") ||
|
|
!strcmp(lpszType, "STR#") ||
|
|
!strcmp(lpszType, "TEXT")
|
|
) {
|
|
int iFileNameLen = strlen((LPSTR)lpImageBuf)+1;
|
|
lpImageBuf = ((BYTE*)lpImageBuf+iFileNameLen);
|
|
dwImageSize -= iFileNameLen;
|
|
}
|
|
|
|
//===============================================================
|
|
// Menus
|
|
if( !strcmp(lpszType, "MENU") )
|
|
return ParseMENU( lpImageBuf, dwImageSize, lpBuffer, dwSize );
|
|
|
|
//===============================================================
|
|
// Dialogs
|
|
if( !strcmp(lpszType, "WDLG") )
|
|
return ParseWDLG( lpImageBuf, dwImageSize, lpBuffer, dwSize );
|
|
|
|
if( !strcmp(lpszType, "DLOG") )
|
|
return ParseDLOG( lpImageBuf, dwImageSize, lpBuffer, dwSize );
|
|
|
|
if( !strcmp(lpszType, "ALRT") )
|
|
return ParseALRT( lpImageBuf, dwImageSize, lpBuffer, dwSize );
|
|
|
|
//===============================================================
|
|
// Strings
|
|
if( !strcmp(lpszType, "STR ") )
|
|
return ParseSTR( lpImageBuf, dwImageSize, lpBuffer, dwSize );
|
|
|
|
if( !strcmp(lpszType, "STR#") )
|
|
return ParseSTRNUM( lpImageBuf, dwImageSize, lpBuffer, dwSize );
|
|
|
|
if( !strcmp(lpszType, "TEXT") )
|
|
return ParseTEXT( lpImageBuf, dwImageSize, lpBuffer, dwSize );
|
|
|
|
if( !strcmp(lpszType, "WIND") )
|
|
return ParseWIND( lpImageBuf, dwImageSize, lpBuffer, dwSize );
|
|
|
|
return uiError;
|
|
}
|
|
|
|
extern"C"
|
|
DllExport
|
|
UINT
|
|
APIENTRY
|
|
RWWriteFile(
|
|
LPCSTR lpszSrcFilename,
|
|
LPCSTR lpszTgtFilename,
|
|
HANDLE hResFileModule,
|
|
LPVOID lpBuffer,
|
|
UINT uiSize,
|
|
HINSTANCE hDllInst,
|
|
LPCSTR lpszSymbolPath
|
|
)
|
|
{
|
|
TRACE("RWMAC.DLL: Source: %s\t Target: %s\n", lpszSrcFilename, lpszTgtFilename);
|
|
UINT uiError = ERROR_NO_ERROR;
|
|
PUPDATEDRESLIST pUpdList = LPNULL;
|
|
|
|
// Get the handle to the IODLL
|
|
if(InitIODLLLink())
|
|
hDllInst = g_IODLLInst;
|
|
else return ERROR_DLL_LOAD;
|
|
|
|
CFile fileIn;
|
|
CFile fileOut;
|
|
|
|
if (!fileIn.Open(lpszSrcFilename, CFile::modeRead | CFile::typeBinary | CFile::shareDenyNone))
|
|
return (DWORD)ERROR_FILE_OPEN;
|
|
|
|
if (!fileOut.Open(lpszTgtFilename, CFile::modeWrite | CFile::typeBinary))
|
|
return (DWORD)ERROR_FILE_OPEN;
|
|
|
|
MACRESHEADER fileHeader;
|
|
// Read the header of the file...
|
|
fileIn.Read(&fileHeader, sizeof(MACRESHEADER));
|
|
|
|
// allocate a buffer to hold the new resource map
|
|
// The buffer will be as big as the other one since there is no
|
|
// need, for now, to support the adding of resource
|
|
LONG lMapSize = MacLongToLong(fileHeader.mulSizeOfResMap);
|
|
BYTE * pNewMap = (BYTE*)malloc(lMapSize);
|
|
|
|
if(!pNewMap) {
|
|
uiError = ERROR_NEW_FAILED;
|
|
goto exit;
|
|
}
|
|
{ // This is for the goto. Check error:C2362
|
|
|
|
PUPDATEDRESLIST pListItem = LPNULL;
|
|
// Create the list of update resource
|
|
pUpdList = UpdatedResList( lpBuffer, uiSize );
|
|
|
|
// set the map buffer to 0 ...
|
|
memset(pNewMap, 0, lMapSize);
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
// Read each resource from the resource map and check if the resource has been
|
|
// updated. If it has been updated, get the new resource image. Otherwise use
|
|
// the original resource data.
|
|
// Write the resource data in the Tgt file and write the info on the offset etc.
|
|
// in the pNewMap buffer so, when all the resources have been read and written
|
|
// the only thing left is to fix up some sizes and to write the buffer to disk.
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Write the resource header in the Tgt file
|
|
fileOut.Write(&fileHeader, sizeof(MACRESHEADER));
|
|
|
|
BYTE * pByte = (BYTE*)malloc(256);
|
|
if(!pByte) {
|
|
uiError = ERROR_NEW_FAILED;
|
|
goto exit;
|
|
}
|
|
|
|
// Copy the Reserved and user data
|
|
fileIn.Read(pByte, 240);
|
|
fileOut.Write(pByte, 240);
|
|
free(pByte);
|
|
|
|
// store the position of the beginning of the res data
|
|
DWORD dwBeginOfResData = fileOut.GetPosition();
|
|
|
|
MACRESMAP resMap;
|
|
// Read the resource map ...
|
|
fileIn.Seek(MacLongToLong(fileHeader.mulOffsetToResMap), CFile::begin);
|
|
fileIn.Read(&resMap, sizeof(MACRESMAP));
|
|
|
|
BYTE * pTypeList = pNewMap+28;
|
|
BYTE * pTypeInfo = pTypeList+2;
|
|
BYTE * pRefList = LPNULL;
|
|
BYTE * pNameList = LPNULL;
|
|
BYTE * pName = LPNULL;
|
|
|
|
DWORD dwOffsetToTypeList = fileIn.GetPosition();
|
|
WORD wType;
|
|
fileIn.Read(&wType, sizeof(WORD));
|
|
memcpy( pNewMap+sizeof(MACRESMAP), &wType, sizeof(WORD)); // number of types - 1
|
|
wType = MacWordToWord((BYTE*)&wType)+1;
|
|
|
|
MACRESTYPELIST TypeList;
|
|
MACRESREFLIST RefList;
|
|
WORD wOffsetToRefList = wType*sizeof(MACRESTYPELIST)+sizeof(WORD);
|
|
DWORD dwOffsetToLastTypeInfo = 0;
|
|
DWORD dwOffsetToLastRefList = 0;
|
|
DWORD dwOffsetToNameList = MacLongToLong(fileHeader.mulOffsetToResMap)+MacWordToWord(resMap.mwOffsetToNameList);
|
|
DWORD dwSizeOfData = 0;
|
|
|
|
while(wType) {
|
|
// Read the type info ...
|
|
fileIn.Read(&TypeList, sizeof(MACRESTYPELIST));
|
|
dwOffsetToLastTypeInfo = fileIn.GetPosition();
|
|
|
|
// ... and update the newmap buffer
|
|
memcpy( pTypeInfo, &TypeList, sizeof(MACRESTYPELIST));
|
|
// Fix up the offset to the ref list
|
|
memcpy(((PMACRESTYPELIST)pTypeInfo)->mwOffsetToRefList, WordToMacWord(wOffsetToRefList), sizeof(WORD));
|
|
pRefList = pTypeList+wOffsetToRefList;
|
|
pTypeInfo = pTypeInfo+sizeof(MACRESTYPELIST);
|
|
|
|
// go to the refence list ...
|
|
fileIn.Seek(dwOffsetToTypeList+MacWordToWord(TypeList.mwOffsetToRefList), CFile::begin);
|
|
|
|
WORD wItems = MacWordToWord(TypeList.mwNumOfThisType)+1;
|
|
while(wItems){
|
|
// and read the reference list for this type
|
|
fileIn.Read( &RefList, sizeof(MACRESREFLIST));
|
|
dwOffsetToLastRefList = fileIn.GetPosition();
|
|
|
|
// is this a named resource ...
|
|
if(MacWordToWord(RefList.mwOffsetToResName)!=0xffff) {
|
|
// read the string
|
|
fileIn.Seek(dwOffsetToNameList+MacWordToWord(RefList.mwOffsetToResName), CFile::begin);
|
|
BYTE bLen = 0;
|
|
fileIn.Read(&bLen, 1);
|
|
if(!pNameList) {
|
|
pName = pNameList = (BYTE*)malloc(1024);
|
|
if(!pNameList) {
|
|
uiError = ERROR_NEW_FAILED;
|
|
goto exit;
|
|
}
|
|
}
|
|
// check the free space we have
|
|
if((1024-((pName-pNameList)%1024))<=bLen+1){
|
|
BYTE * pNew = (BYTE*)realloc(pNameList, _msize(pNameList)+1024);
|
|
if(!pNew) {
|
|
uiError = ERROR_NEW_FAILED;
|
|
goto exit;
|
|
}
|
|
pName = pNew+(pName-pNameList);
|
|
pNameList = pNew;
|
|
}
|
|
|
|
// Update the pointer to the string
|
|
memcpy(RefList.mwOffsetToResName, WordToMacWord((WORD)(pName-pNameList)), 2);
|
|
|
|
memcpy(pName++, &bLen, 1);
|
|
// we have room for the string
|
|
fileIn.Read(pName, bLen);
|
|
|
|
pName = pName+bLen;
|
|
}
|
|
|
|
// check if this item has been updated
|
|
if(pListItem = IsResUpdated(&TypeList.szResName[0], RefList, pUpdList)) {
|
|
// Save the offset to the resource
|
|
DWORD dwOffsetToData = fileOut.GetPosition();
|
|
DWORD dwSize = *pListItem->pSize;
|
|
|
|
// allocate the buffer to hold the resource data
|
|
pByte = (BYTE*)malloc(dwSize);
|
|
if(!pByte){
|
|
uiError = ERROR_NEW_FAILED;
|
|
goto exit;
|
|
}
|
|
|
|
// get the data from the iodll
|
|
LPSTR lpType = LPNULL;
|
|
LPSTR lpRes = LPNULL;
|
|
if (*pListItem->pTypeId) {
|
|
lpType = (LPSTR)((WORD)*pListItem->pTypeId);
|
|
} else {
|
|
lpType = (LPSTR)pListItem->pTypeName;
|
|
}
|
|
if (*pListItem->pResId) {
|
|
lpRes = (LPSTR)((WORD)*pListItem->pResId);
|
|
} else {
|
|
lpRes = (LPSTR)pListItem->pResName;
|
|
}
|
|
|
|
DWORD dwImageBufSize = (*g_lpfnGetImage)( hResFileModule,
|
|
lpType,
|
|
lpRes,
|
|
*pListItem->pLang,
|
|
pByte,
|
|
*pListItem->pSize
|
|
);
|
|
|
|
// Remove the file name from the image
|
|
int iFileNameLen = strlen((LPSTR)pByte)+1;
|
|
dwSize -= iFileNameLen;
|
|
|
|
// write the size of the data block
|
|
fileOut.Write(LongToMacLong(dwSize), sizeof(DWORD));
|
|
dwSizeOfData += dwSize+sizeof(DWORD);
|
|
|
|
fileOut.Write((pByte+iFileNameLen), dwSize);
|
|
|
|
free(pByte);
|
|
|
|
// fix up the offset to the resource in the ref list
|
|
memcpy(RefList.bOffsetToResData, LongToMacOffset(dwOffsetToData-dwBeginOfResData), 3);
|
|
}
|
|
else {
|
|
// Get the data from the Src file
|
|
// get to the data
|
|
fileIn.Seek(MacLongToLong(fileHeader.mulOffsetToResData)+
|
|
MacOffsetToLong(RefList.bOffsetToResData), CFile::begin);
|
|
|
|
// read the size of the data block
|
|
DWORD dwSize = 0;
|
|
fileIn.Read(&dwSize, sizeof(DWORD));
|
|
|
|
// Save the offset to the resource
|
|
DWORD dwOffsetToData = fileOut.GetPosition();
|
|
|
|
// write the size of the data block
|
|
fileOut.Write(&dwSize, sizeof(DWORD));
|
|
dwSizeOfData += sizeof(DWORD);
|
|
|
|
// allocate the buffer to hold the resource data
|
|
dwSizeOfData += dwSize = MacLongToLong((BYTE*)&dwSize);
|
|
pByte = (BYTE*)malloc(dwSize);
|
|
if(!pByte){
|
|
uiError = ERROR_NEW_FAILED;
|
|
goto exit;
|
|
}
|
|
|
|
// copy the data
|
|
fileIn.Read(pByte, dwSize);
|
|
fileOut.Write(pByte, dwSize);
|
|
|
|
free(pByte);
|
|
|
|
// fix up the offset to the resource in the ref list
|
|
memcpy(RefList.bOffsetToResData, LongToMacOffset(dwOffsetToData-dwBeginOfResData), 3);
|
|
|
|
}
|
|
|
|
// return in the right place
|
|
fileIn.Seek(dwOffsetToLastRefList, CFile::begin);
|
|
|
|
// copy this data in the new map buffer
|
|
memcpy(pRefList, &RefList, sizeof(MACRESREFLIST));
|
|
wOffsetToRefList+=sizeof(MACRESREFLIST);
|
|
|
|
// move to the new ref list
|
|
pRefList = pTypeList+wOffsetToRefList;
|
|
wItems--;
|
|
}
|
|
|
|
fileIn.Seek(dwOffsetToLastTypeInfo, CFile::begin);
|
|
wType--;
|
|
}
|
|
|
|
// copy the resource map header info
|
|
memcpy( pNewMap, &resMap, sizeof(MACRESMAP));
|
|
|
|
// copy the name list at the end of the res map
|
|
dwOffsetToNameList = 0;
|
|
if(pNameList) {
|
|
dwOffsetToNameList = (DWORD)(pRefList-pNewMap);
|
|
// copy the name list
|
|
memcpy(pRefList, pNameList, (size_t)(pName-pNameList));
|
|
free(pNameList);
|
|
}
|
|
|
|
// write the resource map
|
|
DWORD dwOffsetToResMap = fileOut.GetPosition();
|
|
fileOut.Write(pNewMap, lMapSize);
|
|
|
|
// We need to fix up the file header ...
|
|
fileOut.Seek(4, CFile::begin);
|
|
fileOut.Write(LongToMacLong(dwOffsetToResMap), sizeof(DWORD));
|
|
fileOut.Write(LongToMacLong(dwSizeOfData), sizeof(DWORD));
|
|
|
|
// ... and the resource map header
|
|
fileOut.Seek(dwOffsetToResMap+4, CFile::begin);
|
|
fileOut.Write(LongToMacLong(dwOffsetToResMap), sizeof(DWORD));
|
|
fileOut.Write(LongToMacLong(dwSizeOfData), sizeof(DWORD));
|
|
|
|
fileOut.Seek(dwOffsetToResMap+26, CFile::begin);
|
|
fileOut.Write(WordToMacWord(LOWORD(dwOffsetToNameList)), sizeof(WORD));
|
|
|
|
|
|
}
|
|
exit:
|
|
fileIn.Close();
|
|
fileOut.Close();
|
|
if(pNewMap)
|
|
free(pNewMap);
|
|
if(pUpdList)
|
|
free(pUpdList);
|
|
|
|
return (UINT)uiError;
|
|
}
|
|
|
|
extern "C"
|
|
DllExport
|
|
UINT
|
|
APIENTRY
|
|
RWUpdateImage(
|
|
LPCSTR lpszType,
|
|
LPVOID lpNewBuf,
|
|
DWORD dwNewSize,
|
|
LPVOID lpOldImage,
|
|
DWORD dwOldImageSize,
|
|
LPVOID lpNewImage,
|
|
DWORD* pdwNewImageSize
|
|
)
|
|
{
|
|
UINT uiError = ERROR_RW_NOTREADY;
|
|
|
|
//===============================================================
|
|
// Since all the Type are named in the mac at this stage we need to
|
|
// know the original name of the Type and not the Windows type.
|
|
// Use the typeID stored in the new ites buffer
|
|
LPSTR lpRealType = ((PRESITEM)lpNewBuf)->lpszTypeID;
|
|
|
|
if(!HIWORD(lpRealType)) // something is wrong if this is not valid
|
|
return uiError;
|
|
|
|
//===============================================================
|
|
// Menus
|
|
if( !strcmp(lpRealType, "MENU") )
|
|
return UpdateMENU( lpNewBuf, dwNewSize, lpOldImage, dwOldImageSize, lpNewImage, pdwNewImageSize );
|
|
|
|
//===============================================================
|
|
// Strings
|
|
if( !strcmp(lpRealType, "STR ") )
|
|
return UpdateSTR( lpNewBuf, dwNewSize, lpOldImage, dwOldImageSize, lpNewImage, pdwNewImageSize );
|
|
|
|
if( !strcmp(lpRealType, "STR#") )
|
|
return UpdateSTRNUM( lpNewBuf, dwNewSize, lpOldImage, dwOldImageSize, lpNewImage, pdwNewImageSize );
|
|
|
|
if( !strcmp(lpRealType, "WIND") )
|
|
return UpdateWIND( lpNewBuf, dwNewSize, lpOldImage, dwOldImageSize, lpNewImage, pdwNewImageSize );
|
|
|
|
//===============================================================
|
|
// Dialogs
|
|
if( !strcmp(lpRealType, "DLOG") )
|
|
return UpdateDLOG( lpNewBuf, dwNewSize, lpOldImage, dwOldImageSize, lpNewImage, pdwNewImageSize );
|
|
if( !strcmp(lpRealType, "ALRT") )
|
|
return UpdateALRT( lpNewBuf, dwNewSize, lpOldImage, dwOldImageSize, lpNewImage, pdwNewImageSize );
|
|
|
|
*pdwNewImageSize = 0L;
|
|
return uiError;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
// Functions implementation
|
|
|
|
//=============================================================================
|
|
// MapToWindowsRes
|
|
//
|
|
// Map a Mac resource name to a Windows resource
|
|
//=============================================================================
|
|
WORD MapToWindowsRes( char * pResName )
|
|
{
|
|
if( !strcmp(pResName, "PICT") ||
|
|
!strcmp(pResName, "WBMP"))
|
|
return 2;
|
|
|
|
if( !strcmp(pResName, "MENU") ||
|
|
!strcmp(pResName, "WMNU"))
|
|
return 4;
|
|
|
|
if( !strcmp(pResName, "DLOG") ||
|
|
!strcmp(pResName, "ALRT") ||
|
|
!strcmp(pResName, "WDLG"))
|
|
return 5;
|
|
|
|
if( !strcmp(pResName, "STR "))
|
|
return STR_TYPE;
|
|
|
|
if( !strcmp(pResName, "STR#") ||
|
|
!strcmp(pResName, "TEXT"))
|
|
return MSG_TYPE;
|
|
|
|
if( !strcmp(pResName, "vers") ||
|
|
!strcmp(pResName, "VERS"))
|
|
return 16;
|
|
|
|
// For the Item list return 17. This means nothing to windows and will
|
|
// give us the flexibility to update the DITL list from the RW, without user
|
|
// input.
|
|
if( !strcmp(pResName, "DITL"))
|
|
return DITL_TYPE;
|
|
|
|
// For the Frame Window Caption mark it as type 18
|
|
if( !strcmp(pResName, "WIND"))
|
|
return WIND_TYPE;
|
|
|
|
return 0;
|
|
}
|
|
|
|
//=============================================================================
|
|
// WriteResInfo
|
|
//
|
|
// Fill the buffer to pass back to the iodll
|
|
//=============================================================================
|
|
|
|
LONG WriteResInfo(
|
|
BYTE** lplpBuffer, LONG* plBufSize,
|
|
WORD wTypeId, LPSTR lpszTypeId, BYTE bMaxTypeLen,
|
|
WORD wNameId, LPSTR lpszNameId, BYTE bMaxNameLen,
|
|
DWORD dwLang,
|
|
DWORD dwSize, DWORD dwFileOffset )
|
|
{
|
|
LONG lSize = 0;
|
|
lSize = PutWord( lplpBuffer, wTypeId, plBufSize );
|
|
lSize += PutStringA( lplpBuffer, lpszTypeId, plBufSize );
|
|
// Check if it is alligned
|
|
lSize += Allign( lplpBuffer, plBufSize, lSize);
|
|
|
|
lSize += PutWord( lplpBuffer, wNameId, plBufSize );
|
|
lSize += PutStringA( lplpBuffer, lpszNameId, plBufSize );
|
|
lSize += Allign( lplpBuffer, plBufSize, lSize);
|
|
|
|
lSize += PutDWord( lplpBuffer, dwLang, plBufSize );
|
|
|
|
lSize += PutDWord( lplpBuffer, dwSize, plBufSize );
|
|
|
|
lSize += PutDWord( lplpBuffer, dwFileOffset, plBufSize );
|
|
|
|
return (LONG)lSize;
|
|
}
|
|
|
|
BOOL InitIODLLLink()
|
|
{
|
|
if(!g_IODLLInst)
|
|
{
|
|
// Init the link with the iodll
|
|
g_IODLLInst = LoadLibrary("iodll.dll");
|
|
if(!g_IODLLInst)
|
|
return FALSE;
|
|
|
|
if((g_lpfnGetImage = (DWORD (PASCAL *)(HANDLE, LPCSTR, LPCSTR, DWORD, LPVOID, DWORD))
|
|
GetProcAddress( g_IODLLInst, "RSGetResImage" ))==NULL)
|
|
return FALSE;
|
|
|
|
if((g_lpfnHandleFromName = (HANDLE (PASCAL *)(LPCSTR))
|
|
GetProcAddress( g_IODLLInst, "RSHandleFromName" ))==NULL)
|
|
return FALSE;
|
|
|
|
if((g_lpfnUpdateResImage = (DWORD (PASCAL *)(HANDLE, LPSTR, LPSTR, DWORD, DWORD, LPVOID, DWORD))
|
|
GetProcAddress( g_IODLLInst, "RSUpdateResImage" ))==NULL)
|
|
return FALSE;
|
|
|
|
|
|
}
|
|
else {
|
|
if(g_lpfnGetImage==NULL || g_lpfnHandleFromName==NULL)
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// DLL Specific code implementation
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// Library init
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// This function should be used verbatim. Any initialization or termination
|
|
// requirements should be handled in InitPackage() and ExitPackage().
|
|
//
|
|
extern "C" int APIENTRY
|
|
DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
|
|
{
|
|
if (dwReason == DLL_PROCESS_ATTACH)
|
|
{
|
|
// NOTE: global/static constructors have already been called!
|
|
// Extension DLL one-time initialization - do not allocate memory
|
|
// here, use the TRACE or ASSERT macros or call MessageBox
|
|
AfxInitExtensionModule(extensionDLL, hInstance);
|
|
}
|
|
else if (dwReason == DLL_PROCESS_DETACH)
|
|
{
|
|
// Terminate the library before destructors are called
|
|
AfxWinTerm();
|
|
|
|
// remove the link with iodll
|
|
if(g_IODLLInst)
|
|
FreeLibrary(g_IODLLInst);
|
|
|
|
}
|
|
|
|
if (dwReason == DLL_PROCESS_DETACH || dwReason == DLL_THREAD_DETACH)
|
|
return 0; // CRT term Failed
|
|
|
|
return 1; // ok
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|