resmgr.cpp
上传用户:kittypts
上传日期:2018-02-11
资源大小:241k
文件大小:10k
源码类别:

PlugIns编程

开发平台:

Visual C++

  1. /*****************************************************************************
  2. Windows Live Messenger Plugin Demo
  3. Copyright (C) 2008  Hern醤 Di Pietro
  4. This program is free software: you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation, either version 3 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program.  If not, see <http://www.gnu.org/licenses/>.
  14. /*****************************************************************************/
  15. #include "resmgr.h"
  16. #include "utility.h"
  17. CResourceManager::CResourceManager(void) {}
  18. CResourceManager::~CResourceManager(void)
  19. {
  20. BOOL fvfResult;
  21. WCHAR msg[MAXSTRL];
  22. // Free resources
  23. for (RESOURCE_POINTER_TABLE::iterator it = m_ptrTable.begin();
  24. it != m_ptrTable.end(); it++)
  25. {
  26. wsprintf(msg, L"Freeing allocated resource at address %#x ", it->second.first);
  27. OutputDebugString (msg);
  28. fvfResult = VirtualFree (it->second.first, 0, MEM_RELEASE);
  29. OutputDebugString (fvfResult != 0 ? L"OK" : L"FAIL" ); 
  30. }
  31. }
  32. // Register a resource to be modified with address and modification type
  33. // (inserting/appending bytes or replacing the entire resource)
  34. //
  35. void CResourceManager::RegisterResource (DWORD dwType, DWORD dwName, LPVOID pResData, DWORD cbSize, 
  36.  UINT iResModType, UINT cbWhere)
  37. {
  38. RESOURCE_MOD_DESCRIPTOR rm;
  39. rm.iModType = iResModType;
  40. rm.cbSize = cbSize;
  41. rm.cbWhere = cbWhere;
  42. rm.cbOldSize= NULL;
  43. rm.pvResData= pResData;
  44. rm.cbNewSize= NULL;
  45. rm.pvAddress= NULL;
  46. rm.fAlloc = false;
  47. m_regResourceTable.insert(RESOURCE_ENTRY(MAKEULONGLONG(dwType,dwName), rm));
  48. }
  49. // Register a resource in the injected DLL
  50. // This is only for res IDs that didn't exist in the original resource 
  51. void CResourceManager::RegisterNewResource (DWORD dwType, DWORD dwName, const RESOURCEINFO& rii)
  52. {
  53. RESOURCE_MOD_DESCRIPTOR rm;
  54. rm.iModType = RR_NEW;
  55. rm.cbSize = rii.dwSize;
  56. rm.cbWhere = NULL;
  57. rm.cbOldSize= NULL;
  58. rm.pvResData= rii.pvData;
  59. rm.cbNewSize= NULL;
  60. rm.pvAddress= NULL;
  61. rm.fAlloc = false;
  62. rm.ri = rii;
  63. m_regResourceTable.insert(RESOURCE_ENTRY(MAKEULONGLONG(dwType, dwName), rm));
  64. }
  65. // Modify a resource identified by the HGLOBAL value returned by LoadResource
  66. // (stored in the resource data pointer table) 
  67. //
  68. LPVOID CResourceManager::AllocResource (const HGLOBAL hDataRes)
  69. {
  70. // find to which resource it maps
  71. RESOURCE_POINTER_TABLE::iterator rpit = m_ptrTable.find(hDataRes);
  72. ULONGLONG resID = rpit->second.second;
  73. REGISTERED_RESOURCE_TABLE::iterator rrtit = m_regResourceTable.find(resID);
  74. RESOURCE_MOD_DESCRIPTOR* rmd = &(rrtit->second);
  75. if (!rmd->fAlloc) // not modified?
  76. {
  77. // allocate memory for resource
  78. _OutputDebugString (L"Allocating bytes for resource data: %d", rmd->cbOldSize + rmd->cbSize);
  79. rmd->pvAddress = VirtualAlloc(0, rmd->cbOldSize + rmd->cbSize, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
  80. LPVOID lpvPrevAddr = rpit->second.first; // original resource address
  81. switch (rmd->iModType)
  82. {
  83. case RR_COPY: // copy the resource in the mem block only
  84. case RR_NEW:
  85. RtlCopyMemory (rmd->pvAddress, lpvPrevAddr, rmd->cbOldSize);
  86. break;
  87. case RR_APPEND: // append the new resource data at the last byte 
  88. RtlCopyMemory (rmd->pvAddress, lpvPrevAddr, rmd->cbOldSize+rmd->cbSize);
  89. RtlCopyMemory ((LPVOID)((DWORD)rmd->pvAddress + rmd->cbOldSize), rmd->pvResData, (SIZE_T)rmd->cbSize);
  90. break;
  91. case RR_INSERT: // insert resource at rmd->cbWhere byte of the resource
  92. RtlCopyMemory (rmd->pvAddress, lpvPrevAddr, rmd->cbWhere);
  93. RtlCopyMemory ((LPVOID)((DWORD)rmd->pvAddress + rmd->cbWhere),  rmd->pvResData, (SIZE_T)rmd->cbSize);
  94. RtlCopyMemory ((LPVOID)((DWORD)rmd->pvAddress + rmd->cbWhere + rmd->cbSize), 
  95. (LPVOID)((DWORD)lpvPrevAddr + rmd->cbWhere), 
  96. (SIZE_T)rmd->cbOldSize + rmd->cbSize - rmd->cbWhere); 
  97. break;
  98. }
  99. rmd->fAlloc = true;
  100. return rmd->pvAddress;
  101. }
  102. else
  103. OutputDebugString (L"CRM::AllocResource Returning already allocated address.");
  104. return rmd->pvAddress;
  105. }
  106. // Return a proper resource size for SizeofResource call
  107. DWORD CResourceManager::GetFixedResourceSize (const HRSRC hr)
  108. {
  109. RESOURCE_HANDLE_TABLE::const_iterator rhit = m_handleTable.find(hr);
  110. ULONGLONG rid = rhit->second;
  111. REGISTERED_RESOURCE_TABLE::iterator rrtit = m_regResourceTable.find(rid);
  112. if (rrtit->second.cbNewSize == NULL)
  113. rrtit->second.cbNewSize = rrtit->second.cbOldSize + rrtit->second.cbSize;
  114. return rrtit->second.cbNewSize;
  115. }
  116. // Save resource size for a resource ID
  117. void CResourceManager::SetResourceSize(const ULONGLONG& ullResID, const DWORD dwSize)
  118. {
  119. REGISTERED_RESOURCE_TABLE::iterator it = m_regResourceTable.find (ullResID);
  120. it->second.cbOldSize = dwSize;
  121. WCHAR buf[MAXSTRL];
  122. wsprintf(buf, L"SetResource old size for res %I64d to %d bytes.", ullResID, dwSize);
  123. OutputDebugString(buf);
  124. }
  125. // Get the handle for a resource present on the injected DLL
  126. HRSRC CResourceManager::GetDLLResourceHandle(const ULONGLONG& ulid)
  127. {
  128. REGISTERED_RESOURCE_TABLE::iterator it = m_regResourceTable.find (ulid);
  129. _ASSERTE(it->second.iModType == RR_NEW);
  130. return it->second.ri.hrsrc;
  131. }
  132. // Get the data handle (returned by LoadResource) for a resource present on the injected DLL
  133. HGLOBAL CResourceManager::GetDLLResourceDataHandle(const ULONGLONG& ulid)
  134. {
  135. REGISTERED_RESOURCE_TABLE::iterator it = m_regResourceTable.find (ulid);
  136. _ASSERTE(it->second.iModType == RR_NEW);
  137. return it->second.ri.hResData;
  138. }
  139. // Get size for a resource present on resource DLL
  140. DWORD CResourceManager::GetDLLResourceSize(const ULONGLONG& ulid)
  141. {
  142. REGISTERED_RESOURCE_TABLE::iterator it = m_regResourceTable.find (ulid);
  143. _ASSERTE(it->second.iModType == RR_NEW);
  144. return it->second.ri.dwSize;
  145. }
  146. // Checks if the resource is present on the registered resource table)
  147. //
  148. bool CResourceManager::IsResourceRegistered(const DWORD dwName, const DWORD dwType)
  149. {
  150. REGISTERED_RESOURCE_TABLE::const_iterator it = 
  151. m_regResourceTable.find (MAKEULONGLONG(dwName,dwType));
  152. return (it != m_regResourceTable.end());
  153. }
  154. // Check if the handle is present on the handle table
  155. //
  156. bool CResourceManager::IsHandleRegistered(const HRSRC hResource)
  157. {
  158. RESOURCE_HANDLE_TABLE::const_iterator rhti = 
  159. m_handleTable.find (hResource);
  160. return (rhti != m_handleTable.end());
  161. }
  162. // Return true for a new resource (previously non-existent)
  163. bool CResourceManager::IsNewResource (const ULONGLONG& rid)
  164. {
  165. REGISTERED_RESOURCE_TABLE::const_iterator it = 
  166. m_regResourceTable.find (rid);
  167. return (it->second.iModType == RR_NEW);
  168. }
  169. // Check if the data handle is present on the data pointer table
  170. //
  171. bool CResourceManager::IsDataPointerRegistered(const HGLOBAL hDataPtr)
  172. {
  173. RESOURCE_POINTER_TABLE::const_iterator itrpt = m_ptrTable.find(hDataPtr);
  174. return (itrpt != m_ptrTable.end());
  175. }
  176. // Add a handle to the handle-table with the resource ID that refers to
  177. //
  178. void CResourceManager::AddHandleTableEntry(const ULONGLONG& ResourceEntry, const HRSRC hResource)
  179. {
  180. m_handleTable.insert(RESOURCE_HANDLE_ENTRY(hResource, ResourceEntry));
  181. }
  182. // Add a resource data handle returned by LoadResource and the Res ID 
  183. //
  184. void CResourceManager::AddPointerTableEntry (const ULONGLONG& resID, const HGLOBAL hResData)
  185. {
  186. m_ptrTable.insert (RESOURCE_POINTER_ENTRY(hResData, RESOURCE_POINTER(NULL, resID)));
  187. }
  188. // Add a pointer for resource data in the pointer table
  189. //
  190. void CResourceManager::SetResourcePointer (const HGLOBAL hResData, LPVOID ptr)
  191. {
  192. RESOURCE_POINTER_TABLE::iterator it = m_ptrTable.find (hResData);
  193. (it->second).first = ptr;
  194. }
  195. // Finds the resource ID that corresponds to an entry in the handle table
  196. //
  197. ULONGLONG CResourceManager::ResourceIDFromHandle (const HRSRC hr)
  198. {
  199. RESOURCE_HANDLE_TABLE::iterator it = m_handleTable.find(hr);
  200. return it->second;
  201. }
  202. // Returns resource size by HRSRC
  203. //
  204. DWORD CResourceManager::GetOriginalResourceSize (const HRSRC hr)
  205. {
  206. ULONGLONG rid = ResourceIDFromHandle(hr);
  207. REGISTERED_RESOURCE_TABLE::const_iterator it = m_regResourceTable.find(rid);
  208. _OutputDebugString (L"GetOriginalResourceSize=%d",it->second.cbOldSize);
  209. return it->second.cbOldSize;
  210. }
  211. // Returns resource size by Resource ID
  212. //
  213. DWORD CResourceManager::GetOriginalResourceSize (const ULONGLONG& rid)
  214. {
  215. REGISTERED_RESOURCE_TABLE::const_iterator it = m_regResourceTable.find(rid);
  216. _OutputDebugString (L"GetOriginalResourceSize=%d",it->second.cbOldSize);
  217. return it->second.cbOldSize;
  218. }
  219. // Finds the resource ID that corresponds to an entry in the data pointer table
  220. //
  221. ULONGLONG CResourceManager::ResourceIDFromDataHandle (const HGLOBAL hg)
  222. {
  223. RESOURCE_POINTER_TABLE::iterator it = m_ptrTable.find(hg);
  224. return (it->second).second;
  225. }
  226. //
  227. //
  228. // Dumps table info to debugging output
  229. //
  230. void CResourceManager::DumpTables()
  231. {
  232. WCHAR buf[MAXSTRL];
  233. OutputDebugString(L"REGISTERED_RESOURCE_TABLEn");
  234. OutputDebugString(L"TYPE+NAME     MOD    ADDR    WHERE   OLDSIZE    DSIZE n");
  235. OutputDebugString(L"--------------------------------------------------------n");
  236. for (REGISTERED_RESOURCE_TABLE::const_iterator it = m_regResourceTable.begin();
  237. it != m_regResourceTable.end(); it ++)
  238. {
  239. wsprintf(buf, L"%#I64x %#x %#x %#x %#x %#xn", it->first, it->second.iModType, it->second.pvAddress, 
  240. it->second.cbWhere, it->second.cbOldSize, it->second.cbSize);
  241. OutputDebugString(buf);
  242. }
  243. OutputDebugString(L"nRESOURCE_HANDLE_TABLEn");
  244. OutputDebugString(L"HANDLE RESOURCE_ID *n");
  245. OutputDebugString(L"----------------------------------------n");
  246. for (RESOURCE_HANDLE_TABLE::const_iterator it = m_handleTable.begin();
  247. it != m_handleTable.end(); it ++)
  248. {
  249. wsprintf(buf, L"%#x %#I64xn", it->first, it->second);
  250. OutputDebugString(buf);
  251. }
  252. OutputDebugString(L"nRESOURCE_POINTER_TABLEn");
  253. OutputDebugString(L"DATA_HANDLE    RESOURCE ADDRESS    R_IDn");
  254. OutputDebugString(L"-------------------------------------------n");
  255. for (RESOURCE_POINTER_TABLE::const_iterator it = m_ptrTable.begin();
  256. it != m_ptrTable.end(); it ++)
  257. {
  258. wsprintf(buf, L"%#x %#x %#I64xn", it->first, it->second.first, it->second.second);
  259. OutputDebugString(buf);
  260. }
  261. }