Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

3589 lines
110 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // File: iodll.cpp
  4. //
  5. // Contents: Implementation for the I/O module
  6. //
  7. // Classes:
  8. //
  9. // History: 27-May-93 alessanm created
  10. // 25-Jun-93 alessanm eliminated TRANSCONTEXT and added RESITEM
  11. //
  12. //----------------------------------------------------------------------------
  13. #include <afx.h>
  14. #include <afxwin.h>
  15. #include <afxcoll.h>
  16. #include <iodll.h>
  17. #include <limits.h>
  18. #include <memory.h>
  19. #include <malloc.h>
  20. #include <stdlib.h>
  21. #include <dos.h>
  22. #include <errno.h>
  23. #include <setjmp.h>
  24. //
  25. // UlongToHandle is defined in basetsd.h now
  26. //
  27. // #define UlongToHandle(x) (HANDLE)UlongToPtr(x)
  28. //
  29. /////////////////////////////////////////////////////////////////////////////
  30. // Initialization of MFC Extension DLL
  31. #include "afxdllx.h" // standard MFC Extension DLL routines
  32. static AFX_EXTENSION_MODULE extensionDLL = { NULL, NULL };
  33. /////////////////////////////////////////////////////////////////////////////
  34. // General Declarations
  35. #define MODULENAME "iodll.dll"
  36. #define Pad4(x) ((((x+3)>>2)<<2)-x)
  37. #define PadPtr(x) ((((x+(sizeof(PVOID)-1))/sizeof(PVOID))*sizeof(PVOID))-x)
  38. #define LPNULL 0L
  39. // INI Informations
  40. #define SECTION "iodll32"
  41. #define MAXENTRYBUF 1024 // Buffer to entry in the INI file
  42. #define MAXDLLNUM 20 // We hard-code the number of DLL. TO fix later
  43. #define MAXKEYLEN 32
  44. // HANDLE Informations
  45. #define FIRSTVALIDVALUE LAST_ERROR // The first valid value for an HANDLE to a module
  46. typedef unsigned char UCHAR;
  47. typedef char * PCHAR;
  48. typedef UCHAR * PUCHAR;
  49. /////////////////////////////////////////////////////////////////////////////
  50. // Function Declarations
  51. /////////////////////////////////////////////////////////////////////////////
  52. // Helper Function Declarations
  53. /////////////////////////////////////////////////////////////////////////////
  54. // Class declarations
  55. class CFileModule;
  56. class CItemInfo : public CObject
  57. {
  58. public:
  59. CItemInfo( WORD x, WORD y,
  60. WORD cx, WORD cy,
  61. DWORD dwPosId, WORD wPos,
  62. DWORD dwStyle, DWORD dwExtendStyle,
  63. CString szText );
  64. CItemInfo( LPRESITEM lpResItem, WORD wTabPos );
  65. CItemInfo( const CItemInfo &iteminfo );
  66. WORD GetId() { return LOWORD(m_dwPosId); }
  67. CString GetCaption() { return m_szCaption; }
  68. WORD GetX() { return m_wX; }
  69. WORD GetY() { return m_wY; }
  70. WORD GetcX() { return m_wCX; }
  71. WORD GetcY() { return m_wCY; }
  72. DWORD GetPosId() {
  73. if (LOWORD(m_dwPosId)==0xFFFF)
  74. return GetTabPosId();
  75. return m_dwPosId;
  76. }
  77. DWORD GetStyle() { return m_dwStyle; }
  78. DWORD GetExtStyle() { return m_dwExtStyle; }
  79. DWORD GetTabPosId();
  80. CString GetFaceName() { return m_szFaceName; }
  81. CString GetClassName() { return m_szClassName; }
  82. DWORD GetCheckSum() { return m_dwCheckSum; }
  83. DWORD GetFlags() { return m_dwFlags; }
  84. DWORD GetCodePage() { return m_dwCodePage; }
  85. DWORD GetLanguage() { return m_dwLanguage; }
  86. WORD GetClassNameID(){ return m_wClassName; }
  87. WORD GetPointSize() { return m_wPointSize; }
  88. WORD GetWeight() { return m_wWeight; }
  89. BYTE GetItalic() { return m_bItalic; }
  90. BYTE GetCharSet() { return m_bCharSet; }
  91. UINT UpdateData( LPVOID lpbuffer, UINT uiBufSize );
  92. UINT UpdateData( LPRESITEM lpResItem );
  93. void SetPos( WORD wPos );
  94. void SetId( WORD wId );
  95. private:
  96. WORD m_wX;
  97. WORD m_wY;
  98. WORD m_wCX;
  99. WORD m_wCY;
  100. DWORD m_dwCheckSum;
  101. DWORD m_dwStyle;
  102. DWORD m_dwExtStyle;
  103. DWORD m_dwFlags;
  104. DWORD m_dwPosId;
  105. WORD m_wTabPos;
  106. DWORD m_dwCodePage;
  107. DWORD m_dwLanguage;
  108. WORD m_wClassName;
  109. WORD m_wPointSize;
  110. WORD m_wWeight;
  111. BYTE m_bItalic;
  112. BYTE m_bCharSet;
  113. CString m_szClassName;
  114. CString m_szFaceName;
  115. CString m_szCaption;
  116. };
  117. // This class will keep all the information about each of the resources in the file
  118. class CResInfo : public CObject
  119. {
  120. public:
  121. CResInfo( WORD Typeid, CString sztypeid,
  122. WORD nameid, CString sznameid,
  123. DWORD dwlang, DWORD dwsize, DWORD dwfileoffset, CFileModule* pFileModule );
  124. ~CResInfo();
  125. WORD GetTypeId()
  126. { return m_TypeId; }
  127. CString GetTypeName()
  128. { return m_TypeName; }
  129. WORD GetResId()
  130. { return m_ResId; }
  131. CString GetResName()
  132. { return m_ResName; }
  133. DWORD GetSize()
  134. { return m_dwImageSize; }
  135. DWORD GetFileOffset()
  136. { return m_FileOffset; }
  137. DWORD GetLanguage()
  138. { return (DWORD)LOWORD(m_Language); }
  139. DWORD GetAllLanguage()
  140. { return m_Language; }
  141. BOOL GetUpdImage()
  142. { return m_ImageUpdated; }
  143. DWORD LoadImage( CString lpszFilename, HINSTANCE hInst );
  144. void FreeImage();
  145. DWORD ParseImage( HINSTANCE hInst );
  146. DWORD GetImage( LPCSTR lpszFilename, HINSTANCE hInst, LPVOID lpbuffer, DWORD dwBufSize );
  147. DWORD UpdateImage( LONG dwSize, HINSTANCE hInst, LPCSTR lpszType );
  148. DWORD ReplaceImage( LPVOID lpNewImage, DWORD dwNewImageSize, DWORD dwLang );
  149. UINT GetData( LPCSTR lpszFilename, HINSTANCE hInst,
  150. DWORD dwItem, LPVOID lpbuffer, UINT uiBufSize );
  151. UINT UpdateData( LPCSTR lpszFilename, HINSTANCE hInst,
  152. DWORD dwItem, LPVOID lpbuffer, UINT uiBufSize );
  153. void SetFileOffset( DWORD dwOffset )
  154. { m_FileOffset = dwOffset; }
  155. void SetFileSize( DWORD dwSize )
  156. { m_FileSize = dwSize; }
  157. void SetImageUpdated( BYTE bStatus )
  158. { m_ImageUpdated = bStatus; }
  159. void FreeItemArray();
  160. DWORD EnumItem( LPCSTR lpszFilename, HINSTANCE hInst, DWORD dwPrevItem );
  161. UINT Copy( CResInfo* pResInfo, CString szFileName, HINSTANCE hInst );
  162. UINT CopyImage( CResInfo* pResInfo );
  163. int AddItem( CItemInfo ItemInfo );
  164. private:
  165. DWORD m_FileOffset;
  166. DWORD m_FileSize;
  167. DWORD m_Language;
  168. CString m_TypeName;
  169. WORD m_TypeId;
  170. CString m_ResName;
  171. WORD m_ResId;
  172. BYTE far * m_lpImageBuf; // This is a pointer to the raw data in the resource
  173. DWORD m_dwImageSize;
  174. BYTE m_ImageUpdated;
  175. CObArray m_ItemArray;
  176. int m_ItemPos;
  177. //
  178. // FileModule the resource belongs to
  179. //
  180. CFileModule* m_pFileModule;
  181. UINT AllocImage(DWORD dwSize);
  182. };
  183. // This class has all the information we need on each of the modules that the user
  184. // open. When the DLL is discarded this class will clean all the memory allocated.
  185. class CFileModule : public CObject
  186. {
  187. public:
  188. CFileModule();
  189. CFileModule( LPCSTR, LPCSTR, int, DWORD );
  190. ~CFileModule();
  191. LPCSTR EnumType( LPCSTR lpszPrevType );
  192. LPCSTR EnumId( LPCSTR lpszType, LPCSTR lpszPrevId );
  193. DWORD EnumLang( LPCSTR lpszType, LPCSTR lpszId, DWORD dwPrevLang );
  194. DWORD EnumItem( LPCSTR lpszType, LPCSTR lpszId, DWORD dwLang, DWORD dwPrevItem );
  195. HINSTANCE LoadDll(); // Load the Dll Hinstance
  196. void FreeDll(); // Free the DLL hInstance
  197. UINT CleanUp(); // Clean the module memory
  198. HINSTANCE GetHInstance()
  199. { return m_DllHInstance; }
  200. CString GetName()
  201. { return m_SrcFileName; }
  202. CString GetRDFName()
  203. { return m_RdfFileName; }
  204. CResInfo* GetResInfo( LPCSTR lpszType, LPCSTR lpszId, DWORD dwPrevLang );
  205. CResInfo* GetResInfo( int iPos )
  206. { return ((CResInfo*)m_ResArray.GetAt(iPos)); }
  207. DWORD GetImage( LPCSTR lpszType, LPCSTR lpszId, DWORD dwLang,
  208. LPVOID lpbuffer, DWORD dwBufSize );
  209. DWORD UpdateImage( LPCSTR lpszType, LPCSTR lpszId, DWORD dwLang,
  210. DWORD dwUpdLang, LPVOID lpbuffer, DWORD dwBufSize );
  211. UINT GetData( LPCSTR lpszType, LPCSTR lpszId, DWORD dwLang, DWORD dwItem,
  212. LPVOID lpbuffer, UINT uiBufSize );
  213. UINT UpdateData( LPCSTR lpszType, LPCSTR lpszId, DWORD dwLang, DWORD dwItem,
  214. LPVOID lpbuffer, UINT uiBufSize );
  215. int AddTypeInfo( INT_PTR iPos, int iId, CString szId );
  216. int AddResInfo(
  217. WORD Typeid, CString sztypeid,
  218. WORD nameid, CString sznameid,
  219. DWORD dwlang, DWORD dwsize, DWORD dwfileoffset );
  220. void GenerateIdTable( LPCSTR lpszType, BOOL bNameOrID );
  221. UINT WriteUpdatedResource( LPCSTR lpszTgtfilename, HANDLE hFileModule, LPCSTR lpszSymbolPath );
  222. void SetResBufSize( UINT uiSize ) { m_ResBufSize = uiSize;}
  223. UINT GetResBufSize() { return m_ResBufSize;}
  224. UINT Copy( CFileModule* pFileModule );
  225. UINT CopyImage( CFileModule* pFileModule, LPCSTR lpszType, LPCSTR lpszResId );
  226. UINT GetLanguageStr( LPSTR lpszLanguage );
  227. private:
  228. CString m_SrcFileName; // The filename of the file to process
  229. CString m_RdfFileName; // The filename of the RDF file
  230. UINT m_DllTypeEntry; // The CDLLTable position for the file type
  231. HINSTANCE m_DllHInstance; // The HINSTANCE to the dll
  232. DWORD m_dwFlags; // IODLL and RW flags
  233. CObArray m_ResArray; // Array of all the Resources in the file.
  234. UINT m_ResBufSize; // Will be usefull when we have to write the resource
  235. int m_TypePos; // Position in the ResArray for the last enum type
  236. CWordArray m_TypeArray; // Array of resource types in the file
  237. int m_IdPos;
  238. CWordArray m_IdArray; // Array of resource id of a types in the file
  239. int m_LangPos;
  240. CWordArray m_LangArray; // Array of Language if of a given type/id
  241. char m_IdStr[100]; // Resource name
  242. char m_TypeStr[100]; // Type name
  243. char m_LastTypeName[100];
  244. LPSTR m_LastTypeID;
  245. };
  246. // This class will old the information on each entry in the INI file related with the
  247. // R/W modules. When the DLL will be discarded the memory will be cleaned.
  248. class CDllEntryTable : public CObject
  249. {
  250. public:
  251. CDllEntryTable( CString szEntry );
  252. ~CDllEntryTable();
  253. CString GetType( ) { return m_szDllType; }
  254. CString GetName( ) { return m_szDllName; }
  255. HINSTANCE LoadEntry( );
  256. BOOL FreeEntry( );
  257. private:
  258. CString m_szDllName; // Dll Name and directory
  259. CString m_szDllType; // Dll type tag
  260. HINSTANCE m_handle;
  261. };
  262. // This class is a dinamyc array of CDllEntryTable elements.
  263. // When the DLL is initialized the class read the INI file and is ready with the information
  264. // on each of the RW Modules present on the hard disk. When the DLL il discarded the Class
  265. // will take care to delete all the entry allocated.
  266. class CDllTable : public CObArray
  267. {
  268. public:
  269. CDllTable( UINT );
  270. ~CDllTable();
  271. UINT GetPosFromTable( CString szFileType );
  272. UINT GetMaxEntry() { return m_MaxEntry; }
  273. private:
  274. UINT m_MaxEntry;
  275. UINT m_InitNum;
  276. };
  277. class CModuleTable : public CObArray
  278. {
  279. public:
  280. CModuleTable( UINT );
  281. ~CModuleTable();
  282. private:
  283. UINT m_LastHandle;
  284. UINT m_InitNum;
  285. };
  286. /////////////////////////////////////////////////////////////////////////////
  287. // Global variables
  288. CDllTable gDllTable(MAXENTRYBUF); // When the DLL is initialized the constructor is called
  289. CModuleTable gModuleTable(2); // When the DLL is initialized the constructor is called
  290. TCHAR szDefaultRcdata[][MAXKEYLEN] = { "kernel32.dll,rcdata1.dll" };
  291. TCHAR szDefaultRWDll[][MAXKEYLEN] = {"rwwin16.dll,WIN16",
  292. "rwwin32.dll,WIN32",
  293. "rwmac.dll,MAC",
  294. "rwres32.dll,RES32",
  295. "rwinf.dll,INF"};
  296. static BYTE sizeofWord = sizeof(WORD);
  297. static BYTE sizeofDWord = sizeof(DWORD);
  298. static BYTE sizeofDWordPtr = sizeof(DWORD_PTR);
  299. static BYTE sizeofByte = sizeof(BYTE);
  300. /////////////////////////////////////////////////////////////////////////////
  301. // Public C interface implementation
  302. static UINT CopyFile( const char * pszfilein, const char * pszfileout );
  303. static BYTE Allign(LONG bLen);
  304. void CheckError(LPCSTR szStr);
  305. int g_iDllLoaded;
  306. SETTINGS g_Settings;
  307. ////////////////////////////////////////////////////////////////////////////
  308. // RDF File support code
  309. HANDLE
  310. OpenModule(
  311. LPCSTR lpszSrcfilename, // File name of the executable to use as source file
  312. LPCSTR lpszfiletype, // Type of the executable file if known
  313. LPCSTR lpszRDFfile,
  314. DWORD dwFlags );
  315. //--------------------------------------------------------------------------------------------
  316. //********************************************************************************************
  317. // Global Settings API
  318. //--------------------------------------------------------------------------------------------
  319. extern "C"
  320. DllExport
  321. UINT
  322. APIENTRY
  323. RSSetGlobals(
  324. SETTINGS Settings) // Set the global variable, like CP to use.
  325. {
  326. g_Settings.cp = Settings.cp;
  327. g_Settings.bAppend = Settings.bAppend;
  328. g_Settings.bUpdOtherResLang = Settings.bUpdOtherResLang;
  329. strncpy(g_Settings.szDefChar, Settings.szDefChar, 1);
  330. g_Settings.szDefChar[1] = '\0';
  331. return 1;
  332. }
  333. extern "C"
  334. DllExport
  335. UINT
  336. APIENTRY
  337. RSGetGlobals(
  338. LPSETTINGS lpSettings) // Retrieve the global variable
  339. {
  340. lpSettings->cp = g_Settings.cp;
  341. lpSettings->bAppend = g_Settings.bAppend;
  342. lpSettings->bUpdOtherResLang = g_Settings.bUpdOtherResLang;
  343. strncpy(lpSettings->szDefChar, g_Settings.szDefChar, 1);
  344. lpSettings->szDefChar[1] = '\0';
  345. return 1;
  346. }
  347. //--------------------------------------------------------------------------------------------
  348. //********************************************************************************************
  349. // Module Opening/Closing API
  350. //--------------------------------------------------------------------------------------------
  351. extern "C"
  352. DllExport
  353. HANDLE
  354. APIENTRY
  355. RSOpenModule(
  356. LPCSTR lpszSrcfilename, // File name of the executable to use as source file
  357. LPCSTR lpszfiletype ) // Type of the executable file if known
  358. {
  359. return OpenModule(lpszSrcfilename, lpszfiletype, NULL, 0 );
  360. }
  361. extern "C"
  362. DllExport
  363. HANDLE
  364. APIENTRY
  365. RSOpenModuleEx(
  366. LPCSTR lpszSrcfilename, // File name of the executable to use as source file
  367. LPCSTR lpszfiletype, // Type of the executable file if known
  368. LPCSTR lpszRDFfile, // Resource Description File (RDF)
  369. DWORD dwFlags ) // HIWORD=rw flags LOWORD=iodll flags
  370. {
  371. // Check if we have a RDF file defined
  372. if(lpszRDFfile) {
  373. return OpenModule(lpszSrcfilename, lpszfiletype, lpszRDFfile, dwFlags );
  374. }
  375. else
  376. return OpenModule(lpszSrcfilename, lpszfiletype, NULL, dwFlags );
  377. }
  378. extern "C"
  379. DllExport
  380. HANDLE
  381. APIENTRY
  382. RSCopyModule(
  383. HANDLE hSrcfilemodule, // Handle to the source file
  384. LPCSTR lpszModuleName, // Name of the new module filename
  385. LPCSTR lpszfiletype ) // Type of the target module
  386. {
  387. TRACE2("IODLL.DLL: RSCopyModule: %d %s\n", (int)hSrcfilemodule, lpszfiletype);
  388. UINT uiError = ERROR_NO_ERROR;
  389. INT_PTR uiHandle = 0 ;
  390. // Check if the type is not null
  391. CString szSrcFileType;
  392. if (!lpszfiletype) {
  393. return UlongToHandle(ERROR_IO_TYPE_NOT_SUPPORTED);
  394. } else szSrcFileType = lpszfiletype;
  395. gModuleTable.Add(new CFileModule( (LPSTR)lpszModuleName,
  396. NULL,
  397. gDllTable.GetPosFromTable(szSrcFileType),
  398. 0 ));
  399. // Get the position in the array.
  400. uiHandle = gModuleTable.GetSize();
  401. // Read the informations on the type in the file.
  402. CFileModule* pFileModule = (CFileModule*)gModuleTable.GetAt(uiHandle-1);
  403. if (!pFileModule)
  404. return UlongToHandle(ERROR_IO_INVALIDMODULE);
  405. // We have to copy the information from the source module
  406. INT_PTR uiSrcHandle = (UINT_PTR)hSrcfilemodule-FIRSTVALIDVALUE-1;
  407. if (uiSrcHandle<0)
  408. return (HANDLE)(ERROR_HANDLE_INVALID);
  409. CFileModule* pSrcFileModule = (CFileModule*)gModuleTable.GetAt((UINT)uiSrcHandle);
  410. if (!pSrcFileModule)
  411. return (HANDLE)(ERROR_IO_INVALIDMODULE);
  412. if (pSrcFileModule->Copy( pFileModule ))
  413. return (HANDLE)(ERROR_IO_INVALIDITEM);
  414. pFileModule->SetResBufSize( pSrcFileModule->GetResBufSize() );
  415. return (HANDLE)(uiHandle+FIRSTVALIDVALUE);
  416. }
  417. extern "C"
  418. DllExport
  419. UINT
  420. APIENTRY
  421. RSCloseModule(
  422. HANDLE hResFileModule ) // Handle to the session opened before
  423. {
  424. TRACE1("IODLL.DLL: RSCloseModule: %d\n", (int)hResFileModule);
  425. UINT uiError = ERROR_NO_ERROR;
  426. INT_PTR uiHandle = (UINT_PTR)hResFileModule-FIRSTVALIDVALUE-1;
  427. if (uiHandle<0)
  428. return ERROR_HANDLE_INVALID;
  429. CFileModule* pFileModule = (CFileModule*)gModuleTable[(UINT)uiHandle];
  430. if (!pFileModule)
  431. return ERROR_IO_INVALIDMODULE;
  432. uiError = pFileModule->CleanUp();
  433. return uiError;
  434. }
  435. extern "C"
  436. DllExport
  437. HANDLE
  438. APIENTRY
  439. RSHandleFromName(
  440. LPCSTR lpszfilename ) // Handle to the session with the file name specified
  441. {
  442. TRACE("IODLL.DLL: RSHandleFromName: %s\n", lpszfilename);
  443. INT_PTR UpperBound = gModuleTable.GetUpperBound();
  444. CFileModule* pFileModule;
  445. while( UpperBound!=-1 ) {
  446. pFileModule = (CFileModule*)gModuleTable.GetAt(UpperBound);
  447. if(pFileModule->GetName()==lpszfilename)
  448. return (HANDLE)(UpperBound+FIRSTVALIDVALUE+1);
  449. UpperBound--;
  450. }
  451. return (HANDLE)0;
  452. }
  453. //--------------------------------------------------------------------------------------------
  454. //********************************************************************************************
  455. // Enumeration API
  456. //--------------------------------------------------------------------------------------------
  457. extern "C"
  458. DllExport
  459. LPCSTR
  460. APIENTRY
  461. RSEnumResType(
  462. HANDLE hResFileModule, // Handle to the file session
  463. LPCSTR lpszPrevResType) // Previously enumerated type
  464. {
  465. TRACE2("IODLL.DLL: RSEnumResType: %u %Fp\n", (UINT)hResFileModule,
  466. lpszPrevResType);
  467. // By now all the information on the types should be here.
  468. // Check the HANDLE and see if it is a valid one
  469. INT_PTR uiHandle = (UINT_PTR)hResFileModule-FIRSTVALIDVALUE-1;
  470. if (uiHandle<0)
  471. return LPNULL;
  472. // Get the File module
  473. CFileModule* pFileModule = (CFileModule*)gModuleTable[(UINT)uiHandle];
  474. if (!pFileModule)
  475. return LPNULL;
  476. return pFileModule->EnumType( lpszPrevResType );
  477. }
  478. extern "C"
  479. DllExport
  480. LPCSTR
  481. APIENTRY
  482. RSEnumResId(
  483. HANDLE hResFileModule, // Handle to the file session
  484. LPCSTR lpszResType, // Previously enumerated type
  485. LPCSTR lpszPrevResId) // Previously enumerated id
  486. {
  487. TRACE3("IODLL.DLL: RSEnumResId: %u %Fp %Fp\n", (UINT)hResFileModule,
  488. lpszResType,
  489. lpszPrevResId);
  490. // Check the HANDLE and see if it is a valid one
  491. INT_PTR uiHandle = (UINT_PTR)hResFileModule-FIRSTVALIDVALUE-1;
  492. if (uiHandle<0) return LPNULL;
  493. // Get the File module
  494. CFileModule* pFileModule = (CFileModule*)gModuleTable[(UINT)uiHandle];
  495. return pFileModule->EnumId( lpszResType, lpszPrevResId );
  496. }
  497. extern "C"
  498. DllExport
  499. DWORD
  500. APIENTRY
  501. RSEnumResLang(
  502. HANDLE hResFileModule, // Handle to the file session
  503. LPCSTR lpszResType, // Previously enumerated type
  504. LPCSTR lpszResId, // Previously enumerated id
  505. DWORD dwPrevResLang) // Previously enumerated language
  506. {
  507. TRACE3("IODLL.DLL: RSEnumResLang: %u %Fp %Fp ", (UINT)hResFileModule,
  508. lpszResType,
  509. lpszResId);
  510. TRACE1("%ld\n", dwPrevResLang);
  511. // Check the HANDLE and see if it is a valid one
  512. INT_PTR uiHandle = (UINT_PTR)hResFileModule-FIRSTVALIDVALUE-1;
  513. if (uiHandle<0) return LPNULL;
  514. // Get the File module
  515. CFileModule* pFileModule = (CFileModule*)gModuleTable[(UINT)uiHandle];
  516. if (!pFileModule)
  517. return ERROR_IO_INVALIDMODULE;
  518. return pFileModule->EnumLang( lpszResType, lpszResId, dwPrevResLang );
  519. }
  520. extern "C"
  521. DllExport
  522. DWORD
  523. APIENTRY
  524. RSEnumResItemId(
  525. HANDLE hResFileModule, // Handle to the file session
  526. LPCSTR lpszResType, // Previously enumerated type
  527. LPCSTR lpszResId, // Previously enumerated id
  528. DWORD dwResLang, // Previously enumerated language
  529. DWORD dwPrevResItemId) // Previously enumerated item id
  530. {
  531. TRACE3("IODLL.DLL: RSEnumResItemId: %u %Fp %Fp ", (UINT)hResFileModule,
  532. lpszResType,
  533. lpszResId);
  534. TRACE2("%ld %Fp\n", dwResLang,
  535. dwPrevResItemId);
  536. // Check the HANDLE and see if it is a valid one
  537. INT_PTR uiHandle = (UINT_PTR)hResFileModule-FIRSTVALIDVALUE-1;
  538. if (uiHandle<0) return LPNULL;
  539. // Get the File module
  540. CFileModule* pFileModule = (CFileModule*)gModuleTable[(UINT)uiHandle];
  541. if (!pFileModule)
  542. return ERROR_IO_INVALIDMODULE;
  543. return pFileModule->EnumItem( lpszResType, lpszResId, dwResLang, dwPrevResItemId );
  544. }
  545. //--------------------------------------------------------------------------------------------
  546. //********************************************************************************************
  547. // Data acquisition API
  548. //--------------------------------------------------------------------------------------------
  549. extern "C"
  550. DllExport
  551. UINT
  552. APIENTRY
  553. RSGetResItemData(
  554. HANDLE hResFileModule, // Handle to the file session
  555. LPCSTR lpszResType, // Previously enumerated type
  556. LPCSTR lpszResId, // Previously enumerated id
  557. DWORD dwResLang, // Previously enumerated language
  558. DWORD dwResItemId, // Previously enumerated item id
  559. LPVOID lpbuffer, // Pointer to the buffer that will get the resource info
  560. UINT uiBufSize) // Size of the buffer that will hold the resource info
  561. {
  562. TRACE3("IODLL.DLL: RSGetResItemData: %u %Fp %Fp ", (UINT)hResFileModule,
  563. lpszResType,
  564. lpszResId);
  565. TRACE3("%ld %Fp %Fp ", dwResLang,
  566. dwResItemId,
  567. lpbuffer);
  568. TRACE1("%d\n", uiBufSize);
  569. // Check the HANDLE and see if it is a valid one
  570. INT_PTR uiHandle = (UINT_PTR)hResFileModule-FIRSTVALIDVALUE-1;
  571. if (uiHandle<0) return LPNULL;
  572. // Get the File module
  573. CFileModule* pFileModule = (CFileModule*)gModuleTable[(UINT)uiHandle];
  574. if (!pFileModule)
  575. return ERROR_IO_INVALIDMODULE;
  576. return pFileModule->GetData( lpszResType, lpszResId, dwResLang, dwResItemId,
  577. lpbuffer, uiBufSize );
  578. }
  579. extern "C"
  580. DllExport
  581. DWORD
  582. APIENTRY
  583. RSGetResImage(
  584. HANDLE hResFileModule, // Handle to the file session
  585. LPCSTR lpszResType, // Previously enumerated type
  586. LPCSTR lpszResId, // Previously enumerated id
  587. DWORD dwResLang, // Previously enumerated language
  588. LPVOID lpbuffer, // Pointer to the buffer to get the resource Data
  589. DWORD dwBufSize) // Size of the allocated buffer
  590. {
  591. TRACE3("IODLL.DLL: RSGetResImage: %u %Fp %Fp ", (UINT)hResFileModule,
  592. lpszResType,
  593. lpszResId);
  594. TRACE2("%ld %Fp ", dwResLang,
  595. lpbuffer);
  596. TRACE1("%lu\n", dwBufSize);
  597. // Check the HANDLE and see if it is a valid one
  598. INT_PTR uiHandle = (UINT_PTR)hResFileModule-FIRSTVALIDVALUE-1;
  599. if (uiHandle<0) return LPNULL;
  600. // Get the File module
  601. CFileModule* pFileModule = (CFileModule*)gModuleTable[(UINT)uiHandle];
  602. if (!pFileModule)
  603. return ERROR_IO_INVALIDMODULE;
  604. return pFileModule->GetImage( lpszResType, lpszResId, dwResLang, lpbuffer, dwBufSize );
  605. }
  606. //--------------------------------------------------------------------------------------------
  607. //********************************************************************************************
  608. // Update API
  609. //--------------------------------------------------------------------------------------------
  610. extern "C"
  611. DllExport
  612. UINT
  613. APIENTRY
  614. RSUpdateResItemData(
  615. HANDLE hResFileModule, // Handle to the file session
  616. LPCSTR lpszResType, // Previously enumerated type
  617. LPCSTR lpszResId, // Previously enumerated id
  618. DWORD dwResLang, // Previously enumerated language
  619. DWORD dwResItemId, // Previously enumerated items id
  620. LPVOID lpbuffer, // Pointer to the buffer to the resource item Data
  621. UINT uiBufSize) // Size of the buffer
  622. {
  623. TRACE3("IODLL.DLL: RSUpdateResItemData: %u %Fp %Fp ", (UINT)hResFileModule,
  624. lpszResType,
  625. lpszResId);
  626. TRACE3("%ld %Fp %Fp ", dwResLang,
  627. dwResItemId,
  628. lpbuffer);
  629. TRACE1("%u\n", uiBufSize);
  630. // Check the HANDLE and see if it is a valid one
  631. INT_PTR uiHandle = (UINT_PTR)hResFileModule-FIRSTVALIDVALUE-1;
  632. if (uiHandle<0) return LPNULL;
  633. // Get the File module
  634. CFileModule* pFileModule = (CFileModule*)gModuleTable[(UINT)uiHandle];
  635. if (!pFileModule)
  636. return ERROR_IO_INVALIDMODULE;
  637. return pFileModule->UpdateData( lpszResType, lpszResId, dwResLang, dwResItemId,
  638. lpbuffer, uiBufSize );
  639. }
  640. extern "C"
  641. DllExport
  642. DWORD
  643. APIENTRY
  644. RSUpdateResImage(
  645. HANDLE hResFileModule, // Handle to the file session
  646. LPCSTR lpszResType, // Previously enumerated type
  647. LPCSTR lpszResId, // Previously enumerated id
  648. DWORD dwResLang, // Previously enumerated language
  649. DWORD dwUpdLang, // Desired output language
  650. LPVOID lpbuffer, // Pointer to the buffer to the resource item Data
  651. DWORD dwBufSize) // Size of the buffer
  652. {
  653. TRACE3("IODLL.DLL: RSUpdateResImage: %d %Fp %Fp ", hResFileModule,
  654. lpszResType,
  655. lpszResId);
  656. TRACE("%Fp %Fp %Fp ", dwResLang,
  657. lpbuffer);
  658. TRACE1("%d\n", dwBufSize);
  659. UINT uiError = ERROR_NO_ERROR;
  660. // Check the HANDLE and see if it is a valid one
  661. INT_PTR uiHandle = (UINT_PTR)hResFileModule-FIRSTVALIDVALUE-1;
  662. if (uiHandle<0) return LPNULL;
  663. // Get the File module
  664. CFileModule* pFileModule = (CFileModule*)gModuleTable[(UINT)uiHandle];
  665. if (!pFileModule)
  666. return ERROR_IO_INVALIDMODULE;
  667. return pFileModule->UpdateImage( lpszResType, lpszResId, dwResLang,
  668. dwUpdLang, lpbuffer, dwBufSize );
  669. return (DWORD)uiError;
  670. }
  671. //--------------------------------------------------------------------------------------------
  672. //********************************************************************************************
  673. // Conversion API
  674. //--------------------------------------------------------------------------------------------
  675. extern "C"
  676. DllExport
  677. UINT
  678. APIENTRY
  679. RSUpdateFromResFile(
  680. HANDLE hResFileModule, // Handle to the file session
  681. LPSTR lpszResFilename) // The resource filename to be converted
  682. {
  683. TRACE2("IODLL.DLL: RSUpdateFromResFile: %d %s\n", hResFileModule,
  684. lpszResFilename);
  685. UINT uiError = 0;
  686. const int CBSTRMAX = 8192;
  687. BOOL fReturn = TRUE;
  688. HANDLE hResFileSrc = NULL;
  689. LPCSTR lpszTypeSrc = NULL;
  690. LPCSTR lpszResSrc = NULL;
  691. DWORD dwLangSrc = 0L;
  692. DWORD dwLangDest = 0L;
  693. DWORD dwItemSrc = 0L;
  694. DWORD dwItemDest = 0L;
  695. WORD cbResItemSrc = 0;
  696. WORD cbResItemDest = 0;
  697. LPRESITEM lpriSrc = NULL;
  698. LPRESITEM lpriDest = NULL;
  699. // Check the HANDLE and see if it is a valid one
  700. INT_PTR uiHandle = (UINT_PTR)hResFileModule-FIRSTVALIDVALUE-1;
  701. if (uiHandle<0) return ERROR_HANDLE_INVALID;
  702. // Get the File module
  703. CFileModule* pFileModule = (CFileModule*)gModuleTable[(UINT)uiHandle];
  704. if (!pFileModule)
  705. return ERROR_IO_INVALIDMODULE;
  706. // Initialize storage for ResItem
  707. if (lpriSrc = (LPRESITEM)malloc(CBSTRMAX))
  708. cbResItemSrc = CBSTRMAX;
  709. else {
  710. AfxThrowMemoryException();
  711. }
  712. // Read in the resource files
  713. if ((UINT_PTR)(hResFileSrc = RSOpenModule((LPSTR)lpszResFilename, "RES32")) <= 100) {
  714. uiError = (UINT)(UINT_PTR)hResFileSrc;
  715. if (lpriSrc)
  716. free(lpriSrc);
  717. return uiError;
  718. }
  719. // Get the File Module of the Resource file. This is needed for the image conversion
  720. CFileModule* pResFileModule = (CFileModule*)gModuleTable[(UINT)((UINT_PTR)hResFileSrc-FIRSTVALIDVALUE-1)];
  721. if(!pResFileModule)
  722. return ERROR_IO_INVALIDMODULE;
  723. while (lpszTypeSrc = RSEnumResType(hResFileSrc,
  724. lpszTypeSrc)) {
  725. while (lpszResSrc = RSEnumResId(hResFileSrc,
  726. lpszTypeSrc,
  727. lpszResSrc)) {
  728. // Hack Hack, This is done to handle Bitmap conversion
  729. // Will need to be done better after the Chicago release
  730. switch(LOWORD(lpszTypeSrc)) {
  731. case 2:
  732. TRACE("Here we will have to swap the images!\n");
  733. pFileModule->CopyImage( pResFileModule, lpszTypeSrc, lpszResSrc );
  734. break;
  735. default:
  736. break;
  737. }
  738. while (dwLangSrc = RSEnumResLang(hResFileSrc,
  739. lpszTypeSrc,
  740. lpszResSrc,
  741. dwLangSrc)) {
  742. while (dwItemSrc = RSEnumResItemId(hResFileSrc,
  743. lpszTypeSrc,
  744. lpszResSrc,
  745. dwLangSrc,
  746. dwItemSrc)){
  747. WORD wSize;
  748. wSize = (WORD)RSGetResItemData(hResFileSrc,
  749. lpszTypeSrc,
  750. lpszResSrc,
  751. dwLangSrc,
  752. dwItemSrc,
  753. (LPRESITEM)lpriSrc,
  754. cbResItemSrc);
  755. if (cbResItemSrc < wSize) {
  756. if (lpriSrc = (LPRESITEM)realloc(lpriSrc, wSize))
  757. cbResItemSrc = wSize;
  758. else
  759. AfxThrowMemoryException();
  760. RSGetResItemData(hResFileSrc,
  761. lpszTypeSrc,
  762. lpszResSrc,
  763. dwLangSrc,
  764. dwItemSrc,
  765. (LPRESITEM)lpriSrc,
  766. cbResItemSrc);
  767. }
  768. if ((uiError = RSUpdateResItemData(hResFileModule,
  769. lpszTypeSrc,
  770. lpszResSrc,
  771. 1033,
  772. dwItemSrc,
  773. lpriSrc,
  774. cbResItemSrc)) != 0) {
  775. /*
  776. if (lpriSrc)
  777. free(lpriSrc);
  778. RSCloseModule(hResFileSrc);
  779. return uiError;
  780. */
  781. }
  782. }
  783. }
  784. }
  785. }
  786. // Save out to the updated resource file, same format.
  787. RSCloseModule(hResFileSrc);
  788. // The user want to write the file with the same format as the original
  789. uiError = pFileModule->WriteUpdatedResource( pFileModule->GetName(), hResFileModule, NULL);
  790. // Clean up
  791. return uiError;
  792. }
  793. //--------------------------------------------------------------------------------------------
  794. //********************************************************************************************
  795. // Writing API
  796. //--------------------------------------------------------------------------------------------
  797. extern "C"
  798. DllExport
  799. UINT
  800. APIENTRY
  801. RSWriteResFile(
  802. HANDLE hResFileModule, // Handle to the file session
  803. LPCSTR lpszTgtfilename, // The new filename to be generated
  804. LPCSTR lpszTgtfileType, // Target Resource type 16/32
  805. LPCSTR lpszSymbolPath) // Symbol Path for updating symbol checksum
  806. {
  807. TRACE3("IODLL.DLL: RSWriteResFile: %d %s %s\n", hResFileModule,
  808. lpszTgtfilename,
  809. lpszTgtfileType);
  810. UINT uiError = ERROR_NO_ERROR;
  811. // Check the HANDLE and see if it is a valid one
  812. INT_PTR uiHandle = (UINT_PTR)hResFileModule-FIRSTVALIDVALUE-1;
  813. if (uiHandle<0) return ERROR_HANDLE_INVALID;
  814. // Get the File module
  815. CFileModule* pFileModule = (CFileModule*)gModuleTable[(UINT)uiHandle];
  816. if (!pFileModule)
  817. return ERROR_IO_INVALIDMODULE;
  818. if(lpszTgtfileType!=LPNULL) {
  819. // The user want a conversion.
  820. // Check if the type the user want is one of the supported one
  821. CDllEntryTable* pDllEntry;
  822. INT_PTR iUpperBound = gDllTable.GetUpperBound();
  823. while(iUpperBound>=0) {
  824. pDllEntry = (CDllEntryTable*) gDllTable.GetAt(iUpperBound);
  825. if ( (pDllEntry) && (pDllEntry->GetType()==lpszTgtfileType) )
  826. iUpperBound = -1;
  827. iUpperBound--;
  828. }
  829. if (iUpperBound==-1)
  830. return ERROR_IO_TYPE_NOT_SUPPORTED;
  831. // We will open a new module now.
  832. // We will generate the images from the other module
  833. HANDLE hTgtFileHandle = RSCopyModule( hResFileModule, LPNULL, lpszTgtfileType );
  834. if ((UINT_PTR)hTgtFileHandle<=FIRSTVALIDVALUE)
  835. return ((UINT)(UINT_PTR)hTgtFileHandle);
  836. // Write the file
  837. CFileModule* pNewFileModule = (CFileModule*)gModuleTable[(UINT)((UINT_PTR)hTgtFileHandle-FIRSTVALIDVALUE-1)];
  838. if (!pNewFileModule)
  839. return ERROR_IO_INVALIDMODULE;
  840. uiError = pNewFileModule->WriteUpdatedResource( lpszTgtfilename, hTgtFileHandle, lpszSymbolPath );
  841. // Close the module we just create
  842. RSCloseModule(hTgtFileHandle);
  843. return uiError;
  844. }
  845. // The user want to write the file with the same format as the original
  846. return pFileModule->WriteUpdatedResource( lpszTgtfilename,
  847. hResFileModule,
  848. lpszSymbolPath);
  849. }
  850. //--------------------------------------------------------------------------------------------
  851. //********************************************************************************************
  852. // Recognition API
  853. //--------------------------------------------------------------------------------------------
  854. extern "C"
  855. DllExport
  856. UINT
  857. APIENTRY
  858. RSFileType(
  859. LPCSTR lpszfilename, // File name of the executable to use as source file
  860. LPSTR lpszfiletype ) // Type of the executable file if known
  861. {
  862. //Get the executable file format querying all the R/W DLL
  863. INT_PTR UpperBound = gDllTable.GetUpperBound();
  864. int c = 0;
  865. CDllEntryTable* pDllEntry;
  866. while(c<=UpperBound) {
  867. // Get the module name
  868. pDllEntry = (CDllEntryTable*) gDllTable.GetAt(c);
  869. if (!pDllEntry)
  870. return ERROR_IO_INVALID_DLL;
  871. // Get the handle to the dll and query validate
  872. HINSTANCE hInst = pDllEntry->LoadEntry();
  873. if (hInst) {
  874. BOOL (FAR PASCAL * lpfnValidateFile)(LPCSTR);
  875. // Get the pointer to the function to extract the resources
  876. lpfnValidateFile = (BOOL (FAR PASCAL *)(LPCSTR))
  877. GetProcAddress( hInst, "RWValidateFileType" );
  878. if (lpfnValidateFile==NULL) {
  879. return ERROR_DLL_PROC_ADDRESS;
  880. }
  881. if( (*lpfnValidateFile)((LPCSTR)lpszfilename) ) {
  882. // this DLL can handle the file type
  883. strcpy(lpszfiletype, pDllEntry->GetType());
  884. return ERROR_NO_ERROR;
  885. }
  886. }
  887. else {
  888. CheckError("(RSFileType) LoadLibrary()" + pDllEntry->GetName());
  889. }
  890. c++;
  891. }
  892. strcpy(lpszfiletype, "");
  893. return ERROR_IO_TYPE_NOT_SUPPORTED;
  894. }
  895. ////////////////////////////////////////////////////////////////////////////
  896. // Return TRUE if the file has more than one language.
  897. // Will fill the lpszLanguage with a list of the languages in the file
  898. ////////////////////////////////////////////////////////////////////////////
  899. extern "C"
  900. DllExport
  901. UINT
  902. APIENTRY
  903. RSLanguages(
  904. HANDLE hfilemodule, // Handle to the file
  905. LPSTR lpszLanguages ) // will be filled with a string of all the languages in the file
  906. {
  907. INT_PTR uiHandle = (UINT_PTR)hfilemodule-FIRSTVALIDVALUE-1;
  908. if (uiHandle<0)
  909. return LPNULL;
  910. // Get the File module
  911. CFileModule* pFileModule = (CFileModule*)gModuleTable[(UINT)uiHandle];
  912. if (!pFileModule)
  913. return LPNULL;
  914. return pFileModule->GetLanguageStr(lpszLanguages);
  915. }
  916. ////////////////////////////////////////////////////////////////////////////
  917. // Class implementation
  918. ////////////////////////////////////////////////////////////////////////////
  919. ////////////////////////////////////////////////////////////////////////////
  920. // CFileModule
  921. CFileModule::CFileModule()
  922. {
  923. //TRACE("IODLL.DLL: CFileModule::CFileModule\n");
  924. m_SrcFileName = "";
  925. m_RdfFileName = "";
  926. m_DllTypeEntry = 0; // Invalid position
  927. m_DllHInstance = 0; // Not loaded yet
  928. m_TypePos = 0;
  929. m_IdPos = 0;
  930. m_LangPos = 0;
  931. m_LastTypeName[0] = '\0';
  932. m_LastTypeID = LPNULL;
  933. m_IdStr[0] = '\0';
  934. m_dwFlags = 0;
  935. m_ResArray.SetSize(100,10);
  936. m_TypeArray.SetSize(100,10);
  937. m_IdArray.SetSize(100,10);
  938. m_LangArray.SetSize(100,10);
  939. }
  940. CFileModule::CFileModule( LPCSTR lpszSrcfilename,
  941. LPCSTR lpszRdffilename,
  942. int DllTblPos,
  943. DWORD dwFlags)
  944. {
  945. //TRACE2("IODLL.DLL: CFileModule::CFileModule %s %d\n", lpszSrcfilename,
  946. // DllTblPos );
  947. m_SrcFileName = lpszSrcfilename;
  948. if(!lpszRdffilename)
  949. {
  950. CString strMap;
  951. // assign a default name
  952. m_RdfFileName = lpszSrcfilename;
  953. // remove the the path...
  954. int iPos = m_RdfFileName.ReverseFind('\\');
  955. if(iPos!=-1)
  956. m_RdfFileName = m_RdfFileName.Mid(iPos+1);
  957. // Get name from INI file
  958. GetProfileString("IODLL-RCDATA", m_RdfFileName, "", strMap.GetBuffer(MAX_PATH), MAX_PATH);
  959. strMap.ReleaseBuffer();
  960. if(strMap.IsEmpty())
  961. {
  962. //
  963. // Not found in win.ini, we use default.
  964. //
  965. int c = 0;
  966. int iMax = sizeof(szDefaultRcdata)/sizeof(TCHAR)/MAXKEYLEN;
  967. PCHAR pstr;
  968. CString Entry;
  969. for ( pstr = szDefaultRcdata[0]; c< iMax; pstr += MAXKEYLEN, c++)
  970. {
  971. Entry = pstr;
  972. if(Entry.Find (m_RdfFileName) !=-1)
  973. {
  974. strMap = Entry.Mid(lstrlen(m_RdfFileName)+1);
  975. break;
  976. }
  977. }
  978. }
  979. if (!strMap.IsEmpty())
  980. {
  981. m_RdfFileName = strMap;
  982. // we will use the dll in the directory from were we have been spawned
  983. GetModuleFileName( NULL, strMap.GetBuffer(MAX_PATH), MAX_PATH );
  984. strMap.ReleaseBuffer(-1);
  985. // remove the file name
  986. iPos = strMap.ReverseFind('\\');
  987. if(iPos!=-1)
  988. strMap = strMap.Left(iPos+1);
  989. // append the path to the file name
  990. m_RdfFileName = strMap + m_RdfFileName;
  991. }
  992. else
  993. {
  994. m_RdfFileName = "";
  995. }
  996. }
  997. else m_RdfFileName = lpszRdffilename;
  998. m_SrcFileName.MakeUpper();
  999. m_DllTypeEntry = DllTblPos;
  1000. m_DllHInstance = 0; // Not loaded yet
  1001. m_TypePos = 0;
  1002. m_IdPos = 0;
  1003. m_LangPos = 0;
  1004. m_LastTypeName[0] = '\0';
  1005. m_LastTypeID = LPNULL;
  1006. m_IdStr[0] = '\0';
  1007. m_dwFlags = dwFlags;
  1008. }
  1009. CFileModule::~CFileModule()
  1010. {
  1011. TRACE("IODLL.DLL: CFileModule::~CFileModule\n");
  1012. CleanUp();
  1013. }
  1014. HINSTANCE CFileModule::LoadDll()
  1015. {
  1016. if (!(m_DllHInstance) && (m_DllTypeEntry))
  1017. if((m_DllHInstance = ((CDllEntryTable*)gDllTable[m_DllTypeEntry-1])->LoadEntry())==NULL) {
  1018. CheckError("(CFileModule::LoadDll) LoadLibrary() for " + ((CDllEntryTable*)gDllTable[m_DllTypeEntry-1])->GetName() );
  1019. } else
  1020. TRACE("CFileModule::LoadDll call %d --->> %08x\n", g_iDllLoaded++, m_DllHInstance);
  1021. return m_DllHInstance;
  1022. }
  1023. void
  1024. CFileModule::FreeDll()
  1025. {
  1026. TRACE("IODLL.DLL: CFileModule::FreeDll() m_DllHInstance=%08x\n", m_DllHInstance );
  1027. if (m_DllHInstance)
  1028. m_DllHInstance = 0;
  1029. }
  1030. UINT
  1031. CFileModule::CleanUp()
  1032. {
  1033. INT_PTR UpperBound = m_ResArray.GetUpperBound();
  1034. TRACE1("IODLL.DLL: CFileModule::CleanUp %d\n", UpperBound);
  1035. // Free the memory for the resource information
  1036. CResInfo* pResInfo;
  1037. for(INT_PTR c=0; c<=UpperBound; c++) {
  1038. pResInfo = (CResInfo*)m_ResArray.GetAt(c);
  1039. TRACE("\tCFileModule\t%d\tCResInfo->%Fp\n", c, pResInfo);
  1040. delete pResInfo;
  1041. }
  1042. m_ResArray.RemoveAll();
  1043. // Unload the DLL
  1044. FreeDll();
  1045. return 0;
  1046. }
  1047. int
  1048. CFileModule::AddResInfo(
  1049. WORD Typeid, CString sztypeid,
  1050. WORD nameid, CString sznameid,
  1051. DWORD dwlang, DWORD dwsize, DWORD dwfileoffset )
  1052. {
  1053. return (int)m_ResArray.Add( new CResInfo(
  1054. Typeid,
  1055. sztypeid,
  1056. nameid,
  1057. sznameid,
  1058. dwlang,
  1059. dwsize,
  1060. dwfileoffset,
  1061. this
  1062. ));
  1063. }
  1064. int
  1065. CFileModule::AddTypeInfo( INT_PTR iPos, int iId, CString szId )
  1066. {
  1067. //TRACE3("IODLL.DLL: CFileModule::AddTypeInfo %d %d %Fp\n", iPos, iId, szId);
  1068. INT_PTR UpperBound = m_TypeArray.GetUpperBound();
  1069. for( INT_PTR c = 0; c<=UpperBound; c++) {
  1070. int pos = m_TypeArray.GetAt(c);
  1071. CResInfo* pResPos = (CResInfo*)m_ResArray.GetAt(pos);
  1072. CResInfo* pResLast = (CResInfo*)m_ResArray.GetAt(iPos);
  1073. if( ((pResPos->GetTypeId()==pResLast->GetTypeId()) &&
  1074. (pResPos->GetTypeName()==pResLast->GetTypeName())
  1075. )) return 0;
  1076. }
  1077. //TRACE3("IODLL.DLL: CFileModule::AddTypeInfo %d %d %Fp\n", iPos, iId, szId);
  1078. m_TypeArray.Add( (WORD)iPos );
  1079. return 1;
  1080. }
  1081. UINT
  1082. CFileModule::GetLanguageStr( LPSTR lpszLanguage )
  1083. {
  1084. CResInfo* pResInfo;
  1085. CString strLang = "";
  1086. char szLang[8];
  1087. BOOL multi_lang = FALSE;
  1088. for(INT_PTR c=0, iUpperBound = m_ResArray.GetUpperBound(); c<=iUpperBound; c++) {
  1089. pResInfo = (CResInfo*)m_ResArray.GetAt(c);
  1090. // Convert the language in to the hex value
  1091. sprintf(szLang,"0x%3.3X", pResInfo->GetLanguage());
  1092. // check if the language is already in the string
  1093. if(strLang.Find(szLang)==-1)
  1094. {
  1095. if(!strLang.IsEmpty())
  1096. {
  1097. multi_lang = TRUE;
  1098. strLang += ", ";
  1099. }
  1100. strLang += szLang;
  1101. }
  1102. }
  1103. strcpy( lpszLanguage, strLang );
  1104. return multi_lang;
  1105. }
  1106. CResInfo*
  1107. CFileModule::GetResInfo( LPCSTR lpszType, LPCSTR lpszId, DWORD dwLang )
  1108. {
  1109. BOOL fIdName = HIWORD(lpszId);
  1110. BOOL fTypeName = HIWORD(lpszType);
  1111. CResInfo* pResInfo;
  1112. // We must have at least the type to procede
  1113. if(!lpszType)
  1114. return LPNULL;
  1115. for( INT_PTR i = 0, iUpperBoundRes = m_ResArray.GetUpperBound() ; i<=iUpperBoundRes ; i++)
  1116. {
  1117. pResInfo = (CResInfo*)m_ResArray.GetAt(i);
  1118. if(pResInfo)
  1119. {
  1120. if( fTypeName ? !strcmp(pResInfo->GetTypeName(), lpszType) : pResInfo->GetTypeId()==LOWORD(lpszType))
  1121. {
  1122. // do we need the ID and language or can we exit
  1123. if(!lpszId)
  1124. return pResInfo;
  1125. if( fIdName ? !strcmp(pResInfo->GetResName(), lpszId) : pResInfo->GetResId()==LOWORD(lpszId))
  1126. {
  1127. // are we done or we want the language as well
  1128. if((LONG)dwLang==-1)
  1129. return pResInfo;
  1130. if( dwLang==pResInfo->GetLanguage() )
  1131. return pResInfo;
  1132. }
  1133. }
  1134. }
  1135. }
  1136. return LPNULL;
  1137. }
  1138. DWORD
  1139. CFileModule::GetImage( LPCSTR lpszType,
  1140. LPCSTR lpszId,
  1141. DWORD dwLang,
  1142. LPVOID lpbuffer,
  1143. DWORD dwBufSize )
  1144. {
  1145. // Check if all the parameters are valid
  1146. if (!lpszType) return 0L;
  1147. if (!lpszId) return 0L;
  1148. //if (!dwLang) return 0L;
  1149. CResInfo* pResInfo = GetResInfo( lpszType, lpszId, dwLang );
  1150. if (!m_DllHInstance)
  1151. if (!LoadDll()) return 0L;
  1152. if (pResInfo)
  1153. return pResInfo->GetImage( m_SrcFileName, m_DllHInstance, lpbuffer, dwBufSize );
  1154. return 0L;
  1155. }
  1156. DWORD
  1157. CFileModule::UpdateImage( LPCSTR lpszType,
  1158. LPCSTR lpszId,
  1159. DWORD dwLang,
  1160. DWORD dwUpdLang,
  1161. LPVOID lpbuffer,
  1162. DWORD dwBufSize )
  1163. {
  1164. // Check if all the parameters are valid
  1165. if (!lpszType) return 0L;
  1166. if (!lpszId) return 0L;
  1167. CResInfo* pResInfo = GetResInfo( lpszType, lpszId, dwLang );
  1168. if (!m_DllHInstance)
  1169. if (!LoadDll()) return 0L;
  1170. if (pResInfo)
  1171. return pResInfo->ReplaceImage(lpbuffer, dwBufSize, dwUpdLang );
  1172. return 0L;
  1173. }
  1174. UINT
  1175. CFileModule::GetData( LPCSTR lpszType,
  1176. LPCSTR lpszId,
  1177. DWORD dwLang,
  1178. DWORD dwItem,
  1179. LPVOID lpbuffer,
  1180. UINT uiBufSize )
  1181. {
  1182. // Check if all the parameters are valid
  1183. if (!lpszType) return 0L;
  1184. if (!lpszId) return 0L;
  1185. //if (!dwLang) return 0L;
  1186. CResInfo* pResInfo = GetResInfo( lpszType, lpszId, dwLang );
  1187. if (!m_DllHInstance)
  1188. if (LoadDll()==NULL) return 0L;
  1189. UINT uiSize = 0;
  1190. if (pResInfo)
  1191. uiSize = pResInfo->GetData( m_SrcFileName, m_DllHInstance,
  1192. dwItem, lpbuffer, uiBufSize );
  1193. return uiSize;
  1194. }
  1195. UINT
  1196. CFileModule::UpdateData( LPCSTR lpszType,
  1197. LPCSTR lpszId,
  1198. DWORD dwLang,
  1199. DWORD dwItem,
  1200. LPVOID lpbuffer,
  1201. UINT uiBufSize )
  1202. {
  1203. // Check if all the parameters are valid
  1204. if (!lpszType) return 0L;
  1205. if (!lpszId) return 0L;
  1206. //if (!dwLang) return 0L;
  1207. CResInfo* pResInfo = GetResInfo( lpszType, lpszId, dwLang );
  1208. if (!m_DllHInstance)
  1209. if (LoadDll()==NULL) return 0L;
  1210. UINT uiError = ERROR_NO_ERROR;
  1211. if (pResInfo)
  1212. uiError = pResInfo->UpdateData( m_SrcFileName, m_DllHInstance,
  1213. dwItem, lpbuffer, uiBufSize );
  1214. return uiError;
  1215. }
  1216. void
  1217. CFileModule::GenerateIdTable( LPCSTR lpszType, BOOL bNameOrId )
  1218. {
  1219. m_IdArray.RemoveAll();
  1220. CResInfo* pResInfo;
  1221. for( WORD c=0, UpperBound= (WORD)m_ResArray.GetUpperBound(); c<=UpperBound; c++) {
  1222. pResInfo = (CResInfo*)m_ResArray.GetAt(c);
  1223. if(bNameOrId) {
  1224. if (pResInfo->GetTypeId() && pResInfo->GetTypeName()=="") {
  1225. if (pResInfo->GetTypeId()==(WORD)LOWORD((DWORD)(DWORD_PTR)lpszType)) {
  1226. //TRACE2("IODLL.DLL: CFileModule::EnumId %d %d\n", c,
  1227. // (WORD)LOWORD((DWORD)lpszType) );
  1228. m_IdArray.Add( c );
  1229. }
  1230. m_LastTypeID = (LPSTR)lpszType;
  1231. m_LastTypeName[0] = '\0';
  1232. } else {
  1233. if (HIWORD((DWORD)(DWORD_PTR)lpszType)!=0) {
  1234. if (pResInfo->GetTypeName()==(CString)(lpszType))
  1235. m_IdArray.Add( c );
  1236. strcpy(m_LastTypeName, lpszType);
  1237. m_LastTypeID = LPNULL;
  1238. }
  1239. }
  1240. }
  1241. else {
  1242. if (pResInfo->GetTypeId()) {
  1243. if (pResInfo->GetTypeId()==(WORD)LOWORD((DWORD)(DWORD_PTR)lpszType)) {
  1244. //TRACE2("IODLL.DLL: CFileModule::EnumId %d %d\n", c,
  1245. // (WORD)LOWORD((DWORD)lpszType) );
  1246. m_IdArray.Add( c );
  1247. }
  1248. m_LastTypeID = (LPSTR)lpszType;
  1249. m_LastTypeName[0] = '\0';
  1250. } else {
  1251. if (HIWORD((DWORD)(DWORD_PTR)lpszType)!=0) {
  1252. if (pResInfo->GetTypeName()==(CString)(lpszType))
  1253. m_IdArray.Add( c );
  1254. strcpy(m_LastTypeName, lpszType);
  1255. m_LastTypeID = LPNULL;
  1256. }
  1257. }
  1258. }
  1259. }
  1260. }
  1261. UINT
  1262. CFileModule::WriteUpdatedResource( LPCSTR lpszTgtfilename, HANDLE hFileModule, LPCSTR szSymbolPath)
  1263. {
  1264. UINT uiError = ERROR_NO_ERROR;
  1265. // We have to check which resource have been updated and
  1266. // generate a list to give back to the RW module
  1267. CResInfo* pResInfo;
  1268. TRACE1("CFileModule::WriteUpdatedResource\tNewSize: %ld\n", (LONG)m_ResBufSize);
  1269. BYTE * pBuf = new BYTE[m_ResBufSize];
  1270. BYTE * pBufStart = pBuf;
  1271. BYTE * pBufPos = pBuf;
  1272. BYTE bPad = 0;
  1273. BOOL bIsTmp = FALSE;
  1274. if (!pBuf)
  1275. return ERROR_NEW_FAILED;
  1276. if (!m_DllHInstance)
  1277. if (LoadDll()==NULL) return 0L;
  1278. UINT uiBufSize = 0;
  1279. // MAC RW fixes. Since the MAC RW will update images while updating images
  1280. // The list of updated images could potentialy be wrong. We first scan the list for
  1281. // Updated resources and then we will do the same thing to write the list in the buffer.
  1282. // So for instance updating the DLG image will update a DITL connected with
  1283. // the DLG itself. If the DITL was already gone in the for loop we would
  1284. // skip it and never save the DITL image that is now updated.
  1285. for( INT_PTR c=0, UpperBound = m_ResArray.GetUpperBound(); c<=UpperBound ; c++) {
  1286. pResInfo = (CResInfo*) m_ResArray.GetAt(c);
  1287. if(!pResInfo)
  1288. return ERROR_IO_RESINFO_NULL;
  1289. if(!pResInfo->GetFileOffset()) {
  1290. // The offset is null. This mean that the resource has been updated.
  1291. // Check if the image is up to date or not
  1292. if (!pResInfo->GetUpdImage()) {
  1293. DWORD dwSize = pResInfo->UpdateImage( 0,
  1294. m_DllHInstance,
  1295. (LPCSTR)UlongToPtr(pResInfo->GetTypeId()) );
  1296. if (dwSize)
  1297. if(pResInfo->UpdateImage( dwSize,
  1298. m_DllHInstance,
  1299. (LPCSTR)UlongToPtr(pResInfo->GetTypeId()))) {
  1300. delete []pBufStart;
  1301. return ERROR_IO_UPDATEIMAGE;
  1302. }
  1303. }
  1304. }
  1305. }
  1306. // Now add the image to the list...
  1307. for( c=0, UpperBound = m_ResArray.GetUpperBound(); c<=UpperBound ; c++) {
  1308. pResInfo = (CResInfo*) m_ResArray.GetAt(c);
  1309. if(!pResInfo)
  1310. return ERROR_IO_RESINFO_NULL;
  1311. if(!pResInfo->GetFileOffset()) {
  1312. // Write the information in the bufer and give it back to the RW module
  1313. pBufPos = pBuf;
  1314. *((WORD*)pBuf) = pResInfo->GetTypeId();
  1315. pBuf += sizeofWord;
  1316. strcpy((char*)pBuf, pResInfo->GetTypeName());
  1317. pBuf += (pResInfo->GetTypeName()).GetLength()+1;
  1318. // Check the allignment
  1319. bPad = Pad4((BYTE)(pBuf-pBufPos));
  1320. while (bPad) {
  1321. *pBuf = 0x00;
  1322. pBuf += 1;
  1323. bPad--;
  1324. }
  1325. *((WORD*)pBuf) = pResInfo->GetResId();
  1326. pBuf += sizeofWord;
  1327. strcpy((char*)pBuf, pResInfo->GetResName());
  1328. pBuf += (pResInfo->GetResName()).GetLength()+1;
  1329. // Check the allignment
  1330. bPad = Pad4((BYTE)(pBuf-pBufPos));
  1331. while (bPad) {
  1332. *pBuf = 0x00;
  1333. pBuf += 1;
  1334. bPad--;
  1335. }
  1336. *((DWORD*)pBuf) = pResInfo->GetAllLanguage();
  1337. pBuf += sizeofDWord;
  1338. *((DWORD*)pBuf) = pResInfo->GetSize();
  1339. pBuf += sizeofDWord;
  1340. uiBufSize += (UINT)(pBuf-pBufPos);
  1341. TRACE1("TypeId: %d\t", pResInfo->GetTypeId());
  1342. TRACE1("TypeName: %s\t", pResInfo->GetTypeName());
  1343. TRACE1("NameId: %d\t", pResInfo->GetResId());
  1344. TRACE1("NameName: %s\t", pResInfo->GetResName());
  1345. TRACE1("ResLang: %lu\t", pResInfo->GetLanguage());
  1346. TRACE1("ResSize: %lu\n", pResInfo->GetSize());
  1347. //TRACE1("uiError: %u\n", uiSize);
  1348. }
  1349. }
  1350. UINT (FAR PASCAL * lpfnWriteFile)(LPCSTR, LPCSTR, HANDLE, LPVOID, UINT, HINSTANCE, LPCSTR);
  1351. // Get the pointer to the function to extract the resources
  1352. lpfnWriteFile = (UINT (FAR PASCAL *)(LPCSTR, LPCSTR, HANDLE, LPVOID, UINT, HINSTANCE, LPCSTR))
  1353. GetProcAddress( m_DllHInstance, "RWWriteFile" );
  1354. if (lpfnWriteFile==NULL) {
  1355. delete []pBufStart;
  1356. return (DWORD)ERROR_DLL_PROC_ADDRESS;
  1357. }
  1358. CString szTgtFilename = lpszTgtfilename;
  1359. // We have to check if the filename is a full qualified filename
  1360. CFileStatus status;
  1361. strcpy(status.m_szFullName, lpszTgtfilename);
  1362. if (CFile::GetStatus( lpszTgtfilename, status ))
  1363. // The file exist, get the full file name
  1364. szTgtFilename = status.m_szFullName;
  1365. // Generate a temporary file name
  1366. bIsTmp = TRUE;
  1367. CString cszTmpPath;
  1368. DWORD dwRet = GetTempPath( 512, cszTmpPath.GetBuffer(512));
  1369. cszTmpPath.ReleaseBuffer(-1);
  1370. if(dwRet>512 )
  1371. dwRet = GetTempPath( dwRet, cszTmpPath.GetBuffer(dwRet));
  1372. cszTmpPath.ReleaseBuffer(-1);
  1373. if(dwRet==0 || GetFileAttributes(cszTmpPath) != FILE_ATTRIBUTE_DIRECTORY){
  1374. // Failed to get the temporary path fail, default to local dir
  1375. dwRet = GetCurrentDirectory(512, cszTmpPath.GetBuffer(512));
  1376. if(dwRet>512 )
  1377. dwRet = GetCurrentDirectory( dwRet, cszTmpPath.GetBuffer(dwRet));
  1378. }
  1379. GetTempFileName(cszTmpPath, "RLT", 0, szTgtFilename.GetBuffer(_MAX_PATH));
  1380. szTgtFilename.ReleaseBuffer();
  1381. szTgtFilename.MakeUpper();
  1382. // Check if the size of the file is bigger that the size on the HD
  1383. if (CFile::GetStatus( m_SrcFileName, status )) {
  1384. // Get drive number
  1385. BYTE ndrive = ((BYTE)*szTgtFilename.GetBuffer(0)-(BYTE)'A')+1;
  1386. // Get the space on the HD
  1387. struct _diskfree_t diskfree;
  1388. if(_getdiskfree(ndrive, &diskfree)) {
  1389. delete []pBufStart;
  1390. return ERROR_OUT_OF_DISKSPACE;
  1391. }
  1392. if ( (status.m_size*3/diskfree.bytes_per_sector)>
  1393. (DWORD)(diskfree.avail_clusters*(DWORD)diskfree.sectors_per_cluster)) {
  1394. delete []pBufStart;
  1395. return ERROR_OUT_OF_DISKSPACE;
  1396. }
  1397. }
  1398. TRY
  1399. {
  1400. uiError = (*lpfnWriteFile)((LPCSTR)m_SrcFileName,
  1401. (LPCSTR)szTgtFilename,
  1402. (HANDLE)hFileModule,
  1403. (LPVOID)pBufStart,
  1404. (UINT)uiBufSize,
  1405. (HINSTANCE)NULL,
  1406. (LPCSTR)szSymbolPath);
  1407. }
  1408. CATCH(CFileException, fe)
  1409. {
  1410. uiError = fe->m_lOsError+LAST_ERROR;
  1411. }
  1412. AND_CATCH( CMemoryException, e )
  1413. {
  1414. uiError = ERROR_NEW_FAILED;
  1415. }
  1416. AND_CATCH( CException, e )
  1417. {
  1418. uiError = ERROR_NEW_FAILED;
  1419. }
  1420. END_CATCH
  1421. delete []pBufStart;
  1422. if ( bIsTmp ) {
  1423. if (uiError < LAST_WRN) {
  1424. TRY {
  1425. //
  1426. // BUG: 409
  1427. // We will rename if on the same drive. Otherwise copy it
  1428. //
  1429. if (_strnicmp( szTgtFilename, lpszTgtfilename, 1 )) {
  1430. UINT ErrTmp;
  1431. TRACE("\t\tCopyFile:\tszTgtFilename: %s\tlpszTgtfilename: %s\n", szTgtFilename.GetBuffer(0), lpszTgtfilename);
  1432. ErrTmp = CopyFile( szTgtFilename, lpszTgtfilename );
  1433. if (ErrTmp){
  1434. uiError = ErrTmp+LAST_ERROR;
  1435. }
  1436. } else {
  1437. TRACE("\t\tMoveFile:\tszTgtFilename: %s\tlpszTgtfilename: %s\n", szTgtFilename.GetBuffer(0), lpszTgtfilename );
  1438. // Remove temporary file
  1439. if(CFile::GetStatus( lpszTgtfilename, status ))
  1440. CFile::Remove(lpszTgtfilename);
  1441. CFile::Rename(szTgtFilename, lpszTgtfilename);
  1442. }
  1443. // Remove temporary file
  1444. if(CFile::GetStatus( szTgtFilename, status ))
  1445. CFile::Remove(szTgtFilename);
  1446. }
  1447. CATCH( CFileException, fe )
  1448. {
  1449. uiError = fe->m_lOsError+LAST_ERROR;
  1450. }
  1451. AND_CATCH( CException, e )
  1452. {
  1453. uiError = ERROR_NEW_FAILED;
  1454. }
  1455. END_CATCH
  1456. }
  1457. }
  1458. return uiError;
  1459. }
  1460. UINT
  1461. CFileModule::CopyImage( CFileModule* pFileModule, LPCSTR lpszType, LPCSTR lpszResId )
  1462. {
  1463. CResInfo* pResInfo;
  1464. CResInfo* pTgtResInfo;
  1465. int iResID = (HIWORD(lpszResId) ? 0 : LOWORD(lpszResId) );
  1466. int iTypeID = (HIWORD(lpszType) ? 0 : LOWORD(lpszType) );
  1467. // Find the CResInfo object we have to copy
  1468. INT_PTR c = m_ResArray.GetUpperBound();
  1469. while(c>=0)
  1470. {
  1471. pResInfo = (CResInfo*)m_ResArray.GetAt(c--);
  1472. if(!pResInfo)
  1473. return ERROR_IO_INVALIDITEM;
  1474. // Check the type ID
  1475. if( iTypeID && pResInfo->GetTypeName()=="" && (int)pResInfo->GetTypeId()==iTypeID) {
  1476. // Check for the res ID
  1477. if( iResID && (int)pResInfo->GetResId()==iResID) {
  1478. c = -2;
  1479. }
  1480. // check for the res name
  1481. else if( (iResID==0) && pResInfo->GetResName()==lpszResId) {
  1482. c = -2;
  1483. }
  1484. }
  1485. // check for the type name
  1486. else if( HIWORD(lpszType) && pResInfo->GetTypeName()==lpszType) {
  1487. // Check for the res ID
  1488. if( iResID && (int)pResInfo->GetResId()==iResID) {
  1489. c = -2;
  1490. }
  1491. // check for the res name
  1492. else if( (iResID==0) && pResInfo->GetResName()==lpszResId) {
  1493. c = -2;
  1494. }
  1495. }
  1496. }
  1497. if (c==-1)
  1498. return ERROR_IO_INVALIDID;
  1499. // find were we have to copy it
  1500. c = pFileModule->m_ResArray.GetUpperBound();
  1501. while(c>=0)
  1502. {
  1503. pTgtResInfo = (CResInfo*)pFileModule->m_ResArray.GetAt(c--);
  1504. if(!pTgtResInfo)
  1505. return ERROR_IO_INVALIDITEM;
  1506. // Check the type ID
  1507. if( iTypeID && pTgtResInfo->GetTypeName()=="" && (int)pTgtResInfo->GetTypeId()==iTypeID) {
  1508. // Check for the res ID
  1509. if( iResID && (int)pTgtResInfo->GetResId()==iResID) {
  1510. c = -2;
  1511. }
  1512. // check for the res name
  1513. else if( (iResID==0) && pTgtResInfo->GetResName()==lpszResId) {
  1514. c = -2;
  1515. }
  1516. }
  1517. // check for the type name
  1518. else if( HIWORD(lpszType) && pTgtResInfo->GetTypeName()==lpszType) {
  1519. // Check for the res ID
  1520. if( iResID && (int)pTgtResInfo->GetResId()==iResID) {
  1521. c = -2;
  1522. }
  1523. // check for the res name
  1524. else if( (iResID==0) && pTgtResInfo->GetResName()==lpszResId) {
  1525. c = -2;
  1526. }
  1527. }
  1528. }
  1529. if(c==-1)
  1530. return ERROR_IO_INVALIDID;
  1531. // Load the image in memory from the res file
  1532. DWORD dwReadSize = pTgtResInfo->LoadImage( pFileModule->GetName(),
  1533. pFileModule->GetHInstance() );
  1534. if (dwReadSize!=pTgtResInfo->GetSize())
  1535. return ERROR_RW_LOADIMAGE;
  1536. // copy the image from the res file
  1537. pTgtResInfo->CopyImage( pResInfo );
  1538. // We have to mark the resource has updated
  1539. pTgtResInfo->SetFileOffset(0L);
  1540. pTgtResInfo->SetImageUpdated(0);
  1541. return 0;
  1542. }
  1543. UINT
  1544. CFileModule::Copy( CFileModule* pFileModule )
  1545. {
  1546. CResInfo* pResInfo;
  1547. CResInfo* pTgtResInfo;
  1548. int TgtPos;
  1549. m_dwFlags = pFileModule->m_dwFlags;
  1550. for(INT_PTR u = m_ResArray.GetUpperBound(), c=0; c<=u ; c++) {
  1551. pResInfo = (CResInfo*) m_ResArray.GetAt(c);
  1552. if(!pResInfo)
  1553. return ERROR_IO_INVALIDITEM;
  1554. TgtPos = pFileModule->AddResInfo( pResInfo->GetTypeId(),
  1555. pResInfo->GetTypeName(),
  1556. pResInfo->GetResId(),
  1557. pResInfo->GetResName(),
  1558. pResInfo->GetLanguage(),
  1559. 0,
  1560. 0);
  1561. pTgtResInfo = (CResInfo*) pFileModule->GetResInfo( TgtPos );
  1562. if(!pTgtResInfo)
  1563. return ERROR_IO_INVALIDITEM;
  1564. pResInfo->Copy( pTgtResInfo, m_SrcFileName, m_DllHInstance );
  1565. }
  1566. return ERROR_NO_ERROR;
  1567. }
  1568. LPCSTR
  1569. CFileModule::EnumType( LPCSTR lpszPrevType)
  1570. {
  1571. if (lpszPrevType) {
  1572. // Check if the value we get is consistent.
  1573. if (m_TypePos==0) return LPNULL;
  1574. if (m_TypePos==m_TypeArray.GetSize()) {
  1575. m_TypePos = 0;
  1576. return LPNULL;
  1577. }
  1578. CResInfo* pResInfo = (CResInfo*)m_ResArray.GetAt(m_TypeArray.GetAt(m_TypePos-1));
  1579. if(HIWORD(lpszPrevType)) {
  1580. if(pResInfo->GetTypeName() != lpszPrevType)
  1581. return LPNULL;
  1582. }
  1583. else {
  1584. if((DWORD_PTR)pResInfo->GetTypeId()!=(DWORD_PTR)lpszPrevType)
  1585. return LPNULL;
  1586. }
  1587. } else {
  1588. // It is the first time we have been called.
  1589. // Generate the list of Types
  1590. m_TypePos = 0;
  1591. if (!m_TypeArray.GetSize())
  1592. // We have to generate the TABLE
  1593. for( INT_PTR c=0, UpperBound=m_ResArray.GetUpperBound(); c<=UpperBound; c++)
  1594. AddTypeInfo( c,
  1595. ((CResInfo*)m_ResArray[c])->GetTypeId(),
  1596. ((CResInfo*)m_ResArray[c])->GetTypeName());
  1597. if (m_TypePos==m_TypeArray.GetSize()) {
  1598. m_TypePos = 0;
  1599. return LPNULL;
  1600. }
  1601. }
  1602. CResInfo* pResInfo = (CResInfo*)m_ResArray.GetAt(m_TypeArray.GetAt(m_TypePos++));
  1603. if (pResInfo->GetTypeId() && pResInfo->GetTypeName()==""){
  1604. // It is an ordinal ID
  1605. DWORD dwReturn = 0L;
  1606. dwReturn = (DWORD)pResInfo->GetTypeId();
  1607. return (LPCSTR) UlongToPtr(dwReturn);
  1608. } else {
  1609. // It is a string type
  1610. strcpy( m_TypeStr, pResInfo->GetTypeName());
  1611. return m_TypeStr;
  1612. }
  1613. }
  1614. LPCSTR
  1615. CFileModule::EnumId( LPCSTR lpszType, LPCSTR lpszPrevId )
  1616. {
  1617. if (!lpszType) return LPNULL;
  1618. if(!lpszPrevId)
  1619. {
  1620. if(m_IdPos==0)
  1621. {
  1622. // Create the list of resources
  1623. BOOL fTypeName = HIWORD(lpszType);
  1624. CResInfo* pResInfo;
  1625. m_IdArray.RemoveAll();
  1626. for( WORD i = 0, iUpperBoundRes = (WORD)m_ResArray.GetUpperBound() ; i<=iUpperBoundRes ; i++)
  1627. {
  1628. pResInfo = (CResInfo*)m_ResArray.GetAt(i);
  1629. if(pResInfo)
  1630. {
  1631. if( fTypeName ? !strcmp(pResInfo->GetTypeName(), lpszType) : pResInfo->GetTypeId()==LOWORD(lpszType))
  1632. {
  1633. // add this item to the LangArray
  1634. m_IdArray.Add(i);
  1635. }
  1636. }
  1637. }
  1638. }
  1639. }
  1640. ASSERT(m_IdArray.GetSize());
  1641. if (m_IdPos>=m_IdArray.GetSize())
  1642. {
  1643. m_IdPos = 0;
  1644. return LPNULL;
  1645. }
  1646. // We will increment m_IdPos in the lang enum since we use the same array m_IdArray
  1647. CResInfo* pResInfo = (CResInfo*)m_ResArray.GetAt(m_IdArray.GetAt(m_IdPos));
  1648. if( pResInfo )
  1649. {
  1650. if (pResInfo->GetResId()){
  1651. // It is an ordinal ID
  1652. return (LPCSTR)pResInfo->GetResId();
  1653. } else {
  1654. // It is a string type
  1655. strcpy( m_IdStr, pResInfo->GetResName());
  1656. return m_IdStr;
  1657. }
  1658. }
  1659. return LPNULL;
  1660. }
  1661. DWORD
  1662. CFileModule::EnumLang( LPCSTR lpszType, LPCSTR lpszId, DWORD dwPrevLang )
  1663. {
  1664. // Parameter checking
  1665. if (!lpszType) return 0L;
  1666. if (!lpszId) return 0L;
  1667. ASSERT(m_IdArray.GetSize());
  1668. // This is true when we have done all the languages
  1669. // Return null but keep the m_IdPos, this will let us exit safelly from the
  1670. // EnumId function
  1671. if (m_IdPos==m_IdArray.GetSize())
  1672. {
  1673. return LPNULL;
  1674. }
  1675. CResInfo* pResInfo = (CResInfo*)m_ResArray.GetAt(m_IdArray.GetAt(m_IdPos++));
  1676. if( pResInfo )
  1677. {
  1678. // Check if the ID match
  1679. if(HIWORD(lpszId) ? !strcmp(lpszId, pResInfo->GetResName() ) : LOWORD(lpszId)==pResInfo->GetResId() )
  1680. {
  1681. if(pResInfo->GetLanguage()!=0)
  1682. return pResInfo->GetLanguage();
  1683. else
  1684. return 0xFFFFFFFF; // for the neutral language case
  1685. }
  1686. }
  1687. m_IdPos--;
  1688. return 0;
  1689. }
  1690. DWORD
  1691. CFileModule::EnumItem( LPCSTR lpszType, LPCSTR lpszId, DWORD dwLang, DWORD dwPrevItem )
  1692. {
  1693. // Check if all the parameters are valid
  1694. if (!lpszType) return 0L;
  1695. if (!lpszId) return 0L;
  1696. //if (!dwLang) return 0L;
  1697. CResInfo* pResInfo = GetResInfo( lpszType, lpszId, dwLang );
  1698. if (!m_DllHInstance)
  1699. if (LoadDll()==NULL) return 0L;
  1700. if (pResInfo)
  1701. return pResInfo->EnumItem( m_SrcFileName, m_DllHInstance, dwPrevItem );
  1702. return 0L;
  1703. }
  1704. ////////////////////////////////////////////////////////////////////////////
  1705. // CDllTable
  1706. CDllTable::CDllTable( UINT InitNum )
  1707. {
  1708. //TRACE1("IODLL.DLL: CDllTable::CDllTable %d\n", InitNum);
  1709. m_InitNum = InitNum;
  1710. PCHAR pkey;
  1711. PCHAR pbuf = new char[InitNum];
  1712. if (pbuf==LPNULL) return;
  1713. GetProfileString(SECTION, NULL, "", pbuf, InitNum);
  1714. int c;
  1715. if (*pbuf != '\0')
  1716. {
  1717. PCHAR pkey;
  1718. CString szString;
  1719. PCHAR pstr = new char[InitNum];
  1720. for( pkey = pbuf, c = 0;
  1721. *pkey != '\0' ; pkey += strlen(pkey)+1 ) {
  1722. GetProfileString( SECTION, pkey, "Empty", pstr, InitNum);
  1723. szString = pstr;
  1724. if (!szString.IsEmpty())
  1725. Add( new CDllEntryTable(szString) );
  1726. c++;
  1727. }
  1728. delete pstr;
  1729. }
  1730. else
  1731. {
  1732. for (pkey = szDefaultRWDll[0], c=0;
  1733. c < sizeof(szDefaultRWDll)/MAXKEYLEN/sizeof(TCHAR) ; pkey+= MAXKEYLEN)
  1734. {
  1735. Add ( new CDllEntryTable(pkey) );
  1736. c++;
  1737. }
  1738. }
  1739. m_MaxEntry = c+1;
  1740. delete pbuf;
  1741. return;
  1742. }
  1743. UINT CDllTable::GetPosFromTable( CString szFileType )
  1744. {
  1745. UINT c = 0;
  1746. // Check if the string type is not empty
  1747. if (szFileType.IsEmpty()) return 0;
  1748. while( (szFileType!=((CDllEntryTable*)GetAt(c))->GetType()) && (c<m_MaxEntry) ) c++;
  1749. // Be really sure
  1750. if ((szFileType!=((CDllEntryTable*)GetAt(c))->GetType()))
  1751. // 0 Is an invalid position in the Table for us
  1752. return 0;
  1753. return c+1;
  1754. }
  1755. CDllTable::~CDllTable()
  1756. {
  1757. INT_PTR UpperBound = GetUpperBound();
  1758. //TRACE1("IODLL.DLL: CDllTable::~CDllTable %d\n", UpperBound);
  1759. CDllEntryTable* pDllEntry;
  1760. for( int c=0 ; c<=UpperBound ; c++) {
  1761. pDllEntry = (CDllEntryTable*)GetAt(c);
  1762. //TRACE1("\tCDllTable\tCDllEntryTable->%Fp\n", pDllEntry);
  1763. delete pDllEntry;
  1764. }
  1765. RemoveAll();
  1766. }
  1767. ////////////////////////////////////////////////////////////////////////////
  1768. // CModuleTable
  1769. CModuleTable::CModuleTable( UINT InitNum)
  1770. {
  1771. //TRACE1("IODLL.DLL: CModuleTable::CModuleTable %d\n", InitNum);
  1772. m_InitNum = InitNum;
  1773. m_LastHandle = 0;
  1774. }
  1775. CModuleTable::~CModuleTable()
  1776. {
  1777. INT_PTR UpperBound = GetUpperBound();
  1778. //TRACE1("IODLL.DLL: CModuleTable::~CModuleTable %d\n", UpperBound);
  1779. CFileModule* pFileModule;
  1780. for( int c=0 ; c<=UpperBound ; c++) {
  1781. pFileModule = (CFileModule*)GetAt(c);
  1782. //TRACE1("\tCModuleTable\tCFileModule->%Fp\n", pFileModule);
  1783. pFileModule->CleanUp();
  1784. delete pFileModule;
  1785. }
  1786. RemoveAll();
  1787. }
  1788. ////////////////////////////////////////////////////////////////////////////
  1789. // CDllEntryTable
  1790. CDllEntryTable::CDllEntryTable( CString szEntry )
  1791. {
  1792. int chPos;
  1793. if ( (chPos = szEntry.Find(","))==-1 ) {
  1794. m_szDllName = "";
  1795. m_szDllType = "";
  1796. return;
  1797. }
  1798. m_szDllName = szEntry.Left(chPos);
  1799. szEntry = szEntry.Right(szEntry.GetLength()-chPos-1);
  1800. m_szDllType = szEntry;
  1801. m_handle = NULL;
  1802. }
  1803. CDllEntryTable::~CDllEntryTable()
  1804. {
  1805. FreeEntry();
  1806. }
  1807. HINSTANCE CDllEntryTable::LoadEntry()
  1808. {
  1809. if(!m_handle) {
  1810. m_handle = LoadLibrary(m_szDllName);
  1811. TRACE("CDllEntryTable::LoadEntry: %s loaded at %p\n",m_szDllName.GetBuffer(0), (UINT_PTR)m_handle);
  1812. }
  1813. return m_handle;
  1814. }
  1815. BOOL CDllEntryTable::FreeEntry()
  1816. {
  1817. BOOL bRet = FALSE;
  1818. if(m_handle) {
  1819. bRet = FreeLibrary(m_handle);
  1820. TRACE("CDllEntryTable::FreeEntry: %s FreeLibrary return %d\n",m_szDllName.GetBuffer(0),bRet);
  1821. }
  1822. return bRet;
  1823. }
  1824. ////////////////////////////////////////////////////////////////////////////
  1825. // CResInfo
  1826. CResInfo::CResInfo( WORD Typeid, CString sztypeid,
  1827. WORD nameid, CString sznameid,
  1828. DWORD dwlang, DWORD dwsize, DWORD dwfileoffset, CFileModule * pFileModule )
  1829. {
  1830. m_FileOffset = dwfileoffset;
  1831. m_FileSize = dwsize;
  1832. m_Language = MAKELONG(LOWORD(dwlang),LOWORD(dwlang));
  1833. m_TypeName = sztypeid;
  1834. m_TypeId = Typeid;
  1835. m_ResName = sznameid;
  1836. m_ResId = nameid;
  1837. m_lpImageBuf = LPNULL;
  1838. m_dwImageSize = 0L;
  1839. m_ItemPos = 0;
  1840. m_pFileModule = pFileModule;
  1841. }
  1842. CResInfo::~CResInfo()
  1843. {
  1844. //TRACE("IODLL.DLL: CResInfo::~CResInfo\n");
  1845. FreeImage();
  1846. FreeItemArray();
  1847. }
  1848. void
  1849. CResInfo::FreeImage()
  1850. {
  1851. if (m_lpImageBuf)
  1852. delete []m_lpImageBuf;
  1853. m_lpImageBuf = LPNULL;
  1854. m_dwImageSize = 0L;
  1855. }
  1856. void
  1857. CResInfo::FreeItemArray()
  1858. {
  1859. CItemInfo* pItemInfo;
  1860. for( INT_PTR c=0, UpperBound=m_ItemArray.GetUpperBound(); c<=UpperBound; c++) {
  1861. pItemInfo = (CItemInfo*)m_ItemArray.GetAt(c);
  1862. delete pItemInfo;
  1863. }
  1864. m_ItemArray.RemoveAll();
  1865. }
  1866. UINT
  1867. CResInfo::AllocImage(DWORD dwSize)
  1868. {
  1869. // Check if we have to free the value in m_lpImageBuf
  1870. if (m_lpImageBuf)
  1871. FreeImage();
  1872. //TRACE2("CResInfo::AllocImage\tNewSize: %ld\tNum: %ld\n", (LONG)dwSize, lRequestLast+1);
  1873. TRACE1("CResInfo::AllocImage\tNewSize: %ld\n", (LONG)dwSize);
  1874. m_lpImageBuf = new BYTE[dwSize];
  1875. if (!m_lpImageBuf) {
  1876. TRACE("\n"
  1877. "************* ERROR **********\n"
  1878. "CResInfo::AllocImage: New Failed!! BYTE far * lpImageBuf = new BYTE[dwSize];\n"
  1879. "************* ERROR **********\n"
  1880. "\n" );
  1881. return ERROR_NEW_FAILED;
  1882. }
  1883. m_dwImageSize = dwSize;
  1884. return 0;
  1885. }
  1886. DWORD
  1887. CResInfo::LoadImage( CString lpszFilename, HINSTANCE hInst )
  1888. {
  1889. if(!m_FileSize)
  1890. return 0;
  1891. if(AllocImage(m_FileSize))
  1892. return ERROR_NEW_FAILED;
  1893. // Call the RW and read thead the Image from the file
  1894. DWORD (FAR PASCAL * lpfnGetImage)(LPCSTR, DWORD, LPVOID, DWORD);
  1895. // Get the pointer to the function to extract the resources
  1896. lpfnGetImage = (DWORD (FAR PASCAL *)(LPCSTR, DWORD, LPVOID, DWORD))
  1897. GetProcAddress( hInst, "RWGetImage" );
  1898. if (lpfnGetImage==NULL) {
  1899. FreeImage();
  1900. return (DWORD)ERROR_DLL_PROC_ADDRESS;
  1901. }
  1902. DWORD dwReadSize = 0l;
  1903. if (m_FileOffset)
  1904. dwReadSize = (*lpfnGetImage)((LPCSTR)lpszFilename,
  1905. (DWORD)m_FileOffset,
  1906. (LPVOID)m_lpImageBuf,
  1907. (DWORD)m_FileSize);
  1908. if (dwReadSize!=m_FileSize) {
  1909. FreeImage();
  1910. return 0l;
  1911. }
  1912. return m_dwImageSize;
  1913. }
  1914. DWORD
  1915. CResInfo::GetImage( LPCSTR lpszFilename, HINSTANCE hInst, LPVOID lpbuffer, DWORD dwBufSize )
  1916. {
  1917. if(!m_FileSize)
  1918. return 0;
  1919. if ( (!m_lpImageBuf) && (m_FileOffset)) {
  1920. DWORD dwReadSize = LoadImage( lpszFilename, hInst );
  1921. if (dwReadSize!=m_dwImageSize)
  1922. return 0L;
  1923. }
  1924. if (dwBufSize<m_dwImageSize)
  1925. return m_dwImageSize;
  1926. memcpy( lpbuffer, m_lpImageBuf, (UINT)m_dwImageSize );
  1927. return m_dwImageSize;
  1928. }
  1929. DWORD
  1930. CResInfo::ReplaceImage( LPVOID lpNewImage, DWORD dwNewImageSize, DWORD dwUpdLang )
  1931. {
  1932. m_ImageUpdated = 1;
  1933. FreeImage();
  1934. if(!m_lpImageBuf) {
  1935. if(AllocImage(dwNewImageSize))
  1936. return ERROR_NEW_FAILED;
  1937. if (lpNewImage){
  1938. memcpy(m_lpImageBuf, lpNewImage, (UINT)dwNewImageSize);
  1939. if (dwUpdLang != 0xffffffff){
  1940. m_Language=MAKELONG(m_Language,dwUpdLang);
  1941. }
  1942. }else{
  1943. m_lpImageBuf = LPNULL;
  1944. }
  1945. // check if the size of the image is 0
  1946. if(!m_FileOffset) {
  1947. // Chances are that this is a conversion.
  1948. // set the file size to the size of the image
  1949. // to have it work in the getimage call back
  1950. m_FileSize = dwNewImageSize;
  1951. }
  1952. m_dwImageSize = dwNewImageSize;
  1953. m_FileOffset = 0;
  1954. }
  1955. return 0;
  1956. }
  1957. DWORD
  1958. CResInfo::UpdateImage( LONG dwSize, HINSTANCE hInst, LPCSTR lpszType )
  1959. {
  1960. // We have to generate a list of info and give it back to the RW
  1961. if (!dwSize) dwSize = m_dwImageSize*4+sizeof(RESITEM);
  1962. if (!dwSize) dwSize = 10000;
  1963. if (dwSize>UINT_MAX) dwSize = UINT_MAX-1024;
  1964. TRACE1("CResInfo::UpdateImage\tNewSize: %ld\n", (LONG)dwSize);
  1965. BYTE far * lpBuf = new BYTE[dwSize];
  1966. if (!lpBuf) return ERROR_NEW_FAILED;
  1967. BYTE far * lpBufStart = lpBuf;
  1968. BYTE far * lpStrBuf = lpBuf+sizeof(RESITEM);
  1969. LPRESITEM lpResItem = (LPRESITEM)lpBuf;
  1970. DWORD dwBufSize = dwSize;
  1971. CItemInfo* pItemInfo;
  1972. DWORD dwUpdLang = m_Language;
  1973. BOOL fUpdLang = TRUE;
  1974. int istrlen;
  1975. LONG lBufSize = 0;
  1976. for(INT_PTR c=0, UpperBound=m_ItemArray.GetUpperBound(); c<=UpperBound; c++) {
  1977. pItemInfo = (CItemInfo*) m_ItemArray.GetAt(c);
  1978. if (!pItemInfo)
  1979. return ERROR_IO_RESINFO_NULL;
  1980. if(fUpdLang)
  1981. {
  1982. dwUpdLang = pItemInfo->GetLanguage();
  1983. if(dwUpdLang==0xffffffff)
  1984. {
  1985. dwUpdLang = m_Language;
  1986. }
  1987. else
  1988. fUpdLang = FALSE;
  1989. }
  1990. lBufSize = (LONG)dwSize;
  1991. if (dwSize>=sizeofDWord) {
  1992. lpResItem->dwSize = sizeof(RESITEM); // Size
  1993. dwSize -= sizeofDWord;
  1994. } else dwSize -= sizeofDWord;
  1995. if (dwSize>=sizeofWord) {
  1996. lpResItem->wX = pItemInfo->GetX(); // Coordinate
  1997. dwSize -= sizeofWord;
  1998. } else dwSize -= sizeofWord;
  1999. if (dwSize>=sizeofWord) {
  2000. lpResItem->wY = pItemInfo->GetY();
  2001. dwSize -= sizeofWord;
  2002. } else dwSize -= sizeofWord;
  2003. if (dwSize>=sizeofWord) {
  2004. lpResItem->wcX = pItemInfo->GetcX(); // Position
  2005. dwSize -= sizeofWord;
  2006. } else dwSize -= sizeofWord;
  2007. if (dwSize>=sizeofWord) {
  2008. lpResItem->wcY = pItemInfo->GetcY();
  2009. dwSize -= sizeofWord;
  2010. } else dwSize -= sizeofWord;
  2011. if (dwSize>=sizeofDWord) {
  2012. lpResItem->dwCheckSum = pItemInfo->GetCheckSum(); // Checksum
  2013. dwSize -= sizeofDWord;
  2014. } else dwSize -= sizeofDWord;
  2015. if (dwSize>=sizeofDWord) {
  2016. lpResItem->dwStyle = pItemInfo->GetStyle(); // Style
  2017. dwSize -= sizeofDWord;
  2018. } else dwSize -= sizeofDWord;
  2019. if (dwSize>=sizeofDWord) {
  2020. lpResItem->dwExtStyle = pItemInfo->GetExtStyle(); // ExtendedStyle
  2021. dwSize -= sizeofDWord;
  2022. } else dwSize -= sizeofDWord;
  2023. if (dwSize>=sizeofDWord) {
  2024. lpResItem->dwFlags = pItemInfo->GetFlags(); // Flags
  2025. dwSize -= sizeofDWord;
  2026. } else dwSize -= sizeofDWord;
  2027. if (dwSize>=sizeofDWord) {
  2028. lpResItem->dwItemID = pItemInfo->GetTabPosId(); // PosId
  2029. dwSize -= sizeofDWord;
  2030. } else dwSize -= sizeofDWord;
  2031. if (dwSize>=sizeofDWord) {
  2032. lpResItem->dwResID = m_ResId; // ResourceID
  2033. dwSize -= sizeofDWord;
  2034. } else dwSize -= sizeofDWord;
  2035. if (dwSize>=sizeofDWord) {
  2036. lpResItem->dwTypeID = m_TypeId; // Type ID
  2037. dwSize -= sizeofDWord;
  2038. } else dwSize -= sizeofDWord;
  2039. if (dwSize>=sizeofDWord) {
  2040. lpResItem->dwLanguage = pItemInfo->GetLanguage(); // Language ID
  2041. dwSize -= sizeofDWord;
  2042. } else dwSize -= sizeofDWord;
  2043. if (dwSize>=sizeofDWord) {
  2044. lpResItem->dwCodePage = pItemInfo->GetCodePage(); // CodePage
  2045. dwSize -= sizeofDWord;
  2046. } else dwSize -= sizeofDWord;
  2047. if (dwSize>=sizeofWord) {
  2048. lpResItem->wClassName = pItemInfo->GetClassNameID();// ClassName
  2049. dwSize -= sizeofWord;
  2050. } else dwSize -= sizeofWord;
  2051. if (dwSize>=sizeofWord) {
  2052. lpResItem->wPointSize = pItemInfo->GetPointSize(); // CodePage
  2053. dwSize -= sizeofWord;
  2054. } else dwSize -= sizeofWord;
  2055. if (dwSize>=sizeofWord) {
  2056. lpResItem->wWeight = pItemInfo->GetWeight(); // Weight
  2057. dwSize -= sizeofWord;
  2058. } else dwSize -= sizeofWord;
  2059. if (dwSize>=sizeofByte) {
  2060. lpResItem->bItalic = pItemInfo->GetItalic(); // Italic
  2061. dwSize -= sizeofByte;
  2062. } else dwSize -= sizeofByte;
  2063. if (dwSize>=sizeofByte) {
  2064. lpResItem->bCharSet = pItemInfo->GetCharSet(); // CharSet
  2065. dwSize -= sizeofByte;
  2066. } else dwSize -= sizeofByte;
  2067. if (dwSize>=sizeofDWordPtr) {
  2068. lpResItem->lpszClassName = LPNULL;
  2069. dwSize -= sizeofDWordPtr;
  2070. } else dwSize -= sizeofDWordPtr;
  2071. if (dwSize>=sizeofDWordPtr) {
  2072. lpResItem->lpszFaceName = LPNULL;
  2073. dwSize -= sizeofDWordPtr;
  2074. } else dwSize -= sizeofDWordPtr;
  2075. if (dwSize>=sizeofDWordPtr) {
  2076. lpResItem->lpszCaption = LPNULL;
  2077. dwSize -= sizeofDWordPtr;
  2078. } else dwSize -= sizeofDWordPtr;
  2079. if (dwSize>=sizeofDWordPtr) {
  2080. lpResItem->lpszResID = LPNULL;
  2081. dwSize -= sizeofDWordPtr;
  2082. } else dwSize -= sizeofDWordPtr;
  2083. if (dwSize>=sizeofDWordPtr) {
  2084. lpResItem->lpszTypeID = LPNULL;
  2085. dwSize -= sizeofDWordPtr;
  2086. } else dwSize -= sizeofDWordPtr;
  2087. // Copy the strings
  2088. istrlen = (pItemInfo->GetClassName()).GetLength()+1;
  2089. if (dwSize>=istrlen) {
  2090. lpResItem->lpszClassName = strcpy((char*)lpStrBuf, pItemInfo->GetClassName());
  2091. lpStrBuf += istrlen;
  2092. dwSize -= istrlen;
  2093. lpResItem->dwSize += istrlen;
  2094. } else dwSize -= istrlen;
  2095. istrlen = (pItemInfo->GetFaceName()).GetLength()+1;
  2096. if (dwSize>=istrlen) {
  2097. lpResItem->lpszFaceName = strcpy((char*)lpStrBuf, pItemInfo->GetFaceName());
  2098. lpStrBuf += istrlen;
  2099. dwSize -= istrlen;
  2100. lpResItem->dwSize += istrlen;
  2101. } else dwSize -= istrlen;
  2102. istrlen = (pItemInfo->GetCaption()).GetLength()+1;
  2103. if (dwSize>=istrlen) {
  2104. lpResItem->lpszCaption = strcpy((char*)lpStrBuf, pItemInfo->GetCaption());
  2105. lpStrBuf += istrlen;
  2106. dwSize -= istrlen;
  2107. lpResItem->dwSize += istrlen;
  2108. } else dwSize -= istrlen;
  2109. istrlen = m_ResName.GetLength()+1;
  2110. if (dwSize>=istrlen) {
  2111. lpResItem->lpszResID = strcpy((char*)lpStrBuf, m_ResName);
  2112. lpStrBuf += istrlen;
  2113. dwSize -= istrlen;
  2114. lpResItem->dwSize += istrlen;
  2115. } else dwSize -= istrlen;
  2116. istrlen = m_TypeName.GetLength()+1;
  2117. if (dwSize>=istrlen) {
  2118. lpResItem->lpszTypeID = strcpy((char*)lpStrBuf, m_TypeName);
  2119. lpStrBuf += istrlen;
  2120. dwSize -= istrlen;
  2121. lpResItem->dwSize += istrlen;
  2122. } else dwSize -= istrlen;
  2123. // Check if we are alligned
  2124. BYTE bPad = Allign(lBufSize-(LONG)dwSize);
  2125. if((LONG)dwSize>=bPad) {
  2126. lpResItem->dwSize += bPad;
  2127. dwSize -= bPad;
  2128. while(bPad) {
  2129. *lpStrBuf = 0x00;
  2130. lpStrBuf += 1;
  2131. bPad--;
  2132. }
  2133. }
  2134. else dwSize -= bPad;
  2135. // move to the next item
  2136. lpResItem = (LPRESITEM) lpStrBuf;
  2137. lpStrBuf += sizeof(RESITEM);
  2138. }
  2139. if (dwSize<0){
  2140. delete []lpBufStart;
  2141. return dwBufSize-dwSize;
  2142. }
  2143. else dwSize = dwBufSize-dwSize;
  2144. // Give all back to the RW and wait
  2145. UINT (FAR PASCAL * lpfnGenerateImage)(LPCSTR, LPVOID, DWORD, LPVOID, DWORD, LPVOID, DWORD*);
  2146. UINT (FAR PASCAL * lpfnGenerateImageEx)(LPCSTR, LPVOID, DWORD, LPVOID, DWORD, LPVOID, DWORD*, LPCSTR);
  2147. //
  2148. // Trye to get the pointer to the extended version of the function...
  2149. //
  2150. lpfnGenerateImageEx = (UINT (FAR PASCAL *)(LPCSTR, LPVOID, DWORD, LPVOID, DWORD, LPVOID, DWORD*, LPCSTR))
  2151. GetProcAddress( hInst, "RWUpdateImageEx" );
  2152. if (lpfnGenerateImageEx==NULL) {
  2153. //
  2154. // get the old update image function since the RW doesn't support RC data
  2155. //
  2156. lpfnGenerateImage = (UINT (FAR PASCAL *)(LPCSTR, LPVOID, DWORD, LPVOID, DWORD, LPVOID, DWORD*))
  2157. GetProcAddress( hInst, "RWUpdateImage" );
  2158. if (lpfnGenerateImage==NULL)
  2159. return ERROR_DLL_PROC_ADDRESS;
  2160. }
  2161. DWORD dwNewImageSize = m_dwImageSize*3+sizeof(RESITEM);
  2162. if(!dwNewImageSize)
  2163. dwNewImageSize = 10000;
  2164. if (dwNewImageSize>UINT_MAX)
  2165. dwNewImageSize = UINT_MAX-1024;
  2166. DWORD dwOriginalImageSize = dwNewImageSize;
  2167. BYTE far * lpNewImage = new BYTE[dwNewImageSize];
  2168. if (!lpNewImage) {
  2169. delete []lpBufStart;
  2170. return ERROR_NEW_FAILED;
  2171. }
  2172. #ifndef _DEBUG
  2173. // set the memory to 0
  2174. memset( lpNewImage, 0, (size_t)dwNewImageSize );
  2175. #endif
  2176. UINT uiError;
  2177. if(lpfnGenerateImageEx)
  2178. {
  2179. uiError = (*lpfnGenerateImageEx)( (LPCSTR)lpszType,
  2180. (LPVOID)lpBufStart,
  2181. (DWORD) dwSize,
  2182. (LPVOID)m_lpImageBuf,
  2183. (DWORD) m_dwImageSize,
  2184. (LPVOID)lpNewImage,
  2185. (DWORD*)&dwNewImageSize,
  2186. (LPCSTR)m_pFileModule->GetRDFName()
  2187. );
  2188. }
  2189. else
  2190. {
  2191. uiError = (*lpfnGenerateImage)( (LPCSTR)lpszType,
  2192. (LPVOID)lpBufStart,
  2193. (DWORD) dwSize,
  2194. (LPVOID)m_lpImageBuf,
  2195. (DWORD) m_dwImageSize,
  2196. (LPVOID)lpNewImage,
  2197. (DWORD*)&dwNewImageSize
  2198. );
  2199. }
  2200. if (dwNewImageSize>dwOriginalImageSize) {
  2201. delete []lpNewImage;
  2202. TRACE1("CResInfo::UpdateImage\tNewSize: %ld\n", (LONG)dwNewImageSize);
  2203. if (dwNewImageSize>UINT_MAX)
  2204. dwNewImageSize = UINT_MAX-1024;
  2205. lpNewImage = new BYTE[dwNewImageSize];
  2206. if (!lpNewImage) {
  2207. delete []lpBufStart;
  2208. return ERROR_NEW_FAILED;
  2209. }
  2210. #ifndef _DEBUG
  2211. // set the memory to 0
  2212. memset( lpNewImage, 0, (size_t)dwNewImageSize );
  2213. #endif
  2214. if(lpfnGenerateImageEx)
  2215. {
  2216. uiError = (*lpfnGenerateImageEx)( (LPCSTR)lpszType,
  2217. (LPVOID)lpBufStart,
  2218. (DWORD) dwSize,
  2219. (LPVOID)m_lpImageBuf,
  2220. (DWORD) m_dwImageSize,
  2221. (LPVOID)lpNewImage,
  2222. (DWORD*)&dwNewImageSize,
  2223. (LPCSTR)m_pFileModule->GetRDFName()
  2224. );
  2225. }
  2226. else
  2227. {
  2228. uiError = (*lpfnGenerateImage)( (LPCSTR)lpszType,
  2229. (LPVOID)lpBufStart,
  2230. (DWORD) dwSize,
  2231. (LPVOID)m_lpImageBuf,
  2232. (DWORD) m_dwImageSize,
  2233. (LPVOID)lpNewImage,
  2234. (DWORD*)&dwNewImageSize
  2235. );
  2236. }
  2237. }
  2238. if ((dwNewImageSize) && (!uiError)) {
  2239. m_ImageUpdated = 1;
  2240. FreeImage();
  2241. if(!m_lpImageBuf) {
  2242. if(AllocImage(dwNewImageSize))
  2243. return ERROR_NEW_FAILED;
  2244. memcpy(m_lpImageBuf, lpNewImage, (UINT)dwNewImageSize);
  2245. // check if the size of the image is 0
  2246. if(!m_FileOffset) {
  2247. // Chances are that this is a conversion.
  2248. // set the file size to the size of the image
  2249. // to have it work in the getimage call back
  2250. m_FileSize = dwNewImageSize;
  2251. }
  2252. m_dwImageSize = dwNewImageSize;
  2253. dwNewImageSize = 0;
  2254. m_Language = MAKELONG(HIWORD(m_Language),LOWORD(dwUpdLang));
  2255. }
  2256. }
  2257. delete []lpNewImage;
  2258. delete []lpBufStart;
  2259. return dwNewImageSize;
  2260. }
  2261. UINT
  2262. CResInfo::GetData( LPCSTR lpszFilename, HINSTANCE hInst,
  2263. DWORD dwItem, LPVOID lpbuffer, UINT uiBufSize )
  2264. {
  2265. // We assume the buffer is pointing to a _ResItem Struct
  2266. // [ALESSANM 25-06-93] - mod 1
  2267. LPRESITEM lpResItem = (LPRESITEM) lpbuffer;
  2268. UINT uiPos = HIWORD(dwItem);
  2269. if (!m_ItemArray.GetSize()) {
  2270. // We have to load the array again. What if the image has been modified?
  2271. // Check the fileoffset to see if it is 0.
  2272. if (!m_lpImageBuf) {
  2273. // Load the resource.image
  2274. DWORD dwReadSize = LoadImage( lpszFilename, hInst );
  2275. if (dwReadSize!=m_dwImageSize)
  2276. return 0;
  2277. }
  2278. // We have now to pass the Buffer back to the RW to Parse the info
  2279. if (!(ParseImage( hInst )) )
  2280. return 0;
  2281. }
  2282. if (uiPos>(UINT)m_ItemArray.GetSize())
  2283. // Wrong pointer to the item
  2284. return 0;
  2285. CItemInfo* pItemInfo = (CItemInfo*)m_ItemArray.GetAt( uiPos-1 );
  2286. if (!pItemInfo)
  2287. return 0;
  2288. // Check if the Id match
  2289. if (pItemInfo->GetId()!=LOWORD(dwItem))
  2290. return 0;
  2291. // fill the structure with the info we have
  2292. UINT uiSize = 0;
  2293. // calc the size and check if the buffer is too small
  2294. // Strings Field in the CItemInfo
  2295. uiSize = (pItemInfo->GetCaption()).GetLength()+1;
  2296. uiSize += (pItemInfo->GetFaceName()).GetLength()+1;
  2297. uiSize += (pItemInfo->GetClassName()).GetLength()+1;
  2298. // Strings field in the CResItem
  2299. uiSize += (m_ResName).GetLength()+1;
  2300. uiSize += (m_TypeName).GetLength()+1;
  2301. // Fixed field in the ResItem Structure
  2302. uiSize += sizeof(RESITEM);
  2303. // Check if the user buffer is too small
  2304. if (uiBufSize<uiSize)
  2305. return uiSize;
  2306. // Get the pointer to the end of the structure (begin of the buffer)
  2307. char far * lpStrBuf = (char far *)lpbuffer+sizeof(RESITEM);
  2308. // Size of the structure
  2309. lpResItem->dwSize = uiSize;
  2310. // Copy the items in the buffer
  2311. // Start from the fixed field
  2312. // Coordinate
  2313. lpResItem->wX = pItemInfo->GetX();
  2314. lpResItem->wY = pItemInfo->GetY();
  2315. lpResItem->wcX = pItemInfo->GetcX();
  2316. lpResItem->wcY = pItemInfo->GetcY();
  2317. // Checksum and Style
  2318. lpResItem->dwCheckSum = pItemInfo->GetCheckSum();
  2319. lpResItem->dwStyle = pItemInfo->GetStyle();
  2320. lpResItem->dwExtStyle = pItemInfo->GetExtStyle();
  2321. lpResItem->dwFlags = pItemInfo->GetFlags();
  2322. // ID
  2323. // This is needed for the update by terms.
  2324. // We have to have unique ID
  2325. if((m_TypeId==4) &&(pItemInfo->GetFlags() & MF_POPUP)) {
  2326. // Check if we have an id. otherwise is the old ID format
  2327. lpResItem->dwItemID = pItemInfo->GetPosId();
  2328. if(!lpResItem->dwItemID)
  2329. lpResItem->dwItemID = pItemInfo->GetTabPosId();
  2330. } else {
  2331. // Fixed bug No: 165
  2332. if(pItemInfo->GetId() != -1)
  2333. lpResItem->dwItemID = pItemInfo->GetPosId();
  2334. else lpResItem->dwItemID = pItemInfo->GetTabPosId();
  2335. }
  2336. lpResItem->dwResID = m_ResId;
  2337. lpResItem->dwTypeID = m_TypeId;
  2338. lpResItem->dwLanguage = LOWORD(m_Language);
  2339. // Code page, Class and Font
  2340. lpResItem->dwCodePage = pItemInfo->GetCodePage();
  2341. lpResItem->wClassName = pItemInfo->GetClassNameID();
  2342. lpResItem->wPointSize = pItemInfo->GetPointSize();
  2343. lpResItem->wWeight = pItemInfo->GetWeight();
  2344. lpResItem->bItalic = pItemInfo->GetItalic();
  2345. lpResItem->bCharSet = pItemInfo->GetCharSet();
  2346. // Let's start copy the string
  2347. lpResItem->lpszClassName = strcpy( lpStrBuf, pItemInfo->GetClassName() );
  2348. lpStrBuf += strlen(lpResItem->lpszClassName)+1;
  2349. lpResItem->lpszFaceName = strcpy( lpStrBuf, pItemInfo->GetFaceName() );
  2350. lpStrBuf += strlen(lpResItem->lpszFaceName)+1;
  2351. lpResItem->lpszCaption = strcpy( lpStrBuf, pItemInfo->GetCaption() );
  2352. lpStrBuf += strlen(lpResItem->lpszCaption)+1;
  2353. lpResItem->lpszResID = strcpy( lpStrBuf, m_ResName );
  2354. lpStrBuf += strlen(lpResItem->lpszResID)+1;
  2355. lpResItem->lpszTypeID = strcpy( lpStrBuf, m_TypeName );
  2356. lpStrBuf += strlen(lpResItem->lpszTypeID)+1;
  2357. return uiSize;
  2358. }
  2359. UINT
  2360. CResInfo::UpdateData( LPCSTR lpszFilename, HINSTANCE hInst,
  2361. DWORD dwItem, LPVOID lpbuffer, UINT uiBufSize )
  2362. {
  2363. UINT uiError = ERROR_NO_ERROR;
  2364. UINT uiPos = HIWORD(dwItem);
  2365. TRACE1("UpdateData:\tdwItem:%lx\t", dwItem);
  2366. // we have to see if the array has been loaded before
  2367. if (!m_ItemArray.GetSize()) {
  2368. // We have to load the array again
  2369. if (!m_lpImageBuf) {
  2370. // Load the resource.image
  2371. DWORD dwReadSize = LoadImage( lpszFilename, hInst );
  2372. if (dwReadSize!=m_dwImageSize)
  2373. return ERROR_RW_LOADIMAGE;
  2374. }
  2375. // We have now to pass the Buffer back to the RW to Parse the info
  2376. if (!(ParseImage( hInst )) )
  2377. return ERROR_RW_PARSEIMAGE;
  2378. }
  2379. if (uiPos>(UINT)m_ItemArray.GetSize())
  2380. // Wrong pointer to the item
  2381. return ERROR_IO_INVALIDITEM;
  2382. CItemInfo* pItemInfo = (CItemInfo*)m_ItemArray.GetAt( uiPos-1 );
  2383. if (!pItemInfo)
  2384. return ERROR_IO_INVALIDITEM;
  2385. TRACE2("m_dwPosId:%lx\tm_wTabPos:%lx\n", pItemInfo->GetPosId(), pItemInfo->GetTabPosId());
  2386. // Check if the Id match
  2387. if (lpbuffer)
  2388. if (pItemInfo->GetPosId()!=((LPRESITEM)lpbuffer)->dwItemID)
  2389. {
  2390. // we have some files with ID = 0, check for that
  2391. if (pItemInfo->GetTabPosId()!=((LPRESITEM)lpbuffer)->dwItemID)
  2392. return ERROR_IO_INVALIDID;
  2393. }
  2394. if ((uiError = pItemInfo->UpdateData( (LPRESITEM)lpbuffer )) )
  2395. return uiError;
  2396. // We have to mark the resource has updated
  2397. m_FileOffset = 0L;
  2398. m_ImageUpdated = 0;
  2399. return uiError;
  2400. }
  2401. DWORD
  2402. CResInfo::ParseImage( HINSTANCE hInst )
  2403. {
  2404. //
  2405. // Check if the new RCData handling is supported
  2406. //
  2407. UINT (FAR PASCAL * lpfnParseImageEx)(LPCSTR, LPCSTR, LPVOID, DWORD, LPVOID, DWORD, LPCSTR);
  2408. UINT (FAR PASCAL * lpfnParseImage)(LPCSTR, LPVOID, DWORD, LPVOID, DWORD);
  2409. // Get the pointer to the function to extract the resources
  2410. lpfnParseImageEx = (UINT (FAR PASCAL *)(LPCSTR, LPCSTR, LPVOID, DWORD, LPVOID, DWORD, LPCSTR))
  2411. GetProcAddress( hInst, "RWParseImageEx" );
  2412. if (lpfnParseImageEx==NULL) {
  2413. //
  2414. // This is and old RW get the old entry point
  2415. //
  2416. lpfnParseImage = (UINT (FAR PASCAL *)(LPCSTR, LPVOID, DWORD, LPVOID, DWORD))
  2417. GetProcAddress( hInst, "RWParseImage" );
  2418. if (lpfnParseImage==NULL) {
  2419. return (DWORD)ERROR_DLL_PROC_ADDRESS;
  2420. }
  2421. }
  2422. BYTE far * lpBuf;
  2423. DWORD dwSize = m_dwImageSize*8+sizeof(RESITEM);
  2424. if ((dwSize>UINT_MAX) || (dwSize==0))
  2425. dwSize = 30000;
  2426. TRACE1("CResInfo::ParseImage\tNewSize: %ld\n", (LONG)dwSize);
  2427. lpBuf = new BYTE[dwSize];
  2428. if (!lpBuf)
  2429. return 0;
  2430. LPSTR lpszType = LPNULL;
  2431. if (m_TypeName=="" && m_TypeId)
  2432. lpszType = (LPSTR)((WORD)m_TypeId);
  2433. else
  2434. lpszType = (LPSTR)(m_TypeName.GetBuffer(0));
  2435. LPSTR lpszResId = LPNULL;
  2436. if (m_ResName=="" && m_ResId)
  2437. lpszResId = (LPSTR)((WORD)m_ResId);
  2438. else
  2439. lpszResId = (LPSTR)(m_ResName.GetBuffer(0));
  2440. LONG dwRead = 0;
  2441. if(lpfnParseImageEx)
  2442. {
  2443. dwRead = (*lpfnParseImageEx)((LPCSTR)lpszType,
  2444. (LPCSTR)lpszResId,
  2445. (LPVOID)m_lpImageBuf,
  2446. (DWORD)m_dwImageSize,
  2447. (LPVOID)lpBuf,
  2448. (DWORD)dwSize,
  2449. (LPCSTR)m_pFileModule->GetRDFName());
  2450. } else
  2451. {
  2452. dwRead = (*lpfnParseImage)((LPCSTR)lpszType,
  2453. (LPVOID)m_lpImageBuf,
  2454. (DWORD)m_dwImageSize,
  2455. (LPVOID)lpBuf,
  2456. (DWORD)dwSize);
  2457. }
  2458. if (dwRead>(LONG)dwSize) {
  2459. // We have to allocate a bigger buffer
  2460. delete []lpBuf;
  2461. TRACE1("CResInfo::ParseImage\tNewSize: %ld\n", (LONG)dwRead);
  2462. lpBuf = (BYTE far *) new BYTE[dwRead];
  2463. if (!lpBuf)
  2464. return 0;
  2465. dwSize = dwRead;
  2466. // try to read again
  2467. if(lpfnParseImageEx)
  2468. {
  2469. dwRead = (*lpfnParseImageEx)((LPCSTR)lpszType,
  2470. (LPCSTR)lpszResId,
  2471. (LPVOID)m_lpImageBuf,
  2472. (DWORD)m_dwImageSize,
  2473. (LPVOID)lpBuf,
  2474. (DWORD)dwSize,
  2475. (LPCSTR)m_pFileModule->GetRDFName());
  2476. } else
  2477. {
  2478. dwRead = (*lpfnParseImage)((LPCSTR)lpszType,
  2479. (LPVOID)m_lpImageBuf,
  2480. (DWORD)m_dwImageSize,
  2481. (LPVOID)lpBuf,
  2482. (DWORD)dwSize);
  2483. }
  2484. if (dwRead>(LONG)dwSize) {
  2485. // Abort
  2486. delete []lpBuf;
  2487. return 0;
  2488. }
  2489. }
  2490. // Parse the buffer we have got and fill the array with the information
  2491. // The buffer we are expecting is a series of ResItem structure
  2492. FreeItemArray();
  2493. // We want to parse all the stucture in the buffer
  2494. LPRESITEM lpResItem = (LPRESITEM) lpBuf;
  2495. BYTE far * lpBufStart = lpBuf;
  2496. WORD wTabPos = 0;
  2497. WORD wPos = 0;
  2498. //m_ItemArray.SetSize(10,5);
  2499. while ( (dwRead>0) && ((LONG)lpResItem->dwSize!=-1) ) {
  2500. //TRACE1("Caption: %Fs\n", lpResItem->lpszCaption);
  2501. wTabPos++;
  2502. if ( !(
  2503. ((int)lpResItem->wX==-1) &&
  2504. ((int)lpResItem->wY==-1) &&
  2505. ((int)lpResItem->wcX==-1) &&
  2506. ((int)lpResItem->wcY==-1) &&
  2507. ((LONG)lpResItem->dwItemID==-1) &&
  2508. //(LOWORD(dwPosId)==0) &&
  2509. ((LONG)lpResItem->dwStyle==-1) &&
  2510. ((LONG)lpResItem->dwExtStyle==-1) &&
  2511. ((LONG)lpResItem->dwFlags==-1) &&
  2512. (strlen((LPSTR)lpResItem->lpszCaption)==0)
  2513. )
  2514. ) {
  2515. TRACE2("\tItems-> x: %d\ty: %d\t", lpResItem->wX, lpResItem->wY );
  2516. TRACE2("cx: %d\tcy: %d\t", lpResItem->wcX, lpResItem->wcY );
  2517. TRACE1("Id: %lu\t", lpResItem->dwItemID);
  2518. TRACE2("Style: %ld\tExtStyle: %ld\n", lpResItem->dwStyle, lpResItem->dwExtStyle);
  2519. if (lpResItem->lpszCaption) {
  2520. UINT len = strlen((LPSTR)lpResItem->lpszCaption);
  2521. TRACE2("Len: %d\tText: %s\n", len,
  2522. (len<256 ? lpResItem->lpszCaption : ""));
  2523. }
  2524. TRACE2("dwRead: %lu\tdwSize: %lu\n", dwRead, lpResItem->dwSize);
  2525. //lpResItem->dwItemID = MAKELONG(LOWORD(lpResItem->dwItemID), ++wPos);
  2526. m_ItemArray.Add( new CItemInfo( lpResItem, wTabPos ));
  2527. }
  2528. // Next Item
  2529. lpBuf += lpResItem->dwSize;
  2530. dwRead -= lpResItem->dwSize;
  2531. lpResItem = (LPRESITEM) lpBuf;
  2532. }
  2533. delete []lpBufStart;
  2534. return (DWORD)m_ItemArray.GetSize();
  2535. }
  2536. UINT
  2537. CResInfo::CopyImage( CResInfo* pResInfo )
  2538. {
  2539. // Will copy the image from this object to the pResInfo object
  2540. // We need this to hack the image transformation
  2541. // When we will have time we will do the thing right
  2542. // Allocate memory for the new image
  2543. if(!m_dwImageSize)
  2544. return 0;
  2545. if(pResInfo->AllocImage(m_dwImageSize))
  2546. return ERROR_NEW_FAILED;
  2547. // Copy the data
  2548. memcpy( pResInfo->m_lpImageBuf, m_lpImageBuf, (size_t)m_dwImageSize );
  2549. // set the file size so the GetImage will not complain
  2550. pResInfo->SetFileSize(m_FileSize);
  2551. return 0;
  2552. }
  2553. UINT
  2554. CResInfo::Copy( CResInfo* pResInfo, CString szFileName, HINSTANCE hInst )
  2555. {
  2556. CItemInfo* pItemInfo;
  2557. INT_PTR u = m_ItemArray.GetUpperBound();
  2558. if (u==-1) {
  2559. if ( (!m_lpImageBuf) && (m_FileOffset)) {
  2560. DWORD dwReadSize = LoadImage( szFileName, hInst );
  2561. if (dwReadSize!=m_dwImageSize)
  2562. return ERROR_RW_LOADIMAGE;
  2563. }
  2564. if (!(ParseImage( hInst )) )
  2565. return ERROR_RW_PARSEIMAGE;
  2566. u = m_ItemArray.GetUpperBound();
  2567. }
  2568. // This is a bad hack and doesn't fit at all in the design of the module.
  2569. // We have to copy the image between ResInfo object to be able to
  2570. // Pass on the raw data. Since in the RESITEM structure there isn't a
  2571. // pointer to a raw data buffer we cannot pass the data for the Cursor, bitmaps...
  2572. // What we will do is hard code the type id of this image and if the resource
  2573. // is one of this we will copy the raw data and perform an UpdateImage in the RES16
  2574. // module. If it is a standard item then we procede as usual calling the GenerateImage
  2575. // in the RES16 Module.
  2576. // The right thing to do should be to have a pointer to the raw data in the RESITEM
  2577. // structure so when the item is a pure data item we can still pass the data on.
  2578. // To do this we have to change the RESITEM structure and this will mean go in each RW
  2579. // and make sure that all the place in which we fill the RESITEM get modified.
  2580. switch(m_TypeId) {
  2581. // Copy only the Bitmaps, Cursors and Icons usualy have no localizable strings
  2582. /*
  2583. case 1:
  2584. // copy the image
  2585. CopyImage( pResInfo );
  2586. break;
  2587. */
  2588. case 2:
  2589. // copy the image
  2590. CopyImage( pResInfo );
  2591. break;
  2592. /*
  2593. case 3:
  2594. // copy the image
  2595. CopyImage( pResInfo );
  2596. break;
  2597. */
  2598. default:
  2599. // do nothing
  2600. break;
  2601. }
  2602. //m_ItemArray.SetSize(u,10);
  2603. for( int c=0; c<=u ; c++) {
  2604. pItemInfo = (CItemInfo*) m_ItemArray.GetAt(c);
  2605. if(!pItemInfo)
  2606. return ERROR_IO_INVALIDITEM;
  2607. pResInfo->AddItem( *pItemInfo );
  2608. }
  2609. // We have to mark the resource has updated
  2610. pResInfo->SetFileOffset(0L);
  2611. pResInfo->SetImageUpdated(0);
  2612. return ERROR_NO_ERROR;
  2613. }
  2614. int
  2615. CResInfo::AddItem( CItemInfo ItemInfo )
  2616. {
  2617. return (int)m_ItemArray.Add( new CItemInfo( ItemInfo ));
  2618. }
  2619. DWORD
  2620. CResInfo::EnumItem( LPCSTR lpszFilename, HINSTANCE hInst, DWORD dwPrevItem )
  2621. {
  2622. if (dwPrevItem) {
  2623. if (m_ItemPos==0) return LPNULL;
  2624. if (m_ItemPos==m_ItemArray.GetSize()) {
  2625. m_ItemPos = 0;
  2626. return LPNULL;
  2627. }
  2628. } else {
  2629. // It is the first time or the user want to restart
  2630. // Load the resource.image
  2631. DWORD dwReadSize = LoadImage( lpszFilename, hInst );
  2632. if (dwReadSize!=m_FileSize) {
  2633. return 0L;
  2634. }
  2635. // We have now to pass the Buffer back to the RW to Parse the info
  2636. if (!(ParseImage( hInst )) )
  2637. return 0L;
  2638. m_ItemPos = 0;
  2639. }
  2640. CItemInfo* pItemInfo = (CItemInfo*)m_ItemArray.GetAt( m_ItemPos++ );
  2641. while( (
  2642. (pItemInfo->GetX()==0) &&
  2643. (pItemInfo->GetY()==0) &&
  2644. (pItemInfo->GetcX()==0) &&
  2645. (pItemInfo->GetcY()==0) &&
  2646. (pItemInfo->GetId()==0) &&
  2647. (pItemInfo->GetStyle()==0) &&
  2648. (pItemInfo->GetExtStyle()==0) &&
  2649. ((pItemInfo->GetCaption()).IsEmpty())
  2650. )
  2651. ) {
  2652. if(m_ItemArray.GetUpperBound()>=m_ItemPos)
  2653. pItemInfo = (CItemInfo*)m_ItemArray.GetAt( m_ItemPos++ );
  2654. else return 0L;
  2655. }
  2656. if (!pItemInfo) return 0L;
  2657. return pItemInfo->GetTabPosId();
  2658. }
  2659. ////////////////////////////////////////////////////////////////////////////
  2660. // CItemInfo
  2661. CItemInfo::CItemInfo( WORD x, WORD y,
  2662. WORD cx, WORD cy,
  2663. DWORD dwPosId, WORD wPos,
  2664. DWORD dwStyle, DWORD dwExtStyle,
  2665. CString szText )
  2666. {
  2667. m_wX = x;
  2668. m_wY = y;
  2669. m_wCX = cx;
  2670. m_wCY = cy;
  2671. m_dwPosId = dwPosId;
  2672. m_wTabPos = wPos;
  2673. m_dwStyle = dwStyle;
  2674. m_dwExtStyle = dwExtStyle;
  2675. m_szCaption = szText;
  2676. }
  2677. CItemInfo::CItemInfo( LPRESITEM lpResItem, WORD wTabPos )
  2678. {
  2679. m_wX = lpResItem->wX;
  2680. m_wY = lpResItem->wY;
  2681. m_wCX = lpResItem->wcX;
  2682. m_wCY = lpResItem->wcY;
  2683. m_dwCheckSum = lpResItem->dwCheckSum;
  2684. m_dwStyle = lpResItem->dwStyle;
  2685. m_dwExtStyle = lpResItem->dwExtStyle;
  2686. m_dwFlags = lpResItem->dwFlags;
  2687. m_dwPosId = lpResItem->dwItemID;
  2688. m_wTabPos = wTabPos;
  2689. m_dwCodePage = lpResItem->dwCodePage;
  2690. m_dwLanguage = lpResItem->dwLanguage;
  2691. m_wClassName = lpResItem->wClassName;
  2692. m_wPointSize = lpResItem->wPointSize;
  2693. m_wWeight = lpResItem->wWeight;
  2694. m_bItalic = lpResItem->bItalic;
  2695. m_bCharSet = lpResItem->bCharSet;
  2696. m_szClassName = lpResItem->lpszClassName;
  2697. m_szFaceName = lpResItem->lpszFaceName;
  2698. m_szCaption = lpResItem->lpszCaption;
  2699. }
  2700. UINT
  2701. CItemInfo::UpdateData( LPVOID lpbuffer, UINT uiBufSize )
  2702. {
  2703. UINT uiError = ERROR_NO_ERROR;
  2704. //
  2705. // This is old and was used at the very beginning. Never used now.
  2706. //
  2707. return uiError;
  2708. }
  2709. UINT
  2710. CItemInfo::UpdateData( LPRESITEM lpResItem )
  2711. {
  2712. if (lpResItem){
  2713. m_wX = lpResItem->wX;
  2714. m_wY = lpResItem->wY;
  2715. m_wCX = lpResItem->wcX;
  2716. m_wCY = lpResItem->wcY;
  2717. m_dwCheckSum = lpResItem->dwCheckSum;
  2718. m_dwStyle = lpResItem->dwStyle;
  2719. m_dwExtStyle = lpResItem->dwExtStyle;
  2720. m_dwFlags = lpResItem->dwFlags;
  2721. SetId(LOWORD(lpResItem->dwItemID)); //m_dwPosId = lpResItem->dwItemId;
  2722. //m_wTabPos = wTabPos;
  2723. m_dwCodePage = lpResItem->dwCodePage;
  2724. m_dwLanguage = lpResItem->dwLanguage;
  2725. m_wClassName = lpResItem->wClassName;
  2726. m_wPointSize = lpResItem->wPointSize;
  2727. m_wWeight = lpResItem->wWeight;
  2728. m_bItalic = lpResItem->bItalic;
  2729. m_bCharSet = lpResItem->bCharSet;
  2730. m_szClassName = lpResItem->lpszClassName;
  2731. m_szFaceName = lpResItem->lpszFaceName;
  2732. m_szCaption = lpResItem->lpszCaption;
  2733. }
  2734. return 0;
  2735. }
  2736. void
  2737. CItemInfo::SetPos( WORD wPos )
  2738. {
  2739. WORD wId = LOWORD(m_dwPosId);
  2740. m_dwPosId = 0;
  2741. m_dwPosId = wPos;
  2742. m_dwPosId = (m_dwPosId << 16);
  2743. if (wId>0)
  2744. m_dwPosId += wId;
  2745. else m_dwPosId -= wId;
  2746. }
  2747. void
  2748. CItemInfo::SetId( WORD wId )
  2749. {
  2750. WORD wPos = HIWORD(m_dwPosId);
  2751. m_dwPosId = 0;
  2752. m_dwPosId = wPos;
  2753. m_dwPosId = (m_dwPosId << 16);
  2754. if (wId>0)
  2755. m_dwPosId += wId;
  2756. else m_dwPosId -= wId;
  2757. }
  2758. DWORD
  2759. CItemInfo::GetTabPosId()
  2760. {
  2761. DWORD dwTabPosId = 0;
  2762. WORD wId = LOWORD(m_dwPosId);
  2763. dwTabPosId = m_wTabPos;
  2764. dwTabPosId = (dwTabPosId << 16);
  2765. if (wId>0)
  2766. dwTabPosId += wId;
  2767. else dwTabPosId -= wId;
  2768. return dwTabPosId;
  2769. }
  2770. CItemInfo::CItemInfo( const CItemInfo &iteminfo )
  2771. {
  2772. m_wX = iteminfo.m_wX;
  2773. m_wY = iteminfo.m_wY;
  2774. m_wCX = iteminfo.m_wCX;
  2775. m_wCY = iteminfo.m_wCY;
  2776. m_dwCheckSum = iteminfo.m_dwCheckSum;
  2777. m_dwStyle = iteminfo.m_dwStyle;
  2778. m_dwExtStyle = iteminfo.m_dwExtStyle;
  2779. m_dwFlags = iteminfo.m_dwFlags;
  2780. m_dwPosId = iteminfo.m_dwPosId;
  2781. m_wTabPos = iteminfo.m_wTabPos;
  2782. m_dwCodePage = iteminfo.m_dwCodePage;
  2783. m_dwLanguage = iteminfo.m_dwLanguage;
  2784. m_wClassName = iteminfo.m_wClassName;
  2785. m_wPointSize = iteminfo.m_wPointSize;
  2786. m_wWeight = iteminfo.m_wWeight;
  2787. m_bItalic = iteminfo.m_bItalic;
  2788. m_bCharSet = iteminfo.m_bCharSet;
  2789. m_szClassName = iteminfo.m_szClassName;
  2790. m_szFaceName = iteminfo.m_szFaceName;
  2791. m_szCaption = iteminfo.m_szCaption;
  2792. }
  2793. static BYTE Allign(LONG bLen)
  2794. {
  2795. BYTE bPad =(BYTE)PadPtr(bLen);
  2796. return bPad;
  2797. }
  2798. static UINT CopyFile( const char * pszfilein, const char * pszfileout )
  2799. {
  2800. CFile filein;
  2801. CFile fileout;
  2802. if (!filein.Open(pszfilein, CFile::modeRead | CFile::typeBinary | CFile::shareDenyNone))
  2803. return ERROR_FILE_OPEN;
  2804. if (!fileout.Open(pszfileout, CFile::modeWrite | CFile::modeCreate | CFile::typeBinary))
  2805. return ERROR_FILE_CREATE;
  2806. LONG lLeft = filein.GetLength();
  2807. WORD wRead = 0;
  2808. DWORD dwOffset = 0;
  2809. BYTE far * pBuf = (BYTE far *) new BYTE[32739];
  2810. if(!pBuf)
  2811. return ERROR_NEW_FAILED;
  2812. while(lLeft>0){
  2813. wRead =(WORD) (32738ul < lLeft ? 32738: lLeft);
  2814. if (wRead!= filein.Read( pBuf, wRead))
  2815. return ERROR_FILE_READ;
  2816. fileout.Write( pBuf, wRead );
  2817. lLeft -= wRead;
  2818. dwOffset += wRead;
  2819. }
  2820. delete []pBuf;
  2821. return ERROR_NO_ERROR;
  2822. }
  2823. void CheckError(LPCSTR szStr)
  2824. {
  2825. TRY
  2826. {
  2827. DWORD dwErr = GetLastError();
  2828. char szBuf[256];
  2829. wsprintf( szBuf, "%s return: %d\n", szStr, dwErr);
  2830. TRACE(szBuf);
  2831. }
  2832. CATCH( CException, e )
  2833. {
  2834. TRACE("There is an Exception!\n");
  2835. }
  2836. END_CATCH
  2837. }
  2838. ////////////////////////////////////////////////////////////////////////////
  2839. // RDF File support code
  2840. HANDLE
  2841. OpenModule(
  2842. LPCSTR lpszSrcfilename, // File name of the executable to use as source file
  2843. LPCSTR lpszfiletype, // Type of the executable file if known
  2844. LPCSTR lpszRDFfile,
  2845. DWORD dwFlags )
  2846. {
  2847. TRACE2("IODLL.DLL: RSOpenModule: %s %s\n", lpszSrcfilename, lpszfiletype);
  2848. UINT uiError = ERROR_NO_ERROR;
  2849. INT_PTR uiHandle = 0 ;
  2850. // Before we do anything we have to check if the file exist
  2851. CFileStatus status;
  2852. if(!CFile::GetStatus( lpszSrcfilename, status ))
  2853. return UlongToHandle(ERROR_FILE_OPEN);
  2854. // Check if the user already knows the type of the executable
  2855. CString szSrcFileType;
  2856. if (!lpszfiletype) {
  2857. if(uiError = RSFileType( lpszSrcfilename, szSrcFileType.GetBuffer(100) ))
  2858. return UlongToHandle(uiError);
  2859. szSrcFileType.ReleaseBuffer(-1);
  2860. } else szSrcFileType = lpszfiletype;
  2861. gModuleTable.Add(new CFileModule( lpszSrcfilename,
  2862. lpszRDFfile,
  2863. gDllTable.GetPosFromTable(szSrcFileType),
  2864. dwFlags ));
  2865. // Get the position in the array.
  2866. uiHandle = gModuleTable.GetSize();
  2867. // Read the informations on the type in the file.
  2868. CFileModule* pFileModule = (CFileModule*)gModuleTable.GetAt(uiHandle-1);
  2869. if (!pFileModule)
  2870. return UlongToHandle(ERROR_IO_INVALIDMODULE);
  2871. if (pFileModule->LoadDll()==NULL)
  2872. return UlongToHandle(ERROR_DLL_LOAD);
  2873. HINSTANCE hInst = pFileModule->GetHInstance();
  2874. UINT (FAR PASCAL * lpfnReadResInfo)(LPCSTR, LPVOID, UINT*);
  2875. // Get the pointer to the function to extract the resources
  2876. lpfnReadResInfo = (UINT (FAR PASCAL *)(LPCSTR, LPVOID, UINT*))
  2877. GetProcAddress( hInst, "RWReadTypeInfo" );
  2878. if (lpfnReadResInfo==NULL) {
  2879. return UlongToHandle(ERROR_DLL_PROC_ADDRESS);
  2880. }
  2881. UINT uiSize = 50000;
  2882. BYTE far * pBuf = new BYTE[uiSize];
  2883. if (!pBuf)
  2884. return UlongToHandle(ERROR_NEW_FAILED);
  2885. uiError = (*lpfnReadResInfo)((LPCSTR)pFileModule->GetName(),
  2886. (LPVOID)pBuf,
  2887. (UINT*) &uiSize);
  2888. // Check if the buffer was big enough
  2889. if (uiSize>50000) {
  2890. // The buffer was too small reallocate
  2891. UINT uiNewSize = uiSize;
  2892. delete [] pBuf;
  2893. pBuf = new BYTE[uiSize];
  2894. if (!pBuf)
  2895. return UlongToHandle(ERROR_NEW_FAILED);
  2896. uiError = (*lpfnReadResInfo)((LPCSTR)pFileModule->GetName(),
  2897. (LPVOID)pBuf,
  2898. (UINT*) &uiSize);
  2899. if (uiSize!=uiNewSize)
  2900. return UlongToHandle(ERROR_NEW_FAILED);
  2901. }
  2902. if (uiError!=ERROR_NO_ERROR) {
  2903. delete pBuf;
  2904. pFileModule->CleanUp();
  2905. return UlongToHandle(uiError);
  2906. }
  2907. // We have a buffer with all the information the DLL was able to get.
  2908. // Fill the array in the CFileModule class
  2909. BYTE* pBufPos = pBuf;
  2910. BYTE* pBufStart = pBuf;
  2911. WORD wTypeId;
  2912. WORD wNameId;
  2913. CString szTypeId;
  2914. CString szNameId;
  2915. DWORD dwlang;
  2916. DWORD dwfileOffset;
  2917. DWORD dwsize;
  2918. pFileModule->SetResBufSize( uiSize );
  2919. while(uiSize) {
  2920. wTypeId = *((WORD*)pBuf);
  2921. pBuf += sizeofWord;
  2922. szTypeId = (char*)pBuf;
  2923. pBuf += strlen((char*)pBuf)+1;
  2924. pBuf += Allign((LONG)(pBuf-pBufPos));
  2925. wNameId = *((WORD*)pBuf);
  2926. pBuf += sizeofWord;
  2927. szNameId = (char*)pBuf;
  2928. pBuf += strlen((char*)pBuf)+1;
  2929. pBuf += Allign((LONG)(pBuf-pBufPos));
  2930. dwlang = *((DWORD*)pBuf);
  2931. pBuf += sizeofDWord;
  2932. dwsize = *((DWORD*)pBuf);
  2933. pBuf += sizeofDWord;
  2934. dwfileOffset = *((DWORD*)pBuf);
  2935. pBuf += sizeofDWord;
  2936. uiSize -= (UINT)(pBuf-pBufPos);
  2937. pBufPos = pBuf;
  2938. TRACE1("TypeId: %d\t", wTypeId);
  2939. TRACE1("TypeName: %s\t", szTypeId);
  2940. TRACE1("NameId: %d\t", wNameId);
  2941. TRACE1("NameName: %s\t", szNameId);
  2942. TRACE1("ResLang: %lu\t", dwlang);
  2943. TRACE1("ResSize: %lu\t", dwsize);
  2944. TRACE1("FileOffset: %lX\n", dwfileOffset);
  2945. //TRACE1("uiError: %u\n", uiSize);
  2946. pFileModule->AddResInfo( wTypeId,
  2947. szTypeId,
  2948. wNameId,
  2949. szNameId,
  2950. dwlang,
  2951. dwsize,
  2952. dwfileOffset );
  2953. }
  2954. delete pBufStart;
  2955. return (HANDLE)(uiHandle+FIRSTVALIDVALUE);
  2956. }
  2957. ////////////////////////////////////////////////////////////////////////////
  2958. // DLL Specific code implementation
  2959. ////////////////////////////////////////////////////////////////////////////
  2960. // Library init
  2961. ////////////////////////////////////////////////////////////////////////////
  2962. // This function should be used verbatim. Any initialization or termination
  2963. // requirements should be handled in InitPackage() and ExitPackage().
  2964. //
  2965. extern "C" int APIENTRY
  2966. DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
  2967. {
  2968. if (dwReason == DLL_PROCESS_ATTACH)
  2969. {
  2970. // NOTE: global/static constructors have already been called!
  2971. // Extension DLL one-time initialization - do not allocate memory
  2972. // here, use the TRACE or ASSERT macros or call MessageBox
  2973. AfxInitExtensionModule(extensionDLL, hInstance);
  2974. g_iDllLoaded = 0;
  2975. }
  2976. else if (dwReason == DLL_PROCESS_DETACH)
  2977. {
  2978. // Terminate the library before destructors are called
  2979. AfxWinTerm();
  2980. }
  2981. if (dwReason == DLL_PROCESS_DETACH || dwReason == DLL_THREAD_DETACH)
  2982. return 0; // CRT term Failed
  2983. return 1; // ok
  2984. }