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.

350 lines
6.9 KiB

  1. // Copyright (C) 1999 Microsoft Corporation
  2. //
  3. // DllMain and COM DllXxx functions
  4. //
  5. // sburns 5-3-99
  6. #include "headers.hxx"
  7. #include "implmain.hpp"
  8. HINSTANCE hResourceModuleHandle = 0;
  9. const wchar_t* HELPFILE_NAME = 0;
  10. const wchar_t* RUNTIME_NAME = L"clonepr";
  11. DWORD DEFAULT_LOGGING_OPTIONS = OUTPUT_MUTE;
  12. TCHAR g_szFileName[MAX_PATH];
  13. struct REG_DATA
  14. {
  15. const wchar_t *keyName;
  16. const wchar_t *valueName;
  17. const wchar_t *value;
  18. };
  19. const REG_DATA g_rgEntries[] =
  20. {
  21. {
  22. L"CLSID\\" CLSID_STRING,
  23. 0,
  24. CLASSNAME_STRING
  25. },
  26. {
  27. L"CLSID\\" CLSID_STRING L"\\InprocServer32",
  28. 0,
  29. g_szFileName
  30. },
  31. {
  32. L"CLSID\\" CLSID_STRING L"\\InprocServer32",
  33. L"ThreadingModel",
  34. L"Apartment"
  35. },
  36. {
  37. L"CLSID\\" CLSID_STRING L"\\ProgID",
  38. 0,
  39. PROGID_VERSION_STRING
  40. },
  41. {
  42. L"CLSID\\" CLSID_STRING L"\\VersionIndependentProgID",
  43. 0,
  44. PROGID_STRING
  45. },
  46. {
  47. PROGID_VERSION_STRING,
  48. 0,
  49. CLASSNAME_STRING
  50. },
  51. {
  52. PROGID_VERSION_STRING L"\\CLSID",
  53. 0,
  54. CLSID_STRING
  55. },
  56. {
  57. PROGID_STRING,
  58. 0,
  59. CLASSNAME_STRING
  60. },
  61. {
  62. PROGID_STRING L"\\CLSID",
  63. 0,
  64. CLSID_STRING
  65. },
  66. {
  67. PROGID_STRING L"\\CurVer",
  68. 0,
  69. PROGID_VERSION_STRING
  70. },
  71. // register for IADsSID
  72. {
  73. PROGID_VERSION_STRING_ADSSID,
  74. 0,
  75. CLASSNAME_STRING
  76. },
  77. {
  78. PROGID_VERSION_STRING_ADSSID L"\\CLSID",
  79. 0,
  80. CLSID_STRING
  81. },
  82. {
  83. PROGID_STRING_ADSSID,
  84. 0,
  85. CLASSNAME_STRING
  86. },
  87. {
  88. PROGID_STRING_ADSSID L"\\CLSID",
  89. 0,
  90. CLSID_STRING
  91. },
  92. {
  93. PROGID_STRING_ADSSID L"\\CurVer",
  94. 0,
  95. PROGID_VERSION_STRING_ADSSID
  96. },
  97. // register for IADsError
  98. {
  99. PROGID_VERSION_STRING_ADSERROR,
  100. 0,
  101. CLASSNAME_STRING
  102. },
  103. {
  104. PROGID_VERSION_STRING_ADSERROR L"\\CLSID",
  105. 0,
  106. CLSID_STRING
  107. },
  108. {
  109. PROGID_STRING_ADSERROR,
  110. 0,
  111. CLASSNAME_STRING
  112. },
  113. {
  114. PROGID_STRING_ADSERROR L"\\CLSID",
  115. 0,
  116. CLSID_STRING
  117. },
  118. {
  119. PROGID_STRING_ADSERROR L"\\CurVer",
  120. 0,
  121. PROGID_VERSION_STRING_ADSERROR
  122. }
  123. };
  124. const int g_cEntries = sizeof(g_rgEntries)/sizeof(*g_rgEntries);
  125. static
  126. HRESULT
  127. Unregister(const REG_DATA *rgEntries, int cEntries)
  128. {
  129. LOG_FUNCTION(Unregister);
  130. LOG(L"Calling UnRegisterTypeLib");
  131. HRESULT hr =
  132. ::UnRegisterTypeLib(LIBID_CloneSecurityPrincipalLib, 1, 0, 0, SYS_WIN32);
  133. LOG_HRESULT(hr);
  134. // don't break: continue on attempting to remove as much as possible
  135. // of our registration
  136. bool success = SUCCEEDED(hr);
  137. for (int i = cEntries - 1; i >= 0; i--)
  138. {
  139. LONG err = ::RegDeleteKey(HKEY_CLASSES_ROOT, rgEntries[i].keyName);
  140. if (err != ERROR_SUCCESS)
  141. {
  142. success = false;
  143. }
  144. }
  145. return success ? S_OK : S_FALSE;
  146. }
  147. static HRESULT Register(const REG_DATA *rgEntries, int cEntries)
  148. {
  149. BOOL bSuccess = TRUE;
  150. HRESULT hr = S_OK; // 447822 prefix warning
  151. const REG_DATA *pEntry = rgEntries;
  152. while (pEntry < rgEntries + cEntries)
  153. {
  154. HKEY hkey;
  155. LONG err = RegCreateKey(HKEY_CLASSES_ROOT,
  156. pEntry->keyName,
  157. &hkey);
  158. if (err == ERROR_SUCCESS)
  159. {
  160. if (pEntry->value)
  161. err = RegSetValueEx(hkey,
  162. pEntry->valueName,
  163. 0, REG_SZ,
  164. (const BYTE*)pEntry->value,
  165. (lstrlen(pEntry->value) + 1) * sizeof(TCHAR));
  166. if (err != ERROR_SUCCESS)
  167. {
  168. bSuccess = FALSE;
  169. Unregister(rgEntries, static_cast<int>(1 + pEntry - rgEntries));
  170. }
  171. RegCloseKey(hkey);
  172. }
  173. if (err != ERROR_SUCCESS)
  174. {
  175. bSuccess = FALSE;
  176. if (pEntry != rgEntries)
  177. Unregister(rgEntries, static_cast<int>(pEntry - rgEntries));
  178. }
  179. pEntry++;
  180. };
  181. if (bSuccess)
  182. {
  183. OLECHAR g_wszFileName[MAX_PATH];
  184. // ISSUE-2002/03/06-sburns consider strsafe function
  185. lstrcpy(g_wszFileName, g_szFileName);
  186. ITypeLib *ptl = 0;
  187. hr = LoadTypeLib(g_wszFileName, &ptl);
  188. if (SUCCEEDED(hr))
  189. {
  190. hr = RegisterTypeLib(ptl, g_wszFileName, 0);
  191. ptl->Release();
  192. }
  193. if (bSuccess)
  194. hr = S_OK;
  195. else
  196. hr = E_FAIL;
  197. }
  198. return hr ;//bSuccess ? S_OK : E_FAIL;
  199. }
  200. BOOL
  201. APIENTRY
  202. DllMain(HINSTANCE h, DWORD dwReason, void *)
  203. {
  204. switch (dwReason)
  205. {
  206. case DLL_PROCESS_ATTACH:
  207. {
  208. hResourceModuleHandle = h;
  209. LOG(L"DLL_PROCESS_ATTACH");
  210. // @@ remove this
  211. GetModuleFileName(h, g_szFileName, MAX_PATH);
  212. break;
  213. }
  214. case DLL_PROCESS_DETACH:
  215. {
  216. #ifdef DEBUG_BUILD
  217. LOG(TEXT("DLL_PROCESS_DETACH"));
  218. if (!ComServerLockState::CanUnloadNow())
  219. {
  220. LOG(L"server locks and/or outstanding object instances exit");
  221. }
  222. else
  223. {
  224. LOG(L"server can unload now.");
  225. }
  226. #endif
  227. break;
  228. }
  229. case DLL_THREAD_ATTACH:
  230. case DLL_THREAD_DETACH:
  231. default:
  232. {
  233. break;
  234. }
  235. }
  236. return TRUE;
  237. }
  238. STDAPI
  239. DllRegisterServer()
  240. {
  241. LOG_FUNCTION(DllRegisterServer);
  242. return Register(g_rgEntries, g_cEntries);
  243. }
  244. STDAPI
  245. DllUnregisterServer()
  246. {
  247. LOG_FUNCTION(DllUnregisterServer);
  248. return Unregister(g_rgEntries, g_cEntries);
  249. }
  250. STDAPI
  251. DllCanUnloadNow()
  252. {
  253. LOG_FUNCTION(DllCanUnloadNow);
  254. if (ComServerLockState::CanUnloadNow())
  255. {
  256. return S_OK;
  257. }
  258. return S_FALSE;
  259. }
  260. STDAPI
  261. DllGetClassObject(
  262. const CLSID& classID,
  263. const IID& interfaceID,
  264. void** interfaceDesired)
  265. {
  266. LOG_FUNCTION(DllGetClassObject);
  267. IClassFactory* factory = 0;
  268. // The class objects are instances of ClassFactory<>, which are ref-counted
  269. // in the usual fashion (i.e. they track their ref counts, and
  270. // self-destruct on final Release). I could have used static instances of
  271. // a C++ class that ignored the refcounting (ala Don Box's examples in
  272. // Essential COM)
  273. if (classID == CLSID_CloneSecurityPrincipal)
  274. {
  275. factory = new ClassFactory<CloneSecurityPrincipal>;
  276. }
  277. else
  278. {
  279. *interfaceDesired = 0;
  280. return CLASS_E_CLASSNOTAVAILABLE;
  281. }
  282. // the class factory instance starts with a ref count of 1. If the QI
  283. // fails, then it self-destructs upon Release.
  284. HRESULT hr = factory->QueryInterface(interfaceID, interfaceDesired);
  285. factory->Release();
  286. return hr;
  287. }