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.

463 lines
12 KiB

  1. /*****************************************************************************
  2. *
  3. * DIReg.c
  4. *
  5. * Copyright (c) 1996 Microsoft Corporation. All Rights Reserved.
  6. *
  7. * Abstract:
  8. *
  9. * OLE self-registration.
  10. *
  11. * Contents:
  12. *
  13. * DllRegisterServer()
  14. * DllUnregisterServer()
  15. *
  16. *****************************************************************************/
  17. #include "dinputpr.h"
  18. /*****************************************************************************
  19. *
  20. * The sqiffle for this file.
  21. *
  22. *****************************************************************************/
  23. #define sqfl sqflDll
  24. /*****************************************************************************
  25. *
  26. * RegSetStringEx
  27. *
  28. * Add a REG_SZ to hkey\sub::value.
  29. *
  30. *****************************************************************************/
  31. void INTERNAL
  32. RegSetStringEx(HKEY hk, LPCTSTR ptszValue, LPCTSTR ptszData)
  33. {
  34. LONG lRc = RegSetValueEx(hk, ptszValue, 0, REG_SZ,
  35. (PV)ptszData, cbCtch(lstrlen(ptszData)+1));
  36. }
  37. /*****************************************************************************
  38. *
  39. * RegDelStringEx
  40. *
  41. * Remove a REG_SZ from hkey\sub::value. The data is ignored.
  42. * It's passed so that RegDelStringEx matches the prototype for a
  43. * REGSTRINGACTION.
  44. *
  45. *****************************************************************************/
  46. void INTERNAL
  47. RegDelStringEx(HKEY hk, LPCTSTR ptszValue, LPCTSTR ptszData)
  48. {
  49. LONG lRc = RegDeleteValue(hk, ptszValue);
  50. }
  51. /*****************************************************************************
  52. *
  53. * RegCloseFinish
  54. *
  55. * Just close the subkey already.
  56. *
  57. *****************************************************************************/
  58. void INTERNAL
  59. RegCloseFinish(HKEY hk, LPCTSTR ptszSub, HKEY hkSub)
  60. {
  61. LONG lRc = RegCloseKey(hkSub);
  62. }
  63. /*****************************************************************************
  64. *
  65. * RegDelFinish
  66. *
  67. * Delete a key if there is nothing in it.
  68. *
  69. * OLE unregistration rules demand that you not delete a key if OLE
  70. * has added something to it.
  71. *
  72. *****************************************************************************/
  73. void INTERNAL
  74. RegDelFinish(HKEY hk, LPCTSTR ptszSub, HKEY hkSub)
  75. {
  76. LONG lRc;
  77. DWORD cKeys = 0, cValues = 0;
  78. RegQueryInfoKey(hkSub, 0, 0, 0, &cKeys, 0, 0, &cValues, 0, 0, 0, 0);
  79. RegCloseKey(hkSub);
  80. if ((cKeys | cValues) == 0) {
  81. #ifdef WINNT
  82. lRc = DIWinnt_RegDeleteKey(hk, ptszSub);
  83. #else
  84. lRc = RegDeleteKey(hk, ptszSub);
  85. #endif
  86. } else {
  87. lRc = 0;
  88. }
  89. }
  90. #ifdef WINNT //The following are only used on WINNT
  91. /*****************************************************************************
  92. *
  93. * @doc INTERNAL
  94. *
  95. * @func void | RegSetPermissionsOnDescendants |
  96. *
  97. * Sets the specified permissions on all descendants of the specified key.
  98. *
  99. * @parm HKEY | hKey |
  100. *
  101. * The reg key on whose descendants we're operating.
  102. *
  103. * @parm SECURITY_DESCRIPTOR* | psd |
  104. *
  105. * Ptr to the SECURITY_DESCRIPTOR we're using.
  106. *
  107. * @returns
  108. *
  109. * Nothing.
  110. * Note that this recurses while having TCHAR szKeyName[MAX_PATH+1]
  111. * for each level. If stack space is a concern, can allocate it on the heap,
  112. * and free after obtain the HKEY (i.e. before recursing).
  113. *
  114. *****************************************************************************/
  115. void INTERNAL
  116. RegSetPermissionsOnDescendants(HKEY hKey, SECURITY_DESCRIPTOR* psd)
  117. {
  118. DWORD dwIndex = 0;
  119. LONG lRetCode = ERROR_SUCCESS;
  120. while (lRetCode == ERROR_SUCCESS)
  121. {
  122. TCHAR szKeyName[MAX_PATH+1];
  123. DWORD cbKeyName = MAX_PATH+1;
  124. lRetCode = RegEnumKeyEx(hKey,
  125. dwIndex,
  126. szKeyName,
  127. &cbKeyName,
  128. NULL, NULL, NULL, NULL);
  129. if (lRetCode == ERROR_SUCCESS)
  130. {
  131. LONG lRetSub;
  132. HKEY hkSubKey;
  133. lRetSub = RegOpenKeyEx(hKey, szKeyName, 0, DI_KEY_ALL_ACCESS | WRITE_DAC, &hkSubKey);
  134. if (lRetSub == ERROR_SUCCESS)
  135. {
  136. //set security on it and its descendants
  137. lRetSub = RegSetKeySecurity(hkSubKey,
  138. (SECURITY_INFORMATION)DACL_SECURITY_INFORMATION,
  139. psd);
  140. RegSetPermissionsOnDescendants(hkSubKey, psd);
  141. RegCloseKey(hkSubKey);
  142. if(lRetSub != ERROR_SUCCESS)
  143. {
  144. RPF("Couldn't RegSetKeySecurity on %hs", szKeyName);
  145. }
  146. }
  147. else
  148. {
  149. RPF("Couldn't open enumed subkey %hs", szKeyName);
  150. }
  151. dwIndex++;
  152. }
  153. }
  154. }
  155. /*****************************************************************************
  156. *
  157. * @doc INTERNAL
  158. *
  159. * @func HRESULT | RegSetSecurity |
  160. *
  161. * Set the security of
  162. * SYSTEM\\CurrentControlSet\\Control\\MediaProperties\\PrivateProperties\\Joystick\\OEM
  163. * SYSTEM\\CurrentControlSet\\Control\\MediaResources\\Joystick\\Dinput.dll
  164. * to be accessible to Everyone on Win2K,
  165. *. to be accessible to Everyone but without WRITE_DAC and WRITE_OWNER permissions on WinXP;
  166. * SYSTEM\\CurrentControlSet\\Control\\MediaProperties\\PrivateProperties\\DirectInput
  167. * to be accessible to Everyone but without WRITE_DAC and WRITE_OWNER permissions on Win2k and WinXP.
  168. *
  169. * @returns
  170. *
  171. * S_OK on success, E_FAIL on error.
  172. *
  173. *****************************************************************************/
  174. HRESULT INTERNAL
  175. RegSetSecurity(void)
  176. {
  177. HKEY hkJoy, hkDin, hkPP, hkMedR, hkJDi;
  178. LONG lRetCode;
  179. // Changed for server per Whistler bug 575181
  180. // open / create the keys
  181. //
  182. //MediaProperties/PrivateProperties/DirectInput
  183. lRetCode = RegOpenKeyEx(
  184. HKEY_LOCAL_MACHINE,
  185. REGSTR_PATH_PRIVATEPROPERTIES,
  186. 0,
  187. KEY_WRITE,
  188. &hkPP
  189. );
  190. if(lRetCode != ERROR_SUCCESS) {
  191. RPF("Couldn't open REGSTR_PATH_PRIVATEPROPERTIES");
  192. return E_FAIL;
  193. }
  194. lRetCode = RegCreateKeyEx(
  195. hkPP,
  196. TEXT("DirectInput"),
  197. 0,
  198. NULL,
  199. REG_OPTION_NON_VOLATILE,
  200. DI_KEY_ALL_ACCESS,
  201. NULL,
  202. &hkDin,
  203. NULL
  204. );
  205. RegCloseKey(hkPP);
  206. if(lRetCode != ERROR_SUCCESS) {
  207. RPF("Couldn't open DirectInput");
  208. return E_FAIL;
  209. }
  210. RegCloseKey(hkDin);
  211. //MediaResources/Joystick/Dinput.dll
  212. lRetCode = RegOpenKeyEx(
  213. HKEY_LOCAL_MACHINE,
  214. REGSTR_PATH_MEDIARESOURCES,
  215. 0,
  216. KEY_WRITE,
  217. &hkMedR
  218. );
  219. if(lRetCode != ERROR_SUCCESS) {
  220. RPF("Couldn't open REGSTR_PATH_MEDIARESOURCES");
  221. return E_FAIL;
  222. }
  223. lRetCode = RegCreateKeyEx(
  224. hkMedR,
  225. TEXT("Joystick"),
  226. 0,
  227. NULL,
  228. REG_OPTION_NON_VOLATILE,
  229. KEY_WRITE,
  230. NULL,
  231. &hkJoy,
  232. NULL
  233. );
  234. RegCloseKey(hkMedR);
  235. if(lRetCode != ERROR_SUCCESS) {
  236. RPF("Couldn't open Joystick");
  237. return E_FAIL;
  238. }
  239. lRetCode = RegCreateKeyEx(
  240. hkJoy,
  241. TEXT("Dinput.dll"),
  242. 0,
  243. NULL,
  244. REG_OPTION_NON_VOLATILE,
  245. DI_KEY_ALL_ACCESS,
  246. NULL,
  247. &hkJDi,
  248. NULL
  249. );
  250. RegCloseKey(hkJoy);
  251. if(lRetCode != ERROR_SUCCESS) {
  252. RPF("Couldn't open Dinput.dll");
  253. return E_FAIL;
  254. }
  255. RegCloseKey(hkJDi);
  256. return S_OK;
  257. }
  258. /*****************************************************************************
  259. *
  260. * @doc INTERNAL
  261. *
  262. * @func HRESULT | DummyRegSetSecurity |
  263. *
  264. * Do nothing
  265. *
  266. * @returns
  267. *
  268. * S_OK.
  269. *
  270. *****************************************************************************/
  271. HRESULT INTERNAL
  272. DummyRegSetSecurity(void)
  273. {
  274. return S_OK;
  275. }
  276. #endif //WINNT
  277. /*****************************************************************************
  278. *
  279. * REGVTBL
  280. *
  281. * Functions for dorking with a registry key, either coming or going.
  282. *
  283. *****************************************************************************/
  284. typedef struct REGVTBL {
  285. /* How to create/open a key */
  286. LONG (INTERNAL *KeyAction)(HKEY hk, LPCTSTR ptszSub, PHKEY phkOut);
  287. /* How to create/delete a string */
  288. void (INTERNAL *StringAction)(HKEY hk, LPCTSTR ptszValue, LPCTSTR ptszData);
  289. /* How to finish using a key */
  290. void (INTERNAL *KeyFinish)(HKEY hk, LPCTSTR ptszSub, HKEY hkSub);
  291. #ifdef WINNT
  292. /* How to set security on OEM key */
  293. HRESULT (INTERNAL *SetSecurity)( void );
  294. #endif //WINNT
  295. } REGVTBL, *PREGVTBL;
  296. typedef const REGVTBL *PCREGVTBL;
  297. #ifdef WINNT
  298. const REGVTBL c_vtblAdd = { RegCreateKey, RegSetStringEx, RegCloseFinish, RegSetSecurity };
  299. const REGVTBL c_vtblDel = { RegOpenKey, RegDelStringEx, RegDelFinish, DummyRegSetSecurity };
  300. #else
  301. const REGVTBL c_vtblAdd = { RegCreateKey, RegSetStringEx, RegCloseFinish };
  302. const REGVTBL c_vtblDel = { RegOpenKey, RegDelStringEx, RegDelFinish };
  303. #endif //WINNT
  304. /*****************************************************************************
  305. *
  306. * @doc INTERNAL
  307. *
  308. * @func void | DllServerAction |
  309. *
  310. * Register or unregister our objects with OLE/COM/ActiveX/
  311. * whatever its name is.
  312. *
  313. *****************************************************************************/
  314. #pragma BEGIN_CONST_DATA
  315. extern const TCHAR c_tszNil[];
  316. #define ctchClsid ctchGuid
  317. const TCHAR c_tszClsidGuid[] =
  318. TEXT("CLSID\\{%08lX-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}");
  319. const TCHAR c_tszInProcServer32[] = TEXT("InProcServer32");
  320. const TCHAR c_tszThreadingModel[] = TEXT("ThreadingModel");
  321. const TCHAR c_tszBoth[] = TEXT("Both");
  322. #pragma END_CONST_DATA
  323. void INTERNAL
  324. DllServerAction(PCREGVTBL pvtbl)
  325. {
  326. TCHAR tszThisDll[MAX_PATH];
  327. UINT iclsidmap;
  328. GetModuleFileName(g_hinst, tszThisDll, cA(tszThisDll));
  329. for (iclsidmap = 0; iclsidmap < cclsidmap; iclsidmap++) {
  330. TCHAR tszClsid[7+ctchClsid];
  331. HKEY hkClsid;
  332. HKEY hkSub;
  333. REFCLSID rclsid = c_rgclsidmap[iclsidmap].rclsid;
  334. wsprintf(tszClsid, c_tszClsidGuid,
  335. rclsid->Data1, rclsid->Data2, rclsid->Data3,
  336. rclsid->Data4[0], rclsid->Data4[1],
  337. rclsid->Data4[2], rclsid->Data4[3],
  338. rclsid->Data4[4], rclsid->Data4[5],
  339. rclsid->Data4[6], rclsid->Data4[7]);
  340. if (pvtbl->KeyAction(HKEY_CLASSES_ROOT, tszClsid, &hkClsid) == 0) {
  341. TCHAR tszName[127];
  342. /* Do the type name */
  343. LoadString(g_hinst, c_rgclsidmap[iclsidmap].ids,
  344. tszName, cA(tszName));
  345. pvtbl->StringAction(hkClsid, 0, tszName);
  346. /* Do the in-proc server name and threading model */
  347. if (pvtbl->KeyAction(hkClsid, c_tszInProcServer32, &hkSub) == 0) {
  348. pvtbl->StringAction(hkSub, 0, tszThisDll);
  349. pvtbl->StringAction(hkSub, c_tszThreadingModel, c_tszBoth);
  350. pvtbl->KeyFinish(hkClsid, c_tszInProcServer32, hkSub);
  351. }
  352. pvtbl->KeyFinish(HKEY_CLASSES_ROOT, tszClsid, hkClsid);
  353. }
  354. }
  355. #ifdef WINNT
  356. pvtbl->SetSecurity();
  357. #endif
  358. }
  359. /*****************************************************************************
  360. *
  361. * @doc INTERNAL
  362. *
  363. * @func void | DllRegisterServer |
  364. *
  365. * Register our classes with OLE/COM/ActiveX/whatever its name is.
  366. *
  367. *****************************************************************************/
  368. void EXTERNAL
  369. DllRegisterServer(void)
  370. {
  371. DllServerAction(&c_vtblAdd);
  372. }
  373. /*****************************************************************************
  374. *
  375. * @doc INTERNAL
  376. *
  377. * @func void | DllUnregisterServer |
  378. *
  379. * Unregister our classes from OLE/COM/ActiveX/whatever its name is.
  380. *
  381. *****************************************************************************/
  382. void EXTERNAL
  383. DllUnregisterServer(void)
  384. {
  385. DllServerAction(&c_vtblDel);
  386. }