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.

589 lines
16 KiB

  1. /*==========================================================================
  2. *
  3. * Copyright (C) 2000 Microsoft Corporation. All Rights Reserved.
  4. *
  5. * File: DNLReg.cpp
  6. * Content: DirectPlay Lobby Registry Functions
  7. *@@BEGIN_MSINTERNAL
  8. * History:
  9. * Date By Reason
  10. * ==== == ======
  11. * 02/21/00 mjn Created
  12. * 04/25/00 rmt Bug #s 33138, 33145, 33150
  13. * 05/03/00 rmt UnRegister was not implemented! Implementing!
  14. * 08/05/00 RichGr IA64: Use %p format specifier in DPFs for 32/64-bit pointers and handles.
  15. * 06/16/2001 rodtoll WINBUG #416983 - RC1: World has full control to HKLM\Software\Microsoft\DirectPlay\Applications on Personal
  16. * Implementing mirror of keys into HKCU. Algorithm is now:
  17. * - Read of entries tries HKCU first, then HKLM
  18. * - Enum of entires is combination of HKCU and HKLM entries with duplicates removed. HKCU takes priority.
  19. * - Write of entries is HKLM and HKCU. (HKLM may fail, but is ignored).
  20. *@@END_MSINTERNAL
  21. *
  22. ***************************************************************************/
  23. #include "dnlobbyi.h"
  24. //**********************************************************************
  25. // Constant definitions
  26. //**********************************************************************
  27. //**********************************************************************
  28. // Macro definitions
  29. //**********************************************************************
  30. //**********************************************************************
  31. // Structure definitions
  32. //**********************************************************************
  33. //**********************************************************************
  34. // Variable definitions
  35. //**********************************************************************
  36. //**********************************************************************
  37. // Function prototypes
  38. //**********************************************************************
  39. //**********************************************************************
  40. // Function definitions
  41. //**********************************************************************
  42. #undef DPF_MODNAME
  43. #define DPF_MODNAME "DPLDeleteProgramDesc"
  44. HRESULT DPLDeleteProgramDesc( const GUID * const pGuidApplication )
  45. {
  46. HRESULT hResultCode = DPN_OK;
  47. CRegistry RegistryEntry;
  48. CRegistry SubEntry;
  49. DWORD dwLastError;
  50. HKEY hkCurrentHive;
  51. BOOL fFound = FALSE;
  52. BOOL fRemoved = FALSE;
  53. DPFX(DPFPREP, 3, "Removing program desc" );
  54. for( DWORD dwIndex = 0; dwIndex < 2; dwIndex++ )
  55. {
  56. if( dwIndex == 0 )
  57. {
  58. hkCurrentHive = HKEY_CURRENT_USER;
  59. }
  60. else
  61. {
  62. hkCurrentHive = HKEY_LOCAL_MACHINE;
  63. }
  64. if( !RegistryEntry.Open( hkCurrentHive,DPL_REG_LOCAL_APPL_SUBKEY,FALSE,FALSE,TRUE,DPN_KEY_ALL_ACCESS ) )
  65. {
  66. DPFX(DPFPREP, 1, "Failed to open key for remove in pass %i", dwIndex );
  67. continue;
  68. }
  69. // This should be down below the next if block, but 8.0 shipped with a bug
  70. // which resulted in this function returning DPNERR_NOTALLOWED in cases where
  71. // the next if block failed. Need to remain compatible
  72. fFound = TRUE;
  73. if( !SubEntry.Open( RegistryEntry, pGuidApplication, FALSE, FALSE,TRUE,DPN_KEY_ALL_ACCESS ) )
  74. {
  75. DPFX(DPFPREP, 1, "Failed to open subkey for remove in pass %i", dwIndex );
  76. continue;
  77. }
  78. SubEntry.Close();
  79. if( !RegistryEntry.DeleteSubKey( pGuidApplication ) )
  80. {
  81. DPFX(DPFPREP, 1, "Failed to delete subkey for remove in pass %i", dwIndex );
  82. continue;
  83. }
  84. fRemoved = TRUE;
  85. RegistryEntry.Close();
  86. }
  87. if( !fFound )
  88. {
  89. DPFX(DPFPREP, 0, "Could not find entry" );
  90. hResultCode = DPNERR_DOESNOTEXIST;
  91. }
  92. else if( !fRemoved )
  93. {
  94. dwLastError = GetLastError();
  95. DPFX(DPFPREP, 0, "Error deleting registry sub-key lastError [0x%lx]", dwLastError );
  96. hResultCode = DPNERR_NOTALLOWED;
  97. }
  98. DPFX(DPFPREP, 3, "Removing program desc [0x%x]", hResultCode );
  99. return hResultCode;
  100. }
  101. //**********************************************************************
  102. // ------------------------------
  103. // DPLWriteProgramDesc
  104. //
  105. // Entry: Nothing
  106. //
  107. // Exit: DPN_OK
  108. // ------------------------------
  109. #undef DPF_MODNAME
  110. #define DPF_MODNAME "DPLWriteProgramDesc"
  111. HRESULT DPLWriteProgramDesc(DPL_PROGRAM_DESC *const pdplProgramDesc)
  112. {
  113. HRESULT hResultCode;
  114. CRegistry RegistryEntry;
  115. CRegistry SubEntry;
  116. WCHAR *pwsz;
  117. WCHAR pwszDefault[] = L"\0";
  118. HKEY hkCurrentHive = NULL;
  119. BOOL fWritten = FALSE;
  120. DPFX(DPFPREP, 3,"Parameters: pdplProgramDesc [0x%p]",pdplProgramDesc);
  121. for( DWORD dwIndex = 0; dwIndex < 2; dwIndex++ )
  122. {
  123. if( dwIndex == 0 )
  124. {
  125. hkCurrentHive = HKEY_LOCAL_MACHINE;
  126. }
  127. else
  128. {
  129. hkCurrentHive = HKEY_CURRENT_USER;
  130. }
  131. if (!RegistryEntry.Open(hkCurrentHive,DPL_REG_LOCAL_APPL_SUBKEY,FALSE,TRUE,TRUE,DPN_KEY_ALL_ACCESS))
  132. {
  133. DPFX( DPFPREP, 1, "Entry not found in user hive on pass %i", dwIndex );
  134. continue;
  135. }
  136. // Get Application name and GUID from each sub key
  137. if (!SubEntry.Open(RegistryEntry,&pdplProgramDesc->guidApplication,FALSE,TRUE,TRUE,DPN_KEY_ALL_ACCESS))
  138. {
  139. DPFX( DPFPREP, 1, "Entry not found in user hive on pass %i", dwIndex );
  140. continue;
  141. }
  142. if (!SubEntry.WriteString(DPL_REG_KEYNAME_APPLICATIONNAME,pdplProgramDesc->pwszApplicationName))
  143. {
  144. DPFX( DPFPREP, 1, "Could not write ApplicationName on pass %i", dwIndex);
  145. goto LOOP_END;
  146. }
  147. if (pdplProgramDesc->pwszCommandLine != NULL)
  148. {
  149. pwsz = pdplProgramDesc->pwszCommandLine;
  150. }
  151. else
  152. {
  153. pwsz = pwszDefault;
  154. }
  155. if (!SubEntry.WriteString(DPL_REG_KEYNAME_COMMANDLINE,pwsz))
  156. {
  157. DPFX( DPFPREP, 1, "Could not write CommandLine on pass %i", dwIndex);
  158. goto LOOP_END;
  159. }
  160. if (pdplProgramDesc->pwszCurrentDirectory != NULL)
  161. {
  162. pwsz = pdplProgramDesc->pwszCurrentDirectory;
  163. }
  164. else
  165. {
  166. pwsz = pwszDefault;
  167. }
  168. if (!SubEntry.WriteString(DPL_REG_KEYNAME_CURRENTDIRECTORY,pwsz))
  169. {
  170. DPFX( DPFPREP, 1, "Could not write CurrentDirectory on pass %i", dwIndex);
  171. goto LOOP_END;
  172. }
  173. if (pdplProgramDesc->pwszDescription != NULL)
  174. {
  175. pwsz = pdplProgramDesc->pwszDescription;
  176. }
  177. else
  178. {
  179. pwsz = pwszDefault;
  180. }
  181. if (!SubEntry.WriteString(DPL_REG_KEYNAME_DESCRIPTION,pwsz))
  182. {
  183. DPFX( DPFPREP, 1, "Could not write Description on pass %i", dwIndex );
  184. goto LOOP_END;
  185. }
  186. if (pdplProgramDesc->pwszExecutableFilename != NULL)
  187. {
  188. pwsz = pdplProgramDesc->pwszExecutableFilename;
  189. }
  190. else
  191. {
  192. pwsz = pwszDefault;
  193. }
  194. if (!SubEntry.WriteString(DPL_REG_KEYNAME_EXECUTABLEFILENAME,pwsz))
  195. {
  196. DPFX( DPFPREP, 1, "Could not write ExecutableFilename on pass %i", dwIndex );
  197. goto LOOP_END;
  198. }
  199. if (pdplProgramDesc->pwszExecutablePath != NULL)
  200. {
  201. pwsz = pdplProgramDesc->pwszExecutablePath;
  202. }
  203. else
  204. {
  205. pwsz = pwszDefault;
  206. }
  207. if (!SubEntry.WriteString(DPL_REG_KEYNAME_EXECUTABLEPATH,pwsz))
  208. {
  209. DPFX( DPFPREP, 1, "Could not write ExecutablePath on pass %i", dwIndex);
  210. goto LOOP_END;
  211. }
  212. if (pdplProgramDesc->pwszLauncherFilename != NULL)
  213. {
  214. pwsz = pdplProgramDesc->pwszLauncherFilename;
  215. }
  216. else
  217. {
  218. pwsz = pwszDefault;
  219. }
  220. if (!SubEntry.WriteString(DPL_REG_KEYNAME_LAUNCHERFILENAME,pwsz))
  221. {
  222. DPFX( DPFPREP, 1, "Could not write LauncherFilename on pass %i", dwIndex);
  223. goto LOOP_END;
  224. }
  225. if (pdplProgramDesc->pwszLauncherPath != NULL)
  226. {
  227. pwsz = pdplProgramDesc->pwszLauncherPath;
  228. }
  229. else
  230. {
  231. pwsz = pwszDefault;
  232. }
  233. if (!SubEntry.WriteString(DPL_REG_KEYNAME_LAUNCHERPATH,pwsz))
  234. {
  235. DPFX( DPFPREP, 1, "Could not write LauncherPath on pass %i", dwIndex);
  236. goto LOOP_END;
  237. }
  238. if (!SubEntry.WriteGUID(DPL_REG_KEYNAME_GUID,pdplProgramDesc->guidApplication))
  239. {
  240. DPFX( DPFPREP, 1, "Could not write GUID on pass %i", dwIndex);
  241. goto LOOP_END;
  242. }
  243. fWritten = TRUE;
  244. LOOP_END:
  245. SubEntry.Close();
  246. RegistryEntry.Close();
  247. }
  248. if( !fWritten )
  249. {
  250. DPFERR("Entry could not be written");
  251. hResultCode = DPNERR_GENERIC;
  252. }
  253. else
  254. {
  255. hResultCode = DPN_OK;
  256. }
  257. DPFX(DPFPREP, 3,"Returning: [0x%lx]",hResultCode);
  258. return(hResultCode);
  259. }
  260. //**********************************************************************
  261. // ------------------------------
  262. // DPLGetProgramDesc
  263. //
  264. // Entry: Nothing
  265. //
  266. // Exit: DPN_OK
  267. // DPNERR_BUFFERTOOSMALL
  268. // ------------------------------
  269. #undef DPF_MODNAME
  270. #define DPF_MODNAME "DPLGetProgramDesc"
  271. HRESULT DPLGetProgramDesc(GUID *const pGuidApplication,
  272. BYTE *const pBuffer,
  273. DWORD *const pdwBufferSize)
  274. {
  275. HRESULT hResultCode;
  276. CRegistry RegistryEntry;
  277. CRegistry SubEntry;
  278. CPackedBuffer PackedBuffer;
  279. DWORD dwEntrySize;
  280. DWORD dwRegValueLengths;
  281. DPL_PROGRAM_DESC *pdnProgramDesc;
  282. DWORD dwValueSize;
  283. HKEY hkCurrentHive = NULL;
  284. BOOL fFound = FALSE;
  285. DPFX(DPFPREP, 3,"Parameters: pGuidApplication [0x%p], pBuffer [0x%p], pdwBufferSize [0x%p]",
  286. pGuidApplication,pBuffer,pdwBufferSize);
  287. for( DWORD dwIndex = 0; dwIndex < 2; dwIndex++ )
  288. {
  289. if( dwIndex == 0 )
  290. {
  291. hkCurrentHive = HKEY_CURRENT_USER;
  292. }
  293. else
  294. {
  295. hkCurrentHive = HKEY_LOCAL_MACHINE;
  296. }
  297. if (!RegistryEntry.Open(hkCurrentHive,DPL_REG_LOCAL_APPL_SUBKEY,TRUE,FALSE,TRUE,DPL_REGISTRY_READ_ACCESS))
  298. {
  299. DPFX( DPFPREP, 1, "Entry not found in user hive on pass %i", dwIndex );
  300. continue;
  301. }
  302. // Get Application name and GUID from each sub key
  303. if (!SubEntry.Open(RegistryEntry,pGuidApplication,TRUE,FALSE,TRUE,DPL_REGISTRY_READ_ACCESS))
  304. {
  305. DPFX( DPFPREP, 1, "Entry not found in user hive on pass %i", dwIndex );
  306. continue;
  307. }
  308. fFound = TRUE;
  309. break;
  310. }
  311. if( !fFound )
  312. {
  313. DPFERR("Entry not found");
  314. hResultCode = DPNERR_DOESNOTEXIST;
  315. goto EXIT_DPLGetProgramDesc;
  316. }
  317. // Calculate total entry size (structure + data)
  318. dwEntrySize = sizeof(DPL_PROGRAM_DESC);
  319. dwRegValueLengths = 0;
  320. if (SubEntry.GetValueLength(DPL_REG_KEYNAME_APPLICATIONNAME,&dwValueSize))
  321. {
  322. dwRegValueLengths += dwValueSize;
  323. }
  324. if (SubEntry.GetValueLength(DPL_REG_KEYNAME_COMMANDLINE,&dwValueSize))
  325. {
  326. dwRegValueLengths += dwValueSize;
  327. }
  328. if (SubEntry.GetValueLength(DPL_REG_KEYNAME_CURRENTDIRECTORY,&dwValueSize))
  329. {
  330. dwRegValueLengths += dwValueSize;
  331. }
  332. if (SubEntry.GetValueLength(DPL_REG_KEYNAME_DESCRIPTION,&dwValueSize))
  333. {
  334. dwRegValueLengths += dwValueSize;
  335. }
  336. if (SubEntry.GetValueLength(DPL_REG_KEYNAME_EXECUTABLEFILENAME,&dwValueSize))
  337. {
  338. dwRegValueLengths += dwValueSize;
  339. }
  340. if (SubEntry.GetValueLength(DPL_REG_KEYNAME_EXECUTABLEPATH,&dwValueSize))
  341. {
  342. dwRegValueLengths += dwValueSize;
  343. }
  344. if (SubEntry.GetValueLength(DPL_REG_KEYNAME_LAUNCHERFILENAME,&dwValueSize))
  345. {
  346. dwRegValueLengths += dwValueSize;
  347. }
  348. if (SubEntry.GetValueLength(DPL_REG_KEYNAME_LAUNCHERPATH,&dwValueSize))
  349. {
  350. dwRegValueLengths += dwValueSize;
  351. }
  352. dwEntrySize += dwRegValueLengths * sizeof( WCHAR );
  353. DPFX(DPFPREP, 7,"dwEntrySize [%ld]",dwEntrySize);
  354. // If supplied buffer sufficient, use it
  355. if (dwEntrySize <= *pdwBufferSize)
  356. {
  357. PackedBuffer.Initialize(pBuffer,*pdwBufferSize);
  358. pdnProgramDesc = static_cast<DPL_PROGRAM_DESC*>(PackedBuffer.GetHeadAddress());
  359. PackedBuffer.AddToFront(NULL,sizeof(DPL_PROGRAM_DESC));
  360. dwValueSize = PackedBuffer.GetSpaceRemaining();
  361. pdnProgramDesc->pwszApplicationName = static_cast<WCHAR*>(PackedBuffer.GetHeadAddress());
  362. if (!SubEntry.ReadString(DPL_REG_KEYNAME_APPLICATIONNAME,
  363. pdnProgramDesc->pwszApplicationName,&dwValueSize))
  364. {
  365. DPFERR( "Unable to get application name for entry" );
  366. hResultCode = DPNERR_GENERIC;
  367. goto EXIT_DPLGetProgramDesc;
  368. }
  369. if (dwValueSize > 1)
  370. {
  371. PackedBuffer.AddToFront(NULL,dwValueSize * sizeof(WCHAR));
  372. }
  373. else
  374. {
  375. pdnProgramDesc->pwszApplicationName = NULL;
  376. }
  377. dwValueSize = PackedBuffer.GetSpaceRemaining();
  378. pdnProgramDesc->pwszCommandLine = static_cast<WCHAR*>(PackedBuffer.GetHeadAddress());
  379. if (!SubEntry.ReadString(DPL_REG_KEYNAME_COMMANDLINE,
  380. pdnProgramDesc->pwszCommandLine,&dwValueSize))
  381. {
  382. DPFERR( "Unable to get commandline for entry" );
  383. hResultCode = DPNERR_GENERIC;
  384. goto EXIT_DPLGetProgramDesc;
  385. }
  386. if (dwValueSize > 1)
  387. {
  388. PackedBuffer.AddToFront(NULL,dwValueSize * sizeof(WCHAR));
  389. }
  390. else
  391. {
  392. pdnProgramDesc->pwszCommandLine = NULL;
  393. }
  394. dwValueSize = PackedBuffer.GetSpaceRemaining();
  395. pdnProgramDesc->pwszCurrentDirectory = static_cast<WCHAR*>(PackedBuffer.GetHeadAddress());
  396. if (!SubEntry.ReadString(DPL_REG_KEYNAME_CURRENTDIRECTORY,
  397. pdnProgramDesc->pwszCurrentDirectory,&dwValueSize))
  398. {
  399. DPFERR( "Unable to get current directory filename for entry" );
  400. hResultCode = DPNERR_GENERIC;
  401. goto EXIT_DPLGetProgramDesc;
  402. }
  403. if (dwValueSize > 1)
  404. {
  405. PackedBuffer.AddToFront(NULL,dwValueSize * sizeof(WCHAR));
  406. }
  407. else
  408. {
  409. pdnProgramDesc->pwszCurrentDirectory = NULL;
  410. }
  411. dwValueSize = PackedBuffer.GetSpaceRemaining();
  412. pdnProgramDesc->pwszDescription = static_cast<WCHAR*>(PackedBuffer.GetHeadAddress());
  413. if (!SubEntry.ReadString(DPL_REG_KEYNAME_DESCRIPTION,
  414. pdnProgramDesc->pwszDescription,&dwValueSize))
  415. {
  416. DPFERR( "Unable to get description for entry" );
  417. hResultCode = DPNERR_GENERIC;
  418. goto EXIT_DPLGetProgramDesc;
  419. }
  420. if (dwValueSize > 1)
  421. {
  422. PackedBuffer.AddToFront(NULL,dwValueSize * sizeof(WCHAR));
  423. }
  424. else
  425. {
  426. pdnProgramDesc->pwszDescription = NULL;
  427. }
  428. dwValueSize = PackedBuffer.GetSpaceRemaining();
  429. pdnProgramDesc->pwszExecutableFilename = static_cast<WCHAR*>(PackedBuffer.GetHeadAddress());
  430. if (!SubEntry.ReadString(DPL_REG_KEYNAME_EXECUTABLEFILENAME,
  431. pdnProgramDesc->pwszExecutableFilename,&dwValueSize))
  432. {
  433. DPFERR( "Unable to get executable filename for entry" );
  434. hResultCode = DPNERR_GENERIC;
  435. goto EXIT_DPLGetProgramDesc;
  436. }
  437. if (dwValueSize > 1)
  438. {
  439. PackedBuffer.AddToFront(NULL,dwValueSize * sizeof(WCHAR));
  440. }
  441. else
  442. {
  443. pdnProgramDesc->pwszExecutableFilename = NULL;
  444. }
  445. dwValueSize = PackedBuffer.GetSpaceRemaining();
  446. pdnProgramDesc->pwszExecutablePath = static_cast<WCHAR*>(PackedBuffer.GetHeadAddress());
  447. if (!SubEntry.ReadString(DPL_REG_KEYNAME_EXECUTABLEPATH,
  448. pdnProgramDesc->pwszExecutablePath,&dwValueSize))
  449. {
  450. DPFERR( "Unable to get executable path for entry" );
  451. hResultCode = DPNERR_GENERIC;
  452. goto EXIT_DPLGetProgramDesc;
  453. }
  454. if (dwValueSize > 1)
  455. {
  456. PackedBuffer.AddToFront(NULL,dwValueSize * sizeof(WCHAR));
  457. }
  458. else
  459. {
  460. pdnProgramDesc->pwszExecutablePath = NULL;
  461. }
  462. dwValueSize = PackedBuffer.GetSpaceRemaining();
  463. pdnProgramDesc->pwszLauncherFilename = static_cast<WCHAR*>(PackedBuffer.GetHeadAddress());
  464. if (!SubEntry.ReadString(DPL_REG_KEYNAME_LAUNCHERFILENAME,
  465. pdnProgramDesc->pwszLauncherFilename,&dwValueSize))
  466. {
  467. DPFERR( "Unable to get launcher filename for entry" );
  468. hResultCode = DPNERR_GENERIC;
  469. goto EXIT_DPLGetProgramDesc;
  470. }
  471. if (dwValueSize > 1)
  472. {
  473. PackedBuffer.AddToFront(NULL,dwValueSize * sizeof(WCHAR));
  474. }
  475. else
  476. {
  477. pdnProgramDesc->pwszLauncherFilename = NULL;
  478. }
  479. dwValueSize = PackedBuffer.GetSpaceRemaining();
  480. pdnProgramDesc->pwszLauncherPath = static_cast<WCHAR*>(PackedBuffer.GetHeadAddress());
  481. if (!SubEntry.ReadString(DPL_REG_KEYNAME_LAUNCHERPATH,
  482. pdnProgramDesc->pwszLauncherPath,&dwValueSize))
  483. {
  484. DPFERR( "Unable to get launcher path for entry" );
  485. hResultCode = DPNERR_GENERIC;
  486. goto EXIT_DPLGetProgramDesc;
  487. }
  488. if (dwValueSize > 1)
  489. {
  490. PackedBuffer.AddToFront(NULL,dwValueSize * sizeof(WCHAR));
  491. }
  492. else
  493. {
  494. pdnProgramDesc->pwszLauncherPath = NULL;
  495. }
  496. pdnProgramDesc->dwSize = sizeof(DPL_PROGRAM_DESC);
  497. pdnProgramDesc->dwFlags = 0;
  498. pdnProgramDesc->guidApplication = *pGuidApplication;
  499. hResultCode = DPN_OK;
  500. }
  501. else
  502. {
  503. hResultCode = DPNERR_BUFFERTOOSMALL;
  504. }
  505. SubEntry.Close();
  506. RegistryEntry.Close();
  507. if (hResultCode == DPN_OK || hResultCode == DPNERR_BUFFERTOOSMALL)
  508. {
  509. *pdwBufferSize = dwEntrySize;
  510. }
  511. EXIT_DPLGetProgramDesc:
  512. DPFX(DPFPREP, 3,"Returning: [0x%lx]",hResultCode);
  513. return(hResultCode);
  514. }