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.

290 lines
8.2 KiB

  1. //
  2. // regsvr.cpp
  3. //
  4. #include "private.h"
  5. #include "regsvr.h"
  6. #include "cregkey.h"
  7. #include <advpub.h>
  8. //+------------------------------------------------------------------------
  9. //
  10. // Function: CLSIDToString
  11. //
  12. // Synopsis: Converts a CLSID to an mbcs string.
  13. //
  14. //-------------------------------------------------------------------------
  15. static const BYTE GuidMap[] = {3, 2, 1, 0, '-', 5, 4, '-', 7, 6, '-',
  16. 8, 9, '-', 10, 11, 12, 13, 14, 15};
  17. static const char szDigits[] = "0123456789ABCDEF";
  18. BOOL CLSIDToStringA(REFGUID refGUID, char *pchA)
  19. {
  20. int i;
  21. char *p = pchA;
  22. const BYTE * pBytes = (const BYTE *) &refGUID;
  23. *p++ = '{';
  24. for (i = 0; i < sizeof(GuidMap); i++)
  25. {
  26. if (GuidMap[i] == '-')
  27. {
  28. *p++ = '-';
  29. }
  30. else
  31. {
  32. *p++ = szDigits[ (pBytes[GuidMap[i]] & 0xF0) >> 4 ];
  33. *p++ = szDigits[ (pBytes[GuidMap[i]] & 0x0F) ];
  34. }
  35. }
  36. *p++ = '}';
  37. *p = '\0';
  38. return TRUE;
  39. }
  40. //+------------------------------------------------------------------------
  41. //
  42. // Function: StringToCLSID
  43. //
  44. // Synopsis: Converts a CLSID to an mbcs string.
  45. //
  46. //-------------------------------------------------------------------------
  47. BOOL HexStringToDword(LPCSTR &lpsz, DWORD &Value, int cDigits, WCHAR chDelim)
  48. {
  49. int Count;
  50. Value = 0;
  51. for (Count = 0; Count < cDigits; Count++, lpsz++)
  52. {
  53. if (*lpsz >= '0' && *lpsz <= '9')
  54. Value = (Value << 4) + *lpsz - '0';
  55. else if (*lpsz >= 'A' && *lpsz <= 'F')
  56. Value = (Value << 4) + *lpsz - 'A' + 10;
  57. else if (*lpsz >= 'a' && *lpsz <= 'f')
  58. Value = (Value << 4) + *lpsz - 'a' + 10;
  59. else
  60. return(FALSE);
  61. }
  62. if (chDelim != 0)
  63. return *lpsz++ == chDelim;
  64. else
  65. return TRUE;
  66. }
  67. BOOL StringAToCLSID(char *pchA, GUID *pGUID)
  68. {
  69. DWORD dw;
  70. char *lpsz;
  71. if (*pchA != '{')
  72. return FALSE;
  73. lpsz = ++pchA;
  74. if (!HexStringToDword(lpsz, pGUID->Data1, sizeof(DWORD)*2, '-'))
  75. return FALSE;
  76. if (!HexStringToDword(lpsz, dw, sizeof(WORD)*2, '-'))
  77. return FALSE;
  78. pGUID->Data2 = (WORD)dw;
  79. if (!HexStringToDword(lpsz, dw, sizeof(WORD)*2, '-'))
  80. return FALSE;
  81. pGUID->Data3 = (WORD)dw;
  82. if (!HexStringToDword(lpsz, dw, sizeof(BYTE)*2, 0))
  83. return FALSE;
  84. pGUID->Data4[0] = (BYTE)dw;
  85. if (!HexStringToDword(lpsz, dw, sizeof(BYTE)*2, '-'))
  86. return FALSE;
  87. pGUID->Data4[1] = (BYTE)dw;
  88. if (!HexStringToDword(lpsz, dw, sizeof(BYTE)*2, 0))
  89. return FALSE;
  90. pGUID->Data4[2] = (BYTE)dw;
  91. if (!HexStringToDword(lpsz, dw, sizeof(BYTE)*2, 0))
  92. return FALSE;
  93. pGUID->Data4[3] = (BYTE)dw;
  94. if (!HexStringToDword(lpsz, dw, sizeof(BYTE)*2, 0))
  95. return FALSE;
  96. pGUID->Data4[4] = (BYTE)dw;
  97. if (!HexStringToDword(lpsz, dw, sizeof(BYTE)*2, 0))
  98. return FALSE;
  99. pGUID->Data4[5] = (BYTE)dw;
  100. if (!HexStringToDword(lpsz, dw, sizeof(BYTE)*2, 0))
  101. return FALSE;
  102. pGUID->Data4[6] = (BYTE)dw;
  103. if (!HexStringToDword(lpsz, dw, sizeof(BYTE)*2, '}'))
  104. return FALSE;
  105. pGUID->Data4[7] = (BYTE)dw;
  106. return (*lpsz == '\0');
  107. }
  108. //+------------------------------------------------------------------------
  109. //
  110. // Function: CLSIDToString
  111. //
  112. // Synopsis: Converts a CLSID to an mbcs string.
  113. //
  114. //-------------------------------------------------------------------------
  115. static const WCHAR wszDigits[] = L"0123456789ABCDEF";
  116. BOOL CLSIDToStringW(REFGUID refGUID, WCHAR *pchW)
  117. {
  118. int i;
  119. WCHAR *p = pchW;
  120. const BYTE * pBytes = (const BYTE *) &refGUID;
  121. *p++ = L'{';
  122. for (i = 0; i < sizeof(GuidMap); i++)
  123. {
  124. if (GuidMap[i] == '-')
  125. {
  126. *p++ = L'-';
  127. }
  128. else
  129. {
  130. *p++ = wszDigits[ (pBytes[GuidMap[i]] & 0xF0) >> 4 ];
  131. *p++ = wszDigits[ (pBytes[GuidMap[i]] & 0x0F) ];
  132. }
  133. }
  134. *p++ = L'}';
  135. *p = L'\0';
  136. return TRUE;
  137. }
  138. //RecurseDeleteKey is necessary because on NT RegDeleteKey doesn't work if the
  139. //specified key has subkeys
  140. LONG RecurseDeleteKey(HKEY hParentKey, LPCTSTR lpszKey)
  141. {
  142. HKEY hKey;
  143. LONG lRes;
  144. FILETIME time;
  145. TCHAR szBuffer[256];
  146. DWORD dwSize = sizeof(szBuffer);
  147. if (RegOpenKey(hParentKey, lpszKey, &hKey) != ERROR_SUCCESS)
  148. return ERROR_SUCCESS; // let's assume we couldn't open it because it's not there
  149. lRes = ERROR_SUCCESS;
  150. while (RegEnumKeyEx(hKey, 0, szBuffer, &dwSize, NULL, NULL, NULL, &time)==ERROR_SUCCESS)
  151. {
  152. lRes = RecurseDeleteKey(hKey, szBuffer);
  153. if (lRes != ERROR_SUCCESS)
  154. break;
  155. dwSize = sizeof(szBuffer);
  156. }
  157. RegCloseKey(hKey);
  158. return lRes == ERROR_SUCCESS ? RegDeleteKey(hParentKey, lpszKey) : lRes;
  159. }
  160. // set pszDesc == NULL to unregister, otherwise register
  161. BOOL RegisterServer(REFCLSID clsid, LPCTSTR pszDesc, LPCTSTR pszPath, LPCTSTR pszModel, LPCTSTR pszSoftwareKey)
  162. {
  163. static const TCHAR c_szInfoKeyPrefix[] = TEXT("CLSID\\");
  164. static const TCHAR c_szInProcSvr32[] = TEXT("InProcServer32");
  165. static const TCHAR c_szModelName[] = TEXT("ThreadingModel");
  166. TCHAR achIMEKey[ARRAYSIZE(c_szInfoKeyPrefix) + CLSID_STRLEN];
  167. DWORD dw;
  168. HKEY hKey;
  169. HKEY hSubKey;
  170. BOOL fRet;
  171. if (!CLSIDToStringA(clsid, achIMEKey + ARRAYSIZE(c_szInfoKeyPrefix) - 1))
  172. return FALSE;
  173. memcpy(achIMEKey, c_szInfoKeyPrefix, sizeof(c_szInfoKeyPrefix)-sizeof(TCHAR));
  174. if (pszDesc != NULL)
  175. {
  176. if (fRet = RegCreateKeyEx(HKEY_CLASSES_ROOT, achIMEKey, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hKey, &dw)
  177. == ERROR_SUCCESS)
  178. {
  179. fRet &= RegSetValueEx(hKey, NULL, 0, REG_SZ, (BYTE *)pszDesc, (lstrlen(pszDesc)+1)*sizeof(TCHAR))
  180. == ERROR_SUCCESS;
  181. if (fRet &= RegCreateKeyEx(hKey, c_szInProcSvr32, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hSubKey, &dw)
  182. == ERROR_SUCCESS)
  183. {
  184. fRet &= RegSetValueEx(hSubKey, NULL, 0, REG_SZ, (BYTE *)pszPath, (lstrlen(pszPath)+1)*sizeof(TCHAR)) == ERROR_SUCCESS;
  185. fRet &= RegSetValueEx(hSubKey, c_szModelName, 0, REG_SZ, (BYTE *)pszModel, (lstrlen(pszModel)+1)*sizeof(TCHAR)) == ERROR_SUCCESS;
  186. RegCloseKey(hSubKey);
  187. }
  188. RegCloseKey(hKey);
  189. }
  190. }
  191. else
  192. {
  193. fRet = (RecurseDeleteKey(HKEY_CLASSES_ROOT, achIMEKey) == ERROR_SUCCESS) &&
  194. (pszSoftwareKey == NULL || RecurseDeleteKey(HKEY_LOCAL_MACHINE, pszSoftwareKey) == ERROR_SUCCESS);
  195. }
  196. return fRet;
  197. }
  198. // set pszDesc == NULL to unregister, otherwise register
  199. BOOL RegisterServerW(REFCLSID clsid, const WCHAR *pszDesc, const WCHAR *pszPath, const WCHAR *pszModel, const WCHAR *pszSoftwareKey, const WCHAR *pszMenuTextPUI)
  200. {
  201. static const WCHAR c_wszInfoKeyPrefix[] = L"CLSID\\";
  202. static const WCHAR c_wszInProcSvr32[] = L"InProcServer32";
  203. static const WCHAR c_wszModelName[] = L"ThreadingModel";
  204. static const WCHAR c_wszMenuTextPUI[] = L"MenuTextPUI";
  205. WCHAR achIMEKey[ARRAYSIZE(c_wszInfoKeyPrefix) + CLSID_STRLEN];
  206. CMyRegKey hKey;
  207. CMyRegKey hSubKey;
  208. BOOL fRet = FALSE;
  209. if (!CLSIDToStringW(clsid, achIMEKey + ARRAYSIZE(c_wszInfoKeyPrefix) - 1))
  210. return fRet;
  211. memcpy(achIMEKey, c_wszInfoKeyPrefix, sizeof(c_wszInfoKeyPrefix)-sizeof(WCHAR));
  212. if (pszDesc != NULL)
  213. {
  214. if (fRet = hKey.CreateW(HKEY_CLASSES_ROOT, achIMEKey, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE) == ERROR_SUCCESS)
  215. {
  216. fRet &= hKey.SetValueW(pszDesc) == ERROR_SUCCESS;
  217. if (pszMenuTextPUI)
  218. fRet &= hKey.SetValueW(pszMenuTextPUI, c_wszMenuTextPUI) == ERROR_SUCCESS;
  219. if (fRet &= hSubKey.CreateW(hKey, c_wszInProcSvr32, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE) == ERROR_SUCCESS)
  220. {
  221. fRet &= hSubKey.SetValueW(pszPath) == ERROR_SUCCESS;
  222. fRet &= hSubKey.SetValueW(pszModel, c_wszModelName) == ERROR_SUCCESS;
  223. }
  224. }
  225. }
  226. return fRet;
  227. }