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.

502 lines
14 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1995.
  5. //
  6. // File: selfreg.cxx
  7. //
  8. // Contents: Taken from Office96
  9. // Source file for the common self registration code used by all the
  10. // sub projects of Sweeper project. They are
  11. // UrlMon
  12. // UrlMnPrx
  13. //
  14. // Exports: HrDllRegisterServer()
  15. // HrDllUnregisterServer()
  16. //
  17. // Classes:
  18. //
  19. // Functions:
  20. //
  21. // History: 5-03-96 JohannP (Johann Posch) Created
  22. //
  23. //----------------------------------------------------------------------------
  24. #include <eapp.h>
  25. HINSTANCE g_hinstDll = NULL;
  26. PFNLOADSTRING g_pfnLoadString = NULL;
  27. //+---------------------------------------------------------------------------
  28. //
  29. // Function: GetDllFullPath
  30. //
  31. // Synopsis:
  32. //
  33. // Arguments: [lpszExeName] --
  34. // [cch] --
  35. //
  36. // Returns:
  37. //
  38. // History: 95 OfficeXX created
  39. // 5-03-96 JohannP (Johann Posch) port urlmon
  40. //
  41. // Notes:
  42. //
  43. //----------------------------------------------------------------------------
  44. BOOL GetDllFullPath( LPSTR lpszExeName, DWORD cch )
  45. {
  46. if ( NULL == g_hinstDll )
  47. {
  48. EProtAssert(( FALSE && "NULL hInst"));
  49. return FALSE;
  50. }
  51. *lpszExeName = NULL;
  52. if ( GetModuleFileName( g_hinstDll, lpszExeName, cch ) == 0)
  53. {
  54. EProtAssert(( FALSE && "GetModuleFileName Failed"));
  55. return FALSE;
  56. }
  57. return TRUE;
  58. }
  59. inline BOOL IsASeparator( char ch )
  60. {
  61. return (ch == '\\' || ch == '/' || ch == ':');
  62. }
  63. //+---------------------------------------------------------------------------
  64. //
  65. // Function: ParseAFileName
  66. //
  67. // Synopsis:
  68. //
  69. // Arguments: [szFileName] --
  70. // [piRetLen] --
  71. //
  72. // Returns:
  73. //
  74. // History: 95 OfficeXX created
  75. // 5-03-96 JohannP (Johann Posch) port urlmon
  76. //
  77. // Notes:
  78. //
  79. //----------------------------------------------------------------------------
  80. LPSTR ParseAFileName( LPSTR szFileName, int *piRetLen)
  81. {
  82. LPSTR pszFile;
  83. // Start at the end of the filename.
  84. pszFile = szFileName + ( lstrlen(szFileName) - 1 );
  85. // Back up to a '\\' or beginning or something!! We just want a file
  86. // name!. Whatever comes first.
  87. while ( pszFile > szFileName && !IsASeparator(*pszFile ) )
  88. pszFile = CharPrev(szFileName, pszFile);
  89. if ( pszFile != szFileName )
  90. pszFile = CharNext(pszFile);
  91. if ( piRetLen )
  92. *piRetLen = lstrlen(pszFile);
  93. return pszFile;
  94. }
  95. //+---------------------------------------------------------------------------
  96. //
  97. // Function: FRegisterEntries
  98. //
  99. // Synopsis: FRegisterEntries: Register a group of reg entries off a base key.
  100. //
  101. // Arguments: [hkRoot] --
  102. // [rgEntries] --
  103. // [dwEntries] --
  104. // [pszPath] --
  105. // [pszBinderName] --
  106. //
  107. // Returns:
  108. //
  109. // History: 95 OfficeXX created
  110. // 5-03-96 JohannP (Johann Posch) port urlmon
  111. //
  112. // Notes:
  113. //
  114. //----------------------------------------------------------------------------
  115. BOOL FRegisterEntries(HKEY hkRoot, const REGENTRY rgEntries[],
  116. DWORD dwEntries, char *pszPath, char *pszBinderName)
  117. {
  118. HKEY hkey = NULL;
  119. LONG lRet;
  120. char szValue[1024];
  121. char szResString[1024];
  122. char szKeyName[1024];
  123. BOOL fRet = FALSE;
  124. int i;
  125. for (i = 0; i < (int)dwEntries; i++)
  126. {
  127. // We work with a copy of the entry, since we might modify it
  128. REGENTRY reCurrentEntry = rgEntries[i];
  129. if (reCurrentEntry.iKeyType == KEYTYPE_RESID)
  130. {
  131. int cch;
  132. if (g_pfnLoadString == NULL)
  133. return FALSE;
  134. cch = g_pfnLoadString(g_hinstDll, (UINT)reCurrentEntry.pszKey, szKeyName,
  135. sizeof(szKeyName));
  136. if (cch > 0 && cch <= 1024)
  137. {
  138. reCurrentEntry.pszKey = szKeyName;
  139. }
  140. else
  141. {
  142. EProtAssert(( FALSE && "LoadString Failed ( 1)"));
  143. continue;
  144. }
  145. }
  146. lRet = RegCreateKey(hkRoot, reCurrentEntry.pszKey, &hkey);
  147. if (lRet != ERROR_SUCCESS)
  148. {
  149. EProtAssert(( FALSE && "RegCreateKey Failed ( 1)"));
  150. continue;
  151. }
  152. // If the type is REG_RESID, then pbData holds the resource ID. We
  153. // load the resource string, then modify our reCurrentEntry to point
  154. // to it.
  155. if (reCurrentEntry.dwType == REG_RESID)
  156. {
  157. int cch;
  158. if (g_pfnLoadString == NULL)
  159. return FALSE;
  160. cch = g_pfnLoadString(g_hinstDll, (UINT)reCurrentEntry.pbData, szResString,
  161. sizeof(szResString));
  162. if (cch > 0 && cch <= 1024)
  163. {
  164. reCurrentEntry.dwType = REG_SZ;
  165. reCurrentEntry.pbData = (BYTE*) szResString;
  166. }
  167. else
  168. {
  169. EProtAssert(( FALSE && "LoadString Failed (2)"));
  170. reCurrentEntry.pbData = NULL;
  171. }
  172. }
  173. // Set the value if there is one
  174. if (reCurrentEntry.pbData != NULL || reCurrentEntry.dwType != REG_SZ)
  175. {
  176. switch (reCurrentEntry.dwType)
  177. {
  178. case REG_SZ:
  179. // Replace the first %s with the path, and the second
  180. // %s with the name of the binder app (may not do anything).
  181. if (pszPath != NULL && pszBinderName != NULL)
  182. {
  183. wsprintf(szValue, (char*)reCurrentEntry.pbData, pszPath,
  184. pszBinderName);
  185. lRet = RegSetValueEx(hkey, reCurrentEntry.pszValueName, 0,
  186. REG_SZ, (BYTE*)szValue, lstrlen(szValue)+1);
  187. #if DBG == 1
  188. if ( ERROR_SUCCESS != lRet )
  189. EProtAssert(( FALSE && "RegSetValueEx Failed ( 1)"));
  190. #endif
  191. }
  192. break;
  193. case REG_DWORD:
  194. lRet = RegSetValueEx(hkey, reCurrentEntry.pszValueName, 0,
  195. REG_DWORD, (BYTE*)&reCurrentEntry.pbData, sizeof(DWORD));
  196. #if DBG == 1
  197. if ( ERROR_SUCCESS != lRet )
  198. EProtAssert(( FALSE && "RegSetValueEx Failed (2)"));
  199. #endif
  200. break;
  201. default:
  202. EProtAssert(( FALSE && "Unexpected reg entry type"));
  203. // Unexpected type: ignore
  204. break;
  205. }
  206. }
  207. // Close the subkey
  208. RegCloseKey(hkey);
  209. hkey = NULL;
  210. }
  211. fRet = TRUE;
  212. // Close the base key if it was open
  213. if (hkey)
  214. RegCloseKey(hkey);
  215. return fRet;
  216. }
  217. /*
  218. * FRegisterEntryGroups: Register several groups of reg entries.
  219. */
  220. BOOL FRegisterEntryGroups(const REGENTRYGROUP *rgRegEntryGroups,
  221. char *pszPath, char *pszBinderName)
  222. {
  223. BOOL fError = FALSE;
  224. int i;
  225. // Keep going even if we get some errors
  226. for (i=0; rgRegEntryGroups[i].hkRoot != NULL; i++)
  227. {
  228. if (!FRegisterEntries(rgRegEntryGroups[i].hkRoot, rgRegEntryGroups[i].rgEntries,
  229. rgRegEntryGroups[i].dwEntries,pszPath, pszBinderName))
  230. {
  231. fError = TRUE;
  232. }
  233. }
  234. return !fError;
  235. }
  236. //+---------------------------------------------------------------------------
  237. //
  238. // Function: FDeleteEntries
  239. //
  240. // Synopsis: Delete a group of reg entries off a base key.
  241. //
  242. // Arguments: [hkRoot] --
  243. // [rgEntries] --
  244. // [dwEntries] --
  245. //
  246. // Returns:
  247. //
  248. // History: 95 OfficeXX created
  249. // 5-03-96 JohannP (Johann Posch) port urlmon
  250. //
  251. // Notes:
  252. //
  253. //----------------------------------------------------------------------------
  254. BOOL FDeleteEntries(HKEY hkRoot, const REGENTRY rgEntries[], DWORD dwEntries)
  255. {
  256. LONG lRet;
  257. int i;
  258. char szKeyName[1024];
  259. PSTR pKey;
  260. // Delete in reverse order, to kill children before parent
  261. for (i = (int)dwEntries - 1; i >= 0; i--)
  262. {
  263. pKey = NULL;
  264. if (rgEntries[i].iKeyType == KEYTYPE_RESID)
  265. {
  266. int cch;
  267. cch = g_pfnLoadString(g_hinstDll, (UINT)rgEntries[i].pszKey, szKeyName,
  268. sizeof(szKeyName));
  269. if (cch > 0 && cch <= 1024)
  270. {
  271. pKey = szKeyName;
  272. }
  273. else
  274. {
  275. EProtAssert(( FALSE && "LoadString Failed (FDeleteEntries)"));
  276. continue;
  277. }
  278. }
  279. else
  280. {
  281. if ( KEYTYPE_STRING != rgEntries[i].iKeyType )
  282. {
  283. EProtAssert(( FALSE && "Unknown Key Type"));
  284. continue;
  285. }
  286. pKey = rgEntries[i].pszKey;
  287. }
  288. if (pKey != NULL)
  289. {
  290. // Delete the current key if it has no subkeys.
  291. // Ignore the return value.
  292. lRet = RegDeleteKey(hkRoot, pKey);
  293. }
  294. }
  295. return TRUE;
  296. }
  297. //+---------------------------------------------------------------------------
  298. //
  299. // Function: FDeleteEntryGroups
  300. //
  301. // Synopsis: Delete the base keys of all the given groups.
  302. //
  303. // Arguments: [rgRegEntryGroups] --
  304. //
  305. // Returns:
  306. //
  307. // History: 95 OfficeXX created
  308. // 5-03-96 JohannP (Johann Posch) port urlmon
  309. //
  310. // Notes:
  311. //
  312. //----------------------------------------------------------------------------
  313. BOOL FDeleteEntryGroups(const REGENTRYGROUP *rgRegEntryGroups)
  314. {
  315. BOOL fError = FALSE;
  316. // Keep going even if we get some errors
  317. for (int i=0; rgRegEntryGroups[i].hkRoot != NULL; i++)
  318. {
  319. if (!FDeleteEntries(rgRegEntryGroups[i].hkRoot,
  320. rgRegEntryGroups[i].rgEntries,
  321. rgRegEntryGroups[i].dwEntries))
  322. {
  323. fError = TRUE;
  324. }
  325. }
  326. return !fError;
  327. }
  328. #ifdef NOT_USED
  329. /*
  330. * FDeleteSubtree - Delete given key and all subkeys
  331. */
  332. BOOL FDeleteSubtree(HKEY hkRoot, char *pszKey)
  333. {
  334. HKEY hkey = NULL;
  335. LONG lRet;
  336. char szSubKey[MAX_PATH];
  337. lRet = RegOpenKey(hkRoot, pszKey, &hkey);
  338. if (lRet != ERROR_SUCCESS)
  339. goto End;
  340. // remove all subkeys
  341. for (;;)
  342. {
  343. lRet = RegEnumKey(hkey, 0, szSubKey, sizeof szSubKey);
  344. if (lRet == ERROR_NO_MORE_ITEMS)
  345. break;
  346. if (lRet != ERROR_SUCCESS)
  347. goto End;
  348. if (!FDeleteSubtree(hkey, szSubKey))
  349. goto End;
  350. }
  351. End:
  352. if (hkey != NULL)
  353. RegCloseKey (hkey);
  354. lRet = RegDeleteKey(hkRoot, pszKey);
  355. return (lRet == ERROR_SUCCESS);
  356. }
  357. #endif // NOT_USED
  358. //+---------------------------------------------------------------------------
  359. //
  360. // Function: HrDllRegisterServer
  361. //
  362. // Synopsis: registers an entrygroup
  363. //
  364. // Arguments: [HINSTANCE] --
  365. // [hinstDll] --
  366. // [pfnLoadString] --
  367. // [pszAppName] --
  368. //
  369. // Returns:
  370. //
  371. // History: 95 OfficeXX created
  372. // 5-03-96 JohannP (Johann Posch) port urlmon
  373. //
  374. // Notes:
  375. //
  376. //----------------------------------------------------------------------------
  377. HRESULT HrDllRegisterServer(const REGENTRYGROUP *rgRegEntryGroups,HINSTANCE hinstDll,
  378. PFNLOADSTRING pfnLoadString, char *pszAppName)
  379. {
  380. // REVIEW: for Windows dll, do we want to register full path?
  381. BOOL fRet = TRUE;
  382. char szFullPath[MAX_PATH];
  383. char szFileName[MAX_PATH];
  384. char *pszFileName;
  385. g_hinstDll = hinstDll;
  386. if ((g_pfnLoadString = pfnLoadString) == NULL)
  387. // set the pointer to windows LoadString() api
  388. g_pfnLoadString = (PFNLOADSTRING) LoadString;
  389. if (!GetDllFullPath(szFullPath, MAX_PATH))
  390. return E_FAIL;
  391. pszFileName = ParseAFileName(szFullPath, NULL);
  392. if (pszAppName != NULL)
  393. lstrcpy(szFileName, pszAppName);
  394. else
  395. lstrcpy(szFileName, pszFileName);
  396. // Terminate the path at the file name
  397. *pszFileName = '\0';
  398. fRet = FRegisterEntryGroups(rgRegEntryGroups, szFullPath, szFileName);
  399. g_hinstDll = NULL;
  400. g_pfnLoadString = NULL;
  401. return fRet ? NOERROR : E_FAIL;
  402. }
  403. //+---------------------------------------------------------------------------
  404. //
  405. // Function: HrDllUnregisterServer
  406. //
  407. // Synopsis: unregisters an entrygroup
  408. //
  409. // Arguments: [HINSTANCE] --
  410. // [hinstDll] --
  411. // [pfnLoadString] --
  412. //
  413. // Returns:
  414. //
  415. // History: 95 OfficeXX created
  416. // 5-03-96 JohannP (Johann Posch) port urlmon
  417. //
  418. // Notes:
  419. //
  420. //----------------------------------------------------------------------------
  421. HRESULT HrDllUnregisterServer(const REGENTRYGROUP *rgRegEntryGroups,HINSTANCE hinstDll, PFNLOADSTRING pfnLoadString)
  422. {
  423. g_hinstDll = hinstDll;
  424. if ((g_pfnLoadString = pfnLoadString) == NULL)
  425. // set the pointer to windows LoadString() api
  426. g_pfnLoadString = (PFNLOADSTRING) LoadString;
  427. FDeleteEntryGroups(rgRegEntryGroups);
  428. g_hinstDll = NULL;
  429. g_pfnLoadString = NULL;
  430. return NOERROR;
  431. }
  432.