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.

401 lines
10 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1993 - 1993.
  5. //
  6. // File: ccompapi.cxx
  7. //
  8. // Contents: common compobj API Worker routines used by com, stg, scm etc
  9. //
  10. // Classes:
  11. //
  12. // Functions:
  13. //
  14. // History: 31-Dec-93 ErikGav Chicago port
  15. //
  16. //----------------------------------------------------------------------------
  17. #include <windows.h>
  18. #include <ole2sp.h>
  19. #include <ole2com.h>
  20. #include <olesem.hxx>
  21. NAME_SEG(CompApi)
  22. ASSERTDATA
  23. static const BYTE GuidMap[] = { 3, 2, 1, 0, '-', 5, 4, '-', 7, 6, '-',
  24. 8, 9, '-', 10, 11, 12, 13, 14, 15};
  25. static const WCHAR wszDigits[] = L"0123456789ABCDEF";
  26. LPVOID WINAPI PrivHeapAlloc(HANDLE hHeap, DWORD dwFlags, SIZE_T dwBytes);
  27. BOOL WINAPI PrivHeapFree (HANDLE hHeap, DWORD dwFlags, LPVOID lpMem);
  28. HANDLE g_hHeap = 0;
  29. HEAP_ALLOC_ROUTINE *pfnHeapAlloc = PrivHeapAlloc;
  30. HEAP_FREE_ROUTINE *pfnHeapFree = PrivHeapFree;
  31. //+-------------------------------------------------------------------------
  32. //
  33. // Function: PrivHeapAlloc (internal)
  34. //
  35. // Synopsis: Allocate memory from the heap.
  36. //
  37. // Notes: This function handles the first call to PrivMemAlloc.
  38. // This function changes pfnHeapAlloc so that subsequent calls
  39. // to PrivMemAlloc will go directly to HeapAlloc.
  40. //
  41. //--------------------------------------------------------------------------
  42. LPVOID WINAPI PrivHeapAlloc(HANDLE hHeap, DWORD dwFlags, SIZE_T dwBytes)
  43. {
  44. // Fault in g_hHeap if it's not initialized already via MallocInitialize
  45. if (g_hHeap == NULL)
  46. {
  47. g_hHeap = GetProcessHeap();
  48. if (g_hHeap == NULL)
  49. {
  50. return NULL;
  51. }
  52. }
  53. pfnHeapFree = HeapFree;
  54. pfnHeapAlloc = HeapAlloc;
  55. return HeapAlloc(g_hHeap, dwFlags, dwBytes);
  56. }
  57. //+-------------------------------------------------------------------------
  58. //
  59. // Function: PrivHeapFree (internal)
  60. //
  61. // Synopsis: Free memory from the heap.
  62. //
  63. // Notes: lpMem should always be zero. We assume that memory
  64. // freed via PrivMemFree has been allocated via PrivMemAlloc.
  65. // The first call to PrivMemAlloc changes pfnHeapFree.
  66. // Subsequent calls to PrivMemFree go directly to HeapFree.
  67. // Therefore PrivHeapFree should never be called with a
  68. // non-zero lpMem.
  69. //
  70. //--------------------------------------------------------------------------
  71. BOOL WINAPI PrivHeapFree (HANDLE hHeap, DWORD dwFlags, LPVOID lpMem)
  72. {
  73. Win4Assert(lpMem == 0 && "PrivMemFree requires PrivMemAlloc.");
  74. return FALSE;
  75. }
  76. //+-------------------------------------------------------------------------
  77. //
  78. // Function: wStringFromUUID (internal)
  79. //
  80. // Synopsis: converts UUID into xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
  81. //
  82. // Arguments: [rguid] - the guid to convert
  83. // [lpszy] - buffer to hold the results
  84. //
  85. // Returns: Number of characters copied to the buffer.
  86. //
  87. //--------------------------------------------------------------------------
  88. INTERNAL wStringFromUUID(REFGUID rguid, LPWSTR lpsz)
  89. {
  90. int i;
  91. LPWSTR p = lpsz;
  92. const BYTE * pBytes = (const BYTE *) &rguid;
  93. for (i = 0; i < sizeof(GuidMap); i++)
  94. {
  95. if (GuidMap[i] == '-')
  96. {
  97. *p++ = L'-';
  98. }
  99. else
  100. {
  101. *p++ = wszDigits[ (pBytes[GuidMap[i]] & 0xF0) >> 4 ];
  102. *p++ = wszDigits[ (pBytes[GuidMap[i]] & 0x0F) ];
  103. }
  104. }
  105. *p = L'\0';
  106. return S_OK;
  107. }
  108. //+-------------------------------------------------------------------------
  109. //
  110. // Function: HexStringToDword (private)
  111. //
  112. // Synopsis: scan lpsz for a number of hex digits (at most 8); update lpsz
  113. // return value in Value; check for chDelim;
  114. //
  115. // Arguments: [lpsz] - the hex string to convert
  116. // [Value] - the returned value
  117. // [cDigits] - count of digits
  118. //
  119. // Returns: TRUE for success
  120. //
  121. //--------------------------------------------------------------------------
  122. static BOOL HexStringToDword(LPCWSTR FAR& lpsz, DWORD FAR& Value,
  123. int cDigits, WCHAR chDelim)
  124. {
  125. int Count;
  126. Value = 0;
  127. for (Count = 0; Count < cDigits; Count++, lpsz++)
  128. {
  129. if (*lpsz >= '0' && *lpsz <= '9')
  130. Value = (Value << 4) + *lpsz - '0';
  131. else if (*lpsz >= 'A' && *lpsz <= 'F')
  132. Value = (Value << 4) + *lpsz - 'A' + 10;
  133. else if (*lpsz >= 'a' && *lpsz <= 'f')
  134. Value = (Value << 4) + *lpsz - 'a' + 10;
  135. else
  136. return(FALSE);
  137. }
  138. if (chDelim != 0)
  139. return *lpsz++ == chDelim;
  140. else
  141. return TRUE;
  142. }
  143. //+-------------------------------------------------------------------------
  144. //
  145. // Function: wUUIDFromString (internal)
  146. //
  147. // Synopsis: Parse UUID such as 00000000-0000-0000-0000-000000000000
  148. //
  149. // Arguments: [lpsz] - Supplies the UUID string to convert
  150. // [pguid] - Returns the GUID.
  151. //
  152. // Returns: TRUE if successful
  153. //
  154. //--------------------------------------------------------------------------
  155. INTERNAL_(BOOL) wUUIDFromString(LPCWSTR lpsz, LPGUID pguid)
  156. {
  157. DWORD dw;
  158. if (!HexStringToDword(lpsz, pguid->Data1, sizeof(DWORD)*2, '-'))
  159. return FALSE;
  160. if (!HexStringToDword(lpsz, dw, sizeof(WORD)*2, '-'))
  161. return FALSE;
  162. pguid->Data2 = (WORD)dw;
  163. if (!HexStringToDword(lpsz, dw, sizeof(WORD)*2, '-'))
  164. return FALSE;
  165. pguid->Data3 = (WORD)dw;
  166. if (!HexStringToDword(lpsz, dw, sizeof(BYTE)*2, 0))
  167. return FALSE;
  168. pguid->Data4[0] = (BYTE)dw;
  169. if (!HexStringToDword(lpsz, dw, sizeof(BYTE)*2, '-'))
  170. return FALSE;
  171. pguid->Data4[1] = (BYTE)dw;
  172. if (!HexStringToDword(lpsz, dw, sizeof(BYTE)*2, 0))
  173. return FALSE;
  174. pguid->Data4[2] = (BYTE)dw;
  175. if (!HexStringToDword(lpsz, dw, sizeof(BYTE)*2, 0))
  176. return FALSE;
  177. pguid->Data4[3] = (BYTE)dw;
  178. if (!HexStringToDword(lpsz, dw, sizeof(BYTE)*2, 0))
  179. return FALSE;
  180. pguid->Data4[4] = (BYTE)dw;
  181. if (!HexStringToDword(lpsz, dw, sizeof(BYTE)*2, 0))
  182. return FALSE;
  183. pguid->Data4[5] = (BYTE)dw;
  184. if (!HexStringToDword(lpsz, dw, sizeof(BYTE)*2, 0))
  185. return FALSE;
  186. pguid->Data4[6] = (BYTE)dw;
  187. if (!HexStringToDword(lpsz, dw, sizeof(BYTE)*2, 0))
  188. return FALSE;
  189. pguid->Data4[7] = (BYTE)dw;
  190. return TRUE;
  191. }
  192. //+-------------------------------------------------------------------------
  193. //
  194. // Function: wGUIDFromString (internal)
  195. //
  196. // Synopsis: Parse GUID such as {00000000-0000-0000-0000-000000000000}
  197. //
  198. // Arguments: [lpsz] - the guid string to convert
  199. // [pguid] - guid to return
  200. //
  201. // Returns: TRUE if successful
  202. //
  203. // CODEWORK: these are common with com\class\compapi.cxx ..
  204. //
  205. //--------------------------------------------------------------------------
  206. INTERNAL_(BOOL) wGUIDFromString(LPCWSTR lpsz, LPGUID pguid)
  207. {
  208. DWORD dw;
  209. if (*lpsz++ != '{' )
  210. return FALSE;
  211. if (wUUIDFromString(lpsz, pguid) != TRUE)
  212. return FALSE;
  213. lpsz +=36;
  214. if (*lpsz++ != '}' )
  215. return FALSE;
  216. if (*lpsz != '\0') // check for zero terminated string - test bug #18307
  217. {
  218. return FALSE;
  219. }
  220. return TRUE;
  221. }
  222. //+-------------------------------------------------------------------------
  223. //
  224. // Function: wStringFromGUID2 (internal)
  225. //
  226. // Synopsis: converts GUID into {...} form without leading identifier;
  227. //
  228. // Arguments: [rguid] - the guid to convert
  229. // [lpszy] - buffer to hold the results
  230. // [cbMax] - sizeof the buffer
  231. //
  232. // Returns: amount of data copied to lpsz if successful
  233. // 0 if buffer too small.
  234. //
  235. //--------------------------------------------------------------------------
  236. INTERNAL_(int) wStringFromGUID2(REFGUID rguid, LPWSTR lpsz, int cbMax)
  237. {
  238. int i;
  239. LPWSTR p = lpsz;
  240. if (cbMax < GUIDSTR_MAX)
  241. return 0;
  242. *p++ = L'{';
  243. wStringFromUUID(rguid, p);
  244. p += 36;
  245. *p++ = L'}';
  246. *p = L'\0';
  247. return GUIDSTR_MAX;
  248. }
  249. static const CHAR szDigits[] = "0123456789ABCDEF";
  250. //+-------------------------------------------------------------------------
  251. //
  252. // Function: wStringFromGUID2A (internal)
  253. //
  254. // Synopsis: Ansi version of wStringFromGUID2 (for Win95 Optimizations)
  255. //
  256. // Arguments: [rguid] - the guid to convert
  257. // [lpszy] - buffer to hold the results
  258. // [cbMax] - sizeof the buffer
  259. //
  260. // Returns: amount of data copied to lpsz if successful
  261. // 0 if buffer too small.
  262. //
  263. //--------------------------------------------------------------------------
  264. INTERNAL_(int) wStringFromGUID2A(REFGUID rguid, LPSTR lpsz, int cbMax) // internal
  265. {
  266. int i;
  267. LPSTR p = lpsz;
  268. const BYTE * pBytes = (const BYTE *) &rguid;
  269. *p++ = '{';
  270. for (i = 0; i < sizeof(GuidMap); i++)
  271. {
  272. if (GuidMap[i] == '-')
  273. {
  274. *p++ = '-';
  275. }
  276. else
  277. {
  278. *p++ = szDigits[ (pBytes[GuidMap[i]] & 0xF0) >> 4 ];
  279. *p++ = szDigits[ (pBytes[GuidMap[i]] & 0x0F) ];
  280. }
  281. }
  282. *p++ = '}';
  283. *p = '\0';
  284. return GUIDSTR_MAX;
  285. }
  286. //+---------------------------------------------------------------------------
  287. //
  288. // Function: FormatHexNumA
  289. //
  290. // Synopsis: Given a value, and a count of characters, translate
  291. // the value into a hex string. This is the ANSI version
  292. //
  293. // Arguments: [ulValue] -- Value to convert
  294. // [chChars] -- Number of characters to format
  295. // [pchStr] -- Pointer to output buffer
  296. //
  297. // Requires: pwcStr must be valid for chChars
  298. //
  299. // History: 12-Dec-95 KevinRo Created
  300. //
  301. // Notes:
  302. //
  303. //----------------------------------------------------------------------------
  304. void FormatHexNumA( unsigned long ulValue, unsigned long chChars, char *pchStr)
  305. {
  306. while (chChars--)
  307. {
  308. pchStr[chChars] = (char) szDigits[ulValue & 0xF];
  309. ulValue = ulValue >> 4;
  310. }
  311. }
  312. //+---------------------------------------------------------------------------
  313. //
  314. // Function: FormatHexNumW
  315. //
  316. // Synopsis: Given a value, and a count of characters, translate
  317. // the value into a hex string. This is the WCHAR version
  318. //
  319. // Arguments: [ulValue] -- Value to convert
  320. // [chChars] -- Number of characters to format
  321. // [pwcStr] -- Pointer to output buffer
  322. //
  323. // Requires: pwcStr must be valid for chChars
  324. //
  325. // History: 12-Dec-95 KevinRo Created
  326. //
  327. // Notes:
  328. //
  329. //----------------------------------------------------------------------------
  330. void FormatHexNumW( unsigned long ulValue, unsigned long chChars, WCHAR *pwcStr)
  331. {
  332. while (chChars--)
  333. {
  334. pwcStr[chChars] = (char) wszDigits[ulValue & 0xF];
  335. ulValue = ulValue >> 4;
  336. }
  337. }