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.

225 lines
6.7 KiB

  1. //=--------------------------------------------------------------------------=
  2. // RegUnReg.cpp
  3. //=--------------------------------------------------------------------------=
  4. // Copyright 1995-1996 Microsoft Corporation. All Rights Reserved.
  5. //
  6. // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
  7. // ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
  8. // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
  9. // PARTICULAR PURPOSE.
  10. //=--------------------------------------------------------------------------=
  11. //
  12. #include "ulsp.h"
  13. #include "regunreg.h"
  14. //=--------------------------------------------------------------------------=
  15. // miscellaneous [useful] numerical constants
  16. //=--------------------------------------------------------------------------=
  17. // the length of a guid once printed out with -'s, leading and trailing bracket,
  18. // plus 1 for NULL
  19. //
  20. #define GUID_STR_LEN 40
  21. #define CLEANUP_ON_ERROR(l) if (l != ERROR_SUCCESS) goto CleanUp
  22. //=--------------------------------------------------------------------------=
  23. // StringFromGuid
  24. //=--------------------------------------------------------------------------=
  25. // returns a string from a CLSID or GUID
  26. //
  27. // Parameters:
  28. // REFIID - [in] clsid to make string out of.
  29. // LPTSTR - [in] buffer in which to place resultant GUID.
  30. //
  31. // Output:
  32. // int - number of chars written out.
  33. //
  34. // Notes:
  35. //
  36. static int StringFromGuid
  37. (
  38. REFIID riid,
  39. LPTSTR pszBuf
  40. )
  41. {
  42. return wsprintf(pszBuf, TEXT("{%08lX-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}"),
  43. riid.Data1,
  44. riid.Data2, riid.Data3, riid.Data4[0], riid.Data4[1], riid.Data4[2],
  45. riid.Data4[3], riid.Data4[4], riid.Data4[5], riid.Data4[6], riid.Data4[7]);
  46. }
  47. //=--------------------------------------------------------------------------=
  48. // RegisterUnknownObject
  49. //=--------------------------------------------------------------------------=
  50. // registers a simple CoCreatable object. nothing terribly serious.
  51. // we add the following information to the registry:
  52. //
  53. // HKEY_CLASSES_ROOT\CLSID\<CLSID> = <ObjectName> Object
  54. // HKEY_CLASSES_ROOT\CLSID\<CLSID>\InprocServer32 = <path to local server>
  55. //
  56. // Parameters:
  57. // LPCSTR - [in] Object Name
  58. // REFCLSID - [in] CLSID of the object
  59. //
  60. // Output:
  61. // BOOL - FALSE means couldn't register it all
  62. //
  63. // Notes:
  64. //
  65. BOOL RegisterUnknownObject
  66. (
  67. LPCTSTR pszObjectName,
  68. REFCLSID riidObject
  69. )
  70. {
  71. HKEY hk = NULL, hkSub = NULL;
  72. TCHAR szGuidStr[GUID_STR_LEN];
  73. DWORD dwPathLen, dwDummy;
  74. TCHAR szScratch[MAX_PATH];
  75. long l;
  76. // clean out any garbage
  77. //
  78. UnregisterUnknownObject(riidObject);
  79. // HKEY_CLASSES_ROOT\CLSID\<CLSID> = <ObjectName> Object
  80. // HKEY_CLASSES_ROOT\CLSID\<CLSID>\InprocServer32 = <path to local server>
  81. // HKEY_CLASSES_ROOT\CLSID\<CLSID>\InprocServer32 @ThreadingModel = Apartment
  82. //
  83. if (!StringFromGuid(riidObject, szGuidStr)) goto CleanUp;
  84. wsprintf(szScratch, TEXT("CLSID\\%s"), szGuidStr);
  85. l = RegCreateKeyEx(HKEY_CLASSES_ROOT, szScratch, 0, TEXT(""), REG_OPTION_NON_VOLATILE,
  86. KEY_READ | KEY_WRITE, NULL, &hk, &dwDummy);
  87. CLEANUP_ON_ERROR(l);
  88. wsprintf(szScratch, TEXT("%s Object"), pszObjectName);
  89. l = RegSetValueEx(hk, NULL, 0, REG_SZ, (BYTE *)szScratch,
  90. (lstrlen(szScratch) + 1)*sizeof(TCHAR));
  91. CLEANUP_ON_ERROR(l);
  92. l = RegCreateKeyEx(hk, TEXT("InprocServer32"), 0, TEXT(""), REG_OPTION_NON_VOLATILE,
  93. KEY_READ | KEY_WRITE, NULL, &hkSub, &dwDummy);
  94. CLEANUP_ON_ERROR(l);
  95. dwPathLen = GetModuleFileName(g_hInstance, szScratch, sizeof(szScratch)/sizeof(TCHAR));
  96. if (!dwPathLen) goto CleanUp;
  97. l = RegSetValueEx(hkSub, NULL, 0, REG_SZ, (BYTE *)szScratch, (dwPathLen + 1)*sizeof(TCHAR));
  98. CLEANUP_ON_ERROR(l);
  99. l = RegSetValueEx(hkSub, TEXT("ThreadingModel"), 0, REG_SZ, (BYTE *)TEXT("Apartment"),
  100. sizeof(TEXT("Apartment")));
  101. CLEANUP_ON_ERROR(l);
  102. RegCloseKey(hkSub);
  103. RegCloseKey(hk);
  104. return TRUE;
  105. // we are not very happy!
  106. //
  107. CleanUp:
  108. if (hk) RegCloseKey(hk);
  109. if (hkSub) RegCloseKey(hkSub);
  110. return FALSE;
  111. }
  112. //=--------------------------------------------------------------------------=
  113. // UnregisterUnknownObject
  114. //=--------------------------------------------------------------------------=
  115. // cleans up all the stuff that RegisterUnknownObject puts in the
  116. // registry.
  117. //
  118. // Parameters:
  119. // REFCLSID - [in] CLSID of the object
  120. //
  121. // Output:
  122. // BOOL - FALSE means not all of it was registered
  123. //
  124. // Notes:
  125. // - WARNING: this routine will blow away all other keys under the CLSID
  126. // for this object. mildly anti-social, but likely not a problem.
  127. //
  128. BOOL UnregisterUnknownObject
  129. (
  130. REFCLSID riidObject
  131. )
  132. {
  133. TCHAR szScratch[MAX_PATH];
  134. HKEY hk;
  135. BOOL f;
  136. long l;
  137. // delete everybody of the form
  138. // HKEY_CLASSES_ROOT\CLSID\<CLSID> [\] *
  139. //
  140. if (!StringFromGuid(riidObject, szScratch))
  141. return FALSE;
  142. l = RegOpenKeyEx(HKEY_CLASSES_ROOT, TEXT("CLSID"), 0, KEY_ALL_ACCESS, &hk);
  143. if (l != ERROR_SUCCESS) return FALSE;
  144. f = DeleteKeyAndSubKeys(hk, szScratch);
  145. RegCloseKey(hk);
  146. return f;
  147. }
  148. //=--------------------------------------------------------------------------=
  149. // DeleteKeyAndSubKeys
  150. //=--------------------------------------------------------------------------=
  151. // delete's a key and all of it's subkeys.
  152. //
  153. // Parameters:
  154. // HKEY - [in] delete the descendant specified
  155. // LPTSTR - [in] i'm the descendant specified
  156. //
  157. // Output:
  158. // BOOL - TRUE OK, FALSE baaaad.
  159. //
  160. // Notes:
  161. // - I don't feel too bad about implementing this recursively, since the
  162. // depth isn't likely to get all the great.
  163. // - Despite the win32 docs claiming it does, RegDeleteKey doesn't seem to
  164. // work with sub-keys under windows 95.
  165. //
  166. BOOL DeleteKeyAndSubKeys
  167. (
  168. HKEY hkIn,
  169. LPTSTR pszSubKey
  170. )
  171. {
  172. HKEY hk;
  173. TCHAR szTmp[MAX_PATH];
  174. DWORD dwTmpSize;
  175. long l;
  176. BOOL f;
  177. int x;
  178. l = RegOpenKeyEx(hkIn, pszSubKey, 0, KEY_ALL_ACCESS, &hk);
  179. if (l != ERROR_SUCCESS) return FALSE;
  180. // loop through all subkeys, blowing them away.
  181. //
  182. f = TRUE;
  183. x = 0;
  184. while (f) {
  185. dwTmpSize = MAX_PATH;
  186. l = RegEnumKeyEx(hk, x, szTmp, &dwTmpSize, 0, NULL, NULL, NULL);
  187. if (l != ERROR_SUCCESS) break;
  188. f = DeleteKeyAndSubKeys(hk, szTmp);
  189. x++;
  190. }
  191. // there are no subkeys left, [or we'll just generate an error and return FALSE].
  192. // let's go blow this dude away.
  193. //
  194. RegCloseKey(hk);
  195. l = RegDeleteKey(hkIn, pszSubKey);
  196. return (l == ERROR_SUCCESS) ? TRUE : FALSE;
  197. }