Leaked source code of windows server 2003
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.

281 lines
7.8 KiB

  1. //---------------------------------------------------------------------------
  2. //
  3. // Copyright (c) Microsoft Corporation 1991-1993
  4. //
  5. // File: ole2dup.c
  6. //
  7. // This file contains all the duplicated code from OLE 2.0 DLLs to avoid
  8. // any link to their DLLs from the shell. If we decided to have links to
  9. // them, we need to delete these files.
  10. //
  11. // History:
  12. // 04-16-97 AndyP moved parts to shlwapi (from shell32)
  13. // 12-29-92 SatoNa Created.
  14. //
  15. //---------------------------------------------------------------------------
  16. #include "priv.h"
  17. //
  18. // SHStringFromGUIDA
  19. //
  20. // converts GUID into (...) form without leading identifier; returns
  21. // amount of data copied to lpsz if successful; 0 if buffer too small.
  22. //
  23. // An endian-dependant map of what bytes go where in the GUID
  24. // text representation.
  25. //
  26. // Do NOT use the TEXT() macro in GuidMap... they're intended to be bytes
  27. //
  28. static const BYTE c_rgbGuidMap[] = { 3, 2, 1, 0, '-', 5, 4, '-', 7, 6, '-',
  29. 8, 9, '-', 10, 11, 12, 13, 14, 15 };
  30. static const CHAR c_szDigitsA[] = "0123456789ABCDEF";
  31. static const WCHAR c_szDigitsW[] = TEXTW("0123456789ABCDEF");
  32. STDAPI_(int)
  33. SHStringFromGUIDA(
  34. UNALIGNED REFGUID rguid,
  35. LPSTR psz,
  36. int cchMax)
  37. {
  38. int i;
  39. const BYTE * pBytes = (const BYTE *) rguid;
  40. if (cchMax < GUIDSTR_MAX)
  41. return 0;
  42. #ifdef BIG_ENDIAN
  43. // This is the slow, but portable version
  44. wnsprintf(psz, cchMax,"{%08lX-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
  45. rguid->Data1, rguid->Data2, rguid->Data3,
  46. rguid->Data4[0], rguid->Data4[1],
  47. rguid->Data4[2], rguid->Data4[3],
  48. rguid->Data4[4], rguid->Data4[5],
  49. rguid->Data4[6], rguid->Data4[7]);
  50. #else
  51. // The following algorithm is faster than the wsprintf.
  52. *psz++ = '{';
  53. for (i = 0; i < sizeof(c_rgbGuidMap); i++)
  54. {
  55. if (c_rgbGuidMap[i] == '-') // don't TEXT() this line
  56. {
  57. *psz++ = '-';
  58. }
  59. else
  60. {
  61. // Convert a byte-value into a character representation
  62. *psz++ = c_szDigitsA[ (pBytes[c_rgbGuidMap[i]] & 0xF0) >> 4 ];
  63. *psz++ = c_szDigitsA[ (pBytes[c_rgbGuidMap[i]] & 0x0F) ];
  64. }
  65. }
  66. *psz++ = '}';
  67. *psz = '\0';
  68. #endif /* !BIG_ENDIAN */
  69. return GUIDSTR_MAX;
  70. }
  71. STDAPI_(int)
  72. SHStringFromGUIDW(
  73. UNALIGNED REFGUID rguid,
  74. LPWSTR psz,
  75. int cchMax)
  76. {
  77. int i;
  78. const BYTE * pBytes = (const BYTE *) rguid;
  79. if (cchMax < GUIDSTR_MAX)
  80. return 0;
  81. #ifdef BIG_ENDIAN
  82. // This is the slow, but portable version
  83. wnsprintfW(psz, cchMax, L"{%08lX-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
  84. rguid->Data1, rguid->Data2, rguid->Data3,
  85. rguid->Data4[0], rguid->Data4[1],
  86. rguid->Data4[2], rguid->Data4[3],
  87. rguid->Data4[4], rguid->Data4[5],
  88. rguid->Data4[6], rguid->Data4[7]);
  89. #else
  90. // The following algorithm is faster than the wsprintf.
  91. *psz++ = TEXTW('{');
  92. for (i = 0; i < sizeof(c_rgbGuidMap); i++)
  93. {
  94. if (c_rgbGuidMap[i] == '-') // don't TEXT() this line
  95. {
  96. *psz++ = TEXTW('-');
  97. }
  98. else
  99. {
  100. // Convert a byte-value into a character representation
  101. *psz++ = c_szDigitsW[ (pBytes[c_rgbGuidMap[i]] & 0xF0) >> 4 ];
  102. *psz++ = c_szDigitsW[ (pBytes[c_rgbGuidMap[i]] & 0x0F) ];
  103. }
  104. }
  105. *psz++ = TEXTW('}');
  106. *psz = TEXTW('\0');
  107. #endif /* !BIG_ENDIAN */
  108. return GUIDSTR_MAX;
  109. }
  110. // this makes sure the DLL for the given clsid stays in memory
  111. // this is needed because we violate COM rules and hold apparment objects
  112. // across the lifetime of appartment threads. these objects really need
  113. // to be free threaded (we have always treated them as such)
  114. //
  115. // Look in the registry and pull out the name of the DLL who owns
  116. // the CLSID. We must pull the DLL name as unicode in case the
  117. // DLL name contains unicode characters.
  118. //
  119. STDAPI_(HINSTANCE) SHPinDllOfCLSID(const CLSID *pclsid)
  120. {
  121. HKEY hk;
  122. DWORD dwSize;
  123. HINSTANCE hinst = NULL;
  124. TCHAR szClass[GUIDSTR_MAX + 64]; // CLSID\{...}\InProcServer32
  125. WCHAR szDllPath[MAX_PATH];
  126. if (SUCCEEDED(StringCchCopy(szClass, ARRAYSIZE(szClass), TEXT("CLSID\\"))) &&
  127. SHStringFromGUID(pclsid, szClass + 6, ARRAYSIZE(szClass) - 6) && // 6 = strlen("CLSID\\")
  128. SUCCEEDED(StringCchCat(szClass, ARRAYSIZE(szClass), TEXT("\\InProcServer32"))))
  129. {
  130. if (RegOpenKeyEx(HKEY_CLASSES_ROOT, szClass, 0, KEY_QUERY_VALUE, &hk) == ERROR_SUCCESS)
  131. {
  132. // Explicitly read as unicode. SHQueryValueEx handles REG_EXPAND_SZ
  133. dwSize = sizeof(szDllPath);
  134. if (SHQueryValueExW(hk, 0, 0, 0, szDllPath, &dwSize) == ERROR_SUCCESS)
  135. {
  136. hinst = LoadLibraryExW(szDllPath, NULL, 0);
  137. }
  138. RegCloseKey(hk);
  139. }
  140. }
  141. return hinst;
  142. }
  143. // scan psz for a number of hex digits (at most 8); update psz, return
  144. // value in Value; check for chDelim; return TRUE for success.
  145. BOOL HexStringToDword(LPCTSTR * ppsz, DWORD * lpValue, int cDigits, TCHAR chDelim)
  146. {
  147. int ich;
  148. LPCTSTR psz = *ppsz;
  149. DWORD Value = 0;
  150. BOOL fRet = TRUE;
  151. for (ich = 0; ich < cDigits; ich++)
  152. {
  153. TCHAR ch = psz[ich];
  154. if (InRange(ch, TEXT('0'), TEXT('9')))
  155. {
  156. Value = (Value << 4) + ch - TEXT('0');
  157. }
  158. else if ( InRange( (ch |= (TEXT('a')-TEXT('A'))), TEXT('a'), TEXT('f')) )
  159. {
  160. Value = (Value << 4) + ch - TEXT('a') + 10;
  161. }
  162. else
  163. return(FALSE);
  164. }
  165. if (chDelim)
  166. {
  167. fRet = (psz[ich++] == chDelim);
  168. }
  169. *lpValue = Value;
  170. *ppsz = psz+ich;
  171. return fRet;
  172. }
  173. // parse above format; return TRUE if succesful; always writes over *pguid.
  174. STDAPI_(BOOL) GUIDFromString(LPCTSTR psz, GUID *pguid)
  175. {
  176. DWORD dw;
  177. if (*psz++ != TEXT('{') /*}*/ )
  178. return FALSE;
  179. if (!HexStringToDword(&psz, &pguid->Data1, sizeof(DWORD)*2, TEXT('-')))
  180. return FALSE;
  181. if (!HexStringToDword(&psz, &dw, sizeof(WORD)*2, TEXT('-')))
  182. return FALSE;
  183. pguid->Data2 = (WORD)dw;
  184. if (!HexStringToDword(&psz, &dw, sizeof(WORD)*2, TEXT('-')))
  185. return FALSE;
  186. pguid->Data3 = (WORD)dw;
  187. if (!HexStringToDword(&psz, &dw, sizeof(BYTE)*2, 0))
  188. return FALSE;
  189. pguid->Data4[0] = (BYTE)dw;
  190. if (!HexStringToDword(&psz, &dw, sizeof(BYTE)*2, TEXT('-')))
  191. return FALSE;
  192. pguid->Data4[1] = (BYTE)dw;
  193. if (!HexStringToDword(&psz, &dw, sizeof(BYTE)*2, 0))
  194. return FALSE;
  195. pguid->Data4[2] = (BYTE)dw;
  196. if (!HexStringToDword(&psz, &dw, sizeof(BYTE)*2, 0))
  197. return FALSE;
  198. pguid->Data4[3] = (BYTE)dw;
  199. if (!HexStringToDword(&psz, &dw, sizeof(BYTE)*2, 0))
  200. return FALSE;
  201. pguid->Data4[4] = (BYTE)dw;
  202. if (!HexStringToDword(&psz, &dw, sizeof(BYTE)*2, 0))
  203. return FALSE;
  204. pguid->Data4[5] = (BYTE)dw;
  205. if (!HexStringToDword(&psz, &dw, sizeof(BYTE)*2, 0))
  206. return FALSE;
  207. pguid->Data4[6] = (BYTE)dw;
  208. if (!HexStringToDword(&psz, &dw, sizeof(BYTE)*2, /*(*/ TEXT('}')))
  209. return FALSE;
  210. pguid->Data4[7] = (BYTE)dw;
  211. return TRUE;
  212. }
  213. #ifdef UNICODE
  214. LWSTDAPI_(BOOL) GUIDFromStringA(LPCSTR psz, GUID *pguid)
  215. {
  216. TCHAR sz[GUIDSTR_MAX];
  217. SHAnsiToTChar(psz, sz, SIZECHARS(sz));
  218. return GUIDFromString(sz, pguid);
  219. }
  220. #else
  221. LWSTDAPI_(BOOL) GUIDFromStringW(LPCWSTR psz, GUID *pguid)
  222. {
  223. TCHAR sz[GUIDSTR_MAX];
  224. SHUnicodeToAnsi(psz, sz, SIZECHARS(sz));
  225. return GUIDFromString(sz, pguid);
  226. }
  227. #endif // UNICODE