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.

418 lines
13 KiB

  1. //+--------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1994 - 1997.
  5. //
  6. // File: snapin.cpp
  7. //
  8. // Contents: DLL support routines, class factory and registration
  9. // functions.
  10. //
  11. // Classes:
  12. //
  13. // Functions:
  14. //
  15. // History: 2-12-1998 stevebl comment header added
  16. // 4-22-1998 rahulth added CSection objects for the ini files
  17. //
  18. //---------------------------------------------------------------------------
  19. #include "precomp.hxx"
  20. #include "initguid.h"
  21. #include "gpedit.h"
  22. extern const CLSID CLSID_Snapin = {0x88E729D6,0xBDC1,0x11D1,{0xBD,0x2A,0x00,0xC0,0x4F,0xB9,0x60,0x3F}};
  23. extern const wchar_t * szCLSID_Snapin = L"{88E729D6-BDC1-11D1-BD2A-00C04FB9603F}";
  24. // Main NodeType GUID on numeric format
  25. extern const GUID cNodeType = {0xE0494114,0xBDC1,0x11D1,{0xBD,0x2A,0x00,0xC0,0x4F,0xB9,0x60,0x3F}};
  26. // Main NodeType GUID on string format
  27. extern const wchar_t* cszNodeType = L"{E0494114-BDC1-11D1-BD2A-00C04FB9603F}";
  28. // RSOP GUIDs
  29. extern const CLSID CLSID_RSOP_Snapin = {0XC40D66A0,0XE90C,0X46C6,{0XAA,0X3B,0X47,0X3E,0X38,0XC7,0X2B,0XF2}};
  30. extern const wchar_t * szCLSID_RSOP_Snapin = L"{C40D66A0-E90C-46C6-AA3B-473E38C72BF2}";
  31. IMalloc * g_pIMalloc;
  32. #include "safereg.hxx"
  33. #define BREAK_ON_FAIL_HRESULT(hr) if (FAILED(hr)) break
  34. #define THREADING_STR L"Apartment"
  35. //+--------------------------------------------------------------------------
  36. //
  37. // Function: RegDeleteTree
  38. //
  39. // Synopsis: deletes a registry key and all of its children
  40. //
  41. // Arguments: [hKey] - handle to the key's parent
  42. // [szSubKey] - name of the key to be deleted
  43. //
  44. // Returns: ERROR_SUCCESS
  45. //
  46. // History: 3-17-1998 stevebl Copied from ADE
  47. //
  48. //---------------------------------------------------------------------------
  49. LONG RegDeleteTree(HKEY hKey, TCHAR * szSubKey)
  50. {
  51. HKEY hKeyNew;
  52. LONG lResult = RegOpenKey(hKey, szSubKey, &hKeyNew);
  53. if (lResult != ERROR_SUCCESS)
  54. {
  55. return lResult;
  56. }
  57. TCHAR szName[256];
  58. while (ERROR_SUCCESS == RegEnumKey(hKeyNew, 0, szName, 256))
  59. {
  60. RegDeleteTree(hKeyNew, szName);
  61. }
  62. RegCloseKey(hKeyNew);
  63. return RegDeleteKey(hKey, szSubKey);
  64. }
  65. HRESULT
  66. RegisterInterface(
  67. CSafeReg *pshkInterface,
  68. LPWSTR wszInterfaceGUID,
  69. LPWSTR wszInterfaceName,
  70. LPWSTR wszNumMethods,
  71. LPWSTR wszProxyCLSID);
  72. CComModule _Module;
  73. BEGIN_OBJECT_MAP(ObjectMap)
  74. OBJECT_ENTRY(CLSID_Snapin, CUserComponentDataImpl)
  75. OBJECT_ENTRY(CLSID_RSOP_Snapin, CRSOPUserComponentDataImpl)
  76. END_OBJECT_MAP()
  77. #ifdef _DEBUG
  78. #define new DEBUG_NEW
  79. #undef THIS_FILE
  80. static char THIS_FILE[] = __FILE__;
  81. #endif
  82. class CSnapinApp : public CWinApp
  83. {
  84. public:
  85. virtual BOOL InitInstance();
  86. virtual int ExitInstance();
  87. };
  88. CSnapinApp theApp;
  89. HINSTANCE ghInstance;
  90. BOOL CSnapinApp::InitInstance()
  91. {
  92. ghInstance = m_hInstance;
  93. _Module.Init(ObjectMap, m_hInstance);
  94. if (FAILED(CoGetMalloc(1, &g_pIMalloc)))
  95. return FALSE;
  96. return CWinApp::InitInstance();
  97. }
  98. int CSnapinApp::ExitInstance()
  99. {
  100. _Module.Term();
  101. DEBUG_VERIFY_INSTANCE_COUNT(CResultPane);
  102. DEBUG_VERIFY_INSTANCE_COUNT(CScopePane);
  103. g_pIMalloc->Release();
  104. return CWinApp::ExitInstance();
  105. }
  106. /////////////////////////////////////////////////////////////////////////////
  107. // Used to determine whether the DLL can be unloaded by OLE
  108. STDAPI DllCanUnloadNow(void)
  109. {
  110. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  111. return (AfxDllCanUnloadNow()==S_OK && _Module.GetLockCount()==0) ? S_OK : S_FALSE;
  112. }
  113. /////////////////////////////////////////////////////////////////////////////
  114. // Returns a class factory to create an object of the requested type
  115. STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv)
  116. {
  117. return _Module.GetClassObject(rclsid, riid, ppv);
  118. }
  119. const wchar_t * szUser_Namespace = L"{08114B47-BDC2-11D1-BD2A-00C04FB9603F}";
  120. const wchar_t * szUserAppName = L"Folder Redirection Editor (Users)";
  121. const wchar_t * szUser_RSOP_Namespace = L"{8CDE1CC8-0D3A-4B60-99EA-27EF3D7C0174}";
  122. /////////////////////////////////////////////////////////////////////////////
  123. // DllRegisterServer - Adds entries to the system registry
  124. STDAPI DllRegisterServer(void)
  125. {
  126. AFX_MANAGE_STATE (AfxGetStaticModuleState());
  127. CSafeReg shk;
  128. CSafeReg shkCLSID;
  129. CSafeReg shkServer;
  130. CSafeReg shkTemp;
  131. WCHAR szMUIUserAppName[MAX_PATH + 50];
  132. WCHAR szModule[MAX_PATH];
  133. HRESULT hr = S_OK;
  134. // Get the path to the module.
  135. if (0 != ::GetModuleFileName(AfxGetInstanceHandle(), szModule, MAX_PATH))
  136. {
  137. // MUI: MMC: Use the new NameStringIndirect value of MMC to display
  138. // a localized name for the snap-in while using MUI.
  139. hr = StringCchPrintf (szMUIUserAppName, sizeof(szMUIUserAppName)/sizeof(szMUIUserAppName[0]), L"@%s,-%d", szModule, IDS_SNAPIN_NAME);
  140. if (FAILED(hr))
  141. {
  142. return hr;
  143. }
  144. }
  145. else
  146. {
  147. szMUIUserAppName[0] = L'\0';
  148. }
  149. do
  150. {
  151. hr = _Module.RegisterServer(FALSE);
  152. BREAK_ON_FAIL_HRESULT(hr);
  153. // register extension
  154. hr = shkCLSID.Open(HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\MMC\\SnapIns", KEY_WRITE);
  155. BREAK_ON_FAIL_HRESULT(hr);
  156. hr = shkCLSID.Create(szCLSID_Snapin, &shk);
  157. BREAK_ON_FAIL_HRESULT(hr);
  158. hr = shk.SetValue(L"NameString",
  159. REG_SZ,
  160. (CONST BYTE *) szUserAppName,
  161. sizeof(WCHAR) * (lstrlen(szUserAppName)+ 1));
  162. // MUI: MMC: Use localized snap-in name for MUI.
  163. if (L'\0' != szMUIUserAppName[0])
  164. {
  165. hr = shk.SetValue(L"NameStringIndirect",
  166. REG_SZ,
  167. (CONST BYTE *) szMUIUserAppName,
  168. sizeof(WCHAR) * (lstrlen(szMUIUserAppName) + 1));
  169. }
  170. hr = shk.Create(L"NodeTypes", &shkTemp);
  171. BREAK_ON_FAIL_HRESULT(hr);
  172. hr = shkTemp.Create(szUser_Namespace, &shkServer);
  173. BREAK_ON_FAIL_HRESULT(hr);
  174. shkServer.Close();
  175. shkTemp.Close();
  176. shk.Close();
  177. shkCLSID.Close();
  178. hr = shkCLSID.Open(HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\MMC\\NodeTypes", KEY_WRITE);
  179. BREAK_ON_FAIL_HRESULT(hr);
  180. hr = shkCLSID.Create(szUser_Namespace, &shk);
  181. BREAK_ON_FAIL_HRESULT(hr);
  182. shk.Close();
  183. WCHAR szGUID[50];
  184. StringFromGUID2 (NODEID_User, szGUID, 50);
  185. hr = shkCLSID.Create(szGUID, &shk);
  186. BREAK_ON_FAIL_HRESULT(hr);
  187. hr = shk.Create(L"Extensions", &shkServer);
  188. BREAK_ON_FAIL_HRESULT(hr);
  189. hr = shkServer.Create(L"NameSpace", &shkTemp);
  190. BREAK_ON_FAIL_HRESULT(hr);
  191. hr = shkTemp.SetValue(szCLSID_Snapin,
  192. REG_SZ,
  193. (CONST BYTE *) szUserAppName,
  194. sizeof(WCHAR) * (lstrlen(szUserAppName)+ 1));
  195. shkTemp.Close();
  196. shkServer.Close();
  197. shk.Close();
  198. shkCLSID.Close();
  199. // register RSOP extension
  200. hr = shkCLSID.Open(HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\MMC\\SnapIns", KEY_WRITE);
  201. BREAK_ON_FAIL_HRESULT(hr);
  202. hr = shkCLSID.Create(szCLSID_RSOP_Snapin, &shk);
  203. BREAK_ON_FAIL_HRESULT(hr);
  204. hr = shk.SetValue(L"NameString",
  205. REG_SZ,
  206. (CONST BYTE *) szUserAppName,
  207. sizeof(WCHAR) * (lstrlen(szUserAppName)+ 1));
  208. // MUI: MMC: Use localized snap-in name for MUI.
  209. if (L'\0' != szMUIUserAppName[0])
  210. {
  211. hr = shk.SetValue(L"NameStringIndirect",
  212. REG_SZ,
  213. (CONST BYTE *) szMUIUserAppName,
  214. sizeof (WCHAR) * (lstrlen(szMUIUserAppName) + 1));
  215. }
  216. hr = shk.Create(L"NodeTypes", &shkTemp);
  217. BREAK_ON_FAIL_HRESULT(hr);
  218. hr = shkTemp.Create(szUser_RSOP_Namespace, &shkServer);
  219. BREAK_ON_FAIL_HRESULT(hr);
  220. shkServer.Close();
  221. shkTemp.Close();
  222. shk.Close();
  223. shkCLSID.Close();
  224. hr = shkCLSID.Open(HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\MMC\\NodeTypes", KEY_WRITE);
  225. BREAK_ON_FAIL_HRESULT(hr);
  226. hr = shkCLSID.Create(szUser_RSOP_Namespace, &shk);
  227. BREAK_ON_FAIL_HRESULT(hr);
  228. shk.Close();
  229. StringFromGUID2 (NODEID_RSOPUser, szGUID, 50);
  230. hr = shkCLSID.Create(szGUID, &shk);
  231. BREAK_ON_FAIL_HRESULT(hr);
  232. hr = shk.Create(L"Extensions", &shkServer);
  233. BREAK_ON_FAIL_HRESULT(hr);
  234. hr = shkServer.Create(L"NameSpace", &shkTemp);
  235. BREAK_ON_FAIL_HRESULT(hr);
  236. hr = shkTemp.SetValue(szCLSID_RSOP_Snapin,
  237. REG_SZ,
  238. (CONST BYTE *) szUserAppName,
  239. sizeof(WCHAR) * (lstrlen(szUserAppName)+ 1));
  240. shkTemp.Close();
  241. shkServer.Close();
  242. shk.Close();
  243. shkCLSID.Close();
  244. } while (0);
  245. return hr;
  246. }
  247. /////////////////////////////////////////////////////////////////////////////
  248. // DllUnregisterServer - Removes entries from the system registry
  249. STDAPI DllUnregisterServer(void)
  250. {
  251. _Module.UnregisterServer();
  252. HKEY hkey;
  253. CString sz;
  254. RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\MMC\\SnapIns\\", 0, KEY_WRITE, &hkey);
  255. RegDeleteTree(hkey, (LPOLESTR)((LPCOLESTR)szCLSID_Snapin));
  256. RegCloseKey(hkey);
  257. RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\MMC\\NodeTypes\\", 0, KEY_WRITE, &hkey);
  258. RegDeleteTree(HKEY_LOCAL_MACHINE, (LPOLESTR)((LPCOLESTR)szUser_Namespace));
  259. RegCloseKey(hkey);
  260. WCHAR szGUID[50];
  261. sz = L"Software\\Microsoft\\MMC\\NodeTypes\\";
  262. StringFromGUID2 (NODEID_User, szGUID, 50);
  263. sz += szGUID;
  264. sz += L"\\Extensions\\NameSpace";
  265. RegOpenKeyEx(HKEY_LOCAL_MACHINE, sz, 0, KEY_WRITE, &hkey);
  266. RegDeleteValue(hkey, szCLSID_Snapin);
  267. RegCloseKey(hkey);
  268. // unregister RSOP nodes
  269. RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\MMC\\SnapIns\\", 0, KEY_WRITE, &hkey);
  270. RegDeleteTree(hkey, (LPOLESTR)((LPCOLESTR)szCLSID_RSOP_Snapin));
  271. RegCloseKey(hkey);
  272. RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\MMC\\NodeTypes\\", 0, KEY_WRITE, &hkey);
  273. RegDeleteTree(HKEY_LOCAL_MACHINE, (LPOLESTR)((LPCOLESTR)szUser_RSOP_Namespace));
  274. RegCloseKey(hkey);
  275. sz = L"Software\\Microsoft\\MMC\\NodeTypes\\";
  276. StringFromGUID2 (NODEID_RSOPUser, szGUID, 50);
  277. sz += szGUID;
  278. sz += L"\\Extensions\\NameSpace";
  279. RegOpenKeyEx(HKEY_LOCAL_MACHINE, sz, 0, KEY_WRITE, &hkey);
  280. RegDeleteValue(hkey, szCLSID_RSOP_Snapin);
  281. RegCloseKey(hkey);
  282. return S_OK;
  283. }
  284. //+--------------------------------------------------------------------------
  285. //
  286. // Function: RegisterInterface
  287. //
  288. // Synopsis: Add the registry entries required for an interface.
  289. //
  290. // Arguments: [pshkInterface] - handle to CLSID\Interface key
  291. // [wszInterfaceGUID] - GUID of interface to add
  292. // [wszInterfaceName] - human-readable name of interface
  293. // [wszNumMethods] - number of methods (including inherited)
  294. // [wszProxyCLSID] - GUID of dll containing proxy/stubs
  295. //
  296. // Returns: HRESULT
  297. //
  298. // History: 3-31-1997 DavidMun Created
  299. // 5-09-1997 SteveBl Modified for use with AppMgr
  300. //
  301. //---------------------------------------------------------------------------
  302. HRESULT
  303. RegisterInterface(
  304. CSafeReg *pshkInterface,
  305. LPWSTR wszInterfaceGUID,
  306. LPWSTR wszInterfaceName,
  307. LPWSTR wszNumMethods,
  308. LPWSTR wszProxyCLSID)
  309. {
  310. HRESULT hr = S_OK;
  311. CSafeReg shkIID;
  312. CSafeReg shkNumMethods;
  313. CSafeReg shkProxy;
  314. do
  315. {
  316. hr = pshkInterface->Create(wszInterfaceGUID, &shkIID);
  317. BREAK_ON_FAIL_HRESULT(hr);
  318. hr = shkIID.SetValue(NULL,
  319. REG_SZ,
  320. (CONST BYTE *) wszInterfaceName,
  321. sizeof(WCHAR) * (lstrlen(wszInterfaceName) + 1));
  322. BREAK_ON_FAIL_HRESULT(hr);
  323. hr = shkIID.Create(L"NumMethods", &shkNumMethods);
  324. BREAK_ON_FAIL_HRESULT(hr);
  325. hr = shkNumMethods.SetValue(NULL,
  326. REG_SZ,
  327. (CONST BYTE *)wszNumMethods,
  328. sizeof(WCHAR) * (lstrlen(wszNumMethods) + 1));
  329. BREAK_ON_FAIL_HRESULT(hr);
  330. hr = shkIID.Create(L"ProxyStubClsid32", &shkProxy);
  331. BREAK_ON_FAIL_HRESULT(hr);
  332. hr = shkProxy.SetValue(NULL,
  333. REG_SZ,
  334. (CONST BYTE *)wszProxyCLSID,
  335. sizeof(WCHAR) * (lstrlen(wszProxyCLSID) + 1));
  336. BREAK_ON_FAIL_HRESULT(hr);
  337. } while (0);
  338. return hr;
  339. }