3590 lines
110 KiB
C++
3590 lines
110 KiB
C++
//+---------------------------------------------------------------------------
|
|
//
|
|
// File: iodll.cpp
|
|
//
|
|
// Contents: Implementation for the I/O module
|
|
//
|
|
// Classes:
|
|
//
|
|
// History: 27-May-93 alessanm created
|
|
// 25-Jun-93 alessanm eliminated TRANSCONTEXT and added RESITEM
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
#include <afx.h>
|
|
#include <afxwin.h>
|
|
#include <afxcoll.h>
|
|
#include <iodll.h>
|
|
#include <limits.h>
|
|
#include <memory.h>
|
|
#include <malloc.h>
|
|
#include <stdlib.h>
|
|
#include <dos.h>
|
|
#include <errno.h>
|
|
#include <setjmp.h>
|
|
|
|
//
|
|
// UlongToHandle is defined in basetsd.h now
|
|
//
|
|
// #define UlongToHandle(x) (HANDLE)UlongToPtr(x)
|
|
//
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// Initialization of MFC Extension DLL
|
|
|
|
#include "afxdllx.h" // standard MFC Extension DLL routines
|
|
|
|
static AFX_EXTENSION_MODULE extensionDLL = { NULL, NULL };
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// General Declarations
|
|
#define MODULENAME "iodll.dll"
|
|
#define Pad4(x) ((((x+3)>>2)<<2)-x)
|
|
#define PadPtr(x) ((((x+(sizeof(PVOID)-1))/sizeof(PVOID))*sizeof(PVOID))-x)
|
|
|
|
#define LPNULL 0L
|
|
|
|
// INI Informations
|
|
#define SECTION "iodll32"
|
|
#define MAXENTRYBUF 1024 // Buffer to entry in the INI file
|
|
#define MAXDLLNUM 20 // We hard-code the number of DLL. TO fix later
|
|
|
|
#define MAXKEYLEN 32
|
|
|
|
// HANDLE Informations
|
|
#define FIRSTVALIDVALUE LAST_ERROR // The first valid value for an HANDLE to a module
|
|
|
|
typedef unsigned char UCHAR;
|
|
typedef char * PCHAR;
|
|
typedef UCHAR * PUCHAR;
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// Function Declarations
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// Helper Function Declarations
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// Class declarations
|
|
|
|
class CFileModule;
|
|
|
|
class CItemInfo : public CObject
|
|
{
|
|
public:
|
|
CItemInfo( WORD x, WORD y,
|
|
WORD cx, WORD cy,
|
|
DWORD dwPosId, WORD wPos,
|
|
DWORD dwStyle, DWORD dwExtendStyle,
|
|
CString szText );
|
|
|
|
CItemInfo( LPRESITEM lpResItem, WORD wTabPos );
|
|
|
|
CItemInfo( const CItemInfo &iteminfo );
|
|
|
|
WORD GetId() { return LOWORD(m_dwPosId); }
|
|
CString GetCaption() { return m_szCaption; }
|
|
WORD GetX() { return m_wX; }
|
|
WORD GetY() { return m_wY; }
|
|
WORD GetcX() { return m_wCX; }
|
|
WORD GetcY() { return m_wCY; }
|
|
DWORD GetPosId() {
|
|
if (LOWORD(m_dwPosId)==0xFFFF)
|
|
return GetTabPosId();
|
|
return m_dwPosId;
|
|
}
|
|
DWORD GetStyle() { return m_dwStyle; }
|
|
DWORD GetExtStyle() { return m_dwExtStyle; }
|
|
DWORD GetTabPosId();
|
|
CString GetFaceName() { return m_szFaceName; }
|
|
CString GetClassName() { return m_szClassName; }
|
|
DWORD GetCheckSum() { return m_dwCheckSum; }
|
|
DWORD GetFlags() { return m_dwFlags; }
|
|
DWORD GetCodePage() { return m_dwCodePage; }
|
|
DWORD GetLanguage() { return m_dwLanguage; }
|
|
WORD GetClassNameID(){ return m_wClassName; }
|
|
WORD GetPointSize() { return m_wPointSize; }
|
|
WORD GetWeight() { return m_wWeight; }
|
|
BYTE GetItalic() { return m_bItalic; }
|
|
BYTE GetCharSet() { return m_bCharSet; }
|
|
|
|
|
|
|
|
UINT UpdateData( LPVOID lpbuffer, UINT uiBufSize );
|
|
UINT UpdateData( LPRESITEM lpResItem );
|
|
|
|
void SetPos( WORD wPos );
|
|
void SetId( WORD wId );
|
|
|
|
private:
|
|
|
|
WORD m_wX;
|
|
WORD m_wY;
|
|
|
|
WORD m_wCX;
|
|
WORD m_wCY;
|
|
|
|
DWORD m_dwCheckSum;
|
|
DWORD m_dwStyle;
|
|
DWORD m_dwExtStyle;
|
|
DWORD m_dwFlags;
|
|
|
|
DWORD m_dwPosId;
|
|
WORD m_wTabPos;
|
|
|
|
DWORD m_dwCodePage;
|
|
DWORD m_dwLanguage;
|
|
WORD m_wClassName;
|
|
WORD m_wPointSize;
|
|
WORD m_wWeight;
|
|
BYTE m_bItalic;
|
|
BYTE m_bCharSet;
|
|
|
|
CString m_szClassName;
|
|
CString m_szFaceName;
|
|
CString m_szCaption;
|
|
|
|
};
|
|
|
|
// This class will keep all the information about each of the resources in the file
|
|
class CResInfo : public CObject
|
|
{
|
|
public:
|
|
CResInfo( WORD Typeid, CString sztypeid,
|
|
WORD nameid, CString sznameid,
|
|
DWORD dwlang, DWORD dwsize, DWORD dwfileoffset, CFileModule* pFileModule );
|
|
|
|
~CResInfo();
|
|
|
|
WORD GetTypeId()
|
|
{ return m_TypeId; }
|
|
CString GetTypeName()
|
|
{ return m_TypeName; }
|
|
|
|
WORD GetResId()
|
|
{ return m_ResId; }
|
|
CString GetResName()
|
|
{ return m_ResName; }
|
|
|
|
DWORD GetSize()
|
|
{ return m_dwImageSize; }
|
|
|
|
DWORD GetFileOffset()
|
|
{ return m_FileOffset; }
|
|
|
|
DWORD GetLanguage()
|
|
{ return (DWORD)LOWORD(m_Language); }
|
|
|
|
DWORD GetAllLanguage()
|
|
{ return m_Language; }
|
|
|
|
BOOL GetUpdImage()
|
|
{ return m_ImageUpdated; }
|
|
|
|
DWORD LoadImage( CString lpszFilename, HINSTANCE hInst );
|
|
void FreeImage();
|
|
|
|
DWORD ParseImage( HINSTANCE hInst );
|
|
DWORD GetImage( LPCSTR lpszFilename, HINSTANCE hInst, LPVOID lpbuffer, DWORD dwBufSize );
|
|
DWORD UpdateImage( LONG dwSize, HINSTANCE hInst, LPCSTR lpszType );
|
|
DWORD ReplaceImage( LPVOID lpNewImage, DWORD dwNewImageSize, DWORD dwLang );
|
|
|
|
UINT GetData( LPCSTR lpszFilename, HINSTANCE hInst,
|
|
DWORD dwItem, LPVOID lpbuffer, UINT uiBufSize );
|
|
|
|
UINT UpdateData( LPCSTR lpszFilename, HINSTANCE hInst,
|
|
DWORD dwItem, LPVOID lpbuffer, UINT uiBufSize );
|
|
|
|
void SetFileOffset( DWORD dwOffset )
|
|
{ m_FileOffset = dwOffset; }
|
|
|
|
void SetFileSize( DWORD dwSize )
|
|
{ m_FileSize = dwSize; }
|
|
|
|
void SetImageUpdated( BYTE bStatus )
|
|
{ m_ImageUpdated = bStatus; }
|
|
|
|
void FreeItemArray();
|
|
|
|
DWORD EnumItem( LPCSTR lpszFilename, HINSTANCE hInst, DWORD dwPrevItem );
|
|
UINT Copy( CResInfo* pResInfo, CString szFileName, HINSTANCE hInst );
|
|
UINT CopyImage( CResInfo* pResInfo );
|
|
int AddItem( CItemInfo ItemInfo );
|
|
|
|
private:
|
|
DWORD m_FileOffset;
|
|
DWORD m_FileSize;
|
|
|
|
DWORD m_Language;
|
|
|
|
CString m_TypeName;
|
|
WORD m_TypeId;
|
|
|
|
CString m_ResName;
|
|
WORD m_ResId;
|
|
|
|
BYTE far * m_lpImageBuf; // This is a pointer to the raw data in the resource
|
|
DWORD m_dwImageSize;
|
|
BYTE m_ImageUpdated;
|
|
|
|
CObArray m_ItemArray;
|
|
int m_ItemPos;
|
|
|
|
//
|
|
// FileModule the resource belongs to
|
|
//
|
|
|
|
CFileModule* m_pFileModule;
|
|
|
|
UINT AllocImage(DWORD dwSize);
|
|
};
|
|
|
|
// This class has all the information we need on each of the modules that the user
|
|
// open. When the DLL is discarded this class will clean all the memory allocated.
|
|
class CFileModule : public CObject
|
|
{
|
|
public:
|
|
CFileModule();
|
|
CFileModule( LPCSTR, LPCSTR, int, DWORD );
|
|
~CFileModule();
|
|
|
|
LPCSTR EnumType( LPCSTR lpszPrevType );
|
|
LPCSTR EnumId( LPCSTR lpszType, LPCSTR lpszPrevId );
|
|
DWORD EnumLang( LPCSTR lpszType, LPCSTR lpszId, DWORD dwPrevLang );
|
|
DWORD EnumItem( LPCSTR lpszType, LPCSTR lpszId, DWORD dwLang, DWORD dwPrevItem );
|
|
|
|
HINSTANCE LoadDll(); // Load the Dll Hinstance
|
|
void FreeDll(); // Free the DLL hInstance
|
|
UINT CleanUp(); // Clean the module memory
|
|
|
|
HINSTANCE GetHInstance()
|
|
{ return m_DllHInstance; }
|
|
|
|
CString GetName()
|
|
{ return m_SrcFileName; }
|
|
CString GetRDFName()
|
|
{ return m_RdfFileName; }
|
|
|
|
CResInfo* GetResInfo( LPCSTR lpszType, LPCSTR lpszId, DWORD dwPrevLang );
|
|
CResInfo* GetResInfo( int iPos )
|
|
{ return ((CResInfo*)m_ResArray.GetAt(iPos)); }
|
|
|
|
DWORD GetImage( LPCSTR lpszType, LPCSTR lpszId, DWORD dwLang,
|
|
LPVOID lpbuffer, DWORD dwBufSize );
|
|
|
|
DWORD UpdateImage( LPCSTR lpszType, LPCSTR lpszId, DWORD dwLang,
|
|
DWORD dwUpdLang, LPVOID lpbuffer, DWORD dwBufSize );
|
|
|
|
UINT GetData( LPCSTR lpszType, LPCSTR lpszId, DWORD dwLang, DWORD dwItem,
|
|
LPVOID lpbuffer, UINT uiBufSize );
|
|
|
|
UINT UpdateData( LPCSTR lpszType, LPCSTR lpszId, DWORD dwLang, DWORD dwItem,
|
|
LPVOID lpbuffer, UINT uiBufSize );
|
|
|
|
int AddTypeInfo( INT_PTR iPos, int iId, CString szId );
|
|
|
|
int AddResInfo(
|
|
WORD Typeid, CString sztypeid,
|
|
WORD nameid, CString sznameid,
|
|
DWORD dwlang, DWORD dwsize, DWORD dwfileoffset );
|
|
|
|
void GenerateIdTable( LPCSTR lpszType, BOOL bNameOrID );
|
|
|
|
UINT WriteUpdatedResource( LPCSTR lpszTgtfilename, HANDLE hFileModule, LPCSTR lpszSymbolPath );
|
|
|
|
|
|
void SetResBufSize( UINT uiSize ) { m_ResBufSize = uiSize;}
|
|
UINT GetResBufSize() { return m_ResBufSize;}
|
|
UINT Copy( CFileModule* pFileModule );
|
|
UINT CopyImage( CFileModule* pFileModule, LPCSTR lpszType, LPCSTR lpszResId );
|
|
|
|
UINT GetLanguageStr( LPSTR lpszLanguage );
|
|
|
|
private:
|
|
CString m_SrcFileName; // The filename of the file to process
|
|
CString m_RdfFileName; // The filename of the RDF file
|
|
UINT m_DllTypeEntry; // The CDLLTable position for the file type
|
|
HINSTANCE m_DllHInstance; // The HINSTANCE to the dll
|
|
DWORD m_dwFlags; // IODLL and RW flags
|
|
|
|
CObArray m_ResArray; // Array of all the Resources in the file.
|
|
UINT m_ResBufSize; // Will be usefull when we have to write the resource
|
|
|
|
int m_TypePos; // Position in the ResArray for the last enum type
|
|
CWordArray m_TypeArray; // Array of resource types in the file
|
|
|
|
int m_IdPos;
|
|
CWordArray m_IdArray; // Array of resource id of a types in the file
|
|
|
|
int m_LangPos;
|
|
CWordArray m_LangArray; // Array of Language if of a given type/id
|
|
|
|
char m_IdStr[100]; // Resource name
|
|
char m_TypeStr[100]; // Type name
|
|
char m_LastTypeName[100];
|
|
LPSTR m_LastTypeID;
|
|
};
|
|
|
|
// This class will old the information on each entry in the INI file related with the
|
|
// R/W modules. When the DLL will be discarded the memory will be cleaned.
|
|
class CDllEntryTable : public CObject
|
|
{
|
|
public:
|
|
CDllEntryTable( CString szEntry );
|
|
~CDllEntryTable();
|
|
|
|
CString GetType( ) { return m_szDllType; }
|
|
CString GetName( ) { return m_szDllName; }
|
|
HINSTANCE LoadEntry( );
|
|
BOOL FreeEntry( );
|
|
private:
|
|
CString m_szDllName; // Dll Name and directory
|
|
CString m_szDllType; // Dll type tag
|
|
HINSTANCE m_handle;
|
|
};
|
|
|
|
// This class is a dinamyc array of CDllEntryTable elements.
|
|
// When the DLL is initialized the class read the INI file and is ready with the information
|
|
// on each of the RW Modules present on the hard disk. When the DLL il discarded the Class
|
|
// will take care to delete all the entry allocated.
|
|
class CDllTable : public CObArray
|
|
{
|
|
public:
|
|
CDllTable( UINT );
|
|
~CDllTable();
|
|
|
|
UINT GetPosFromTable( CString szFileType );
|
|
UINT GetMaxEntry() { return m_MaxEntry; }
|
|
|
|
private:
|
|
UINT m_MaxEntry;
|
|
UINT m_InitNum;
|
|
};
|
|
|
|
class CModuleTable : public CObArray
|
|
{
|
|
public:
|
|
CModuleTable( UINT );
|
|
~CModuleTable();
|
|
|
|
private:
|
|
UINT m_LastHandle;
|
|
UINT m_InitNum;
|
|
};
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// Global variables
|
|
CDllTable gDllTable(MAXENTRYBUF); // When the DLL is initialized the constructor is called
|
|
CModuleTable gModuleTable(2); // When the DLL is initialized the constructor is called
|
|
|
|
TCHAR szDefaultRcdata[][MAXKEYLEN] = { "kernel32.dll,rcdata1.dll" };
|
|
TCHAR szDefaultRWDll[][MAXKEYLEN] = {"rwwin16.dll,WIN16",
|
|
"rwwin32.dll,WIN32",
|
|
"rwmac.dll,MAC",
|
|
"rwres32.dll,RES32",
|
|
"rwinf.dll,INF"};
|
|
|
|
static BYTE sizeofWord = sizeof(WORD);
|
|
static BYTE sizeofDWord = sizeof(DWORD);
|
|
static BYTE sizeofDWordPtr = sizeof(DWORD_PTR);
|
|
static BYTE sizeofByte = sizeof(BYTE);
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// Public C interface implementation
|
|
|
|
static UINT CopyFile( const char * pszfilein, const char * pszfileout );
|
|
static BYTE Allign(LONG bLen);
|
|
void CheckError(LPCSTR szStr);
|
|
|
|
int g_iDllLoaded;
|
|
SETTINGS g_Settings;
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// RDF File support code
|
|
|
|
HANDLE
|
|
OpenModule(
|
|
LPCSTR lpszSrcfilename, // File name of the executable to use as source file
|
|
LPCSTR lpszfiletype, // Type of the executable file if known
|
|
LPCSTR lpszRDFfile,
|
|
DWORD dwFlags );
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------
|
|
//********************************************************************************************
|
|
// Global Settings API
|
|
//--------------------------------------------------------------------------------------------
|
|
|
|
extern "C"
|
|
DllExport
|
|
UINT
|
|
APIENTRY
|
|
RSSetGlobals(
|
|
SETTINGS Settings) // Set the global variable, like CP to use.
|
|
{
|
|
g_Settings.cp = Settings.cp;
|
|
g_Settings.bAppend = Settings.bAppend;
|
|
g_Settings.bUpdOtherResLang = Settings.bUpdOtherResLang;
|
|
strncpy(g_Settings.szDefChar, Settings.szDefChar, 1);
|
|
g_Settings.szDefChar[1] = '\0';
|
|
|
|
return 1;
|
|
}
|
|
|
|
extern "C"
|
|
DllExport
|
|
UINT
|
|
APIENTRY
|
|
RSGetGlobals(
|
|
LPSETTINGS lpSettings) // Retrieve the global variable
|
|
{
|
|
lpSettings->cp = g_Settings.cp;
|
|
lpSettings->bAppend = g_Settings.bAppend;
|
|
lpSettings->bUpdOtherResLang = g_Settings.bUpdOtherResLang;
|
|
strncpy(lpSettings->szDefChar, g_Settings.szDefChar, 1);
|
|
lpSettings->szDefChar[1] = '\0';
|
|
|
|
|
|
|
|
return 1;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------
|
|
//********************************************************************************************
|
|
// Module Opening/Closing API
|
|
//--------------------------------------------------------------------------------------------
|
|
|
|
extern "C"
|
|
DllExport
|
|
HANDLE
|
|
APIENTRY
|
|
RSOpenModule(
|
|
LPCSTR lpszSrcfilename, // File name of the executable to use as source file
|
|
LPCSTR lpszfiletype ) // Type of the executable file if known
|
|
{
|
|
return OpenModule(lpszSrcfilename, lpszfiletype, NULL, 0 );
|
|
}
|
|
|
|
extern "C"
|
|
DllExport
|
|
HANDLE
|
|
APIENTRY
|
|
RSOpenModuleEx(
|
|
LPCSTR lpszSrcfilename, // File name of the executable to use as source file
|
|
LPCSTR lpszfiletype, // Type of the executable file if known
|
|
LPCSTR lpszRDFfile, // Resource Description File (RDF)
|
|
DWORD dwFlags ) // HIWORD=rw flags LOWORD=iodll flags
|
|
{
|
|
// Check if we have a RDF file defined
|
|
if(lpszRDFfile) {
|
|
return OpenModule(lpszSrcfilename, lpszfiletype, lpszRDFfile, dwFlags );
|
|
}
|
|
else
|
|
return OpenModule(lpszSrcfilename, lpszfiletype, NULL, dwFlags );
|
|
}
|
|
|
|
extern "C"
|
|
DllExport
|
|
HANDLE
|
|
APIENTRY
|
|
RSCopyModule(
|
|
HANDLE hSrcfilemodule, // Handle to the source file
|
|
LPCSTR lpszModuleName, // Name of the new module filename
|
|
LPCSTR lpszfiletype ) // Type of the target module
|
|
{
|
|
TRACE2("IODLL.DLL: RSCopyModule: %d %s\n", (int)hSrcfilemodule, lpszfiletype);
|
|
UINT uiError = ERROR_NO_ERROR;
|
|
INT_PTR uiHandle = 0 ;
|
|
|
|
// Check if the type is not null
|
|
CString szSrcFileType;
|
|
if (!lpszfiletype) {
|
|
return UlongToHandle(ERROR_IO_TYPE_NOT_SUPPORTED);
|
|
} else szSrcFileType = lpszfiletype;
|
|
|
|
gModuleTable.Add(new CFileModule( (LPSTR)lpszModuleName,
|
|
NULL,
|
|
gDllTable.GetPosFromTable(szSrcFileType),
|
|
0 ));
|
|
|
|
// Get the position in the array.
|
|
uiHandle = gModuleTable.GetSize();
|
|
|
|
// Read the informations on the type in the file.
|
|
CFileModule* pFileModule = (CFileModule*)gModuleTable.GetAt(uiHandle-1);
|
|
|
|
if (!pFileModule)
|
|
return UlongToHandle(ERROR_IO_INVALIDMODULE);
|
|
|
|
// We have to copy the information from the source module
|
|
INT_PTR uiSrcHandle = (UINT_PTR)hSrcfilemodule-FIRSTVALIDVALUE-1;
|
|
if (uiSrcHandle<0)
|
|
return (HANDLE)(ERROR_HANDLE_INVALID);
|
|
CFileModule* pSrcFileModule = (CFileModule*)gModuleTable.GetAt((UINT)uiSrcHandle);
|
|
if (!pSrcFileModule)
|
|
return (HANDLE)(ERROR_IO_INVALIDMODULE);
|
|
|
|
if (pSrcFileModule->Copy( pFileModule ))
|
|
return (HANDLE)(ERROR_IO_INVALIDITEM);
|
|
|
|
pFileModule->SetResBufSize( pSrcFileModule->GetResBufSize() );
|
|
|
|
return (HANDLE)(uiHandle+FIRSTVALIDVALUE);
|
|
}
|
|
|
|
|
|
extern "C"
|
|
DllExport
|
|
UINT
|
|
APIENTRY
|
|
RSCloseModule(
|
|
HANDLE hResFileModule ) // Handle to the session opened before
|
|
{
|
|
TRACE1("IODLL.DLL: RSCloseModule: %d\n", (int)hResFileModule);
|
|
UINT uiError = ERROR_NO_ERROR;
|
|
|
|
INT_PTR uiHandle = (UINT_PTR)hResFileModule-FIRSTVALIDVALUE-1;
|
|
if (uiHandle<0)
|
|
return ERROR_HANDLE_INVALID;
|
|
|
|
CFileModule* pFileModule = (CFileModule*)gModuleTable[(UINT)uiHandle];
|
|
|
|
if (!pFileModule)
|
|
return ERROR_IO_INVALIDMODULE;
|
|
|
|
uiError = pFileModule->CleanUp();
|
|
|
|
return uiError;
|
|
}
|
|
|
|
extern "C"
|
|
DllExport
|
|
HANDLE
|
|
APIENTRY
|
|
RSHandleFromName(
|
|
LPCSTR lpszfilename ) // Handle to the session with the file name specified
|
|
{
|
|
TRACE("IODLL.DLL: RSHandleFromName: %s\n", lpszfilename);
|
|
|
|
INT_PTR UpperBound = gModuleTable.GetUpperBound();
|
|
CFileModule* pFileModule;
|
|
while( UpperBound!=-1 ) {
|
|
pFileModule = (CFileModule*)gModuleTable.GetAt(UpperBound);
|
|
if(pFileModule->GetName()==lpszfilename)
|
|
return (HANDLE)(UpperBound+FIRSTVALIDVALUE+1);
|
|
UpperBound--;
|
|
}
|
|
|
|
return (HANDLE)0;
|
|
}
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------
|
|
//********************************************************************************************
|
|
// Enumeration API
|
|
//--------------------------------------------------------------------------------------------
|
|
|
|
extern "C"
|
|
DllExport
|
|
LPCSTR
|
|
APIENTRY
|
|
RSEnumResType(
|
|
HANDLE hResFileModule, // Handle to the file session
|
|
LPCSTR lpszPrevResType) // Previously enumerated type
|
|
{
|
|
TRACE2("IODLL.DLL: RSEnumResType: %u %Fp\n", (UINT)hResFileModule,
|
|
lpszPrevResType);
|
|
|
|
// By now all the information on the types should be here.
|
|
// Check the HANDLE and see if it is a valid one
|
|
INT_PTR uiHandle = (UINT_PTR)hResFileModule-FIRSTVALIDVALUE-1;
|
|
if (uiHandle<0)
|
|
return LPNULL;
|
|
|
|
// Get the File module
|
|
CFileModule* pFileModule = (CFileModule*)gModuleTable[(UINT)uiHandle];
|
|
|
|
if (!pFileModule)
|
|
return LPNULL;
|
|
|
|
return pFileModule->EnumType( lpszPrevResType );
|
|
}
|
|
|
|
extern "C"
|
|
DllExport
|
|
LPCSTR
|
|
APIENTRY
|
|
RSEnumResId(
|
|
HANDLE hResFileModule, // Handle to the file session
|
|
LPCSTR lpszResType, // Previously enumerated type
|
|
LPCSTR lpszPrevResId) // Previously enumerated id
|
|
{
|
|
TRACE3("IODLL.DLL: RSEnumResId: %u %Fp %Fp\n", (UINT)hResFileModule,
|
|
lpszResType,
|
|
lpszPrevResId);
|
|
// Check the HANDLE and see if it is a valid one
|
|
INT_PTR uiHandle = (UINT_PTR)hResFileModule-FIRSTVALIDVALUE-1;
|
|
if (uiHandle<0) return LPNULL;
|
|
|
|
// Get the File module
|
|
CFileModule* pFileModule = (CFileModule*)gModuleTable[(UINT)uiHandle];
|
|
|
|
return pFileModule->EnumId( lpszResType, lpszPrevResId );
|
|
}
|
|
|
|
extern "C"
|
|
DllExport
|
|
DWORD
|
|
APIENTRY
|
|
RSEnumResLang(
|
|
HANDLE hResFileModule, // Handle to the file session
|
|
LPCSTR lpszResType, // Previously enumerated type
|
|
LPCSTR lpszResId, // Previously enumerated id
|
|
DWORD dwPrevResLang) // Previously enumerated language
|
|
{
|
|
TRACE3("IODLL.DLL: RSEnumResLang: %u %Fp %Fp ", (UINT)hResFileModule,
|
|
lpszResType,
|
|
lpszResId);
|
|
TRACE1("%ld\n", dwPrevResLang);
|
|
// Check the HANDLE and see if it is a valid one
|
|
INT_PTR uiHandle = (UINT_PTR)hResFileModule-FIRSTVALIDVALUE-1;
|
|
if (uiHandle<0) return LPNULL;
|
|
|
|
// Get the File module
|
|
CFileModule* pFileModule = (CFileModule*)gModuleTable[(UINT)uiHandle];
|
|
|
|
if (!pFileModule)
|
|
return ERROR_IO_INVALIDMODULE;
|
|
|
|
return pFileModule->EnumLang( lpszResType, lpszResId, dwPrevResLang );
|
|
}
|
|
|
|
extern "C"
|
|
DllExport
|
|
DWORD
|
|
APIENTRY
|
|
RSEnumResItemId(
|
|
HANDLE hResFileModule, // Handle to the file session
|
|
LPCSTR lpszResType, // Previously enumerated type
|
|
LPCSTR lpszResId, // Previously enumerated id
|
|
DWORD dwResLang, // Previously enumerated language
|
|
DWORD dwPrevResItemId) // Previously enumerated item id
|
|
{
|
|
TRACE3("IODLL.DLL: RSEnumResItemId: %u %Fp %Fp ", (UINT)hResFileModule,
|
|
lpszResType,
|
|
lpszResId);
|
|
TRACE2("%ld %Fp\n", dwResLang,
|
|
dwPrevResItemId);
|
|
|
|
// Check the HANDLE and see if it is a valid one
|
|
INT_PTR uiHandle = (UINT_PTR)hResFileModule-FIRSTVALIDVALUE-1;
|
|
if (uiHandle<0) return LPNULL;
|
|
|
|
// Get the File module
|
|
CFileModule* pFileModule = (CFileModule*)gModuleTable[(UINT)uiHandle];
|
|
|
|
if (!pFileModule)
|
|
return ERROR_IO_INVALIDMODULE;
|
|
|
|
return pFileModule->EnumItem( lpszResType, lpszResId, dwResLang, dwPrevResItemId );
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------
|
|
//********************************************************************************************
|
|
// Data acquisition API
|
|
//--------------------------------------------------------------------------------------------
|
|
|
|
extern "C"
|
|
DllExport
|
|
UINT
|
|
APIENTRY
|
|
RSGetResItemData(
|
|
HANDLE hResFileModule, // Handle to the file session
|
|
LPCSTR lpszResType, // Previously enumerated type
|
|
LPCSTR lpszResId, // Previously enumerated id
|
|
DWORD dwResLang, // Previously enumerated language
|
|
DWORD dwResItemId, // Previously enumerated item id
|
|
LPVOID lpbuffer, // Pointer to the buffer that will get the resource info
|
|
UINT uiBufSize) // Size of the buffer that will hold the resource info
|
|
{
|
|
TRACE3("IODLL.DLL: RSGetResItemData: %u %Fp %Fp ", (UINT)hResFileModule,
|
|
lpszResType,
|
|
lpszResId);
|
|
TRACE3("%ld %Fp %Fp ", dwResLang,
|
|
dwResItemId,
|
|
lpbuffer);
|
|
TRACE1("%d\n", uiBufSize);
|
|
// Check the HANDLE and see if it is a valid one
|
|
INT_PTR uiHandle = (UINT_PTR)hResFileModule-FIRSTVALIDVALUE-1;
|
|
if (uiHandle<0) return LPNULL;
|
|
|
|
// Get the File module
|
|
CFileModule* pFileModule = (CFileModule*)gModuleTable[(UINT)uiHandle];
|
|
|
|
if (!pFileModule)
|
|
return ERROR_IO_INVALIDMODULE;
|
|
|
|
return pFileModule->GetData( lpszResType, lpszResId, dwResLang, dwResItemId,
|
|
lpbuffer, uiBufSize );
|
|
}
|
|
|
|
extern "C"
|
|
DllExport
|
|
DWORD
|
|
APIENTRY
|
|
RSGetResImage(
|
|
HANDLE hResFileModule, // Handle to the file session
|
|
LPCSTR lpszResType, // Previously enumerated type
|
|
LPCSTR lpszResId, // Previously enumerated id
|
|
DWORD dwResLang, // Previously enumerated language
|
|
LPVOID lpbuffer, // Pointer to the buffer to get the resource Data
|
|
DWORD dwBufSize) // Size of the allocated buffer
|
|
{
|
|
TRACE3("IODLL.DLL: RSGetResImage: %u %Fp %Fp ", (UINT)hResFileModule,
|
|
lpszResType,
|
|
lpszResId);
|
|
TRACE2("%ld %Fp ", dwResLang,
|
|
lpbuffer);
|
|
TRACE1("%lu\n", dwBufSize);
|
|
|
|
// Check the HANDLE and see if it is a valid one
|
|
INT_PTR uiHandle = (UINT_PTR)hResFileModule-FIRSTVALIDVALUE-1;
|
|
if (uiHandle<0) return LPNULL;
|
|
|
|
// Get the File module
|
|
CFileModule* pFileModule = (CFileModule*)gModuleTable[(UINT)uiHandle];
|
|
|
|
if (!pFileModule)
|
|
return ERROR_IO_INVALIDMODULE;
|
|
|
|
return pFileModule->GetImage( lpszResType, lpszResId, dwResLang, lpbuffer, dwBufSize );
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------
|
|
//********************************************************************************************
|
|
// Update API
|
|
//--------------------------------------------------------------------------------------------
|
|
|
|
extern "C"
|
|
DllExport
|
|
UINT
|
|
APIENTRY
|
|
RSUpdateResItemData(
|
|
HANDLE hResFileModule, // Handle to the file session
|
|
LPCSTR lpszResType, // Previously enumerated type
|
|
LPCSTR lpszResId, // Previously enumerated id
|
|
DWORD dwResLang, // Previously enumerated language
|
|
DWORD dwResItemId, // Previously enumerated items id
|
|
LPVOID lpbuffer, // Pointer to the buffer to the resource item Data
|
|
UINT uiBufSize) // Size of the buffer
|
|
{
|
|
TRACE3("IODLL.DLL: RSUpdateResItemData: %u %Fp %Fp ", (UINT)hResFileModule,
|
|
lpszResType,
|
|
lpszResId);
|
|
TRACE3("%ld %Fp %Fp ", dwResLang,
|
|
dwResItemId,
|
|
lpbuffer);
|
|
TRACE1("%u\n", uiBufSize);
|
|
// Check the HANDLE and see if it is a valid one
|
|
INT_PTR uiHandle = (UINT_PTR)hResFileModule-FIRSTVALIDVALUE-1;
|
|
if (uiHandle<0) return LPNULL;
|
|
|
|
// Get the File module
|
|
CFileModule* pFileModule = (CFileModule*)gModuleTable[(UINT)uiHandle];
|
|
|
|
if (!pFileModule)
|
|
return ERROR_IO_INVALIDMODULE;
|
|
|
|
return pFileModule->UpdateData( lpszResType, lpszResId, dwResLang, dwResItemId,
|
|
lpbuffer, uiBufSize );
|
|
}
|
|
|
|
extern "C"
|
|
DllExport
|
|
DWORD
|
|
APIENTRY
|
|
RSUpdateResImage(
|
|
HANDLE hResFileModule, // Handle to the file session
|
|
LPCSTR lpszResType, // Previously enumerated type
|
|
LPCSTR lpszResId, // Previously enumerated id
|
|
DWORD dwResLang, // Previously enumerated language
|
|
DWORD dwUpdLang, // Desired output language
|
|
LPVOID lpbuffer, // Pointer to the buffer to the resource item Data
|
|
DWORD dwBufSize) // Size of the buffer
|
|
{
|
|
TRACE3("IODLL.DLL: RSUpdateResImage: %d %Fp %Fp ", hResFileModule,
|
|
lpszResType,
|
|
lpszResId);
|
|
TRACE("%Fp %Fp %Fp ", dwResLang,
|
|
lpbuffer);
|
|
TRACE1("%d\n", dwBufSize);
|
|
UINT uiError = ERROR_NO_ERROR;
|
|
|
|
// Check the HANDLE and see if it is a valid one
|
|
INT_PTR uiHandle = (UINT_PTR)hResFileModule-FIRSTVALIDVALUE-1;
|
|
if (uiHandle<0) return LPNULL;
|
|
|
|
// Get the File module
|
|
CFileModule* pFileModule = (CFileModule*)gModuleTable[(UINT)uiHandle];
|
|
|
|
if (!pFileModule)
|
|
return ERROR_IO_INVALIDMODULE;
|
|
|
|
return pFileModule->UpdateImage( lpszResType, lpszResId, dwResLang,
|
|
dwUpdLang, lpbuffer, dwBufSize );
|
|
|
|
return (DWORD)uiError;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------
|
|
//********************************************************************************************
|
|
// Conversion API
|
|
//--------------------------------------------------------------------------------------------
|
|
|
|
extern "C"
|
|
DllExport
|
|
UINT
|
|
APIENTRY
|
|
RSUpdateFromResFile(
|
|
HANDLE hResFileModule, // Handle to the file session
|
|
LPSTR lpszResFilename) // The resource filename to be converted
|
|
{
|
|
TRACE2("IODLL.DLL: RSUpdateFromResFile: %d %s\n", hResFileModule,
|
|
lpszResFilename);
|
|
UINT uiError = 0;
|
|
const int CBSTRMAX = 8192;
|
|
BOOL fReturn = TRUE;
|
|
HANDLE hResFileSrc = NULL;
|
|
LPCSTR lpszTypeSrc = NULL;
|
|
LPCSTR lpszResSrc = NULL;
|
|
DWORD dwLangSrc = 0L;
|
|
DWORD dwLangDest = 0L;
|
|
DWORD dwItemSrc = 0L;
|
|
DWORD dwItemDest = 0L;
|
|
WORD cbResItemSrc = 0;
|
|
WORD cbResItemDest = 0;
|
|
LPRESITEM lpriSrc = NULL;
|
|
LPRESITEM lpriDest = NULL;
|
|
|
|
// Check the HANDLE and see if it is a valid one
|
|
INT_PTR uiHandle = (UINT_PTR)hResFileModule-FIRSTVALIDVALUE-1;
|
|
if (uiHandle<0) return ERROR_HANDLE_INVALID;
|
|
|
|
// Get the File module
|
|
CFileModule* pFileModule = (CFileModule*)gModuleTable[(UINT)uiHandle];
|
|
if (!pFileModule)
|
|
return ERROR_IO_INVALIDMODULE;
|
|
|
|
|
|
// Initialize storage for ResItem
|
|
if (lpriSrc = (LPRESITEM)malloc(CBSTRMAX))
|
|
cbResItemSrc = CBSTRMAX;
|
|
else {
|
|
AfxThrowMemoryException();
|
|
}
|
|
|
|
// Read in the resource files
|
|
if ((UINT_PTR)(hResFileSrc = RSOpenModule((LPSTR)lpszResFilename, "RES32")) <= 100) {
|
|
uiError = (UINT)(UINT_PTR)hResFileSrc;
|
|
if (lpriSrc)
|
|
free(lpriSrc);
|
|
return uiError;
|
|
}
|
|
|
|
// Get the File Module of the Resource file. This is needed for the image conversion
|
|
|
|
CFileModule* pResFileModule = (CFileModule*)gModuleTable[(UINT)((UINT_PTR)hResFileSrc-FIRSTVALIDVALUE-1)];
|
|
if(!pResFileModule)
|
|
return ERROR_IO_INVALIDMODULE;
|
|
|
|
while (lpszTypeSrc = RSEnumResType(hResFileSrc,
|
|
lpszTypeSrc)) {
|
|
while (lpszResSrc = RSEnumResId(hResFileSrc,
|
|
lpszTypeSrc,
|
|
lpszResSrc)) {
|
|
// Hack Hack, This is done to handle Bitmap conversion
|
|
// Will need to be done better after the Chicago release
|
|
switch(LOWORD(lpszTypeSrc)) {
|
|
case 2:
|
|
TRACE("Here we will have to swap the images!\n");
|
|
pFileModule->CopyImage( pResFileModule, lpszTypeSrc, lpszResSrc );
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
while (dwLangSrc = RSEnumResLang(hResFileSrc,
|
|
lpszTypeSrc,
|
|
lpszResSrc,
|
|
dwLangSrc)) {
|
|
while (dwItemSrc = RSEnumResItemId(hResFileSrc,
|
|
lpszTypeSrc,
|
|
lpszResSrc,
|
|
dwLangSrc,
|
|
dwItemSrc)){
|
|
|
|
WORD wSize;
|
|
wSize = (WORD)RSGetResItemData(hResFileSrc,
|
|
lpszTypeSrc,
|
|
lpszResSrc,
|
|
dwLangSrc,
|
|
dwItemSrc,
|
|
(LPRESITEM)lpriSrc,
|
|
cbResItemSrc);
|
|
|
|
if (cbResItemSrc < wSize) {
|
|
if (lpriSrc = (LPRESITEM)realloc(lpriSrc, wSize))
|
|
cbResItemSrc = wSize;
|
|
else
|
|
AfxThrowMemoryException();
|
|
RSGetResItemData(hResFileSrc,
|
|
lpszTypeSrc,
|
|
lpszResSrc,
|
|
dwLangSrc,
|
|
dwItemSrc,
|
|
(LPRESITEM)lpriSrc,
|
|
cbResItemSrc);
|
|
}
|
|
|
|
if ((uiError = RSUpdateResItemData(hResFileModule,
|
|
lpszTypeSrc,
|
|
lpszResSrc,
|
|
1033,
|
|
dwItemSrc,
|
|
lpriSrc,
|
|
cbResItemSrc)) != 0) {
|
|
/*
|
|
if (lpriSrc)
|
|
free(lpriSrc);
|
|
RSCloseModule(hResFileSrc);
|
|
return uiError;
|
|
*/
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
// Save out to the updated resource file, same format.
|
|
RSCloseModule(hResFileSrc);
|
|
|
|
// The user want to write the file with the same format as the original
|
|
uiError = pFileModule->WriteUpdatedResource( pFileModule->GetName(), hResFileModule, NULL);
|
|
|
|
// Clean up
|
|
return uiError;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------
|
|
//********************************************************************************************
|
|
// Writing API
|
|
//--------------------------------------------------------------------------------------------
|
|
|
|
extern "C"
|
|
DllExport
|
|
UINT
|
|
APIENTRY
|
|
RSWriteResFile(
|
|
HANDLE hResFileModule, // Handle to the file session
|
|
LPCSTR lpszTgtfilename, // The new filename to be generated
|
|
LPCSTR lpszTgtfileType, // Target Resource type 16/32
|
|
LPCSTR lpszSymbolPath) // Symbol Path for updating symbol checksum
|
|
{
|
|
TRACE3("IODLL.DLL: RSWriteResFile: %d %s %s\n", hResFileModule,
|
|
lpszTgtfilename,
|
|
lpszTgtfileType);
|
|
UINT uiError = ERROR_NO_ERROR;
|
|
|
|
// Check the HANDLE and see if it is a valid one
|
|
INT_PTR uiHandle = (UINT_PTR)hResFileModule-FIRSTVALIDVALUE-1;
|
|
if (uiHandle<0) return ERROR_HANDLE_INVALID;
|
|
|
|
// Get the File module
|
|
CFileModule* pFileModule = (CFileModule*)gModuleTable[(UINT)uiHandle];
|
|
|
|
if (!pFileModule)
|
|
return ERROR_IO_INVALIDMODULE;
|
|
|
|
|
|
if(lpszTgtfileType!=LPNULL) {
|
|
// The user want a conversion.
|
|
// Check if the type the user want is one of the supported one
|
|
CDllEntryTable* pDllEntry;
|
|
INT_PTR iUpperBound = gDllTable.GetUpperBound();
|
|
while(iUpperBound>=0) {
|
|
pDllEntry = (CDllEntryTable*) gDllTable.GetAt(iUpperBound);
|
|
if ( (pDllEntry) && (pDllEntry->GetType()==lpszTgtfileType) )
|
|
iUpperBound = -1;
|
|
iUpperBound--;
|
|
}
|
|
if (iUpperBound==-1)
|
|
return ERROR_IO_TYPE_NOT_SUPPORTED;
|
|
|
|
// We will open a new module now.
|
|
// We will generate the images from the other module
|
|
HANDLE hTgtFileHandle = RSCopyModule( hResFileModule, LPNULL, lpszTgtfileType );
|
|
if ((UINT_PTR)hTgtFileHandle<=FIRSTVALIDVALUE)
|
|
return ((UINT)(UINT_PTR)hTgtFileHandle);
|
|
|
|
// Write the file
|
|
CFileModule* pNewFileModule = (CFileModule*)gModuleTable[(UINT)((UINT_PTR)hTgtFileHandle-FIRSTVALIDVALUE-1)];
|
|
if (!pNewFileModule)
|
|
return ERROR_IO_INVALIDMODULE;
|
|
|
|
uiError = pNewFileModule->WriteUpdatedResource( lpszTgtfilename, hTgtFileHandle, lpszSymbolPath );
|
|
|
|
// Close the module we just create
|
|
RSCloseModule(hTgtFileHandle);
|
|
return uiError;
|
|
}
|
|
|
|
// The user want to write the file with the same format as the original
|
|
return pFileModule->WriteUpdatedResource( lpszTgtfilename,
|
|
hResFileModule,
|
|
lpszSymbolPath);
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------
|
|
//********************************************************************************************
|
|
// Recognition API
|
|
//--------------------------------------------------------------------------------------------
|
|
|
|
extern "C"
|
|
DllExport
|
|
UINT
|
|
APIENTRY
|
|
RSFileType(
|
|
LPCSTR lpszfilename, // File name of the executable to use as source file
|
|
LPSTR lpszfiletype ) // Type of the executable file if known
|
|
{
|
|
//Get the executable file format querying all the R/W DLL
|
|
INT_PTR UpperBound = gDllTable.GetUpperBound();
|
|
int c = 0;
|
|
CDllEntryTable* pDllEntry;
|
|
while(c<=UpperBound) {
|
|
// Get the module name
|
|
pDllEntry = (CDllEntryTable*) gDllTable.GetAt(c);
|
|
|
|
if (!pDllEntry)
|
|
return ERROR_IO_INVALID_DLL;
|
|
// Get the handle to the dll and query validate
|
|
HINSTANCE hInst = pDllEntry->LoadEntry();
|
|
|
|
if (hInst) {
|
|
BOOL (FAR PASCAL * lpfnValidateFile)(LPCSTR);
|
|
// Get the pointer to the function to extract the resources
|
|
lpfnValidateFile = (BOOL (FAR PASCAL *)(LPCSTR))
|
|
GetProcAddress( hInst, "RWValidateFileType" );
|
|
if (lpfnValidateFile==NULL) {
|
|
return ERROR_DLL_PROC_ADDRESS;
|
|
}
|
|
if( (*lpfnValidateFile)((LPCSTR)lpszfilename) ) {
|
|
// this DLL can handle the file type
|
|
strcpy(lpszfiletype, pDllEntry->GetType());
|
|
return ERROR_NO_ERROR;
|
|
}
|
|
}
|
|
else {
|
|
CheckError("(RSFileType) LoadLibrary()" + pDllEntry->GetName());
|
|
}
|
|
|
|
c++;
|
|
}
|
|
strcpy(lpszfiletype, "");
|
|
return ERROR_IO_TYPE_NOT_SUPPORTED;
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// Return TRUE if the file has more than one language.
|
|
// Will fill the lpszLanguage with a list of the languages in the file
|
|
////////////////////////////////////////////////////////////////////////////
|
|
extern "C"
|
|
DllExport
|
|
UINT
|
|
APIENTRY
|
|
RSLanguages(
|
|
HANDLE hfilemodule, // Handle to the file
|
|
LPSTR lpszLanguages ) // will be filled with a string of all the languages in the file
|
|
{
|
|
INT_PTR uiHandle = (UINT_PTR)hfilemodule-FIRSTVALIDVALUE-1;
|
|
if (uiHandle<0)
|
|
return LPNULL;
|
|
|
|
// Get the File module
|
|
CFileModule* pFileModule = (CFileModule*)gModuleTable[(UINT)uiHandle];
|
|
|
|
if (!pFileModule)
|
|
return LPNULL;
|
|
|
|
return pFileModule->GetLanguageStr(lpszLanguages);
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// Class implementation
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// CFileModule
|
|
|
|
CFileModule::CFileModule()
|
|
{
|
|
//TRACE("IODLL.DLL: CFileModule::CFileModule\n");
|
|
|
|
m_SrcFileName = "";
|
|
m_RdfFileName = "";
|
|
m_DllTypeEntry = 0; // Invalid position
|
|
m_DllHInstance = 0; // Not loaded yet
|
|
m_TypePos = 0;
|
|
m_IdPos = 0;
|
|
m_LangPos = 0;
|
|
m_LastTypeName[0] = '\0';
|
|
m_LastTypeID = LPNULL;
|
|
m_IdStr[0] = '\0';
|
|
m_dwFlags = 0;
|
|
|
|
m_ResArray.SetSize(100,10);
|
|
m_TypeArray.SetSize(100,10);
|
|
m_IdArray.SetSize(100,10);
|
|
m_LangArray.SetSize(100,10);
|
|
}
|
|
|
|
CFileModule::CFileModule( LPCSTR lpszSrcfilename,
|
|
LPCSTR lpszRdffilename,
|
|
int DllTblPos,
|
|
DWORD dwFlags)
|
|
{
|
|
//TRACE2("IODLL.DLL: CFileModule::CFileModule %s %d\n", lpszSrcfilename,
|
|
// DllTblPos );
|
|
|
|
|
|
m_SrcFileName = lpszSrcfilename;
|
|
if(!lpszRdffilename)
|
|
{
|
|
CString strMap;
|
|
|
|
// assign a default name
|
|
m_RdfFileName = lpszSrcfilename;
|
|
|
|
// remove the the path...
|
|
int iPos = m_RdfFileName.ReverseFind('\\');
|
|
if(iPos!=-1)
|
|
m_RdfFileName = m_RdfFileName.Mid(iPos+1);
|
|
|
|
// Get name from INI file
|
|
GetProfileString("IODLL-RCDATA", m_RdfFileName, "", strMap.GetBuffer(MAX_PATH), MAX_PATH);
|
|
strMap.ReleaseBuffer();
|
|
|
|
if(strMap.IsEmpty())
|
|
{
|
|
//
|
|
// Not found in win.ini, we use default.
|
|
//
|
|
int c = 0;
|
|
int iMax = sizeof(szDefaultRcdata)/sizeof(TCHAR)/MAXKEYLEN;
|
|
PCHAR pstr;
|
|
CString Entry;
|
|
|
|
for ( pstr = szDefaultRcdata[0]; c< iMax; pstr += MAXKEYLEN, c++)
|
|
{
|
|
Entry = pstr;
|
|
if(Entry.Find (m_RdfFileName) !=-1)
|
|
{
|
|
strMap = Entry.Mid(lstrlen(m_RdfFileName)+1);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!strMap.IsEmpty())
|
|
{
|
|
m_RdfFileName = strMap;
|
|
// we will use the dll in the directory from were we have been spawned
|
|
GetModuleFileName( NULL, strMap.GetBuffer(MAX_PATH), MAX_PATH );
|
|
strMap.ReleaseBuffer(-1);
|
|
|
|
// remove the file name
|
|
iPos = strMap.ReverseFind('\\');
|
|
if(iPos!=-1)
|
|
strMap = strMap.Left(iPos+1);
|
|
|
|
// append the path to the file name
|
|
m_RdfFileName = strMap + m_RdfFileName;
|
|
}
|
|
else
|
|
{
|
|
m_RdfFileName = "";
|
|
}
|
|
}
|
|
else m_RdfFileName = lpszRdffilename;
|
|
|
|
m_SrcFileName.MakeUpper();
|
|
m_DllTypeEntry = DllTblPos;
|
|
m_DllHInstance = 0; // Not loaded yet
|
|
|
|
m_TypePos = 0;
|
|
m_IdPos = 0;
|
|
m_LangPos = 0;
|
|
m_LastTypeName[0] = '\0';
|
|
m_LastTypeID = LPNULL;
|
|
m_IdStr[0] = '\0';
|
|
m_dwFlags = dwFlags;
|
|
}
|
|
|
|
CFileModule::~CFileModule()
|
|
{
|
|
TRACE("IODLL.DLL: CFileModule::~CFileModule\n");
|
|
CleanUp();
|
|
}
|
|
|
|
HINSTANCE CFileModule::LoadDll()
|
|
{
|
|
if (!(m_DllHInstance) && (m_DllTypeEntry))
|
|
if((m_DllHInstance = ((CDllEntryTable*)gDllTable[m_DllTypeEntry-1])->LoadEntry())==NULL) {
|
|
CheckError("(CFileModule::LoadDll) LoadLibrary() for " + ((CDllEntryTable*)gDllTable[m_DllTypeEntry-1])->GetName() );
|
|
} else
|
|
TRACE("CFileModule::LoadDll call %d --->> %08x\n", g_iDllLoaded++, m_DllHInstance);
|
|
return m_DllHInstance;
|
|
}
|
|
|
|
void
|
|
CFileModule::FreeDll()
|
|
{
|
|
TRACE("IODLL.DLL: CFileModule::FreeDll() m_DllHInstance=%08x\n", m_DllHInstance );
|
|
|
|
if (m_DllHInstance)
|
|
m_DllHInstance = 0;
|
|
}
|
|
|
|
UINT
|
|
CFileModule::CleanUp()
|
|
{
|
|
INT_PTR UpperBound = m_ResArray.GetUpperBound();
|
|
TRACE1("IODLL.DLL: CFileModule::CleanUp %d\n", UpperBound);
|
|
|
|
// Free the memory for the resource information
|
|
CResInfo* pResInfo;
|
|
for(INT_PTR c=0; c<=UpperBound; c++) {
|
|
pResInfo = (CResInfo*)m_ResArray.GetAt(c);
|
|
TRACE("\tCFileModule\t%d\tCResInfo->%Fp\n", c, pResInfo);
|
|
delete pResInfo;
|
|
}
|
|
m_ResArray.RemoveAll();
|
|
|
|
// Unload the DLL
|
|
FreeDll();
|
|
|
|
return 0;
|
|
}
|
|
|
|
int
|
|
CFileModule::AddResInfo(
|
|
WORD Typeid, CString sztypeid,
|
|
WORD nameid, CString sznameid,
|
|
DWORD dwlang, DWORD dwsize, DWORD dwfileoffset )
|
|
{
|
|
return (int)m_ResArray.Add( new CResInfo(
|
|
Typeid,
|
|
sztypeid,
|
|
nameid,
|
|
sznameid,
|
|
dwlang,
|
|
dwsize,
|
|
dwfileoffset,
|
|
this
|
|
));
|
|
}
|
|
|
|
int
|
|
CFileModule::AddTypeInfo( INT_PTR iPos, int iId, CString szId )
|
|
{
|
|
//TRACE3("IODLL.DLL: CFileModule::AddTypeInfo %d %d %Fp\n", iPos, iId, szId);
|
|
INT_PTR UpperBound = m_TypeArray.GetUpperBound();
|
|
|
|
for( INT_PTR c = 0; c<=UpperBound; c++) {
|
|
int pos = m_TypeArray.GetAt(c);
|
|
CResInfo* pResPos = (CResInfo*)m_ResArray.GetAt(pos);
|
|
CResInfo* pResLast = (CResInfo*)m_ResArray.GetAt(iPos);
|
|
|
|
if( ((pResPos->GetTypeId()==pResLast->GetTypeId()) &&
|
|
(pResPos->GetTypeName()==pResLast->GetTypeName())
|
|
)) return 0;
|
|
}
|
|
//TRACE3("IODLL.DLL: CFileModule::AddTypeInfo %d %d %Fp\n", iPos, iId, szId);
|
|
m_TypeArray.Add( (WORD)iPos );
|
|
return 1;
|
|
}
|
|
|
|
UINT
|
|
CFileModule::GetLanguageStr( LPSTR lpszLanguage )
|
|
{
|
|
CResInfo* pResInfo;
|
|
CString strLang = "";
|
|
char szLang[8];
|
|
BOOL multi_lang = FALSE;
|
|
|
|
for(INT_PTR c=0, iUpperBound = m_ResArray.GetUpperBound(); c<=iUpperBound; c++) {
|
|
pResInfo = (CResInfo*)m_ResArray.GetAt(c);
|
|
|
|
// Convert the language in to the hex value
|
|
sprintf(szLang,"0x%3.3X", pResInfo->GetLanguage());
|
|
|
|
// check if the language is already in the string
|
|
if(strLang.Find(szLang)==-1)
|
|
{
|
|
if(!strLang.IsEmpty())
|
|
{
|
|
multi_lang = TRUE;
|
|
strLang += ", ";
|
|
}
|
|
|
|
strLang += szLang;
|
|
}
|
|
}
|
|
|
|
strcpy( lpszLanguage, strLang );
|
|
|
|
return multi_lang;
|
|
}
|
|
|
|
CResInfo*
|
|
CFileModule::GetResInfo( LPCSTR lpszType, LPCSTR lpszId, DWORD dwLang )
|
|
{
|
|
BOOL fIdName = HIWORD(lpszId);
|
|
BOOL fTypeName = HIWORD(lpszType);
|
|
CResInfo* pResInfo;
|
|
|
|
// We must have at least the type to procede
|
|
if(!lpszType)
|
|
return LPNULL;
|
|
|
|
for( INT_PTR i = 0, iUpperBoundRes = m_ResArray.GetUpperBound() ; i<=iUpperBoundRes ; i++)
|
|
{
|
|
pResInfo = (CResInfo*)m_ResArray.GetAt(i);
|
|
if(pResInfo)
|
|
{
|
|
if( fTypeName ? !strcmp(pResInfo->GetTypeName(), lpszType) : pResInfo->GetTypeId()==LOWORD(lpszType))
|
|
{
|
|
// do we need the ID and language or can we exit
|
|
if(!lpszId)
|
|
return pResInfo;
|
|
|
|
if( fIdName ? !strcmp(pResInfo->GetResName(), lpszId) : pResInfo->GetResId()==LOWORD(lpszId))
|
|
{
|
|
// are we done or we want the language as well
|
|
if((LONG)dwLang==-1)
|
|
return pResInfo;
|
|
|
|
if( dwLang==pResInfo->GetLanguage() )
|
|
return pResInfo;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return LPNULL;
|
|
}
|
|
|
|
DWORD
|
|
CFileModule::GetImage( LPCSTR lpszType,
|
|
LPCSTR lpszId,
|
|
DWORD dwLang,
|
|
LPVOID lpbuffer,
|
|
DWORD dwBufSize )
|
|
{
|
|
// Check if all the parameters are valid
|
|
if (!lpszType) return 0L;
|
|
if (!lpszId) return 0L;
|
|
//if (!dwLang) return 0L;
|
|
|
|
CResInfo* pResInfo = GetResInfo( lpszType, lpszId, dwLang );
|
|
|
|
if (!m_DllHInstance)
|
|
if (!LoadDll()) return 0L;
|
|
|
|
if (pResInfo)
|
|
return pResInfo->GetImage( m_SrcFileName, m_DllHInstance, lpbuffer, dwBufSize );
|
|
|
|
return 0L;
|
|
}
|
|
|
|
DWORD
|
|
CFileModule::UpdateImage( LPCSTR lpszType,
|
|
LPCSTR lpszId,
|
|
DWORD dwLang,
|
|
DWORD dwUpdLang,
|
|
LPVOID lpbuffer,
|
|
DWORD dwBufSize )
|
|
{
|
|
// Check if all the parameters are valid
|
|
if (!lpszType) return 0L;
|
|
if (!lpszId) return 0L;
|
|
|
|
CResInfo* pResInfo = GetResInfo( lpszType, lpszId, dwLang );
|
|
|
|
if (!m_DllHInstance)
|
|
if (!LoadDll()) return 0L;
|
|
if (pResInfo)
|
|
return pResInfo->ReplaceImage(lpbuffer, dwBufSize, dwUpdLang );
|
|
|
|
return 0L;
|
|
}
|
|
|
|
|
|
UINT
|
|
CFileModule::GetData( LPCSTR lpszType,
|
|
LPCSTR lpszId,
|
|
DWORD dwLang,
|
|
DWORD dwItem,
|
|
LPVOID lpbuffer,
|
|
UINT uiBufSize )
|
|
{
|
|
// Check if all the parameters are valid
|
|
if (!lpszType) return 0L;
|
|
if (!lpszId) return 0L;
|
|
//if (!dwLang) return 0L;
|
|
|
|
CResInfo* pResInfo = GetResInfo( lpszType, lpszId, dwLang );
|
|
|
|
if (!m_DllHInstance)
|
|
if (LoadDll()==NULL) return 0L;
|
|
|
|
UINT uiSize = 0;
|
|
if (pResInfo)
|
|
uiSize = pResInfo->GetData( m_SrcFileName, m_DllHInstance,
|
|
dwItem, lpbuffer, uiBufSize );
|
|
|
|
return uiSize;
|
|
}
|
|
|
|
UINT
|
|
CFileModule::UpdateData( LPCSTR lpszType,
|
|
LPCSTR lpszId,
|
|
DWORD dwLang,
|
|
DWORD dwItem,
|
|
LPVOID lpbuffer,
|
|
UINT uiBufSize )
|
|
{
|
|
// Check if all the parameters are valid
|
|
if (!lpszType) return 0L;
|
|
if (!lpszId) return 0L;
|
|
//if (!dwLang) return 0L;
|
|
|
|
CResInfo* pResInfo = GetResInfo( lpszType, lpszId, dwLang );
|
|
|
|
if (!m_DllHInstance)
|
|
if (LoadDll()==NULL) return 0L;
|
|
|
|
UINT uiError = ERROR_NO_ERROR;
|
|
if (pResInfo)
|
|
uiError = pResInfo->UpdateData( m_SrcFileName, m_DllHInstance,
|
|
dwItem, lpbuffer, uiBufSize );
|
|
|
|
return uiError;
|
|
}
|
|
|
|
void
|
|
CFileModule::GenerateIdTable( LPCSTR lpszType, BOOL bNameOrId )
|
|
{
|
|
m_IdArray.RemoveAll();
|
|
|
|
CResInfo* pResInfo;
|
|
for( WORD c=0, UpperBound= (WORD)m_ResArray.GetUpperBound(); c<=UpperBound; c++) {
|
|
pResInfo = (CResInfo*)m_ResArray.GetAt(c);
|
|
|
|
if(bNameOrId) {
|
|
if (pResInfo->GetTypeId() && pResInfo->GetTypeName()=="") {
|
|
if (pResInfo->GetTypeId()==(WORD)LOWORD((DWORD)(DWORD_PTR)lpszType)) {
|
|
//TRACE2("IODLL.DLL: CFileModule::EnumId %d %d\n", c,
|
|
// (WORD)LOWORD((DWORD)lpszType) );
|
|
m_IdArray.Add( c );
|
|
}
|
|
m_LastTypeID = (LPSTR)lpszType;
|
|
m_LastTypeName[0] = '\0';
|
|
} else {
|
|
if (HIWORD((DWORD)(DWORD_PTR)lpszType)!=0) {
|
|
if (pResInfo->GetTypeName()==(CString)(lpszType))
|
|
m_IdArray.Add( c );
|
|
strcpy(m_LastTypeName, lpszType);
|
|
m_LastTypeID = LPNULL;
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
if (pResInfo->GetTypeId()) {
|
|
if (pResInfo->GetTypeId()==(WORD)LOWORD((DWORD)(DWORD_PTR)lpszType)) {
|
|
//TRACE2("IODLL.DLL: CFileModule::EnumId %d %d\n", c,
|
|
// (WORD)LOWORD((DWORD)lpszType) );
|
|
m_IdArray.Add( c );
|
|
}
|
|
m_LastTypeID = (LPSTR)lpszType;
|
|
m_LastTypeName[0] = '\0';
|
|
} else {
|
|
if (HIWORD((DWORD)(DWORD_PTR)lpszType)!=0) {
|
|
if (pResInfo->GetTypeName()==(CString)(lpszType))
|
|
m_IdArray.Add( c );
|
|
strcpy(m_LastTypeName, lpszType);
|
|
m_LastTypeID = LPNULL;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
UINT
|
|
CFileModule::WriteUpdatedResource( LPCSTR lpszTgtfilename, HANDLE hFileModule, LPCSTR szSymbolPath)
|
|
{
|
|
UINT uiError = ERROR_NO_ERROR;
|
|
// We have to check which resource have been updated and
|
|
// generate a list to give back to the RW module
|
|
CResInfo* pResInfo;
|
|
TRACE1("CFileModule::WriteUpdatedResource\tNewSize: %ld\n", (LONG)m_ResBufSize);
|
|
BYTE * pBuf = new BYTE[m_ResBufSize];
|
|
BYTE * pBufStart = pBuf;
|
|
BYTE * pBufPos = pBuf;
|
|
BYTE bPad = 0;
|
|
BOOL bIsTmp = FALSE;
|
|
if (!pBuf)
|
|
return ERROR_NEW_FAILED;
|
|
if (!m_DllHInstance)
|
|
if (LoadDll()==NULL) return 0L;
|
|
|
|
UINT uiBufSize = 0;
|
|
|
|
// MAC RW fixes. Since the MAC RW will update images while updating images
|
|
// The list of updated images could potentialy be wrong. We first scan the list for
|
|
// Updated resources and then we will do the same thing to write the list in the buffer.
|
|
// So for instance updating the DLG image will update a DITL connected with
|
|
// the DLG itself. If the DITL was already gone in the for loop we would
|
|
// skip it and never save the DITL image that is now updated.
|
|
for( INT_PTR c=0, UpperBound = m_ResArray.GetUpperBound(); c<=UpperBound ; c++) {
|
|
pResInfo = (CResInfo*) m_ResArray.GetAt(c);
|
|
if(!pResInfo)
|
|
return ERROR_IO_RESINFO_NULL;
|
|
|
|
if(!pResInfo->GetFileOffset()) {
|
|
// The offset is null. This mean that the resource has been updated.
|
|
// Check if the image is up to date or not
|
|
if (!pResInfo->GetUpdImage()) {
|
|
DWORD dwSize = pResInfo->UpdateImage( 0,
|
|
m_DllHInstance,
|
|
(LPCSTR)UlongToPtr(pResInfo->GetTypeId()) );
|
|
if (dwSize)
|
|
if(pResInfo->UpdateImage( dwSize,
|
|
m_DllHInstance,
|
|
(LPCSTR)UlongToPtr(pResInfo->GetTypeId()))) {
|
|
delete []pBufStart;
|
|
return ERROR_IO_UPDATEIMAGE;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Now add the image to the list...
|
|
for( c=0, UpperBound = m_ResArray.GetUpperBound(); c<=UpperBound ; c++) {
|
|
pResInfo = (CResInfo*) m_ResArray.GetAt(c);
|
|
if(!pResInfo)
|
|
return ERROR_IO_RESINFO_NULL;
|
|
|
|
if(!pResInfo->GetFileOffset()) {
|
|
// Write the information in the bufer and give it back to the RW module
|
|
pBufPos = pBuf;
|
|
*((WORD*)pBuf) = pResInfo->GetTypeId();
|
|
pBuf += sizeofWord;
|
|
|
|
strcpy((char*)pBuf, pResInfo->GetTypeName());
|
|
pBuf += (pResInfo->GetTypeName()).GetLength()+1;
|
|
|
|
// Check the allignment
|
|
bPad = Pad4((BYTE)(pBuf-pBufPos));
|
|
while (bPad) {
|
|
*pBuf = 0x00;
|
|
pBuf += 1;
|
|
bPad--;
|
|
}
|
|
|
|
*((WORD*)pBuf) = pResInfo->GetResId();
|
|
pBuf += sizeofWord;
|
|
|
|
strcpy((char*)pBuf, pResInfo->GetResName());
|
|
pBuf += (pResInfo->GetResName()).GetLength()+1;
|
|
|
|
// Check the allignment
|
|
bPad = Pad4((BYTE)(pBuf-pBufPos));
|
|
while (bPad) {
|
|
*pBuf = 0x00;
|
|
pBuf += 1;
|
|
bPad--;
|
|
}
|
|
|
|
*((DWORD*)pBuf) = pResInfo->GetAllLanguage();
|
|
pBuf += sizeofDWord;
|
|
|
|
*((DWORD*)pBuf) = pResInfo->GetSize();
|
|
pBuf += sizeofDWord;
|
|
|
|
uiBufSize += (UINT)(pBuf-pBufPos);
|
|
|
|
TRACE1("TypeId: %d\t", pResInfo->GetTypeId());
|
|
TRACE1("TypeName: %s\t", pResInfo->GetTypeName());
|
|
TRACE1("NameId: %d\t", pResInfo->GetResId());
|
|
TRACE1("NameName: %s\t", pResInfo->GetResName());
|
|
TRACE1("ResLang: %lu\t", pResInfo->GetLanguage());
|
|
TRACE1("ResSize: %lu\n", pResInfo->GetSize());
|
|
|
|
//TRACE1("uiError: %u\n", uiSize);
|
|
}
|
|
}
|
|
|
|
UINT (FAR PASCAL * lpfnWriteFile)(LPCSTR, LPCSTR, HANDLE, LPVOID, UINT, HINSTANCE, LPCSTR);
|
|
// Get the pointer to the function to extract the resources
|
|
lpfnWriteFile = (UINT (FAR PASCAL *)(LPCSTR, LPCSTR, HANDLE, LPVOID, UINT, HINSTANCE, LPCSTR))
|
|
GetProcAddress( m_DllHInstance, "RWWriteFile" );
|
|
if (lpfnWriteFile==NULL) {
|
|
delete []pBufStart;
|
|
return (DWORD)ERROR_DLL_PROC_ADDRESS;
|
|
}
|
|
|
|
CString szTgtFilename = lpszTgtfilename;
|
|
|
|
|
|
// We have to check if the filename is a full qualified filename
|
|
CFileStatus status;
|
|
|
|
strcpy(status.m_szFullName, lpszTgtfilename);
|
|
if (CFile::GetStatus( lpszTgtfilename, status ))
|
|
// The file exist, get the full file name
|
|
szTgtFilename = status.m_szFullName;
|
|
|
|
// Generate a temporary file name
|
|
bIsTmp = TRUE;
|
|
CString cszTmpPath;
|
|
DWORD dwRet = GetTempPath( 512, cszTmpPath.GetBuffer(512));
|
|
cszTmpPath.ReleaseBuffer(-1);
|
|
if(dwRet>512 )
|
|
dwRet = GetTempPath( dwRet, cszTmpPath.GetBuffer(dwRet));
|
|
cszTmpPath.ReleaseBuffer(-1);
|
|
|
|
if(dwRet==0 || GetFileAttributes(cszTmpPath) != FILE_ATTRIBUTE_DIRECTORY){
|
|
// Failed to get the temporary path fail, default to local dir
|
|
dwRet = GetCurrentDirectory(512, cszTmpPath.GetBuffer(512));
|
|
if(dwRet>512 )
|
|
dwRet = GetCurrentDirectory( dwRet, cszTmpPath.GetBuffer(dwRet));
|
|
}
|
|
|
|
GetTempFileName(cszTmpPath, "RLT", 0, szTgtFilename.GetBuffer(_MAX_PATH));
|
|
szTgtFilename.ReleaseBuffer();
|
|
|
|
szTgtFilename.MakeUpper();
|
|
|
|
// Check if the size of the file is bigger that the size on the HD
|
|
if (CFile::GetStatus( m_SrcFileName, status )) {
|
|
// Get drive number
|
|
BYTE ndrive = ((BYTE)*szTgtFilename.GetBuffer(0)-(BYTE)'A')+1;
|
|
|
|
|
|
// Get the space on the HD
|
|
struct _diskfree_t diskfree;
|
|
if(_getdiskfree(ndrive, &diskfree)) {
|
|
delete []pBufStart;
|
|
return ERROR_OUT_OF_DISKSPACE;
|
|
}
|
|
if ( (status.m_size*3/diskfree.bytes_per_sector)>
|
|
(DWORD)(diskfree.avail_clusters*(DWORD)diskfree.sectors_per_cluster)) {
|
|
delete []pBufStart;
|
|
return ERROR_OUT_OF_DISKSPACE;
|
|
}
|
|
|
|
}
|
|
|
|
TRY
|
|
{
|
|
uiError = (*lpfnWriteFile)((LPCSTR)m_SrcFileName,
|
|
(LPCSTR)szTgtFilename,
|
|
(HANDLE)hFileModule,
|
|
(LPVOID)pBufStart,
|
|
(UINT)uiBufSize,
|
|
(HINSTANCE)NULL,
|
|
(LPCSTR)szSymbolPath);
|
|
}
|
|
CATCH(CFileException, fe)
|
|
{
|
|
uiError = fe->m_lOsError+LAST_ERROR;
|
|
}
|
|
AND_CATCH( CMemoryException, e )
|
|
{
|
|
uiError = ERROR_NEW_FAILED;
|
|
}
|
|
AND_CATCH( CException, e )
|
|
{
|
|
uiError = ERROR_NEW_FAILED;
|
|
}
|
|
END_CATCH
|
|
|
|
delete []pBufStart;
|
|
|
|
if ( bIsTmp ) {
|
|
if (uiError < LAST_WRN) {
|
|
TRY {
|
|
//
|
|
// BUG: 409
|
|
// We will rename if on the same drive. Otherwise copy it
|
|
//
|
|
if (_strnicmp( szTgtFilename, lpszTgtfilename, 1 )) {
|
|
UINT ErrTmp;
|
|
TRACE("\t\tCopyFile:\tszTgtFilename: %s\tlpszTgtfilename: %s\n", szTgtFilename.GetBuffer(0), lpszTgtfilename);
|
|
ErrTmp = CopyFile( szTgtFilename, lpszTgtfilename );
|
|
if (ErrTmp){
|
|
uiError = ErrTmp+LAST_ERROR;
|
|
}
|
|
} else {
|
|
TRACE("\t\tMoveFile:\tszTgtFilename: %s\tlpszTgtfilename: %s\n", szTgtFilename.GetBuffer(0), lpszTgtfilename );
|
|
// Remove temporary file
|
|
if(CFile::GetStatus( lpszTgtfilename, status ))
|
|
CFile::Remove(lpszTgtfilename);
|
|
CFile::Rename(szTgtFilename, lpszTgtfilename);
|
|
}
|
|
// Remove temporary file
|
|
if(CFile::GetStatus( szTgtFilename, status ))
|
|
CFile::Remove(szTgtFilename);
|
|
}
|
|
CATCH( CFileException, fe )
|
|
{
|
|
uiError = fe->m_lOsError+LAST_ERROR;
|
|
}
|
|
AND_CATCH( CException, e )
|
|
{
|
|
uiError = ERROR_NEW_FAILED;
|
|
}
|
|
END_CATCH
|
|
}
|
|
}
|
|
|
|
return uiError;
|
|
}
|
|
|
|
UINT
|
|
CFileModule::CopyImage( CFileModule* pFileModule, LPCSTR lpszType, LPCSTR lpszResId )
|
|
{
|
|
CResInfo* pResInfo;
|
|
CResInfo* pTgtResInfo;
|
|
int iResID = (HIWORD(lpszResId) ? 0 : LOWORD(lpszResId) );
|
|
int iTypeID = (HIWORD(lpszType) ? 0 : LOWORD(lpszType) );
|
|
|
|
// Find the CResInfo object we have to copy
|
|
INT_PTR c = m_ResArray.GetUpperBound();
|
|
while(c>=0)
|
|
{
|
|
pResInfo = (CResInfo*)m_ResArray.GetAt(c--);
|
|
if(!pResInfo)
|
|
return ERROR_IO_INVALIDITEM;
|
|
|
|
// Check the type ID
|
|
if( iTypeID && pResInfo->GetTypeName()=="" && (int)pResInfo->GetTypeId()==iTypeID) {
|
|
// Check for the res ID
|
|
if( iResID && (int)pResInfo->GetResId()==iResID) {
|
|
c = -2;
|
|
}
|
|
// check for the res name
|
|
else if( (iResID==0) && pResInfo->GetResName()==lpszResId) {
|
|
c = -2;
|
|
}
|
|
}
|
|
// check for the type name
|
|
else if( HIWORD(lpszType) && pResInfo->GetTypeName()==lpszType) {
|
|
// Check for the res ID
|
|
if( iResID && (int)pResInfo->GetResId()==iResID) {
|
|
c = -2;
|
|
}
|
|
// check for the res name
|
|
else if( (iResID==0) && pResInfo->GetResName()==lpszResId) {
|
|
c = -2;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (c==-1)
|
|
return ERROR_IO_INVALIDID;
|
|
|
|
// find were we have to copy it
|
|
c = pFileModule->m_ResArray.GetUpperBound();
|
|
while(c>=0)
|
|
{
|
|
pTgtResInfo = (CResInfo*)pFileModule->m_ResArray.GetAt(c--);
|
|
if(!pTgtResInfo)
|
|
return ERROR_IO_INVALIDITEM;
|
|
|
|
// Check the type ID
|
|
if( iTypeID && pTgtResInfo->GetTypeName()=="" && (int)pTgtResInfo->GetTypeId()==iTypeID) {
|
|
// Check for the res ID
|
|
if( iResID && (int)pTgtResInfo->GetResId()==iResID) {
|
|
c = -2;
|
|
}
|
|
// check for the res name
|
|
else if( (iResID==0) && pTgtResInfo->GetResName()==lpszResId) {
|
|
c = -2;
|
|
}
|
|
}
|
|
// check for the type name
|
|
else if( HIWORD(lpszType) && pTgtResInfo->GetTypeName()==lpszType) {
|
|
// Check for the res ID
|
|
if( iResID && (int)pTgtResInfo->GetResId()==iResID) {
|
|
c = -2;
|
|
}
|
|
// check for the res name
|
|
else if( (iResID==0) && pTgtResInfo->GetResName()==lpszResId) {
|
|
c = -2;
|
|
}
|
|
}
|
|
}
|
|
|
|
if(c==-1)
|
|
return ERROR_IO_INVALIDID;
|
|
|
|
// Load the image in memory from the res file
|
|
DWORD dwReadSize = pTgtResInfo->LoadImage( pFileModule->GetName(),
|
|
pFileModule->GetHInstance() );
|
|
if (dwReadSize!=pTgtResInfo->GetSize())
|
|
return ERROR_RW_LOADIMAGE;
|
|
|
|
// copy the image from the res file
|
|
pTgtResInfo->CopyImage( pResInfo );
|
|
|
|
// We have to mark the resource has updated
|
|
pTgtResInfo->SetFileOffset(0L);
|
|
pTgtResInfo->SetImageUpdated(0);
|
|
|
|
return 0;
|
|
}
|
|
|
|
UINT
|
|
CFileModule::Copy( CFileModule* pFileModule )
|
|
{
|
|
CResInfo* pResInfo;
|
|
CResInfo* pTgtResInfo;
|
|
int TgtPos;
|
|
m_dwFlags = pFileModule->m_dwFlags;
|
|
|
|
for(INT_PTR u = m_ResArray.GetUpperBound(), c=0; c<=u ; c++) {
|
|
pResInfo = (CResInfo*) m_ResArray.GetAt(c);
|
|
if(!pResInfo)
|
|
return ERROR_IO_INVALIDITEM;
|
|
TgtPos = pFileModule->AddResInfo( pResInfo->GetTypeId(),
|
|
pResInfo->GetTypeName(),
|
|
pResInfo->GetResId(),
|
|
pResInfo->GetResName(),
|
|
pResInfo->GetLanguage(),
|
|
0,
|
|
0);
|
|
pTgtResInfo = (CResInfo*) pFileModule->GetResInfo( TgtPos );
|
|
if(!pTgtResInfo)
|
|
return ERROR_IO_INVALIDITEM;
|
|
pResInfo->Copy( pTgtResInfo, m_SrcFileName, m_DllHInstance );
|
|
}
|
|
return ERROR_NO_ERROR;
|
|
}
|
|
|
|
LPCSTR
|
|
CFileModule::EnumType( LPCSTR lpszPrevType)
|
|
{
|
|
if (lpszPrevType) {
|
|
// Check if the value we get is consistent.
|
|
if (m_TypePos==0) return LPNULL;
|
|
if (m_TypePos==m_TypeArray.GetSize()) {
|
|
m_TypePos = 0;
|
|
return LPNULL;
|
|
}
|
|
CResInfo* pResInfo = (CResInfo*)m_ResArray.GetAt(m_TypeArray.GetAt(m_TypePos-1));
|
|
if(HIWORD(lpszPrevType)) {
|
|
if(pResInfo->GetTypeName() != lpszPrevType)
|
|
return LPNULL;
|
|
}
|
|
else {
|
|
if((DWORD_PTR)pResInfo->GetTypeId()!=(DWORD_PTR)lpszPrevType)
|
|
return LPNULL;
|
|
}
|
|
} else {
|
|
// It is the first time we have been called.
|
|
// Generate the list of Types
|
|
m_TypePos = 0;
|
|
|
|
if (!m_TypeArray.GetSize())
|
|
// We have to generate the TABLE
|
|
for( INT_PTR c=0, UpperBound=m_ResArray.GetUpperBound(); c<=UpperBound; c++)
|
|
AddTypeInfo( c,
|
|
((CResInfo*)m_ResArray[c])->GetTypeId(),
|
|
((CResInfo*)m_ResArray[c])->GetTypeName());
|
|
|
|
if (m_TypePos==m_TypeArray.GetSize()) {
|
|
m_TypePos = 0;
|
|
return LPNULL;
|
|
}
|
|
}
|
|
|
|
|
|
CResInfo* pResInfo = (CResInfo*)m_ResArray.GetAt(m_TypeArray.GetAt(m_TypePos++));
|
|
if (pResInfo->GetTypeId() && pResInfo->GetTypeName()==""){
|
|
// It is an ordinal ID
|
|
DWORD dwReturn = 0L;
|
|
dwReturn = (DWORD)pResInfo->GetTypeId();
|
|
return (LPCSTR) UlongToPtr(dwReturn);
|
|
} else {
|
|
// It is a string type
|
|
strcpy( m_TypeStr, pResInfo->GetTypeName());
|
|
return m_TypeStr;
|
|
}
|
|
}
|
|
|
|
LPCSTR
|
|
CFileModule::EnumId( LPCSTR lpszType, LPCSTR lpszPrevId )
|
|
{
|
|
if (!lpszType) return LPNULL;
|
|
|
|
if(!lpszPrevId)
|
|
{
|
|
if(m_IdPos==0)
|
|
{
|
|
// Create the list of resources
|
|
BOOL fTypeName = HIWORD(lpszType);
|
|
CResInfo* pResInfo;
|
|
|
|
m_IdArray.RemoveAll();
|
|
|
|
for( WORD i = 0, iUpperBoundRes = (WORD)m_ResArray.GetUpperBound() ; i<=iUpperBoundRes ; i++)
|
|
{
|
|
pResInfo = (CResInfo*)m_ResArray.GetAt(i);
|
|
if(pResInfo)
|
|
{
|
|
if( fTypeName ? !strcmp(pResInfo->GetTypeName(), lpszType) : pResInfo->GetTypeId()==LOWORD(lpszType))
|
|
{
|
|
// add this item to the LangArray
|
|
m_IdArray.Add(i);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
ASSERT(m_IdArray.GetSize());
|
|
|
|
if (m_IdPos>=m_IdArray.GetSize())
|
|
{
|
|
m_IdPos = 0;
|
|
return LPNULL;
|
|
}
|
|
|
|
// We will increment m_IdPos in the lang enum since we use the same array m_IdArray
|
|
CResInfo* pResInfo = (CResInfo*)m_ResArray.GetAt(m_IdArray.GetAt(m_IdPos));
|
|
if( pResInfo )
|
|
{
|
|
if (pResInfo->GetResId()){
|
|
// It is an ordinal ID
|
|
return (LPCSTR)pResInfo->GetResId();
|
|
} else {
|
|
// It is a string type
|
|
strcpy( m_IdStr, pResInfo->GetResName());
|
|
return m_IdStr;
|
|
}
|
|
}
|
|
|
|
return LPNULL;
|
|
}
|
|
|
|
DWORD
|
|
CFileModule::EnumLang( LPCSTR lpszType, LPCSTR lpszId, DWORD dwPrevLang )
|
|
{
|
|
// Parameter checking
|
|
if (!lpszType) return 0L;
|
|
if (!lpszId) return 0L;
|
|
|
|
ASSERT(m_IdArray.GetSize());
|
|
|
|
// This is true when we have done all the languages
|
|
// Return null but keep the m_IdPos, this will let us exit safelly from the
|
|
// EnumId function
|
|
if (m_IdPos==m_IdArray.GetSize())
|
|
{
|
|
return LPNULL;
|
|
}
|
|
|
|
CResInfo* pResInfo = (CResInfo*)m_ResArray.GetAt(m_IdArray.GetAt(m_IdPos++));
|
|
if( pResInfo )
|
|
{
|
|
// Check if the ID match
|
|
if(HIWORD(lpszId) ? !strcmp(lpszId, pResInfo->GetResName() ) : LOWORD(lpszId)==pResInfo->GetResId() )
|
|
{
|
|
if(pResInfo->GetLanguage()!=0)
|
|
return pResInfo->GetLanguage();
|
|
else
|
|
return 0xFFFFFFFF; // for the neutral language case
|
|
}
|
|
}
|
|
|
|
m_IdPos--;
|
|
return 0;
|
|
}
|
|
|
|
DWORD
|
|
CFileModule::EnumItem( LPCSTR lpszType, LPCSTR lpszId, DWORD dwLang, DWORD dwPrevItem )
|
|
{
|
|
// Check if all the parameters are valid
|
|
if (!lpszType) return 0L;
|
|
if (!lpszId) return 0L;
|
|
//if (!dwLang) return 0L;
|
|
|
|
CResInfo* pResInfo = GetResInfo( lpszType, lpszId, dwLang );
|
|
|
|
if (!m_DllHInstance)
|
|
if (LoadDll()==NULL) return 0L;
|
|
|
|
if (pResInfo)
|
|
return pResInfo->EnumItem( m_SrcFileName, m_DllHInstance, dwPrevItem );
|
|
return 0L;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// CDllTable
|
|
|
|
CDllTable::CDllTable( UINT InitNum )
|
|
{
|
|
|
|
//TRACE1("IODLL.DLL: CDllTable::CDllTable %d\n", InitNum);
|
|
m_InitNum = InitNum;
|
|
PCHAR pkey;
|
|
PCHAR pbuf = new char[InitNum];
|
|
if (pbuf==LPNULL) return;
|
|
|
|
GetProfileString(SECTION, NULL, "", pbuf, InitNum);
|
|
|
|
int c;
|
|
if (*pbuf != '\0')
|
|
{
|
|
PCHAR pkey;
|
|
CString szString;
|
|
|
|
PCHAR pstr = new char[InitNum];
|
|
for( pkey = pbuf, c = 0;
|
|
*pkey != '\0' ; pkey += strlen(pkey)+1 ) {
|
|
GetProfileString( SECTION, pkey, "Empty", pstr, InitNum);
|
|
szString = pstr;
|
|
if (!szString.IsEmpty())
|
|
Add( new CDllEntryTable(szString) );
|
|
c++;
|
|
}
|
|
delete pstr;
|
|
}
|
|
else
|
|
{
|
|
for (pkey = szDefaultRWDll[0], c=0;
|
|
c < sizeof(szDefaultRWDll)/MAXKEYLEN/sizeof(TCHAR) ; pkey+= MAXKEYLEN)
|
|
{
|
|
Add ( new CDllEntryTable(pkey) );
|
|
c++;
|
|
}
|
|
}
|
|
m_MaxEntry = c+1;
|
|
|
|
delete pbuf;
|
|
|
|
return;
|
|
}
|
|
|
|
UINT CDllTable::GetPosFromTable( CString szFileType )
|
|
{
|
|
UINT c = 0;
|
|
|
|
// Check if the string type is not empty
|
|
if (szFileType.IsEmpty()) return 0;
|
|
|
|
while( (szFileType!=((CDllEntryTable*)GetAt(c))->GetType()) && (c<m_MaxEntry) ) c++;
|
|
|
|
// Be really sure
|
|
if ((szFileType!=((CDllEntryTable*)GetAt(c))->GetType()))
|
|
// 0 Is an invalid position in the Table for us
|
|
return 0;
|
|
return c+1;
|
|
}
|
|
|
|
CDllTable::~CDllTable()
|
|
{
|
|
INT_PTR UpperBound = GetUpperBound();
|
|
//TRACE1("IODLL.DLL: CDllTable::~CDllTable %d\n", UpperBound);
|
|
CDllEntryTable* pDllEntry;
|
|
for( int c=0 ; c<=UpperBound ; c++) {
|
|
pDllEntry = (CDllEntryTable*)GetAt(c);
|
|
//TRACE1("\tCDllTable\tCDllEntryTable->%Fp\n", pDllEntry);
|
|
delete pDllEntry;
|
|
}
|
|
RemoveAll();
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// CModuleTable
|
|
|
|
CModuleTable::CModuleTable( UINT InitNum)
|
|
{
|
|
//TRACE1("IODLL.DLL: CModuleTable::CModuleTable %d\n", InitNum);
|
|
m_InitNum = InitNum;
|
|
m_LastHandle = 0;
|
|
}
|
|
|
|
CModuleTable::~CModuleTable()
|
|
{
|
|
INT_PTR UpperBound = GetUpperBound();
|
|
//TRACE1("IODLL.DLL: CModuleTable::~CModuleTable %d\n", UpperBound);
|
|
CFileModule* pFileModule;
|
|
for( int c=0 ; c<=UpperBound ; c++) {
|
|
pFileModule = (CFileModule*)GetAt(c);
|
|
//TRACE1("\tCModuleTable\tCFileModule->%Fp\n", pFileModule);
|
|
pFileModule->CleanUp();
|
|
delete pFileModule;
|
|
}
|
|
RemoveAll();
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// CDllEntryTable
|
|
|
|
CDllEntryTable::CDllEntryTable( CString szEntry )
|
|
{
|
|
int chPos;
|
|
if ( (chPos = szEntry.Find(","))==-1 ) {
|
|
m_szDllName = "";
|
|
m_szDllType = "";
|
|
return;
|
|
}
|
|
|
|
m_szDllName = szEntry.Left(chPos);
|
|
szEntry = szEntry.Right(szEntry.GetLength()-chPos-1);
|
|
|
|
m_szDllType = szEntry;
|
|
m_handle = NULL;
|
|
}
|
|
|
|
CDllEntryTable::~CDllEntryTable()
|
|
{
|
|
FreeEntry();
|
|
}
|
|
|
|
HINSTANCE CDllEntryTable::LoadEntry()
|
|
{
|
|
if(!m_handle) {
|
|
m_handle = LoadLibrary(m_szDllName);
|
|
TRACE("CDllEntryTable::LoadEntry: %s loaded at %p\n",m_szDllName.GetBuffer(0), (UINT_PTR)m_handle);
|
|
}
|
|
return m_handle;
|
|
}
|
|
|
|
BOOL CDllEntryTable::FreeEntry()
|
|
{
|
|
BOOL bRet = FALSE;
|
|
if(m_handle) {
|
|
bRet = FreeLibrary(m_handle);
|
|
TRACE("CDllEntryTable::FreeEntry: %s FreeLibrary return %d\n",m_szDllName.GetBuffer(0),bRet);
|
|
}
|
|
return bRet;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// CResInfo
|
|
|
|
CResInfo::CResInfo( WORD Typeid, CString sztypeid,
|
|
WORD nameid, CString sznameid,
|
|
DWORD dwlang, DWORD dwsize, DWORD dwfileoffset, CFileModule * pFileModule )
|
|
{
|
|
m_FileOffset = dwfileoffset;
|
|
m_FileSize = dwsize;
|
|
|
|
m_Language = MAKELONG(LOWORD(dwlang),LOWORD(dwlang));
|
|
|
|
m_TypeName = sztypeid;
|
|
m_TypeId = Typeid;
|
|
|
|
m_ResName = sznameid;
|
|
m_ResId = nameid;
|
|
|
|
m_lpImageBuf = LPNULL;
|
|
m_dwImageSize = 0L;
|
|
|
|
m_ItemPos = 0;
|
|
|
|
m_pFileModule = pFileModule;
|
|
}
|
|
|
|
CResInfo::~CResInfo()
|
|
{
|
|
//TRACE("IODLL.DLL: CResInfo::~CResInfo\n");
|
|
FreeImage();
|
|
FreeItemArray();
|
|
}
|
|
|
|
void
|
|
CResInfo::FreeImage()
|
|
{
|
|
if (m_lpImageBuf)
|
|
delete []m_lpImageBuf;
|
|
|
|
m_lpImageBuf = LPNULL;
|
|
m_dwImageSize = 0L;
|
|
}
|
|
|
|
void
|
|
CResInfo::FreeItemArray()
|
|
{
|
|
CItemInfo* pItemInfo;
|
|
for( INT_PTR c=0, UpperBound=m_ItemArray.GetUpperBound(); c<=UpperBound; c++) {
|
|
pItemInfo = (CItemInfo*)m_ItemArray.GetAt(c);
|
|
delete pItemInfo;
|
|
}
|
|
|
|
m_ItemArray.RemoveAll();
|
|
}
|
|
|
|
UINT
|
|
CResInfo::AllocImage(DWORD dwSize)
|
|
{
|
|
// Check if we have to free the value in m_lpImageBuf
|
|
if (m_lpImageBuf)
|
|
FreeImage();
|
|
|
|
//TRACE2("CResInfo::AllocImage\tNewSize: %ld\tNum: %ld\n", (LONG)dwSize, lRequestLast+1);
|
|
TRACE1("CResInfo::AllocImage\tNewSize: %ld\n", (LONG)dwSize);
|
|
m_lpImageBuf = new BYTE[dwSize];
|
|
if (!m_lpImageBuf) {
|
|
TRACE("\n"
|
|
"************* ERROR **********\n"
|
|
"CResInfo::AllocImage: New Failed!! BYTE far * lpImageBuf = new BYTE[dwSize];\n"
|
|
"************* ERROR **********\n"
|
|
"\n" );
|
|
return ERROR_NEW_FAILED;
|
|
}
|
|
|
|
m_dwImageSize = dwSize;
|
|
return 0;
|
|
}
|
|
|
|
DWORD
|
|
CResInfo::LoadImage( CString lpszFilename, HINSTANCE hInst )
|
|
{
|
|
if(!m_FileSize)
|
|
return 0;
|
|
|
|
if(AllocImage(m_FileSize))
|
|
return ERROR_NEW_FAILED;
|
|
|
|
// Call the RW and read thead the Image from the file
|
|
DWORD (FAR PASCAL * lpfnGetImage)(LPCSTR, DWORD, LPVOID, DWORD);
|
|
// Get the pointer to the function to extract the resources
|
|
lpfnGetImage = (DWORD (FAR PASCAL *)(LPCSTR, DWORD, LPVOID, DWORD))
|
|
GetProcAddress( hInst, "RWGetImage" );
|
|
if (lpfnGetImage==NULL) {
|
|
FreeImage();
|
|
return (DWORD)ERROR_DLL_PROC_ADDRESS;
|
|
}
|
|
|
|
DWORD dwReadSize = 0l;
|
|
if (m_FileOffset)
|
|
dwReadSize = (*lpfnGetImage)((LPCSTR)lpszFilename,
|
|
(DWORD)m_FileOffset,
|
|
(LPVOID)m_lpImageBuf,
|
|
(DWORD)m_FileSize);
|
|
if (dwReadSize!=m_FileSize) {
|
|
FreeImage();
|
|
return 0l;
|
|
}
|
|
return m_dwImageSize;
|
|
}
|
|
|
|
DWORD
|
|
CResInfo::GetImage( LPCSTR lpszFilename, HINSTANCE hInst, LPVOID lpbuffer, DWORD dwBufSize )
|
|
{
|
|
if(!m_FileSize)
|
|
return 0;
|
|
|
|
if ( (!m_lpImageBuf) && (m_FileOffset)) {
|
|
DWORD dwReadSize = LoadImage( lpszFilename, hInst );
|
|
if (dwReadSize!=m_dwImageSize)
|
|
return 0L;
|
|
}
|
|
if (dwBufSize<m_dwImageSize)
|
|
return m_dwImageSize;
|
|
|
|
memcpy( lpbuffer, m_lpImageBuf, (UINT)m_dwImageSize );
|
|
|
|
return m_dwImageSize;
|
|
}
|
|
|
|
DWORD
|
|
CResInfo::ReplaceImage( LPVOID lpNewImage, DWORD dwNewImageSize, DWORD dwUpdLang )
|
|
{
|
|
m_ImageUpdated = 1;
|
|
FreeImage();
|
|
if(!m_lpImageBuf) {
|
|
if(AllocImage(dwNewImageSize))
|
|
return ERROR_NEW_FAILED;
|
|
|
|
if (lpNewImage){
|
|
memcpy(m_lpImageBuf, lpNewImage, (UINT)dwNewImageSize);
|
|
if (dwUpdLang != 0xffffffff){
|
|
m_Language=MAKELONG(m_Language,dwUpdLang);
|
|
}
|
|
}else{
|
|
m_lpImageBuf = LPNULL;
|
|
}
|
|
|
|
// check if the size of the image is 0
|
|
if(!m_FileOffset) {
|
|
// Chances are that this is a conversion.
|
|
// set the file size to the size of the image
|
|
// to have it work in the getimage call back
|
|
m_FileSize = dwNewImageSize;
|
|
}
|
|
m_dwImageSize = dwNewImageSize;
|
|
m_FileOffset = 0;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
DWORD
|
|
CResInfo::UpdateImage( LONG dwSize, HINSTANCE hInst, LPCSTR lpszType )
|
|
{
|
|
// We have to generate a list of info and give it back to the RW
|
|
|
|
if (!dwSize) dwSize = m_dwImageSize*4+sizeof(RESITEM);
|
|
if (!dwSize) dwSize = 10000;
|
|
if (dwSize>UINT_MAX) dwSize = UINT_MAX-1024;
|
|
TRACE1("CResInfo::UpdateImage\tNewSize: %ld\n", (LONG)dwSize);
|
|
BYTE far * lpBuf = new BYTE[dwSize];
|
|
if (!lpBuf) return ERROR_NEW_FAILED;
|
|
BYTE far * lpBufStart = lpBuf;
|
|
BYTE far * lpStrBuf = lpBuf+sizeof(RESITEM);
|
|
LPRESITEM lpResItem = (LPRESITEM)lpBuf;
|
|
DWORD dwBufSize = dwSize;
|
|
CItemInfo* pItemInfo;
|
|
DWORD dwUpdLang = m_Language;
|
|
BOOL fUpdLang = TRUE;
|
|
|
|
int istrlen;
|
|
LONG lBufSize = 0;
|
|
for(INT_PTR c=0, UpperBound=m_ItemArray.GetUpperBound(); c<=UpperBound; c++) {
|
|
|
|
pItemInfo = (CItemInfo*) m_ItemArray.GetAt(c);
|
|
if (!pItemInfo)
|
|
return ERROR_IO_RESINFO_NULL;
|
|
|
|
if(fUpdLang)
|
|
{
|
|
dwUpdLang = pItemInfo->GetLanguage();
|
|
if(dwUpdLang==0xffffffff)
|
|
{
|
|
dwUpdLang = m_Language;
|
|
}
|
|
else
|
|
fUpdLang = FALSE;
|
|
}
|
|
|
|
lBufSize = (LONG)dwSize;
|
|
if (dwSize>=sizeofDWord) {
|
|
lpResItem->dwSize = sizeof(RESITEM); // Size
|
|
dwSize -= sizeofDWord;
|
|
} else dwSize -= sizeofDWord;
|
|
|
|
if (dwSize>=sizeofWord) {
|
|
lpResItem->wX = pItemInfo->GetX(); // Coordinate
|
|
dwSize -= sizeofWord;
|
|
} else dwSize -= sizeofWord;
|
|
if (dwSize>=sizeofWord) {
|
|
lpResItem->wY = pItemInfo->GetY();
|
|
dwSize -= sizeofWord;
|
|
} else dwSize -= sizeofWord;
|
|
|
|
if (dwSize>=sizeofWord) {
|
|
lpResItem->wcX = pItemInfo->GetcX(); // Position
|
|
dwSize -= sizeofWord;
|
|
} else dwSize -= sizeofWord;
|
|
if (dwSize>=sizeofWord) {
|
|
lpResItem->wcY = pItemInfo->GetcY();
|
|
dwSize -= sizeofWord;
|
|
} else dwSize -= sizeofWord;
|
|
|
|
if (dwSize>=sizeofDWord) {
|
|
lpResItem->dwCheckSum = pItemInfo->GetCheckSum(); // Checksum
|
|
dwSize -= sizeofDWord;
|
|
} else dwSize -= sizeofDWord;
|
|
|
|
if (dwSize>=sizeofDWord) {
|
|
lpResItem->dwStyle = pItemInfo->GetStyle(); // Style
|
|
dwSize -= sizeofDWord;
|
|
} else dwSize -= sizeofDWord;
|
|
|
|
if (dwSize>=sizeofDWord) {
|
|
lpResItem->dwExtStyle = pItemInfo->GetExtStyle(); // ExtendedStyle
|
|
dwSize -= sizeofDWord;
|
|
} else dwSize -= sizeofDWord;
|
|
|
|
if (dwSize>=sizeofDWord) {
|
|
lpResItem->dwFlags = pItemInfo->GetFlags(); // Flags
|
|
dwSize -= sizeofDWord;
|
|
} else dwSize -= sizeofDWord;
|
|
|
|
if (dwSize>=sizeofDWord) {
|
|
lpResItem->dwItemID = pItemInfo->GetTabPosId(); // PosId
|
|
dwSize -= sizeofDWord;
|
|
} else dwSize -= sizeofDWord;
|
|
|
|
if (dwSize>=sizeofDWord) {
|
|
lpResItem->dwResID = m_ResId; // ResourceID
|
|
dwSize -= sizeofDWord;
|
|
} else dwSize -= sizeofDWord;
|
|
if (dwSize>=sizeofDWord) {
|
|
lpResItem->dwTypeID = m_TypeId; // Type ID
|
|
dwSize -= sizeofDWord;
|
|
} else dwSize -= sizeofDWord;
|
|
if (dwSize>=sizeofDWord) {
|
|
lpResItem->dwLanguage = pItemInfo->GetLanguage(); // Language ID
|
|
dwSize -= sizeofDWord;
|
|
} else dwSize -= sizeofDWord;
|
|
|
|
if (dwSize>=sizeofDWord) {
|
|
lpResItem->dwCodePage = pItemInfo->GetCodePage(); // CodePage
|
|
dwSize -= sizeofDWord;
|
|
} else dwSize -= sizeofDWord;
|
|
|
|
if (dwSize>=sizeofWord) {
|
|
lpResItem->wClassName = pItemInfo->GetClassNameID();// ClassName
|
|
dwSize -= sizeofWord;
|
|
} else dwSize -= sizeofWord;
|
|
if (dwSize>=sizeofWord) {
|
|
lpResItem->wPointSize = pItemInfo->GetPointSize(); // CodePage
|
|
dwSize -= sizeofWord;
|
|
} else dwSize -= sizeofWord;
|
|
|
|
if (dwSize>=sizeofWord) {
|
|
lpResItem->wWeight = pItemInfo->GetWeight(); // Weight
|
|
dwSize -= sizeofWord;
|
|
} else dwSize -= sizeofWord;
|
|
|
|
if (dwSize>=sizeofByte) {
|
|
lpResItem->bItalic = pItemInfo->GetItalic(); // Italic
|
|
dwSize -= sizeofByte;
|
|
} else dwSize -= sizeofByte;
|
|
|
|
if (dwSize>=sizeofByte) {
|
|
lpResItem->bCharSet = pItemInfo->GetCharSet(); // CharSet
|
|
dwSize -= sizeofByte;
|
|
} else dwSize -= sizeofByte;
|
|
|
|
if (dwSize>=sizeofDWordPtr) {
|
|
lpResItem->lpszClassName = LPNULL;
|
|
dwSize -= sizeofDWordPtr;
|
|
} else dwSize -= sizeofDWordPtr;
|
|
if (dwSize>=sizeofDWordPtr) {
|
|
lpResItem->lpszFaceName = LPNULL;
|
|
dwSize -= sizeofDWordPtr;
|
|
} else dwSize -= sizeofDWordPtr;
|
|
if (dwSize>=sizeofDWordPtr) {
|
|
lpResItem->lpszCaption = LPNULL;
|
|
dwSize -= sizeofDWordPtr;
|
|
} else dwSize -= sizeofDWordPtr;
|
|
if (dwSize>=sizeofDWordPtr) {
|
|
lpResItem->lpszResID = LPNULL;
|
|
dwSize -= sizeofDWordPtr;
|
|
} else dwSize -= sizeofDWordPtr;
|
|
if (dwSize>=sizeofDWordPtr) {
|
|
lpResItem->lpszTypeID = LPNULL;
|
|
dwSize -= sizeofDWordPtr;
|
|
} else dwSize -= sizeofDWordPtr;
|
|
|
|
// Copy the strings
|
|
istrlen = (pItemInfo->GetClassName()).GetLength()+1;
|
|
if (dwSize>=istrlen) {
|
|
lpResItem->lpszClassName = strcpy((char*)lpStrBuf, pItemInfo->GetClassName());
|
|
lpStrBuf += istrlen;
|
|
dwSize -= istrlen;
|
|
lpResItem->dwSize += istrlen;
|
|
} else dwSize -= istrlen;
|
|
|
|
istrlen = (pItemInfo->GetFaceName()).GetLength()+1;
|
|
if (dwSize>=istrlen) {
|
|
lpResItem->lpszFaceName = strcpy((char*)lpStrBuf, pItemInfo->GetFaceName());
|
|
lpStrBuf += istrlen;
|
|
dwSize -= istrlen;
|
|
lpResItem->dwSize += istrlen;
|
|
} else dwSize -= istrlen;
|
|
|
|
istrlen = (pItemInfo->GetCaption()).GetLength()+1;
|
|
if (dwSize>=istrlen) {
|
|
lpResItem->lpszCaption = strcpy((char*)lpStrBuf, pItemInfo->GetCaption());
|
|
lpStrBuf += istrlen;
|
|
dwSize -= istrlen;
|
|
lpResItem->dwSize += istrlen;
|
|
} else dwSize -= istrlen;
|
|
|
|
istrlen = m_ResName.GetLength()+1;
|
|
if (dwSize>=istrlen) {
|
|
lpResItem->lpszResID = strcpy((char*)lpStrBuf, m_ResName);
|
|
lpStrBuf += istrlen;
|
|
dwSize -= istrlen;
|
|
lpResItem->dwSize += istrlen;
|
|
} else dwSize -= istrlen;
|
|
|
|
istrlen = m_TypeName.GetLength()+1;
|
|
if (dwSize>=istrlen) {
|
|
lpResItem->lpszTypeID = strcpy((char*)lpStrBuf, m_TypeName);
|
|
lpStrBuf += istrlen;
|
|
dwSize -= istrlen;
|
|
lpResItem->dwSize += istrlen;
|
|
} else dwSize -= istrlen;
|
|
|
|
// Check if we are alligned
|
|
BYTE bPad = Allign(lBufSize-(LONG)dwSize);
|
|
if((LONG)dwSize>=bPad) {
|
|
lpResItem->dwSize += bPad;
|
|
dwSize -= bPad;
|
|
while(bPad) {
|
|
*lpStrBuf = 0x00;
|
|
lpStrBuf += 1;
|
|
bPad--;
|
|
}
|
|
}
|
|
else dwSize -= bPad;
|
|
|
|
// move to the next item
|
|
lpResItem = (LPRESITEM) lpStrBuf;
|
|
lpStrBuf += sizeof(RESITEM);
|
|
|
|
}
|
|
|
|
if (dwSize<0){
|
|
delete []lpBufStart;
|
|
return dwBufSize-dwSize;
|
|
}
|
|
else dwSize = dwBufSize-dwSize;
|
|
|
|
// Give all back to the RW and wait
|
|
UINT (FAR PASCAL * lpfnGenerateImage)(LPCSTR, LPVOID, DWORD, LPVOID, DWORD, LPVOID, DWORD*);
|
|
UINT (FAR PASCAL * lpfnGenerateImageEx)(LPCSTR, LPVOID, DWORD, LPVOID, DWORD, LPVOID, DWORD*, LPCSTR);
|
|
|
|
//
|
|
// Trye to get the pointer to the extended version of the function...
|
|
//
|
|
lpfnGenerateImageEx = (UINT (FAR PASCAL *)(LPCSTR, LPVOID, DWORD, LPVOID, DWORD, LPVOID, DWORD*, LPCSTR))
|
|
GetProcAddress( hInst, "RWUpdateImageEx" );
|
|
|
|
if (lpfnGenerateImageEx==NULL) {
|
|
//
|
|
// get the old update image function since the RW doesn't support RC data
|
|
//
|
|
lpfnGenerateImage = (UINT (FAR PASCAL *)(LPCSTR, LPVOID, DWORD, LPVOID, DWORD, LPVOID, DWORD*))
|
|
GetProcAddress( hInst, "RWUpdateImage" );
|
|
|
|
if (lpfnGenerateImage==NULL)
|
|
return ERROR_DLL_PROC_ADDRESS;
|
|
}
|
|
|
|
DWORD dwNewImageSize = m_dwImageSize*3+sizeof(RESITEM);
|
|
if(!dwNewImageSize)
|
|
dwNewImageSize = 10000;
|
|
if (dwNewImageSize>UINT_MAX)
|
|
dwNewImageSize = UINT_MAX-1024;
|
|
DWORD dwOriginalImageSize = dwNewImageSize;
|
|
BYTE far * lpNewImage = new BYTE[dwNewImageSize];
|
|
if (!lpNewImage) {
|
|
delete []lpBufStart;
|
|
return ERROR_NEW_FAILED;
|
|
}
|
|
|
|
#ifndef _DEBUG
|
|
// set the memory to 0
|
|
memset( lpNewImage, 0, (size_t)dwNewImageSize );
|
|
#endif
|
|
|
|
UINT uiError;
|
|
if(lpfnGenerateImageEx)
|
|
{
|
|
|
|
uiError = (*lpfnGenerateImageEx)( (LPCSTR)lpszType,
|
|
(LPVOID)lpBufStart,
|
|
(DWORD) dwSize,
|
|
(LPVOID)m_lpImageBuf,
|
|
(DWORD) m_dwImageSize,
|
|
(LPVOID)lpNewImage,
|
|
(DWORD*)&dwNewImageSize,
|
|
(LPCSTR)m_pFileModule->GetRDFName()
|
|
);
|
|
}
|
|
else
|
|
{
|
|
uiError = (*lpfnGenerateImage)( (LPCSTR)lpszType,
|
|
(LPVOID)lpBufStart,
|
|
(DWORD) dwSize,
|
|
(LPVOID)m_lpImageBuf,
|
|
(DWORD) m_dwImageSize,
|
|
(LPVOID)lpNewImage,
|
|
(DWORD*)&dwNewImageSize
|
|
);
|
|
}
|
|
|
|
if (dwNewImageSize>dwOriginalImageSize) {
|
|
delete []lpNewImage;
|
|
TRACE1("CResInfo::UpdateImage\tNewSize: %ld\n", (LONG)dwNewImageSize);
|
|
if (dwNewImageSize>UINT_MAX)
|
|
dwNewImageSize = UINT_MAX-1024;
|
|
lpNewImage = new BYTE[dwNewImageSize];
|
|
if (!lpNewImage) {
|
|
delete []lpBufStart;
|
|
return ERROR_NEW_FAILED;
|
|
}
|
|
|
|
#ifndef _DEBUG
|
|
// set the memory to 0
|
|
memset( lpNewImage, 0, (size_t)dwNewImageSize );
|
|
#endif
|
|
|
|
if(lpfnGenerateImageEx)
|
|
{
|
|
|
|
uiError = (*lpfnGenerateImageEx)( (LPCSTR)lpszType,
|
|
(LPVOID)lpBufStart,
|
|
(DWORD) dwSize,
|
|
(LPVOID)m_lpImageBuf,
|
|
(DWORD) m_dwImageSize,
|
|
(LPVOID)lpNewImage,
|
|
(DWORD*)&dwNewImageSize,
|
|
(LPCSTR)m_pFileModule->GetRDFName()
|
|
);
|
|
}
|
|
else
|
|
{
|
|
uiError = (*lpfnGenerateImage)( (LPCSTR)lpszType,
|
|
(LPVOID)lpBufStart,
|
|
(DWORD) dwSize,
|
|
(LPVOID)m_lpImageBuf,
|
|
(DWORD) m_dwImageSize,
|
|
(LPVOID)lpNewImage,
|
|
(DWORD*)&dwNewImageSize
|
|
);
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
if ((dwNewImageSize) && (!uiError)) {
|
|
m_ImageUpdated = 1;
|
|
FreeImage();
|
|
if(!m_lpImageBuf) {
|
|
if(AllocImage(dwNewImageSize))
|
|
return ERROR_NEW_FAILED;
|
|
memcpy(m_lpImageBuf, lpNewImage, (UINT)dwNewImageSize);
|
|
// check if the size of the image is 0
|
|
if(!m_FileOffset) {
|
|
// Chances are that this is a conversion.
|
|
// set the file size to the size of the image
|
|
// to have it work in the getimage call back
|
|
m_FileSize = dwNewImageSize;
|
|
}
|
|
m_dwImageSize = dwNewImageSize;
|
|
dwNewImageSize = 0;
|
|
m_Language = MAKELONG(HIWORD(m_Language),LOWORD(dwUpdLang));
|
|
}
|
|
}
|
|
|
|
delete []lpNewImage;
|
|
delete []lpBufStart;
|
|
|
|
return dwNewImageSize;
|
|
}
|
|
|
|
UINT
|
|
CResInfo::GetData( LPCSTR lpszFilename, HINSTANCE hInst,
|
|
DWORD dwItem, LPVOID lpbuffer, UINT uiBufSize )
|
|
{
|
|
// We assume the buffer is pointing to a _ResItem Struct
|
|
|
|
// [ALESSANM 25-06-93] - mod 1
|
|
LPRESITEM lpResItem = (LPRESITEM) lpbuffer;
|
|
|
|
UINT uiPos = HIWORD(dwItem);
|
|
|
|
if (!m_ItemArray.GetSize()) {
|
|
// We have to load the array again. What if the image has been modified?
|
|
// Check the fileoffset to see if it is 0.
|
|
if (!m_lpImageBuf) {
|
|
// Load the resource.image
|
|
DWORD dwReadSize = LoadImage( lpszFilename, hInst );
|
|
|
|
if (dwReadSize!=m_dwImageSize)
|
|
return 0;
|
|
}
|
|
|
|
// We have now to pass the Buffer back to the RW to Parse the info
|
|
if (!(ParseImage( hInst )) )
|
|
return 0;
|
|
}
|
|
|
|
if (uiPos>(UINT)m_ItemArray.GetSize())
|
|
// Wrong pointer to the item
|
|
return 0;
|
|
|
|
CItemInfo* pItemInfo = (CItemInfo*)m_ItemArray.GetAt( uiPos-1 );
|
|
|
|
if (!pItemInfo)
|
|
return 0;
|
|
|
|
// Check if the Id match
|
|
if (pItemInfo->GetId()!=LOWORD(dwItem))
|
|
return 0;
|
|
|
|
// fill the structure with the info we have
|
|
UINT uiSize = 0;
|
|
|
|
// calc the size and check if the buffer is too small
|
|
// Strings Field in the CItemInfo
|
|
uiSize = (pItemInfo->GetCaption()).GetLength()+1;
|
|
uiSize += (pItemInfo->GetFaceName()).GetLength()+1;
|
|
uiSize += (pItemInfo->GetClassName()).GetLength()+1;
|
|
// Strings field in the CResItem
|
|
uiSize += (m_ResName).GetLength()+1;
|
|
uiSize += (m_TypeName).GetLength()+1;
|
|
// Fixed field in the ResItem Structure
|
|
uiSize += sizeof(RESITEM);
|
|
|
|
// Check if the user buffer is too small
|
|
if (uiBufSize<uiSize)
|
|
return uiSize;
|
|
|
|
// Get the pointer to the end of the structure (begin of the buffer)
|
|
char far * lpStrBuf = (char far *)lpbuffer+sizeof(RESITEM);
|
|
|
|
// Size of the structure
|
|
lpResItem->dwSize = uiSize;
|
|
|
|
// Copy the items in the buffer
|
|
// Start from the fixed field
|
|
// Coordinate
|
|
lpResItem->wX = pItemInfo->GetX();
|
|
lpResItem->wY = pItemInfo->GetY();
|
|
lpResItem->wcX = pItemInfo->GetcX();
|
|
lpResItem->wcY = pItemInfo->GetcY();
|
|
|
|
// Checksum and Style
|
|
lpResItem->dwCheckSum = pItemInfo->GetCheckSum();
|
|
lpResItem->dwStyle = pItemInfo->GetStyle();
|
|
lpResItem->dwExtStyle = pItemInfo->GetExtStyle();
|
|
lpResItem->dwFlags = pItemInfo->GetFlags();
|
|
|
|
// ID
|
|
// This is needed for the update by terms.
|
|
// We have to have unique ID
|
|
if((m_TypeId==4) &&(pItemInfo->GetFlags() & MF_POPUP)) {
|
|
// Check if we have an id. otherwise is the old ID format
|
|
lpResItem->dwItemID = pItemInfo->GetPosId();
|
|
|
|
if(!lpResItem->dwItemID)
|
|
lpResItem->dwItemID = pItemInfo->GetTabPosId();
|
|
} else {
|
|
// Fixed bug No: 165
|
|
if(pItemInfo->GetId() != -1)
|
|
lpResItem->dwItemID = pItemInfo->GetPosId();
|
|
else lpResItem->dwItemID = pItemInfo->GetTabPosId();
|
|
}
|
|
|
|
lpResItem->dwResID = m_ResId;
|
|
lpResItem->dwTypeID = m_TypeId;
|
|
lpResItem->dwLanguage = LOWORD(m_Language);
|
|
|
|
// Code page, Class and Font
|
|
lpResItem->dwCodePage = pItemInfo->GetCodePage();
|
|
lpResItem->wClassName = pItemInfo->GetClassNameID();
|
|
lpResItem->wPointSize = pItemInfo->GetPointSize();
|
|
lpResItem->wWeight = pItemInfo->GetWeight();
|
|
lpResItem->bItalic = pItemInfo->GetItalic();
|
|
lpResItem->bCharSet = pItemInfo->GetCharSet();
|
|
|
|
// Let's start copy the string
|
|
|
|
lpResItem->lpszClassName = strcpy( lpStrBuf, pItemInfo->GetClassName() );
|
|
lpStrBuf += strlen(lpResItem->lpszClassName)+1;
|
|
|
|
lpResItem->lpszFaceName = strcpy( lpStrBuf, pItemInfo->GetFaceName() );
|
|
lpStrBuf += strlen(lpResItem->lpszFaceName)+1;
|
|
|
|
lpResItem->lpszCaption = strcpy( lpStrBuf, pItemInfo->GetCaption() );
|
|
lpStrBuf += strlen(lpResItem->lpszCaption)+1;
|
|
|
|
lpResItem->lpszResID = strcpy( lpStrBuf, m_ResName );
|
|
lpStrBuf += strlen(lpResItem->lpszResID)+1;
|
|
|
|
lpResItem->lpszTypeID = strcpy( lpStrBuf, m_TypeName );
|
|
lpStrBuf += strlen(lpResItem->lpszTypeID)+1;
|
|
|
|
return uiSize;
|
|
}
|
|
|
|
UINT
|
|
CResInfo::UpdateData( LPCSTR lpszFilename, HINSTANCE hInst,
|
|
DWORD dwItem, LPVOID lpbuffer, UINT uiBufSize )
|
|
{
|
|
UINT uiError = ERROR_NO_ERROR;
|
|
UINT uiPos = HIWORD(dwItem);
|
|
TRACE1("UpdateData:\tdwItem:%lx\t", dwItem);
|
|
// we have to see if the array has been loaded before
|
|
if (!m_ItemArray.GetSize()) {
|
|
// We have to load the array again
|
|
if (!m_lpImageBuf) {
|
|
// Load the resource.image
|
|
DWORD dwReadSize = LoadImage( lpszFilename, hInst );
|
|
|
|
if (dwReadSize!=m_dwImageSize)
|
|
return ERROR_RW_LOADIMAGE;
|
|
}
|
|
|
|
// We have now to pass the Buffer back to the RW to Parse the info
|
|
if (!(ParseImage( hInst )) )
|
|
return ERROR_RW_PARSEIMAGE;
|
|
}
|
|
|
|
if (uiPos>(UINT)m_ItemArray.GetSize())
|
|
// Wrong pointer to the item
|
|
return ERROR_IO_INVALIDITEM;
|
|
|
|
CItemInfo* pItemInfo = (CItemInfo*)m_ItemArray.GetAt( uiPos-1 );
|
|
|
|
if (!pItemInfo)
|
|
return ERROR_IO_INVALIDITEM;
|
|
|
|
TRACE2("m_dwPosId:%lx\tm_wTabPos:%lx\n", pItemInfo->GetPosId(), pItemInfo->GetTabPosId());
|
|
// Check if the Id match
|
|
if (lpbuffer)
|
|
if (pItemInfo->GetPosId()!=((LPRESITEM)lpbuffer)->dwItemID)
|
|
{
|
|
// we have some files with ID = 0, check for that
|
|
if (pItemInfo->GetTabPosId()!=((LPRESITEM)lpbuffer)->dwItemID)
|
|
return ERROR_IO_INVALIDID;
|
|
}
|
|
|
|
if ((uiError = pItemInfo->UpdateData( (LPRESITEM)lpbuffer )) )
|
|
return uiError;
|
|
|
|
// We have to mark the resource has updated
|
|
m_FileOffset = 0L;
|
|
m_ImageUpdated = 0;
|
|
return uiError;
|
|
}
|
|
|
|
DWORD
|
|
CResInfo::ParseImage( HINSTANCE hInst )
|
|
{
|
|
//
|
|
// Check if the new RCData handling is supported
|
|
//
|
|
|
|
UINT (FAR PASCAL * lpfnParseImageEx)(LPCSTR, LPCSTR, LPVOID, DWORD, LPVOID, DWORD, LPCSTR);
|
|
UINT (FAR PASCAL * lpfnParseImage)(LPCSTR, LPVOID, DWORD, LPVOID, DWORD);
|
|
|
|
// Get the pointer to the function to extract the resources
|
|
lpfnParseImageEx = (UINT (FAR PASCAL *)(LPCSTR, LPCSTR, LPVOID, DWORD, LPVOID, DWORD, LPCSTR))
|
|
GetProcAddress( hInst, "RWParseImageEx" );
|
|
if (lpfnParseImageEx==NULL) {
|
|
//
|
|
// This is and old RW get the old entry point
|
|
//
|
|
lpfnParseImage = (UINT (FAR PASCAL *)(LPCSTR, LPVOID, DWORD, LPVOID, DWORD))
|
|
GetProcAddress( hInst, "RWParseImage" );
|
|
if (lpfnParseImage==NULL) {
|
|
return (DWORD)ERROR_DLL_PROC_ADDRESS;
|
|
}
|
|
}
|
|
|
|
BYTE far * lpBuf;
|
|
DWORD dwSize = m_dwImageSize*8+sizeof(RESITEM);
|
|
|
|
if ((dwSize>UINT_MAX) || (dwSize==0))
|
|
dwSize = 30000;
|
|
|
|
TRACE1("CResInfo::ParseImage\tNewSize: %ld\n", (LONG)dwSize);
|
|
lpBuf = new BYTE[dwSize];
|
|
if (!lpBuf)
|
|
return 0;
|
|
|
|
LPSTR lpszType = LPNULL;
|
|
if (m_TypeName=="" && m_TypeId)
|
|
lpszType = (LPSTR)((WORD)m_TypeId);
|
|
else
|
|
lpszType = (LPSTR)(m_TypeName.GetBuffer(0));
|
|
|
|
LPSTR lpszResId = LPNULL;
|
|
if (m_ResName=="" && m_ResId)
|
|
lpszResId = (LPSTR)((WORD)m_ResId);
|
|
else
|
|
lpszResId = (LPSTR)(m_ResName.GetBuffer(0));
|
|
|
|
LONG dwRead = 0;
|
|
|
|
if(lpfnParseImageEx)
|
|
{
|
|
dwRead = (*lpfnParseImageEx)((LPCSTR)lpszType,
|
|
(LPCSTR)lpszResId,
|
|
(LPVOID)m_lpImageBuf,
|
|
(DWORD)m_dwImageSize,
|
|
(LPVOID)lpBuf,
|
|
(DWORD)dwSize,
|
|
(LPCSTR)m_pFileModule->GetRDFName());
|
|
} else
|
|
{
|
|
dwRead = (*lpfnParseImage)((LPCSTR)lpszType,
|
|
(LPVOID)m_lpImageBuf,
|
|
(DWORD)m_dwImageSize,
|
|
(LPVOID)lpBuf,
|
|
(DWORD)dwSize);
|
|
}
|
|
|
|
if (dwRead>(LONG)dwSize) {
|
|
// We have to allocate a bigger buffer
|
|
delete []lpBuf;
|
|
TRACE1("CResInfo::ParseImage\tNewSize: %ld\n", (LONG)dwRead);
|
|
lpBuf = (BYTE far *) new BYTE[dwRead];
|
|
|
|
if (!lpBuf)
|
|
return 0;
|
|
|
|
dwSize = dwRead;
|
|
// try to read again
|
|
if(lpfnParseImageEx)
|
|
{
|
|
dwRead = (*lpfnParseImageEx)((LPCSTR)lpszType,
|
|
(LPCSTR)lpszResId,
|
|
(LPVOID)m_lpImageBuf,
|
|
(DWORD)m_dwImageSize,
|
|
(LPVOID)lpBuf,
|
|
(DWORD)dwSize,
|
|
(LPCSTR)m_pFileModule->GetRDFName());
|
|
} else
|
|
{
|
|
dwRead = (*lpfnParseImage)((LPCSTR)lpszType,
|
|
(LPVOID)m_lpImageBuf,
|
|
(DWORD)m_dwImageSize,
|
|
(LPVOID)lpBuf,
|
|
(DWORD)dwSize);
|
|
}
|
|
|
|
if (dwRead>(LONG)dwSize) {
|
|
// Abort
|
|
delete []lpBuf;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
// Parse the buffer we have got and fill the array with the information
|
|
// The buffer we are expecting is a series of ResItem structure
|
|
FreeItemArray();
|
|
|
|
// We want to parse all the stucture in the buffer
|
|
LPRESITEM lpResItem = (LPRESITEM) lpBuf;
|
|
BYTE far * lpBufStart = lpBuf;
|
|
WORD wTabPos = 0;
|
|
WORD wPos = 0;
|
|
//m_ItemArray.SetSize(10,5);
|
|
while ( (dwRead>0) && ((LONG)lpResItem->dwSize!=-1) ) {
|
|
//TRACE1("Caption: %Fs\n", lpResItem->lpszCaption);
|
|
wTabPos++;
|
|
if ( !(
|
|
((int)lpResItem->wX==-1) &&
|
|
((int)lpResItem->wY==-1) &&
|
|
((int)lpResItem->wcX==-1) &&
|
|
((int)lpResItem->wcY==-1) &&
|
|
((LONG)lpResItem->dwItemID==-1) &&
|
|
//(LOWORD(dwPosId)==0) &&
|
|
((LONG)lpResItem->dwStyle==-1) &&
|
|
((LONG)lpResItem->dwExtStyle==-1) &&
|
|
((LONG)lpResItem->dwFlags==-1) &&
|
|
(strlen((LPSTR)lpResItem->lpszCaption)==0)
|
|
)
|
|
) {
|
|
|
|
TRACE2("\tItems-> x: %d\ty: %d\t", lpResItem->wX, lpResItem->wY );
|
|
TRACE2("cx: %d\tcy: %d\t", lpResItem->wcX, lpResItem->wcY );
|
|
TRACE1("Id: %lu\t", lpResItem->dwItemID);
|
|
TRACE2("Style: %ld\tExtStyle: %ld\n", lpResItem->dwStyle, lpResItem->dwExtStyle);
|
|
if (lpResItem->lpszCaption) {
|
|
UINT len = strlen((LPSTR)lpResItem->lpszCaption);
|
|
TRACE2("Len: %d\tText: %s\n", len,
|
|
(len<256 ? lpResItem->lpszCaption : ""));
|
|
}
|
|
TRACE2("dwRead: %lu\tdwSize: %lu\n", dwRead, lpResItem->dwSize);
|
|
|
|
//lpResItem->dwItemID = MAKELONG(LOWORD(lpResItem->dwItemID), ++wPos);
|
|
|
|
m_ItemArray.Add( new CItemInfo( lpResItem, wTabPos ));
|
|
}
|
|
|
|
// Next Item
|
|
lpBuf += lpResItem->dwSize;
|
|
dwRead -= lpResItem->dwSize;
|
|
lpResItem = (LPRESITEM) lpBuf;
|
|
|
|
}
|
|
|
|
delete []lpBufStart;
|
|
|
|
|
|
return (DWORD)m_ItemArray.GetSize();
|
|
}
|
|
|
|
UINT
|
|
CResInfo::CopyImage( CResInfo* pResInfo )
|
|
{
|
|
// Will copy the image from this object to the pResInfo object
|
|
// We need this to hack the image transformation
|
|
// When we will have time we will do the thing right
|
|
// Allocate memory for the new image
|
|
if(!m_dwImageSize)
|
|
return 0;
|
|
if(pResInfo->AllocImage(m_dwImageSize))
|
|
return ERROR_NEW_FAILED;
|
|
|
|
// Copy the data
|
|
memcpy( pResInfo->m_lpImageBuf, m_lpImageBuf, (size_t)m_dwImageSize );
|
|
|
|
// set the file size so the GetImage will not complain
|
|
pResInfo->SetFileSize(m_FileSize);
|
|
|
|
return 0;
|
|
}
|
|
|
|
UINT
|
|
CResInfo::Copy( CResInfo* pResInfo, CString szFileName, HINSTANCE hInst )
|
|
{
|
|
CItemInfo* pItemInfo;
|
|
INT_PTR u = m_ItemArray.GetUpperBound();
|
|
if (u==-1) {
|
|
if ( (!m_lpImageBuf) && (m_FileOffset)) {
|
|
DWORD dwReadSize = LoadImage( szFileName, hInst );
|
|
if (dwReadSize!=m_dwImageSize)
|
|
return ERROR_RW_LOADIMAGE;
|
|
}
|
|
if (!(ParseImage( hInst )) )
|
|
return ERROR_RW_PARSEIMAGE;
|
|
u = m_ItemArray.GetUpperBound();
|
|
}
|
|
|
|
// This is a bad hack and doesn't fit at all in the design of the module.
|
|
// We have to copy the image between ResInfo object to be able to
|
|
// Pass on the raw data. Since in the RESITEM structure there isn't a
|
|
// pointer to a raw data buffer we cannot pass the data for the Cursor, bitmaps...
|
|
// What we will do is hard code the type id of this image and if the resource
|
|
// is one of this we will copy the raw data and perform an UpdateImage in the RES16
|
|
// module. If it is a standard item then we procede as usual calling the GenerateImage
|
|
// in the RES16 Module.
|
|
// The right thing to do should be to have a pointer to the raw data in the RESITEM
|
|
// structure so when the item is a pure data item we can still pass the data on.
|
|
// To do this we have to change the RESITEM structure and this will mean go in each RW
|
|
// and make sure that all the place in which we fill the RESITEM get modified.
|
|
|
|
switch(m_TypeId) {
|
|
// Copy only the Bitmaps, Cursors and Icons usualy have no localizable strings
|
|
/*
|
|
case 1:
|
|
// copy the image
|
|
CopyImage( pResInfo );
|
|
break;
|
|
*/
|
|
case 2:
|
|
// copy the image
|
|
CopyImage( pResInfo );
|
|
break;
|
|
/*
|
|
case 3:
|
|
// copy the image
|
|
CopyImage( pResInfo );
|
|
break;
|
|
*/
|
|
default:
|
|
// do nothing
|
|
break;
|
|
}
|
|
//m_ItemArray.SetSize(u,10);
|
|
for( int c=0; c<=u ; c++) {
|
|
pItemInfo = (CItemInfo*) m_ItemArray.GetAt(c);
|
|
if(!pItemInfo)
|
|
return ERROR_IO_INVALIDITEM;
|
|
pResInfo->AddItem( *pItemInfo );
|
|
}
|
|
|
|
// We have to mark the resource has updated
|
|
pResInfo->SetFileOffset(0L);
|
|
pResInfo->SetImageUpdated(0);
|
|
|
|
return ERROR_NO_ERROR;
|
|
}
|
|
|
|
int
|
|
CResInfo::AddItem( CItemInfo ItemInfo )
|
|
{
|
|
return (int)m_ItemArray.Add( new CItemInfo( ItemInfo ));
|
|
}
|
|
|
|
DWORD
|
|
CResInfo::EnumItem( LPCSTR lpszFilename, HINSTANCE hInst, DWORD dwPrevItem )
|
|
{
|
|
if (dwPrevItem) {
|
|
if (m_ItemPos==0) return LPNULL;
|
|
if (m_ItemPos==m_ItemArray.GetSize()) {
|
|
m_ItemPos = 0;
|
|
return LPNULL;
|
|
}
|
|
} else {
|
|
// It is the first time or the user want to restart
|
|
|
|
// Load the resource.image
|
|
DWORD dwReadSize = LoadImage( lpszFilename, hInst );
|
|
|
|
if (dwReadSize!=m_FileSize) {
|
|
return 0L;
|
|
}
|
|
|
|
// We have now to pass the Buffer back to the RW to Parse the info
|
|
if (!(ParseImage( hInst )) )
|
|
return 0L;
|
|
|
|
m_ItemPos = 0;
|
|
}
|
|
|
|
CItemInfo* pItemInfo = (CItemInfo*)m_ItemArray.GetAt( m_ItemPos++ );
|
|
while( (
|
|
(pItemInfo->GetX()==0) &&
|
|
(pItemInfo->GetY()==0) &&
|
|
(pItemInfo->GetcX()==0) &&
|
|
(pItemInfo->GetcY()==0) &&
|
|
(pItemInfo->GetId()==0) &&
|
|
(pItemInfo->GetStyle()==0) &&
|
|
(pItemInfo->GetExtStyle()==0) &&
|
|
((pItemInfo->GetCaption()).IsEmpty())
|
|
)
|
|
) {
|
|
if(m_ItemArray.GetUpperBound()>=m_ItemPos)
|
|
pItemInfo = (CItemInfo*)m_ItemArray.GetAt( m_ItemPos++ );
|
|
else return 0L;
|
|
|
|
}
|
|
|
|
|
|
if (!pItemInfo) return 0L;
|
|
|
|
return pItemInfo->GetTabPosId();
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// CItemInfo
|
|
|
|
CItemInfo::CItemInfo( WORD x, WORD y,
|
|
WORD cx, WORD cy,
|
|
DWORD dwPosId, WORD wPos,
|
|
DWORD dwStyle, DWORD dwExtStyle,
|
|
CString szText )
|
|
{
|
|
m_wX = x;
|
|
m_wY = y;
|
|
|
|
m_wCX = cx;
|
|
m_wCY = cy;
|
|
|
|
m_dwPosId = dwPosId;
|
|
m_wTabPos = wPos;
|
|
|
|
m_dwStyle = dwStyle;
|
|
m_dwExtStyle = dwExtStyle;
|
|
|
|
m_szCaption = szText;
|
|
}
|
|
|
|
CItemInfo::CItemInfo( LPRESITEM lpResItem, WORD wTabPos )
|
|
{
|
|
m_wX = lpResItem->wX;
|
|
m_wY = lpResItem->wY;
|
|
|
|
m_wCX = lpResItem->wcX;
|
|
m_wCY = lpResItem->wcY;
|
|
|
|
m_dwCheckSum = lpResItem->dwCheckSum;
|
|
m_dwStyle = lpResItem->dwStyle;
|
|
m_dwExtStyle = lpResItem->dwExtStyle;
|
|
m_dwFlags = lpResItem->dwFlags;
|
|
m_dwPosId = lpResItem->dwItemID;
|
|
m_wTabPos = wTabPos;
|
|
|
|
m_dwCodePage = lpResItem->dwCodePage;
|
|
m_dwLanguage = lpResItem->dwLanguage;
|
|
m_wClassName = lpResItem->wClassName;
|
|
m_wPointSize = lpResItem->wPointSize;
|
|
m_wWeight = lpResItem->wWeight;
|
|
m_bItalic = lpResItem->bItalic;
|
|
m_bCharSet = lpResItem->bCharSet;
|
|
|
|
m_szClassName = lpResItem->lpszClassName;
|
|
m_szFaceName = lpResItem->lpszFaceName;
|
|
m_szCaption = lpResItem->lpszCaption;
|
|
}
|
|
|
|
UINT
|
|
CItemInfo::UpdateData( LPVOID lpbuffer, UINT uiBufSize )
|
|
{
|
|
UINT uiError = ERROR_NO_ERROR;
|
|
//
|
|
// This is old and was used at the very beginning. Never used now.
|
|
//
|
|
return uiError;
|
|
|
|
}
|
|
|
|
UINT
|
|
CItemInfo::UpdateData( LPRESITEM lpResItem )
|
|
{
|
|
if (lpResItem){
|
|
m_wX = lpResItem->wX;
|
|
m_wY = lpResItem->wY;
|
|
|
|
m_wCX = lpResItem->wcX;
|
|
m_wCY = lpResItem->wcY;
|
|
|
|
m_dwCheckSum = lpResItem->dwCheckSum;
|
|
m_dwStyle = lpResItem->dwStyle;
|
|
m_dwExtStyle = lpResItem->dwExtStyle;
|
|
m_dwFlags = lpResItem->dwFlags;
|
|
|
|
SetId(LOWORD(lpResItem->dwItemID)); //m_dwPosId = lpResItem->dwItemId;
|
|
//m_wTabPos = wTabPos;
|
|
|
|
m_dwCodePage = lpResItem->dwCodePage;
|
|
m_dwLanguage = lpResItem->dwLanguage;
|
|
m_wClassName = lpResItem->wClassName;
|
|
m_wPointSize = lpResItem->wPointSize;
|
|
m_wWeight = lpResItem->wWeight;
|
|
m_bItalic = lpResItem->bItalic;
|
|
m_bCharSet = lpResItem->bCharSet;
|
|
|
|
m_szClassName = lpResItem->lpszClassName;
|
|
m_szFaceName = lpResItem->lpszFaceName;
|
|
m_szCaption = lpResItem->lpszCaption;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
void
|
|
CItemInfo::SetPos( WORD wPos )
|
|
{
|
|
WORD wId = LOWORD(m_dwPosId);
|
|
|
|
m_dwPosId = 0;
|
|
m_dwPosId = wPos;
|
|
m_dwPosId = (m_dwPosId << 16);
|
|
|
|
if (wId>0)
|
|
m_dwPosId += wId;
|
|
else m_dwPosId -= wId;
|
|
}
|
|
|
|
void
|
|
CItemInfo::SetId( WORD wId )
|
|
{
|
|
WORD wPos = HIWORD(m_dwPosId);
|
|
|
|
m_dwPosId = 0;
|
|
m_dwPosId = wPos;
|
|
m_dwPosId = (m_dwPosId << 16);
|
|
|
|
if (wId>0)
|
|
m_dwPosId += wId;
|
|
else m_dwPosId -= wId;
|
|
}
|
|
|
|
DWORD
|
|
CItemInfo::GetTabPosId()
|
|
{
|
|
DWORD dwTabPosId = 0;
|
|
WORD wId = LOWORD(m_dwPosId);
|
|
|
|
dwTabPosId = m_wTabPos;
|
|
dwTabPosId = (dwTabPosId << 16);
|
|
|
|
if (wId>0)
|
|
dwTabPosId += wId;
|
|
else dwTabPosId -= wId;
|
|
return dwTabPosId;
|
|
}
|
|
|
|
CItemInfo::CItemInfo( const CItemInfo &iteminfo )
|
|
{
|
|
m_wX = iteminfo.m_wX;
|
|
m_wY = iteminfo.m_wY;
|
|
|
|
m_wCX = iteminfo.m_wCX;
|
|
m_wCY = iteminfo.m_wCY;
|
|
|
|
m_dwCheckSum = iteminfo.m_dwCheckSum;
|
|
m_dwStyle = iteminfo.m_dwStyle;
|
|
m_dwExtStyle = iteminfo.m_dwExtStyle;
|
|
m_dwFlags = iteminfo.m_dwFlags;
|
|
|
|
m_dwPosId = iteminfo.m_dwPosId;
|
|
m_wTabPos = iteminfo.m_wTabPos;
|
|
|
|
m_dwCodePage = iteminfo.m_dwCodePage;
|
|
m_dwLanguage = iteminfo.m_dwLanguage;
|
|
m_wClassName = iteminfo.m_wClassName;
|
|
m_wPointSize = iteminfo.m_wPointSize;
|
|
m_wWeight = iteminfo.m_wWeight;
|
|
m_bItalic = iteminfo.m_bItalic;
|
|
m_bCharSet = iteminfo.m_bCharSet;
|
|
|
|
m_szClassName = iteminfo.m_szClassName;
|
|
m_szFaceName = iteminfo.m_szFaceName;
|
|
m_szCaption = iteminfo.m_szCaption;
|
|
}
|
|
|
|
static BYTE Allign(LONG bLen)
|
|
{
|
|
BYTE bPad =(BYTE)PadPtr(bLen);
|
|
return bPad;
|
|
}
|
|
|
|
static UINT CopyFile( const char * pszfilein, const char * pszfileout )
|
|
{
|
|
CFile filein;
|
|
CFile fileout;
|
|
|
|
if (!filein.Open(pszfilein, CFile::modeRead | CFile::typeBinary | CFile::shareDenyNone))
|
|
return ERROR_FILE_OPEN;
|
|
|
|
if (!fileout.Open(pszfileout, CFile::modeWrite | CFile::modeCreate | CFile::typeBinary))
|
|
return ERROR_FILE_CREATE;
|
|
|
|
LONG lLeft = filein.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!= filein.Read( pBuf, wRead))
|
|
return ERROR_FILE_READ;
|
|
fileout.Write( pBuf, wRead );
|
|
lLeft -= wRead;
|
|
dwOffset += wRead;
|
|
}
|
|
|
|
delete []pBuf;
|
|
return ERROR_NO_ERROR;
|
|
}
|
|
|
|
|
|
void CheckError(LPCSTR szStr)
|
|
{
|
|
TRY
|
|
{
|
|
DWORD dwErr = GetLastError();
|
|
char szBuf[256];
|
|
wsprintf( szBuf, "%s return: %d\n", szStr, dwErr);
|
|
TRACE(szBuf);
|
|
}
|
|
CATCH( CException, e )
|
|
{
|
|
TRACE("There is an Exception!\n");
|
|
}
|
|
END_CATCH
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// RDF File support code
|
|
|
|
HANDLE
|
|
OpenModule(
|
|
LPCSTR lpszSrcfilename, // File name of the executable to use as source file
|
|
LPCSTR lpszfiletype, // Type of the executable file if known
|
|
LPCSTR lpszRDFfile,
|
|
DWORD dwFlags )
|
|
{
|
|
TRACE2("IODLL.DLL: RSOpenModule: %s %s\n", lpszSrcfilename, lpszfiletype);
|
|
UINT uiError = ERROR_NO_ERROR;
|
|
INT_PTR uiHandle = 0 ;
|
|
|
|
// Before we do anything we have to check if the file exist
|
|
CFileStatus status;
|
|
if(!CFile::GetStatus( lpszSrcfilename, status ))
|
|
return UlongToHandle(ERROR_FILE_OPEN);
|
|
|
|
// Check if the user already knows the type of the executable
|
|
CString szSrcFileType;
|
|
if (!lpszfiletype) {
|
|
if(uiError = RSFileType( lpszSrcfilename, szSrcFileType.GetBuffer(100) ))
|
|
return UlongToHandle(uiError);
|
|
szSrcFileType.ReleaseBuffer(-1);
|
|
} else szSrcFileType = lpszfiletype;
|
|
|
|
gModuleTable.Add(new CFileModule( lpszSrcfilename,
|
|
lpszRDFfile,
|
|
gDllTable.GetPosFromTable(szSrcFileType),
|
|
dwFlags ));
|
|
|
|
// Get the position in the array.
|
|
uiHandle = gModuleTable.GetSize();
|
|
|
|
// Read the informations on the type in the file.
|
|
CFileModule* pFileModule = (CFileModule*)gModuleTable.GetAt(uiHandle-1);
|
|
|
|
if (!pFileModule)
|
|
return UlongToHandle(ERROR_IO_INVALIDMODULE);
|
|
|
|
if (pFileModule->LoadDll()==NULL)
|
|
return UlongToHandle(ERROR_DLL_LOAD);
|
|
|
|
HINSTANCE hInst = pFileModule->GetHInstance();
|
|
UINT (FAR PASCAL * lpfnReadResInfo)(LPCSTR, LPVOID, UINT*);
|
|
// Get the pointer to the function to extract the resources
|
|
lpfnReadResInfo = (UINT (FAR PASCAL *)(LPCSTR, LPVOID, UINT*))
|
|
GetProcAddress( hInst, "RWReadTypeInfo" );
|
|
if (lpfnReadResInfo==NULL) {
|
|
return UlongToHandle(ERROR_DLL_PROC_ADDRESS);
|
|
}
|
|
|
|
UINT uiSize = 50000;
|
|
BYTE far * pBuf = new BYTE[uiSize];
|
|
|
|
if (!pBuf)
|
|
return UlongToHandle(ERROR_NEW_FAILED);
|
|
|
|
uiError = (*lpfnReadResInfo)((LPCSTR)pFileModule->GetName(),
|
|
(LPVOID)pBuf,
|
|
(UINT*) &uiSize);
|
|
|
|
// Check if the buffer was big enough
|
|
if (uiSize>50000) {
|
|
// The buffer was too small reallocate
|
|
UINT uiNewSize = uiSize;
|
|
delete [] pBuf;
|
|
pBuf = new BYTE[uiSize];
|
|
if (!pBuf)
|
|
return UlongToHandle(ERROR_NEW_FAILED);
|
|
uiError = (*lpfnReadResInfo)((LPCSTR)pFileModule->GetName(),
|
|
(LPVOID)pBuf,
|
|
(UINT*) &uiSize);
|
|
if (uiSize!=uiNewSize)
|
|
return UlongToHandle(ERROR_NEW_FAILED);
|
|
|
|
}
|
|
|
|
if (uiError!=ERROR_NO_ERROR) {
|
|
delete pBuf;
|
|
pFileModule->CleanUp();
|
|
return UlongToHandle(uiError);
|
|
}
|
|
|
|
// We have a buffer with all the information the DLL was able to get.
|
|
// Fill the array in the CFileModule class
|
|
|
|
BYTE* pBufPos = pBuf;
|
|
BYTE* pBufStart = pBuf;
|
|
|
|
WORD wTypeId;
|
|
WORD wNameId;
|
|
|
|
CString szTypeId;
|
|
CString szNameId;
|
|
|
|
DWORD dwlang;
|
|
DWORD dwfileOffset;
|
|
DWORD dwsize;
|
|
|
|
pFileModule->SetResBufSize( uiSize );
|
|
while(uiSize) {
|
|
wTypeId = *((WORD*)pBuf);
|
|
pBuf += sizeofWord;
|
|
|
|
szTypeId = (char*)pBuf;
|
|
pBuf += strlen((char*)pBuf)+1;
|
|
pBuf += Allign((LONG)(pBuf-pBufPos));
|
|
|
|
wNameId = *((WORD*)pBuf);
|
|
pBuf += sizeofWord;
|
|
|
|
szNameId = (char*)pBuf;
|
|
pBuf += strlen((char*)pBuf)+1;
|
|
pBuf += Allign((LONG)(pBuf-pBufPos));
|
|
|
|
dwlang = *((DWORD*)pBuf);
|
|
pBuf += sizeofDWord;
|
|
|
|
dwsize = *((DWORD*)pBuf);
|
|
pBuf += sizeofDWord;
|
|
|
|
dwfileOffset = *((DWORD*)pBuf);
|
|
pBuf += sizeofDWord;
|
|
|
|
uiSize -= (UINT)(pBuf-pBufPos);
|
|
pBufPos = pBuf;
|
|
|
|
|
|
TRACE1("TypeId: %d\t", wTypeId);
|
|
TRACE1("TypeName: %s\t", szTypeId);
|
|
TRACE1("NameId: %d\t", wNameId);
|
|
TRACE1("NameName: %s\t", szNameId);
|
|
TRACE1("ResLang: %lu\t", dwlang);
|
|
TRACE1("ResSize: %lu\t", dwsize);
|
|
TRACE1("FileOffset: %lX\n", dwfileOffset);
|
|
|
|
//TRACE1("uiError: %u\n", uiSize);
|
|
pFileModule->AddResInfo( wTypeId,
|
|
szTypeId,
|
|
wNameId,
|
|
szNameId,
|
|
dwlang,
|
|
dwsize,
|
|
dwfileOffset );
|
|
}
|
|
|
|
delete pBufStart;
|
|
return (HANDLE)(uiHandle+FIRSTVALIDVALUE);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// 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);
|
|
g_iDllLoaded = 0;
|
|
}
|
|
else if (dwReason == DLL_PROCESS_DETACH)
|
|
{
|
|
// Terminate the library before destructors are called
|
|
AfxWinTerm();
|
|
}
|
|
|
|
if (dwReason == DLL_PROCESS_DETACH || dwReason == DLL_THREAD_DETACH)
|
|
return 0; // CRT term Failed
|
|
|
|
return 1; // ok
|
|
}
|