//+--------------------------------------------------------------------------- // // 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 #include #include #include #include #include #include #include #include #include #include // // 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()) && (cGetType())) // 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 (dwBufSizeUINT_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 (uiBufSizedwSize = 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 }