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.

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