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.

543 lines
12 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1995
  5. //
  6. // File: ole.cxx
  7. //
  8. // Contents: Implements ntsd extensions to dump ole tables
  9. //
  10. // Functions:
  11. //
  12. //
  13. // History: 06-01-95 BruceMa Created
  14. //
  15. //
  16. //--------------------------------------------------------------------------
  17. #include <ole2int.h>
  18. #include <windows.h>
  19. #include "ole.h"
  20. //+-------------------------------------------------------------------------
  21. //
  22. // Function: readMemory
  23. //
  24. // Synopsis: Transfer memory from debuggee virtual space to a local
  25. // kernel memory
  26. //
  27. // Arguments: [lpArgumentString] - command line string
  28. // [a] - where to return next argument
  29. //
  30. // Returns: -
  31. //
  32. //--------------------------------------------------------------------------
  33. void readMemory(HANDLE hProcess, PNTSD_EXTENSION_APIS lpExtensionApis,
  34. BYTE *to, BYTE *from, INT cbSize)
  35. {
  36. __try
  37. {
  38. NtReadVirtualMemory(hProcess, (void *) from, (void *) to,
  39. cbSize , NULL);
  40. }
  41. __except (EXCEPTION_EXECUTE_HANDLER)
  42. {
  43. Printf("...Exception reading %08x-%08x\n", from, from + cbSize - 1);
  44. }
  45. }
  46. //+-------------------------------------------------------------------------
  47. //
  48. // Function: writeMemory
  49. //
  50. // Synopsis: Transfer memory from local memoryto debuggee virtual space
  51. //
  52. // Arguments:
  53. //
  54. // Returns: -
  55. //
  56. //--------------------------------------------------------------------------
  57. void writeMemory(HANDLE hProcess, PNTSD_EXTENSION_APIS lpExtensionApis,
  58. BYTE *to, BYTE *from, INT cbSize)
  59. {
  60. __try
  61. {
  62. NtWriteVirtualMemory(hProcess, (void *) to, (void *) from,
  63. cbSize, NULL);
  64. }
  65. __except (EXCEPTION_EXECUTE_HANDLER)
  66. {
  67. Printf("...Exception writing %08x-%08x\n", to, to + cbSize - 1);
  68. }
  69. }
  70. //+-------------------------------------------------------------------------
  71. //
  72. // Function: getArgument
  73. //
  74. // Synopsis: Return next command line argument
  75. //
  76. // Arguments: [lpArgumentString] - command line string
  77. // [a] - where to return next argument
  78. //
  79. // Returns: -
  80. //
  81. //--------------------------------------------------------------------------
  82. void getArgument(LPSTR *lpArgumentString, LPSTR a)
  83. {
  84. char *s = *lpArgumentString;
  85. // Skip whitespace
  86. while (*s && (*s == ' ' || *s == '\t'))
  87. {
  88. s++;
  89. }
  90. while (*s && *s != ' ' && *s != '\t')
  91. {
  92. *a++ = *s++;
  93. }
  94. *a = '\0';
  95. *lpArgumentString = s;
  96. }
  97. //+-------------------------------------------------------------------------
  98. //
  99. // Function: IsEqualGUID
  100. //
  101. // Synopsis: Compares two guids for equality
  102. //
  103. // Arguments: [pClsid1] - the first clsid
  104. // [pClsid2] - the second clsid to compare the first one with
  105. //
  106. // Returns: TRUE if equal, FALSE if not.
  107. //
  108. //--------------------------------------------------------------------------
  109. BOOL IsEqualCLSID(CLSID *pClsid1, CLSID *pClsid2)
  110. {
  111. return !memcmp((void *) pClsid1,(void *) pClsid2, sizeof(CLSID));
  112. }
  113. //+-------------------------------------------------------------------------
  114. //
  115. // Function: ScanAddr
  116. //
  117. // Synopsis: Parse the indput string as a hexadecimal address
  118. //
  119. // Arguments: [lpsz] - the hex string to convert
  120. //
  121. // Returns: TRUE for success
  122. //
  123. //--------------------------------------------------------------------------
  124. ULONG ScanAddr(char *lpsz)
  125. {
  126. ULONG val = NULL;
  127. // Peel off any leading "0x"
  128. if (lpsz[0] == '0' && lpsz[1] == 'x')
  129. {
  130. lpsz += 2;
  131. }
  132. // Parse as a hex address
  133. while (*lpsz)
  134. {
  135. if (*lpsz >= '0' && *lpsz <= '9')
  136. {
  137. val = (val << 4) + *lpsz - '0';
  138. }
  139. else if (*lpsz >= 'A' && *lpsz <= 'F')
  140. {
  141. val = (val << 4) + *lpsz - 'A' + 10;
  142. }
  143. else if (*lpsz >= 'a' && *lpsz <= 'f')
  144. {
  145. val = (val << 4) + *lpsz - 'a' + 10;
  146. }
  147. else
  148. {
  149. return NULL;
  150. }
  151. lpsz++;
  152. }
  153. return val;
  154. }
  155. //+-------------------------------------------------------------------------
  156. //
  157. // Function: HexStringToDword
  158. //
  159. // Synopsis: scan lpsz for a number of hex digits (at most 8); update lpsz
  160. // return value in Value; check for chDelim;
  161. //
  162. // Arguments: [lpsz] - the hex string to convert
  163. // [Value] - the returned value
  164. // [cDigits] - count of digits
  165. //
  166. // Returns: TRUE for success
  167. //
  168. //--------------------------------------------------------------------------
  169. static BOOL HexStringToDword(LPSTR &lpsz, DWORD &Value,
  170. int cDigits, WCHAR chDelim)
  171. {
  172. int Count;
  173. Value = 0;
  174. for (Count = 0; Count < cDigits; Count++, lpsz++)
  175. {
  176. if (*lpsz >= '0' && *lpsz <= '9')
  177. Value = (Value << 4) + *lpsz - '0';
  178. else if (*lpsz >= 'A' && *lpsz <= 'F')
  179. Value = (Value << 4) + *lpsz - 'A' + 10;
  180. else if (*lpsz >= 'a' && *lpsz <= 'f')
  181. Value = (Value << 4) + *lpsz - 'a' + 10;
  182. else
  183. return(FALSE);
  184. }
  185. if (chDelim != 0)
  186. return *lpsz++ == chDelim;
  187. else
  188. return TRUE;
  189. }
  190. //+-------------------------------------------------------------------------
  191. //
  192. // Function: CLSIDFromString
  193. //
  194. // Synopsis: Parse above format; always writes over *pguid.
  195. //
  196. // Arguments: [lpsz] - the guid string to convert
  197. // [pguid] - guid to return
  198. //
  199. // Returns: TRUE if successful
  200. //
  201. //--------------------------------------------------------------------------
  202. BOOL ScanCLSID(LPSTR lpsz, CLSID *pClsid)
  203. {
  204. DWORD dw;
  205. if (*lpsz++ != '{')
  206. return FALSE;
  207. if (!HexStringToDword(lpsz, pClsid->Data1, sizeof(DWORD)*2, '-'))
  208. return FALSE;
  209. if (!HexStringToDword(lpsz, dw, sizeof(WORD)*2, '-'))
  210. return FALSE;
  211. pClsid->Data2 = (WORD)dw;
  212. if (!HexStringToDword(lpsz, dw, sizeof(WORD)*2, '-'))
  213. return FALSE;
  214. pClsid->Data3 = (WORD)dw;
  215. if (!HexStringToDword(lpsz, dw, sizeof(BYTE)*2, 0))
  216. return FALSE;
  217. pClsid->Data4[0] = (BYTE)dw;
  218. if (!HexStringToDword(lpsz, dw, sizeof(BYTE)*2, '-'))
  219. return FALSE;
  220. pClsid->Data4[1] = (BYTE)dw;
  221. if (!HexStringToDword(lpsz, dw, sizeof(BYTE)*2, 0))
  222. return FALSE;
  223. pClsid->Data4[2] = (BYTE)dw;
  224. if (!HexStringToDword(lpsz, dw, sizeof(BYTE)*2, 0))
  225. return FALSE;
  226. pClsid->Data4[3] = (BYTE)dw;
  227. if (!HexStringToDword(lpsz, dw, sizeof(BYTE)*2, 0))
  228. return FALSE;
  229. pClsid->Data4[4] = (BYTE)dw;
  230. if (!HexStringToDword(lpsz, dw, sizeof(BYTE)*2, 0))
  231. return FALSE;
  232. pClsid->Data4[5] = (BYTE)dw;
  233. if (!HexStringToDword(lpsz, dw, sizeof(BYTE)*2, 0))
  234. return FALSE;
  235. pClsid->Data4[6] = (BYTE)dw;
  236. if (!HexStringToDword(lpsz, dw, sizeof(BYTE)*2, /*(*/ '}'))
  237. return FALSE;
  238. pClsid->Data4[7] = (BYTE)dw;
  239. return TRUE;
  240. }
  241. //+-------------------------------------------------------------------------
  242. //
  243. // Function: FormatCLSID
  244. //
  245. // Synopsis: converts GUID into {...} form without leading identifier;
  246. //
  247. // Arguments: [rguid] - the guid to convert
  248. // [lpszy] - buffer to hold the results
  249. // [cbMax] - sizeof the buffer
  250. //
  251. // Returns: amount of data copied to lpsz if successful
  252. // 0 if buffer too small.
  253. //
  254. //--------------------------------------------------------------------------
  255. void FormatCLSID(REFGUID rguid, LPSTR lpsz)
  256. {
  257. wsprintf(lpsz, "{%08lX-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}\0",
  258. rguid.Data1, rguid.Data2, rguid.Data3,
  259. rguid.Data4[0], rguid.Data4[1],
  260. rguid.Data4[2], rguid.Data4[3],
  261. rguid.Data4[4], rguid.Data4[5],
  262. rguid.Data4[6], rguid.Data4[7]);
  263. }
  264. extern BOOL fScmNeedsInit;
  265. extern BOOL fInScm;
  266. //+-------------------------------------------------------------------------
  267. //
  268. // Function: CheckForScm
  269. //
  270. // Synopsis: Checks whether the debuggee is 'scm'
  271. //
  272. // Arguments: -
  273. //
  274. // Returns: Sets global boolean fInScm to TRUE if this is the scm;
  275. // FALSE otherwise
  276. //
  277. //--------------------------------------------------------------------------
  278. void checkForScm(PNTSD_EXTENSION_APIS lpExtensionApis)
  279. {
  280. ULONG padr = NULL;
  281. if (fScmNeedsInit)
  282. {
  283. fScmNeedsInit = FALSE;
  284. padr = GetExpression("scm!CPerMachineROT__CPerMachineROT");
  285. fInScm = padr != NULL ? TRUE : FALSE;
  286. }
  287. }
  288. //+-------------------------------------------------------------------------
  289. //
  290. // Function: NotInScm
  291. //
  292. // Synopsis: Prints error message
  293. //
  294. // Arguments: -
  295. //
  296. // Returns:
  297. //
  298. //--------------------------------------------------------------------------
  299. void NotInScm(PNTSD_EXTENSION_APIS lpExtensionApis)
  300. {
  301. Printf("...not meaningful in the scm\n");
  302. }
  303. //+-------------------------------------------------------------------------
  304. //
  305. // Function: NotInOle
  306. //
  307. // Synopsis: Prints error message
  308. //
  309. // Arguments: -
  310. //
  311. // Returns:
  312. //
  313. //--------------------------------------------------------------------------
  314. void NotInOle(PNTSD_EXTENSION_APIS lpExtensionApis)
  315. {
  316. Printf("...only meaningful in the scm\n");
  317. }
  318. ///////////////////////////////////////////////////////////////////
  319. // F O R D E B U G G I N G
  320. void dbTrace(char *sz, DWORD *adr, ULONG amt,
  321. PNTSD_EXTENSION_APIS lpExtensionApis)
  322. {
  323. UINT k;
  324. Printf("\n%s", sz);
  325. for (k = 0; k < amt; k++)
  326. {
  327. if (k % 8 == 0)
  328. {
  329. Printf("\n");
  330. }
  331. Printf("%08x ", *adr++);
  332. }
  333. Printf("\n");
  334. }
  335. //+--------------------------------------------------------
  336. //
  337. // Function: GetRegistryInterfaceName
  338. //
  339. // Algorithm: Fetch the name from the registry for the specified interface
  340. //
  341. // History: 21-Jun-95 BruceMa Created
  342. //
  343. //---------------------------------------------------------
  344. BOOL GetRegistryInterfaceName(REFIID iid, char *szValue, DWORD *pcbValue)
  345. {
  346. DWORD dwRESERVED = 0;
  347. HKEY hKey;
  348. char szIID[CLSIDSTR_MAX];
  349. char szInterface[32 + 1 + CLSIDSTR_MAX];
  350. DWORD dwValueType;
  351. HKEY hClsidKey;
  352. HKEY hInproc32Key;
  353. // Prepare to open the "...Interface\<iid>" key
  354. FormatCLSID(iid, szIID);
  355. lstrcpy(szInterface, "Interface\\");
  356. lstrcat(szInterface, szIID);
  357. // Open the key for the specified interface
  358. if (RegOpenKeyEx(HKEY_CLASSES_ROOT, szInterface, dwRESERVED,
  359. KEY_READ, &hKey) != ERROR_SUCCESS)
  360. {
  361. return FALSE;
  362. }
  363. // Read the value as the interface name
  364. if (RegQueryValueEx(hKey, NULL, NULL, &dwValueType,
  365. (LPBYTE) szValue, pcbValue) != ERROR_SUCCESS)
  366. {
  367. CloseHandle(hKey);
  368. return FALSE;
  369. }
  370. // Close registry handle and return success
  371. CloseHandle(hKey);
  372. return TRUE;
  373. }
  374. //+--------------------------------------------------------
  375. //
  376. // Function: GetRegistryClsidKey
  377. //
  378. // Algorithm: Fetch the value from the registry for the specified clsid
  379. // and key
  380. //
  381. // History: 21-Jun-95 BruceMa Created
  382. //
  383. //---------------------------------------------------------
  384. BOOL GetRegistryClsidKey(REFCLSID clsid, char *szKey,
  385. char *szValue, DWORD *pcbValue)
  386. {
  387. DWORD dwRESERVED = 0;
  388. HKEY hKey;
  389. char szCLSID[CLSIDSTR_MAX];
  390. char szClsid[5 + 1 + CLSIDSTR_MAX + 1 + 32];
  391. DWORD dwValueType;
  392. HKEY hClsidKey;
  393. HKEY hInproc32Key;
  394. // Prepare to open the "...Interface\<clsid>" key
  395. FormatCLSID(clsid, szCLSID);
  396. lstrcpy(szClsid, "CLSID\\");
  397. lstrcat(szClsid, szCLSID);
  398. lstrcat(szClsid,"\\");
  399. lstrcat(szClsid, szKey);
  400. // Open the key for the specified clsid and key
  401. if (RegOpenKeyEx(HKEY_CLASSES_ROOT, szClsid, dwRESERVED,
  402. KEY_READ, &hKey) != ERROR_SUCCESS)
  403. {
  404. return FALSE;
  405. }
  406. // Read the value for the specified key
  407. if (RegQueryValueEx(hKey, NULL, NULL, &dwValueType,
  408. (LPBYTE) szValue, pcbValue) != ERROR_SUCCESS)
  409. {
  410. CloseHandle(hKey);
  411. return FALSE;
  412. }
  413. // Close registry handle and return success
  414. CloseHandle(hKey);
  415. return TRUE;
  416. }