Source code of Windows XP (NT5)
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.

1322 lines
36 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. }
  515. // ------------------------------------------------------------------------------
  516. #if 0
  517. // HRESULT DnAddRegKey
  518. // HKEY hBase Open key from which to start
  519. // LPSTR lpszLocation Key path in Subkey1/Subkey2... format (ANSI string)
  520. // LPSTR lpszName Name of key (ANSI string)
  521. // LPWSTR lpwszValue Value of key (Unicode string)
  522. //
  523. // Returns
  524. // DPN_OK If the key was added successfully
  525. // DPNERR_GENERIC If there was a problem opening/creating/adding
  526. // DPNERR_OUTOFMEMORY If it could not allocate memory
  527. //
  528. // Notes
  529. // The key path and name are in ANSI CHAR format, and the key value to add is in
  530. // Unicode WCHAR format. This function recursively calls itself to descend the
  531. // registry tree staring from the open key, hBase, creating keys as required.
  532. //
  533. // Key names are limited to ANSI, whereas key values are in Unicode
  534. #undef DPF_MODNAME
  535. #define DPF_MODNAME "DnAddRegKey"
  536. HRESULT DnAddRegKey(HKEY hBase, LPSTR lpszLocation, LPSTR lpszName, LPWSTR lpwszValue)
  537. {
  538. LPSTR lpc;
  539. LPSTR lpszCopy = NULL;
  540. LPSTR lpszAnsiValue = NULL;
  541. LPWSTR lpwszUnicodeName = NULL;
  542. DWORD dwLen,dwDisposition;
  543. int iLen;
  544. HKEY h;
  545. HRESULT hResultCode = DPN_OK;
  546. LONG tmp;
  547. DPFX(DPFPREP, 3,"Parameters: hBase [%p], lpszLocation [%p], lpszName [%p], lpwszValue [%p]",
  548. hBase,lpszLocation,lpszName,lpwszValue);
  549. if (strlen(lpszLocation) == 0)
  550. {
  551. DPFX(DPFPREP, 7,"RegSetValue");
  552. // Add key here
  553. iLen = wcslen(lpwszValue) + 1;
  554. if (DN_RUNNING_NT)
  555. {
  556. // For WindowsNT, just place the Unicode key value into the key
  557. DPFX(DPFPREP, 5,"WinNT - Use Unicode");
  558. // Convert key name from ANSI to Unicode
  559. if ((lpwszUnicodeName = (LPWSTR)GLOBALALLOC((strlen(lpszName)+1)*sizeof(WCHAR))) == NULL)
  560. {
  561. hResultCode = DPNERR_OUTOFMEMORY;
  562. goto EXIT_DnAddRegKey;
  563. }
  564. AnsiToWide(lpwszUnicodeName,lpszName,strlen(lpszName)+1);
  565. // Set key value
  566. if (RegSetValueExW(hBase,lpwszUnicodeName,0,REG_EXPAND_SZ,(CONST BYTE *)lpwszValue,
  567. iLen*sizeof(WCHAR)) != ERROR_SUCCESS)
  568. {
  569. hResultCode = DPNERR_GENERIC;
  570. goto EXIT_DnAddRegKey;
  571. }
  572. }
  573. else
  574. {
  575. // For Windows9x, convert Unicode key value to ANSI before placing in key
  576. DPFX(DPFPREP, 5,"Win9x - Use ANSI");
  577. // Convert key value from Unicode to ANSI first
  578. if ((lpszAnsiValue = (LPSTR)GLOBALALLOC(iLen)) == NULL)
  579. {
  580. hResultCode = DPNERR_OUTOFMEMORY;
  581. goto EXIT_DnAddRegKey;
  582. }
  583. WideToAnsi(lpszAnsiValue,lpwszValue,iLen);
  584. // Set key value
  585. if (RegSetValueExA(hBase,lpszName,0,REG_EXPAND_SZ,(CONST BYTE *)lpszAnsiValue,
  586. iLen) != ERROR_SUCCESS)
  587. {
  588. hResultCode = DPNERR_GENERIC;
  589. goto EXIT_DnAddRegKey;
  590. }
  591. }
  592. }
  593. else
  594. {
  595. for(lpc = lpszLocation ; *lpc != '/' && *lpc != '\0' ; lpc++)
  596. ;
  597. dwLen = lpc-lpszLocation+1;
  598. if ((lpszCopy = (LPSTR)GLOBALALLOC(dwLen)) == NULL)
  599. {
  600. hResultCode = DPNERR_OUTOFMEMORY;
  601. goto EXIT_DnAddRegKey;
  602. }
  603. memcpy((void *)lpszCopy,(void *)lpszLocation,dwLen);
  604. *((LPSTR)(lpszCopy+dwLen-1)) = '\0';
  605. DPFX(DPFPREP, 5,"Calling RegCreateKeyExA() to create %s",lpszCopy);
  606. if ((tmp = RegCreateKeyExA(hBase,lpszCopy,0,"None",REG_OPTION_NON_VOLATILE,
  607. KEY_ALL_ACCESS,NULL,&h,&dwDisposition)) != ERROR_SUCCESS)
  608. {
  609. hResultCode = DPNERR_GENERIC;
  610. goto EXIT_DnAddRegKey;
  611. }
  612. if (*lpc == '/')
  613. lpc++;
  614. hResultCode = DnAddRegKey(h,lpc,lpszName,lpwszValue);
  615. RegCloseKey(h);
  616. }
  617. EXIT_DnAddRegKey: // Clean up
  618. DPFX(DPFPREP, 3, "hResultCode = %ld",hResultCode);
  619. if (lpszCopy != NULL)
  620. GlobalFree(lpszCopy);
  621. if (lpszAnsiValue != NULL)
  622. GlobalFree(lpszAnsiValue);
  623. if (lpwszUnicodeName != NULL)
  624. GlobalFree(lpwszUnicodeName);
  625. return(hResultCode);
  626. }
  627. // HRESULT DnOpenRegKey
  628. // HKEY hBase Open key from which to start
  629. // LPSTR lpszLocation Key path in Subkey1/Subkey2... format (ANSI string)
  630. // HKEY * lpHkey Pointer to key handle
  631. //
  632. // Returns
  633. // DPN_OK If the key was opened successfully
  634. // DPNERR_DOESNOTEXIST If a key could not be opened
  635. // DPNERR_OUTOFMEMORY If it could not allocate memory
  636. // DPNERR_INVALIDPARAM If there was an invalid key pay (end in / or is NULL)
  637. //
  638. // Notes
  639. // The key path is in ANSI CHAR format.
  640. #undef DPF_MODNAME
  641. #define DPF_MODNAME "DnOpenRegKey"
  642. HRESULT DnOpenRegKey(HKEY hBase, LPSTR lpszLocation, HKEY *lpHkey)
  643. {
  644. LPSTR lpc;
  645. LPSTR lpszCopy = NULL;
  646. DWORD dwLen;
  647. HKEY h;
  648. HRESULT hResultCode = DPN_OK;
  649. DPFX(DPFPREP, 3,"Parameters: hBase [%p], lpszLocation [%p], lpHkey [%p]",
  650. hBase,lpszLocation,lpHkey);
  651. if (strlen(lpszLocation) == 0)
  652. {
  653. hResultCode = DPNERR_INVALIDPARAM;
  654. goto EXIT_DnOpenRegKey;
  655. }
  656. else
  657. {
  658. for (lpc = lpszLocation ; *lpc != '/' && *lpc != '\0' ; lpc++)
  659. ;
  660. dwLen = lpc-lpszLocation;
  661. if ((lpszCopy = (LPSTR)GLOBALALLOC(dwLen+1)) == NULL)
  662. {
  663. hResultCode = DPNERR_OUTOFMEMORY;
  664. goto EXIT_DnOpenRegKey;
  665. }
  666. memcpy(lpszCopy,lpszLocation,dwLen);
  667. *(lpszCopy+dwLen) = '\0';
  668. if (RegOpenKeyExA(hBase,lpszCopy,0,KEY_READ,&h) != ERROR_SUCCESS)
  669. {
  670. hResultCode = DPNERR_DOESNOTEXIST;
  671. goto EXIT_DnOpenRegKey;
  672. }
  673. if (*lpc == '/') // More keys - open next sub key
  674. {
  675. lpc++;
  676. hResultCode = DnOpenRegKey(h,lpc,lpHkey);
  677. RegCloseKey(h);
  678. }
  679. else // Last key - set handle
  680. {
  681. *lpHkey = h;
  682. goto EXIT_DnOpenRegKey;
  683. }
  684. }
  685. EXIT_DnOpenRegKey:
  686. if (lpszCopy != NULL)
  687. GlobalFree(lpszCopy);
  688. DPFX(DPFPREP, 3,"Returning: hResultCode = [%lx]",hResultCode);
  689. return(hResultCode);
  690. }
  691. // HRESULT DnGetRegKeyValue
  692. // HKEY hKey Open key from which to start
  693. // LPSTR lpszKeyName Key name (ANSI string) to retrieve
  694. // LPWSTR *lplpwszKeyValue Pointer to the address pointer to a Unicode string
  695. //
  696. // Returns
  697. // DPN_OK If successfull
  698. // DPNERR_DOESNOTEXIST If there was a problem opening/reading the key
  699. // DPNERR_OUTOFMEMORY If it could not allocate memory
  700. //
  701. // Notes
  702. // The key name is an Ansi string. The function gets the length of the key value,
  703. // allocates a buffer for it, and then reads the key into the buffer.
  704. #undef DPF_MODNAME
  705. #define DPF_MODNAME "DnGetRegKeyValue"
  706. HRESULT DnGetRegKeyValue(HKEY hKey, LPSTR lpszKeyName, LPWSTR *lplpwszKeyValue)
  707. {
  708. HRESULT hResultCode = DPN_OK;
  709. LPSTR lpszValue = NULL;
  710. LPWSTR lpwszValue = NULL;
  711. DWORD dwValueLen;
  712. LONG lReturnValue;
  713. DPFX(DPFPREP, 3,"Parameters: hKey [%p], lpszKeyName[%p], lplpwszKeyValue [%p]",
  714. hKey,lpszKeyName,lplpwszKeyValue);
  715. dwValueLen = 0;
  716. lReturnValue = RegQueryValueExA(hKey,lpszKeyName,NULL,NULL,NULL,&dwValueLen);
  717. if (lReturnValue == ERROR_SUCCESS)
  718. {
  719. if ((lpszValue = (LPSTR)GLOBALALLOC(dwValueLen)) == NULL)
  720. {
  721. hResultCode = DPNERR_OUTOFMEMORY;
  722. goto EXIT_DnGetRegKeyValue;
  723. }
  724. if (RegQueryValueExA(hKey,lpszKeyName,NULL,NULL,(LPBYTE)lpszValue,&dwValueLen) != ERROR_SUCCESS)
  725. {
  726. hResultCode = DPNERR_DOESNOTEXIST;
  727. goto EXIT_DnGetRegKeyValue;
  728. }
  729. }
  730. else
  731. {
  732. hResultCode = DPNERR_DOESNOTEXIST;
  733. goto EXIT_DnGetRegKeyValue;
  734. }
  735. dwValueLen++; // \0 char
  736. if ((lpwszValue = (LPWSTR)GLOBALALLOC(dwValueLen*sizeof(WCHAR))) == NULL)
  737. {
  738. hResultCode = DPNERR_OUTOFMEMORY;
  739. goto EXIT_DnGetRegKeyValue;
  740. }
  741. AnsiToWide(lpwszValue,lpszValue,dwValueLen);
  742. *lplpwszKeyValue = lpwszValue;
  743. EXIT_DnGetRegKeyValue:
  744. if (lpszValue != NULL)
  745. GlobalFree(lpszValue);
  746. DPFX(DPFPREP, 3,"Returning: hResultCode = [%lx]",hResultCode);
  747. return(hResultCode);
  748. }
  749. // void DnFreeProgramDesc
  750. // LPDNPROGRAMDESC lpdnProgramDesc Pointer to a program description structure
  751. //
  752. // Returns
  753. // nothing
  754. //
  755. // Notes
  756. // This function should be called to free program descriptions which were created
  757. // using DnRegRegProgramDesc() or DnGetProgramDesc().
  758. #undef DPF_MODNAME
  759. #define DPF_MODNAME "DnFreeProgramDesc"
  760. void DnFreeProgramDesc(LPDNPROGRAMDESC lpdnProgramDesc)
  761. {
  762. DPFX(DPFPREP, 3,"Parameters: lpdnProgramDesc [%p]",lpdnProgramDesc);
  763. if (lpdnProgramDesc->lpwszApplicationName != NULL)
  764. GlobalFree(lpdnProgramDesc->lpwszApplicationName);
  765. if (lpdnProgramDesc->lpwszApplicationLauncher != NULL)
  766. GlobalFree(lpdnProgramDesc->lpwszApplicationLauncher);
  767. if (lpdnProgramDesc->lpwszCommandLine != NULL)
  768. GlobalFree(lpdnProgramDesc->lpwszCommandLine);
  769. if (lpdnProgramDesc->lpwszCurrentDirectory != NULL)
  770. GlobalFree(lpdnProgramDesc->lpwszCurrentDirectory);
  771. if (lpdnProgramDesc->lpwszDescription != NULL)
  772. GlobalFree(lpdnProgramDesc->lpwszDescription);
  773. if (lpdnProgramDesc->lpwszFilename != NULL)
  774. GlobalFree(lpdnProgramDesc->lpwszFilename);
  775. if (lpdnProgramDesc->lpwszPath != NULL)
  776. GlobalFree(lpdnProgramDesc->lpwszPath);
  777. }
  778. // HRESULT DnReadRegProgramDesc
  779. // HKEY hKey Handle to open key containing program description
  780. // LPDNPROGRAMDESC lpdnProgramDesc Pointer to a program description structure
  781. //
  782. // Returns
  783. // DPN_OK If successfull
  784. // DPNERR_DOESNOTEXIST If there was a problem opening/reading the entry
  785. // DPNERR_OUTOFMEMORY If it could not allocate memory
  786. //
  787. // Notes
  788. // This function reads the program description entry from the registry at hKey into the
  789. // supplied structure. The function will call DnGetRegKeyValue, which allocates
  790. // space for strings as needed. Use DnFreeProgramDesc() to free the program
  791. // description structure.
  792. #undef DPF_MODNAME
  793. #define DPF_MODNAME "DnReadRegProgramDesc"
  794. HRESULT DnReadRegProgramDesc(HKEY hKey, LPDNPROGRAMDESC lpdnProgramDesc)
  795. {
  796. HRESULT hResultCode = DPN_OK;
  797. DPFX(DPFPREP, 3,"Parameters: hKey [%p], lpdnProgramDesc [%p]",hKey,lpdnProgramDesc);
  798. if ((hResultCode = DnGetRegKeyValue(hKey,DN_REG_KEYNAME_APPLICATIONLAUNCHER,
  799. &(lpdnProgramDesc->lpwszApplicationLauncher))) != DPN_OK)
  800. {
  801. DnFreeProgramDesc(lpdnProgramDesc);
  802. goto EXIT_DnReadRegProgramDesc;
  803. }
  804. if ((hResultCode = DnGetRegKeyValue(hKey,DN_REG_KEYNAME_APPLICATIONNAME,
  805. &(lpdnProgramDesc->lpwszApplicationName))) != DPN_OK)
  806. {
  807. DnFreeProgramDesc(lpdnProgramDesc);
  808. goto EXIT_DnReadRegProgramDesc;
  809. }
  810. if ((hResultCode = DnGetRegKeyValue(hKey,DN_REG_KEYNAME_COMMANDLINE,
  811. &(lpdnProgramDesc->lpwszCommandLine))) != DPN_OK)
  812. {
  813. DnFreeProgramDesc(lpdnProgramDesc);
  814. goto EXIT_DnReadRegProgramDesc;
  815. }
  816. if ((hResultCode = DnGetRegKeyValue(hKey,DN_REG_KEYNAME_CURRENTDIRECTORY,
  817. &(lpdnProgramDesc->lpwszCurrentDirectory))) != DPN_OK)
  818. {
  819. DnFreeProgramDesc(lpdnProgramDesc);
  820. goto EXIT_DnReadRegProgramDesc;
  821. }
  822. if ((hResultCode = DnGetRegKeyValue(hKey,DN_REG_KEYNAME_DESCRIPTION,
  823. &(lpdnProgramDesc->lpwszDescription))) != DPN_OK)
  824. {
  825. DnFreeProgramDesc(lpdnProgramDesc);
  826. goto EXIT_DnReadRegProgramDesc;
  827. }
  828. if ((hResultCode = DnGetRegKeyValue(hKey,DN_REG_KEYNAME_FILENAME,
  829. &(lpdnProgramDesc->lpwszFilename))) != DPN_OK)
  830. {
  831. DnFreeProgramDesc(lpdnProgramDesc);
  832. goto EXIT_DnReadRegProgramDesc;
  833. }
  834. if ((hResultCode = DnGetRegKeyValue(hKey,DN_REG_KEYNAME_PATH,
  835. &(lpdnProgramDesc->lpwszPath))) != DPN_OK)
  836. {
  837. DnFreeProgramDesc(lpdnProgramDesc);
  838. goto EXIT_DnReadRegProgramDesc;
  839. }
  840. EXIT_DnReadRegProgramDesc:
  841. DPFX(DPFPREP, 3,"Returning: hResultCode = [%lx]",hResultCode);
  842. return(hResultCode);
  843. }
  844. // HRESULT DnDelAppKey
  845. // lpGuid lpGuid Pointer to GUID of program desired
  846. //
  847. // Returns
  848. // DPN_OK If successfull
  849. // DPNERR_OUTOFMEMORY If it could not allocate memory
  850. // DPNERR_DOESNOTEXIST If the entry does not exist, or there was a problem opening/reading a key
  851. // DPNERR_GENERIC If the application key could not be deleted
  852. //
  853. // Notes
  854. // This function deletes a GUID specified application registry entry.
  855. #undef DPF_MODNAME
  856. #define DPF_MODNAME "DnDelAppKey"
  857. HRESULT DnDelAppKey(LPGUID lpGuid)
  858. {
  859. HRESULT hResultCode = DPN_OK;
  860. HKEY hBaseKey = NULL;
  861. HKEY hSubKey;
  862. DWORD dwEnumIndex = 0;
  863. BOOL bFound = FALSE;
  864. DWORD dwMaxSubKeyLen;
  865. LPSTR lpszSubKey = NULL;
  866. DWORD dwSubKeyLen;
  867. CHAR lpszGuid[DN_GUID_STR_LEN+1];
  868. DWORD dwKeyValueLen;
  869. GUID guidApplication;
  870. DPFX(DPFPREP, 3,"Parameters: lpGuid [%p]",lpGuid);
  871. // Open base key
  872. if (DnOpenRegKey(HKEY_LOCAL_MACHINE,DN_REG_LOCAL_APPL_SUBKEY,&hBaseKey) != DPN_OK)
  873. {
  874. hResultCode = DPNERR_DOESNOTEXIST;
  875. goto EXIT_DnDelAppKey;
  876. }
  877. // Create buffer to read each subkey (application) name into
  878. if (RegQueryInfoKeyA(hBaseKey,NULL,NULL,NULL,NULL,&dwMaxSubKeyLen,NULL,NULL,NULL,NULL,NULL,NULL)
  879. != ERROR_SUCCESS)
  880. {
  881. DPFX(DPFPREP, 9,"RegQueryInfoKey() failed");
  882. hResultCode = DPNERR_DOESNOTEXIST;
  883. goto EXIT_DnDelAppKey;
  884. }
  885. dwMaxSubKeyLen++; // Space for null terminator
  886. if ((lpszSubKey = (LPSTR)GLOBALALLOC(dwMaxSubKeyLen)) == NULL)
  887. {
  888. DPFX(DPFPREP, 9,"lpszSubKey = GLOBALALLOC(%d) failed",dwMaxSubKeyLen);
  889. hResultCode = DPNERR_OUTOFMEMORY;
  890. goto EXIT_DnDelAppKey;
  891. }
  892. // For each subkey (application) get guid and check against lpGuid
  893. dwEnumIndex = 0;
  894. dwSubKeyLen = dwMaxSubKeyLen;
  895. while (RegEnumKeyExA(hBaseKey,dwEnumIndex++,lpszSubKey,&dwSubKeyLen,NULL,NULL,NULL,NULL) == ERROR_SUCCESS)
  896. {
  897. if (DnOpenRegKey(hBaseKey,lpszSubKey,&hSubKey) != DPN_OK)
  898. {
  899. hResultCode = DPNERR_DOESNOTEXIST;
  900. goto EXIT_DnDelAppKey;
  901. }
  902. dwKeyValueLen = DN_GUID_STR_LEN+1;
  903. if (RegQueryValueExA(hSubKey,DN_REG_KEYNAME_GUIDAPPLICATION,NULL,NULL,(LPBYTE)lpszGuid,&dwKeyValueLen) != DPN_OK)
  904. {
  905. RegCloseKey(hSubKey);
  906. dwSubKeyLen = dwMaxSubKeyLen;
  907. continue;
  908. }
  909. if (GUIDFromStringA(lpszGuid,&guidApplication) != DPN_OK)
  910. {
  911. RegCloseKey(hSubKey);
  912. dwSubKeyLen = dwMaxSubKeyLen;
  913. continue;
  914. }
  915. if (IsEqualGuid(lpGuid,&guidApplication))
  916. { // Found it !
  917. if (RegDeleteKey(hBaseKey,lpszSubKey) != ERROR_SUCCESS)
  918. {
  919. hResultCode = DPNERR_GENERIC;
  920. }
  921. RegCloseKey(hSubKey);
  922. bFound = TRUE;
  923. break;
  924. }
  925. RegCloseKey(hSubKey);
  926. dwSubKeyLen = dwMaxSubKeyLen;
  927. }
  928. if (!bFound)
  929. hResultCode = DPNERR_DOESNOTEXIST;
  930. EXIT_DnDelAppKey:
  931. if (hBaseKey != NULL)
  932. RegCloseKey(hBaseKey);
  933. if (lpszSubKey != NULL)
  934. GlobalFree(lpszSubKey);
  935. DPFX(DPFPREP, 3,"Returning: hResultCode = [%lx]",hResultCode);
  936. return(hResultCode);
  937. }
  938. // HRESULT DnGetProgramDesc
  939. // lpGuid lpGuid Pointer to GUID of program desired
  940. // LPDNPROGRAMDESC lpdnProgramDesc Pointer to a program description structure
  941. //
  942. // Returns
  943. // DPN_OK If successfull
  944. // DPNERR_OUTOFMEMORY If it could not allocate memory
  945. // DPNERR_DOESNOTEXIST If the entry does not exist, or there was a problem opening/reading a key
  946. //
  947. // Notes
  948. // This function gets the program description for a GUID specified program. The
  949. // function will search for the program description entry in the registry, and the
  950. // LPDNPROGRAMDESC structure will then be filled in. Any strings required will be
  951. // allocated. When done with the structure, DnFreeProgramDesc() should be used to
  952. // release it. The program description structure should be empty (string pointers
  953. // invalid) when passed into this function.
  954. #undef DPF_MODNAME
  955. #define DPF_MODNAME "DnGetProgramDesc"
  956. HRESULT DnGetProgramDesc(LPGUID lpGuid, LPDNPROGRAMDESC lpdnProgramDesc)
  957. {
  958. HRESULT hResultCode = DPN_OK;
  959. HKEY hBaseKey = NULL;
  960. HKEY hSubKey;
  961. DWORD dwEnumIndex = 0;
  962. BOOL bFound = FALSE;
  963. DWORD dwMaxSubKeyLen;
  964. LPSTR lpszSubKey = NULL;
  965. DWORD dwSubKeyLen;
  966. CHAR lpszGuid[DN_GUID_STR_LEN+1];
  967. DWORD dwKeyValueLen;
  968. GUID guidApplication;
  969. DPFX(DPFPREP, 3,"Parameters: lpGuid [%p], lpdnProgramDesc [%p]",lpGuid,lpdnProgramDesc);
  970. // Clean up structure
  971. lpdnProgramDesc->lpwszApplicationLauncher = NULL;
  972. lpdnProgramDesc->lpwszApplicationName = NULL;
  973. lpdnProgramDesc->lpwszCommandLine = NULL;
  974. lpdnProgramDesc->lpwszCurrentDirectory = NULL;
  975. lpdnProgramDesc->lpwszDescription = NULL;
  976. lpdnProgramDesc->lpwszFilename = NULL;
  977. lpdnProgramDesc->lpwszPath = NULL;
  978. // Open base key
  979. if (DnOpenRegKey(HKEY_LOCAL_MACHINE,DN_REG_LOCAL_APPL_SUBKEY,&hBaseKey) != DPN_OK)
  980. {
  981. hResultCode = DPNERR_DOESNOTEXIST;
  982. goto EXIT_DnGetProgramDesc;
  983. }
  984. // Create buffer to read each subkey (application) name into
  985. if (RegQueryInfoKeyA(hBaseKey,NULL,NULL,NULL,NULL,&dwMaxSubKeyLen,NULL,NULL,NULL,NULL,NULL,NULL)
  986. != ERROR_SUCCESS)
  987. {
  988. DPFX(DPFPREP, 9,"RegQueryInfoKey() failed");
  989. hResultCode = DPNERR_DOESNOTEXIST;
  990. goto EXIT_DnGetProgramDesc;
  991. }
  992. dwMaxSubKeyLen++; // Space for null terminator
  993. if ((lpszSubKey = (LPSTR)GLOBALALLOC(dwMaxSubKeyLen)) == NULL)
  994. {
  995. DPFX(DPFPREP, 9,"lpszSubKey = GLOBALALLOC(%d) failed",dwMaxSubKeyLen);
  996. hResultCode = DPNERR_OUTOFMEMORY;
  997. goto EXIT_DnGetProgramDesc;
  998. }
  999. // For each subkey (application) get guid and check against lpGuid
  1000. dwEnumIndex = 0;
  1001. dwSubKeyLen = dwMaxSubKeyLen;
  1002. while (RegEnumKeyExA(hBaseKey,dwEnumIndex++,lpszSubKey,&dwSubKeyLen,NULL,NULL,NULL,NULL) == ERROR_SUCCESS)
  1003. {
  1004. if (DnOpenRegKey(hBaseKey,lpszSubKey,&hSubKey) != DPN_OK)
  1005. {
  1006. hResultCode = DPNERR_DOESNOTEXIST;
  1007. goto EXIT_DnGetProgramDesc;
  1008. }
  1009. dwKeyValueLen = DN_GUID_STR_LEN+1;
  1010. if (RegQueryValueExA(hSubKey,DN_REG_KEYNAME_GUIDAPPLICATION,NULL,NULL,(LPBYTE)lpszGuid,&dwKeyValueLen) != DPN_OK)
  1011. {
  1012. RegCloseKey(hSubKey);
  1013. dwSubKeyLen = dwMaxSubKeyLen;
  1014. continue;
  1015. }
  1016. if (GUIDFromStringA(lpszGuid,&guidApplication) != DPN_OK)
  1017. {
  1018. RegCloseKey(hSubKey);
  1019. dwSubKeyLen = dwMaxSubKeyLen;
  1020. continue;
  1021. }
  1022. if (IsEqualGuid(lpGuid,&guidApplication))
  1023. { // Found it !
  1024. CopyGuid(&(lpdnProgramDesc->guidApplication),&guidApplication);
  1025. hResultCode = DnReadRegProgramDesc(hSubKey,lpdnProgramDesc);
  1026. RegCloseKey(hSubKey);
  1027. bFound = TRUE;
  1028. break;
  1029. }
  1030. RegCloseKey(hSubKey);
  1031. dwSubKeyLen = dwMaxSubKeyLen;
  1032. }
  1033. if (!bFound)
  1034. hResultCode = DPNERR_DOESNOTEXIST;
  1035. EXIT_DnGetProgramDesc:
  1036. if (hBaseKey != NULL)
  1037. RegCloseKey(hBaseKey);
  1038. if (lpszSubKey != NULL)
  1039. GlobalFree(lpszSubKey);
  1040. DPFX(DPFPREP, 3,"Returning: hResultCode = [%lx]",hResultCode);
  1041. return(hResultCode);
  1042. }
  1043. // HRESULT DnExpandEnvStringA
  1044. // LPSTR lpszOrig Orginal string, including environment variables
  1045. // LPSTR *lplpszResult Resulting string, after expanding environemnt variables
  1046. //
  1047. // Returns
  1048. // DPN_OK If successfull
  1049. // DPNERR_OUTOFMEMORY If it could not allocate memory
  1050. //
  1051. // Notes
  1052. // This function expands embedded environment strings. It calculates the expected size of the
  1053. // required expanded string, allocates it, expands environment variables and returns a pointer
  1054. // to the new string to the caller.
  1055. #undef DPF_MODNAME
  1056. #define DPF_MODNAME "DnExpandEnvStringA"
  1057. HRESULT DnExpandEnvStringA(LPSTR lpszOrig, LPSTR *lplpszResult)
  1058. {
  1059. HRESULT hResultCode = DPN_OK;
  1060. LPSTR lpszResult;
  1061. DWORD dwStrLen;
  1062. DPFX(DPFPREP, 3,"Parameters: lpszOrig [%p], lplpszRestul [%p]",lpszOrig,lplpszResult);
  1063. // Expand environment strings
  1064. if ((dwStrLen = ExpandEnvironmentStringsA(lpszOrig,NULL,0)) == 0)
  1065. {
  1066. hResultCode = DPNERR_OUTOFMEMORY;
  1067. goto EXIT_DnExpandEnvStringA;
  1068. }
  1069. if ((lpszResult = (LPSTR)GLOBALALLOC(dwStrLen)) == NULL)
  1070. {
  1071. hResultCode = DPNERR_OUTOFMEMORY;
  1072. goto EXIT_DnExpandEnvStringA;
  1073. }
  1074. if (ExpandEnvironmentStringsA(lpszOrig,lpszResult,dwStrLen) == 0)
  1075. {
  1076. GlobalFree(lpszResult);
  1077. hResultCode = DPNERR_OUTOFMEMORY;
  1078. goto EXIT_DnExpandEnvStringA;
  1079. }
  1080. *lplpszResult = lpszResult;
  1081. EXIT_DnExpandEnvStringA:
  1082. DPFX(DPFPREP, 3,"Returning: hResultCode = [%lx]",hResultCode);
  1083. return(hResultCode);
  1084. }
  1085. // HRESULT DnExpandEnvStringW
  1086. // LPWSTR lpwszOrig Orginal string, including environment variables
  1087. // LPWSTR *lplpwszResult Resulting string, after expanding environemnt variables
  1088. //
  1089. // Returns
  1090. // DPN_OK If successfull
  1091. // DPNERR_OUTOFMEMORY If it could not allocate memory
  1092. //
  1093. // Notes
  1094. // This function expands embedded environment strings. It calculates the expected size of the
  1095. // required expanded string, allocates it, expands environment variables and returns a pointer
  1096. // to the new string to the caller.
  1097. #undef DPF_MODNAME
  1098. #define DPF_MODNAME "DnExpandEnvStringW"
  1099. HRESULT DnExpandEnvStringW(LPWSTR lpwszOrig, LPWSTR *lplpwszResult)
  1100. {
  1101. HRESULT hResultCode = DPN_OK;
  1102. LPWSTR lpwszResult;
  1103. DWORD dwStrLen;
  1104. DPFX(DPFPREP, 3,"Parameters: lpwszOrig [%p], lplpwszRestul [%p]",lpwszOrig,lplpwszResult);
  1105. // Expand environment strings
  1106. if ((dwStrLen = ExpandEnvironmentStringsW(lpwszOrig,NULL,0)) == 0)
  1107. {
  1108. hResultCode = DPNERR_OUTOFMEMORY;
  1109. goto EXIT_DnExpandEnvStringW;
  1110. }
  1111. if ((lpwszResult = (LPWSTR)GLOBALALLOC(dwStrLen*sizeof(WCHAR))) == NULL)
  1112. {
  1113. hResultCode = DPNERR_OUTOFMEMORY;
  1114. goto EXIT_DnExpandEnvStringW;
  1115. }
  1116. if (ExpandEnvironmentStringsW(lpwszOrig,lpwszResult,dwStrLen) == 0)
  1117. {
  1118. GlobalFree(lpwszResult);
  1119. hResultCode = DPNERR_OUTOFMEMORY;
  1120. goto EXIT_DnExpandEnvStringW;
  1121. }
  1122. *lplpwszResult = lpwszResult;
  1123. EXIT_DnExpandEnvStringW:
  1124. DPFX(DPFPREP, 3,"Returning: hResultCode = [%lx]",hResultCode);
  1125. return(hResultCode);
  1126. }
  1127. // HRESULT DnGetOsPlatformId
  1128. //
  1129. // Returns
  1130. // DPN_OK If successfull
  1131. // DPNERR_GENERIC If not
  1132. //
  1133. // Notes
  1134. // This function determines the version of the operating system being run
  1135. #undef DPF_MODNAME
  1136. #define DPF_MODNAME "DnGetOsPlatformId"
  1137. HRESULT DnGetOsPlatformId(void)
  1138. {
  1139. OSVERSIONINFO osv;
  1140. DPFX(DPFPREP, 3,"Parameters: (none)");
  1141. // Set Global
  1142. osv.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
  1143. if (GetVersionEx(&osv) == FALSE)
  1144. return(DPNERR_GENERIC);
  1145. DnOsPlatformId = osv.dwPlatformId;
  1146. return(DPN_OK);
  1147. }
  1148. #endif