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.

283 lines
6.3 KiB

  1. // Copyright (c) 1998-1999 Microsoft Corporation
  2. // oledll.cpp
  3. //
  4. // Handle standard methods for OLE server DLL
  5. //
  6. #include <objbase.h>
  7. #include "debug.h"
  8. #include <iostream.h>
  9. #include "oledll.h"
  10. #ifdef UNICODE
  11. #ifndef UNDER_CE
  12. #error DirectMusic Win NT/9x must be compiled without UNICODE
  13. #endif
  14. #endif
  15. static const TCHAR g_szCLSID[] = TEXT("CLSID");
  16. static const TCHAR g_szCLSIDSlash[] = TEXT("CLSID\\");
  17. static const TCHAR g_szInProc32[] = TEXT("InProcServer32");
  18. static const TCHAR g_szProgIDKey[] = TEXT("ProgID");
  19. static const TCHAR g_szVerIndProgIDKey[] = TEXT("VersionIndependentProgID");
  20. static const TCHAR g_szCurVer[] = TEXT("CurVer");
  21. static const TCHAR g_szThreadingModel[] = TEXT("ThreadingModel");
  22. static const TCHAR g_szBoth[] = TEXT("Both");
  23. static const int CLSID_STRING_SIZE = 39;
  24. static LONG RegSetDefValue(LPCTSTR pstrKey, LPCTSTR pstrSubkey, LPCTSTR pstrValueName, LPCTSTR pstrValue);
  25. static void RegRemoveSubtree(HKEY hk, LPCTSTR pstrChild);
  26. STDAPI
  27. RegisterServer(HMODULE hModule,
  28. const CLSID &clsid,
  29. const TCHAR *szFriendlyName,
  30. const TCHAR *szVerIndProgID,
  31. const TCHAR *szProgID)
  32. {
  33. TCHAR szCLSID[CLSID_STRING_SIZE];
  34. HRESULT hr;
  35. LONG lr;
  36. hr = CLSIDToStr(clsid, szCLSID, sizeof(szCLSID));
  37. if (!SUCCEEDED(hr)) {
  38. return hr;
  39. }
  40. TCHAR szClsKey[256];
  41. lstrcpy(szClsKey, g_szCLSIDSlash);
  42. lstrcat(szClsKey, szCLSID);
  43. TCHAR szModule[512];
  44. lr = ::GetModuleFileName(hModule, szModule, sizeof(szModule));
  45. assert(lr);
  46. lr = 0;
  47. lr |= RegSetDefValue(szClsKey, NULL, NULL, szFriendlyName);
  48. lr |= RegSetDefValue(szClsKey, g_szInProc32, NULL, szModule);
  49. lr |= RegSetDefValue(szClsKey, g_szInProc32, g_szThreadingModel, g_szBoth);
  50. lr |= RegSetDefValue(szClsKey, g_szProgIDKey, NULL, szProgID);
  51. lr |= RegSetDefValue(szClsKey, g_szVerIndProgIDKey, NULL, szVerIndProgID);
  52. lr |= RegSetDefValue(szVerIndProgID, NULL, NULL, szFriendlyName);
  53. lr |= RegSetDefValue(szVerIndProgID, g_szCLSID, NULL, szCLSID);
  54. lr |= RegSetDefValue(szVerIndProgID, g_szCurVer, NULL, szProgID);
  55. lr |= RegSetDefValue(szProgID, NULL, NULL, szFriendlyName);
  56. lr |= RegSetDefValue(szProgID, g_szCLSID, NULL, szCLSID);
  57. #if 0
  58. if (lr) {
  59. UnregisterServer(clsid,
  60. szFriendlyName,
  61. szVerIndProgID,
  62. szProgID);
  63. // ???
  64. //
  65. return S_OK;
  66. }
  67. #endif
  68. return S_OK;
  69. }
  70. STDAPI
  71. UnregisterServer(const CLSID &clsid,
  72. const TCHAR *szFriendlyName,
  73. const TCHAR *szVerIndProgID,
  74. const TCHAR *szProgID)
  75. {
  76. TCHAR szCLSID[CLSID_STRING_SIZE];
  77. HRESULT hr;
  78. hr = CLSIDToStr(clsid, szCLSID, sizeof(szCLSID));
  79. if (!SUCCEEDED(hr)) {
  80. return hr;
  81. }
  82. TCHAR szClsKey[256];
  83. lstrcpy(szClsKey, g_szCLSIDSlash);
  84. lstrcat(szClsKey, szCLSID);
  85. RegRemoveSubtree(HKEY_CLASSES_ROOT, szClsKey);
  86. RegRemoveSubtree(HKEY_CLASSES_ROOT, szVerIndProgID);
  87. RegRemoveSubtree(HKEY_CLASSES_ROOT, szProgID);
  88. return S_OK;
  89. }
  90. BOOL
  91. GetCLSIDRegValue(const CLSID &clsid,
  92. const TCHAR *szKey,
  93. LPVOID pValue,
  94. LPDWORD pcbValue)
  95. {
  96. TCHAR szCLSID[CLSID_STRING_SIZE];
  97. HRESULT hr;
  98. HKEY hk;
  99. DWORD dw;
  100. hr = CLSIDToStr(clsid, szCLSID, sizeof(szCLSID));
  101. if (!SUCCEEDED(hr)) {
  102. return FALSE;
  103. }
  104. TCHAR szClsKey[256];
  105. lstrcpy(szClsKey, g_szCLSIDSlash);
  106. lstrcat(szClsKey, szCLSID);
  107. lstrcat(szClsKey, TEXT("\\"));
  108. if (szKey)
  109. {
  110. lstrcat(szClsKey, szKey);
  111. }
  112. if (RegOpenKeyEx(HKEY_CLASSES_ROOT,
  113. szClsKey,
  114. 0,
  115. KEY_READ,
  116. &hk)) {
  117. return FALSE;
  118. }
  119. if (RegQueryValueEx(hk,
  120. NULL,
  121. NULL,
  122. &dw,
  123. (LPBYTE)pValue,
  124. pcbValue)) {
  125. RegCloseKey(hk);
  126. return FALSE;
  127. }
  128. RegCloseKey(hk);
  129. return TRUE;
  130. }
  131. HRESULT
  132. CLSIDToStr(const CLSID &clsid,
  133. TCHAR *szStr,
  134. int cbStr)
  135. {
  136. // XXX What to return here?
  137. //
  138. assert(cbStr >= CLSID_STRING_SIZE);
  139. LPOLESTR wszCLSID = NULL;
  140. HRESULT hr = StringFromCLSID(clsid, &wszCLSID);
  141. if (!SUCCEEDED(hr)) {
  142. return hr;
  143. }
  144. #ifdef UNICODE
  145. lstrcpy(szStr, wszCLSID);
  146. #else
  147. // Covert from wide characters to non-wide.
  148. wcstombs(szStr, wszCLSID, cbStr);
  149. #endif
  150. // Free memory.
  151. CoTaskMemFree(wszCLSID);
  152. return S_OK;
  153. }
  154. HRESULT
  155. StrToCLSID(TCHAR *szStr,
  156. CLSID &clsid,
  157. int cbStr)
  158. {
  159. #ifdef UNICODE
  160. return CLSIDFromString(szStr, &clsid);
  161. #else
  162. WCHAR wsz[512];
  163. if (cbStr > 512)
  164. {
  165. cbStr = 512;
  166. }
  167. mbstowcs(wsz, szStr, cbStr);
  168. return CLSIDFromString(wsz, &clsid);
  169. #endif
  170. }
  171. static LONG
  172. RegSetDefValue(LPCTSTR pstrKey,
  173. LPCTSTR pstrSubkey,
  174. LPCTSTR pstrValueName,
  175. LPCTSTR pstrValue)
  176. {
  177. HKEY hk;
  178. LONG lr;
  179. TCHAR sz[1024];
  180. LPCTSTR pstr;
  181. if (!pstrSubkey) {
  182. pstr = pstrKey;
  183. } else {
  184. lstrcpy(sz, pstrKey);
  185. lstrcat(sz, TEXT("\\"));
  186. lstrcat(sz, pstrSubkey);
  187. pstr = sz;
  188. }
  189. lr = RegCreateKeyEx(HKEY_CLASSES_ROOT,
  190. pstr,
  191. 0,
  192. NULL,
  193. REG_OPTION_NON_VOLATILE,
  194. KEY_ALL_ACCESS,
  195. NULL,
  196. &hk,
  197. NULL);
  198. if (lr) {
  199. return lr;
  200. }
  201. lr = RegSetValueEx(hk,
  202. pstrValueName,
  203. 0,
  204. REG_SZ,
  205. (CONST BYTE*)pstrValue,
  206. 1+lstrlen(pstrValue));
  207. RegCloseKey(hk);
  208. return lr;
  209. }
  210. static void
  211. RegRemoveSubtree(HKEY hk,
  212. LPCTSTR pstrChild)
  213. {
  214. LONG lResult;
  215. HKEY hkChild;
  216. lResult = RegOpenKeyEx(hk,
  217. pstrChild,
  218. 0,
  219. KEY_ALL_ACCESS,
  220. &hkChild);
  221. if (lResult) {
  222. return;
  223. }
  224. #ifndef UNDER_CE // CE doesn't support RegEnumKey()
  225. TCHAR szSubkey[256];
  226. // NOTE: Unlike regular enumeration, we always grab the 0th item
  227. // and delete it.
  228. //
  229. while (!RegEnumKey(hkChild, 0, szSubkey, sizeof(szSubkey))) {
  230. RegRemoveSubtree(hkChild, szSubkey);
  231. }
  232. #endif
  233. RegCloseKey(hkChild);
  234. RegDeleteKey(hk, pstrChild);
  235. }