1323 lines
36 KiB
C++
1323 lines
36 KiB
C++
/*==========================================================================
|
|
*
|
|
* Copyright (C) 2000 Microsoft Corporation. All Rights Reserved.
|
|
*
|
|
* File: DNLReg.cpp
|
|
* Content: DirectPlay Lobby Registry Functions
|
|
*@@BEGIN_MSINTERNAL
|
|
* History:
|
|
* Date By Reason
|
|
* ==== == ======
|
|
* 02/21/00 mjn Created
|
|
* 04/25/00 rmt Bug #s 33138, 33145, 33150
|
|
* 05/03/00 rmt UnRegister was not implemented! Implementing!
|
|
* 08/05/00 RichGr IA64: Use %p format specifier in DPFs for 32/64-bit pointers and handles.
|
|
* 06/16/2001 rodtoll WINBUG #416983 - RC1: World has full control to HKLM\Software\Microsoft\DirectPlay\Applications on Personal
|
|
* Implementing mirror of keys into HKCU. Algorithm is now:
|
|
* - Read of entries tries HKCU first, then HKLM
|
|
* - Enum of entires is combination of HKCU and HKLM entries with duplicates removed. HKCU takes priority.
|
|
* - Write of entries is HKLM and HKCU. (HKLM may fail, but is ignored).
|
|
*@@END_MSINTERNAL
|
|
*
|
|
***************************************************************************/
|
|
|
|
#include "dnlobbyi.h"
|
|
|
|
|
|
//**********************************************************************
|
|
// Constant definitions
|
|
//**********************************************************************
|
|
|
|
//**********************************************************************
|
|
// Macro definitions
|
|
//**********************************************************************
|
|
|
|
//**********************************************************************
|
|
// Structure definitions
|
|
//**********************************************************************
|
|
|
|
//**********************************************************************
|
|
// Variable definitions
|
|
//**********************************************************************
|
|
|
|
//**********************************************************************
|
|
// Function prototypes
|
|
//**********************************************************************
|
|
|
|
//**********************************************************************
|
|
// Function definitions
|
|
//**********************************************************************
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "DPLDeleteProgramDesc"
|
|
HRESULT DPLDeleteProgramDesc( const GUID * const pGuidApplication )
|
|
{
|
|
HRESULT hResultCode = DPN_OK;
|
|
CRegistry RegistryEntry;
|
|
CRegistry SubEntry;
|
|
DWORD dwLastError;
|
|
HKEY hkCurrentHive;
|
|
BOOL fFound = FALSE;
|
|
BOOL fRemoved = FALSE;
|
|
|
|
DPFX(DPFPREP, 3, "Removing program desc" );
|
|
|
|
for( DWORD dwIndex = 0; dwIndex < 2; dwIndex++ )
|
|
{
|
|
if( dwIndex == 0 )
|
|
{
|
|
hkCurrentHive = HKEY_CURRENT_USER;
|
|
}
|
|
else
|
|
{
|
|
hkCurrentHive = HKEY_LOCAL_MACHINE;
|
|
}
|
|
|
|
if( !RegistryEntry.Open( hkCurrentHive,DPL_REG_LOCAL_APPL_SUBKEY,FALSE,FALSE,TRUE,DPN_KEY_ALL_ACCESS ) )
|
|
{
|
|
DPFX(DPFPREP, 1, "Failed to open key for remove in pass %i", dwIndex );
|
|
continue;
|
|
}
|
|
|
|
// This should be down below the next if block, but 8.0 shipped with a bug
|
|
// which resulted in this function returning DPNERR_NOTALLOWED in cases where
|
|
// the next if block failed. Need to remain compatible
|
|
fFound = TRUE;
|
|
|
|
if( !SubEntry.Open( RegistryEntry, pGuidApplication, FALSE, FALSE,TRUE,DPN_KEY_ALL_ACCESS ) )
|
|
{
|
|
DPFX(DPFPREP, 1, "Failed to open subkey for remove in pass %i", dwIndex );
|
|
continue;
|
|
}
|
|
|
|
SubEntry.Close();
|
|
|
|
if( !RegistryEntry.DeleteSubKey( pGuidApplication ) )
|
|
{
|
|
DPFX(DPFPREP, 1, "Failed to delete subkey for remove in pass %i", dwIndex );
|
|
continue;
|
|
}
|
|
|
|
fRemoved = TRUE;
|
|
|
|
RegistryEntry.Close();
|
|
}
|
|
|
|
if( !fFound )
|
|
{
|
|
DPFX(DPFPREP, 0, "Could not find entry" );
|
|
hResultCode = DPNERR_DOESNOTEXIST;
|
|
}
|
|
else if( !fRemoved )
|
|
{
|
|
dwLastError = GetLastError();
|
|
DPFX(DPFPREP, 0, "Error deleting registry sub-key lastError [0x%lx]", dwLastError );
|
|
hResultCode = DPNERR_NOTALLOWED;
|
|
}
|
|
|
|
DPFX(DPFPREP, 3, "Removing program desc [0x%x]", hResultCode );
|
|
|
|
return hResultCode;
|
|
|
|
}
|
|
|
|
//**********************************************************************
|
|
// ------------------------------
|
|
// DPLWriteProgramDesc
|
|
//
|
|
// Entry: Nothing
|
|
//
|
|
// Exit: DPN_OK
|
|
// ------------------------------
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "DPLWriteProgramDesc"
|
|
|
|
HRESULT DPLWriteProgramDesc(DPL_PROGRAM_DESC *const pdplProgramDesc)
|
|
{
|
|
HRESULT hResultCode;
|
|
CRegistry RegistryEntry;
|
|
CRegistry SubEntry;
|
|
WCHAR *pwsz;
|
|
WCHAR pwszDefault[] = L"\0";
|
|
HKEY hkCurrentHive = NULL;
|
|
BOOL fWritten = FALSE;
|
|
|
|
DPFX(DPFPREP, 3,"Parameters: pdplProgramDesc [0x%p]",pdplProgramDesc);
|
|
|
|
for( DWORD dwIndex = 0; dwIndex < 2; dwIndex++ )
|
|
{
|
|
if( dwIndex == 0 )
|
|
{
|
|
hkCurrentHive = HKEY_LOCAL_MACHINE;
|
|
}
|
|
else
|
|
{
|
|
hkCurrentHive = HKEY_CURRENT_USER;
|
|
}
|
|
|
|
if (!RegistryEntry.Open(hkCurrentHive,DPL_REG_LOCAL_APPL_SUBKEY,FALSE,TRUE,TRUE,DPN_KEY_ALL_ACCESS))
|
|
{
|
|
DPFX( DPFPREP, 1, "Entry not found in user hive on pass %i", dwIndex );
|
|
continue;
|
|
}
|
|
|
|
// Get Application name and GUID from each sub key
|
|
if (!SubEntry.Open(RegistryEntry,&pdplProgramDesc->guidApplication,FALSE,TRUE,TRUE,DPN_KEY_ALL_ACCESS))
|
|
{
|
|
DPFX( DPFPREP, 1, "Entry not found in user hive on pass %i", dwIndex );
|
|
continue;
|
|
}
|
|
|
|
if (!SubEntry.WriteString(DPL_REG_KEYNAME_APPLICATIONNAME,pdplProgramDesc->pwszApplicationName))
|
|
{
|
|
DPFX( DPFPREP, 1, "Could not write ApplicationName on pass %i", dwIndex);
|
|
goto LOOP_END;
|
|
}
|
|
|
|
if (pdplProgramDesc->pwszCommandLine != NULL)
|
|
{
|
|
pwsz = pdplProgramDesc->pwszCommandLine;
|
|
}
|
|
else
|
|
{
|
|
pwsz = pwszDefault;
|
|
}
|
|
if (!SubEntry.WriteString(DPL_REG_KEYNAME_COMMANDLINE,pwsz))
|
|
{
|
|
DPFX( DPFPREP, 1, "Could not write CommandLine on pass %i", dwIndex);
|
|
goto LOOP_END;
|
|
}
|
|
|
|
if (pdplProgramDesc->pwszCurrentDirectory != NULL)
|
|
{
|
|
pwsz = pdplProgramDesc->pwszCurrentDirectory;
|
|
}
|
|
else
|
|
{
|
|
pwsz = pwszDefault;
|
|
}
|
|
if (!SubEntry.WriteString(DPL_REG_KEYNAME_CURRENTDIRECTORY,pwsz))
|
|
{
|
|
DPFX( DPFPREP, 1, "Could not write CurrentDirectory on pass %i", dwIndex);
|
|
goto LOOP_END;
|
|
}
|
|
|
|
if (pdplProgramDesc->pwszDescription != NULL)
|
|
{
|
|
pwsz = pdplProgramDesc->pwszDescription;
|
|
}
|
|
else
|
|
{
|
|
pwsz = pwszDefault;
|
|
}
|
|
if (!SubEntry.WriteString(DPL_REG_KEYNAME_DESCRIPTION,pwsz))
|
|
{
|
|
DPFX( DPFPREP, 1, "Could not write Description on pass %i", dwIndex );
|
|
goto LOOP_END;
|
|
}
|
|
|
|
if (pdplProgramDesc->pwszExecutableFilename != NULL)
|
|
{
|
|
pwsz = pdplProgramDesc->pwszExecutableFilename;
|
|
}
|
|
else
|
|
{
|
|
pwsz = pwszDefault;
|
|
}
|
|
if (!SubEntry.WriteString(DPL_REG_KEYNAME_EXECUTABLEFILENAME,pwsz))
|
|
{
|
|
DPFX( DPFPREP, 1, "Could not write ExecutableFilename on pass %i", dwIndex );
|
|
goto LOOP_END;
|
|
}
|
|
|
|
if (pdplProgramDesc->pwszExecutablePath != NULL)
|
|
{
|
|
pwsz = pdplProgramDesc->pwszExecutablePath;
|
|
}
|
|
else
|
|
{
|
|
pwsz = pwszDefault;
|
|
}
|
|
|
|
if (!SubEntry.WriteString(DPL_REG_KEYNAME_EXECUTABLEPATH,pwsz))
|
|
{
|
|
DPFX( DPFPREP, 1, "Could not write ExecutablePath on pass %i", dwIndex);
|
|
goto LOOP_END;
|
|
}
|
|
|
|
if (pdplProgramDesc->pwszLauncherFilename != NULL)
|
|
{
|
|
pwsz = pdplProgramDesc->pwszLauncherFilename;
|
|
}
|
|
else
|
|
{
|
|
pwsz = pwszDefault;
|
|
}
|
|
if (!SubEntry.WriteString(DPL_REG_KEYNAME_LAUNCHERFILENAME,pwsz))
|
|
{
|
|
DPFX( DPFPREP, 1, "Could not write LauncherFilename on pass %i", dwIndex);
|
|
goto LOOP_END;
|
|
}
|
|
|
|
if (pdplProgramDesc->pwszLauncherPath != NULL)
|
|
{
|
|
pwsz = pdplProgramDesc->pwszLauncherPath;
|
|
}
|
|
else
|
|
{
|
|
pwsz = pwszDefault;
|
|
}
|
|
if (!SubEntry.WriteString(DPL_REG_KEYNAME_LAUNCHERPATH,pwsz))
|
|
{
|
|
DPFX( DPFPREP, 1, "Could not write LauncherPath on pass %i", dwIndex);
|
|
goto LOOP_END;
|
|
}
|
|
|
|
if (!SubEntry.WriteGUID(DPL_REG_KEYNAME_GUID,pdplProgramDesc->guidApplication))
|
|
{
|
|
DPFX( DPFPREP, 1, "Could not write GUID on pass %i", dwIndex);
|
|
goto LOOP_END;
|
|
}
|
|
|
|
fWritten = TRUE;
|
|
|
|
LOOP_END:
|
|
|
|
SubEntry.Close();
|
|
RegistryEntry.Close();
|
|
}
|
|
|
|
if( !fWritten )
|
|
{
|
|
DPFERR("Entry could not be written");
|
|
hResultCode = DPNERR_GENERIC;
|
|
}
|
|
else
|
|
{
|
|
hResultCode = DPN_OK;
|
|
}
|
|
|
|
DPFX(DPFPREP, 3,"Returning: [0x%lx]",hResultCode);
|
|
return(hResultCode);
|
|
}
|
|
|
|
|
|
//**********************************************************************
|
|
// ------------------------------
|
|
// DPLGetProgramDesc
|
|
//
|
|
// Entry: Nothing
|
|
//
|
|
// Exit: DPN_OK
|
|
// DPNERR_BUFFERTOOSMALL
|
|
// ------------------------------
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "DPLGetProgramDesc"
|
|
|
|
HRESULT DPLGetProgramDesc(GUID *const pGuidApplication,
|
|
BYTE *const pBuffer,
|
|
DWORD *const pdwBufferSize)
|
|
{
|
|
HRESULT hResultCode;
|
|
CRegistry RegistryEntry;
|
|
CRegistry SubEntry;
|
|
CPackedBuffer PackedBuffer;
|
|
DWORD dwEntrySize;
|
|
DWORD dwRegValueLengths;
|
|
DPL_PROGRAM_DESC *pdnProgramDesc;
|
|
DWORD dwValueSize;
|
|
HKEY hkCurrentHive = NULL;
|
|
BOOL fFound = FALSE;
|
|
|
|
DPFX(DPFPREP, 3,"Parameters: pGuidApplication [0x%p], pBuffer [0x%p], pdwBufferSize [0x%p]",
|
|
pGuidApplication,pBuffer,pdwBufferSize);
|
|
|
|
for( DWORD dwIndex = 0; dwIndex < 2; dwIndex++ )
|
|
{
|
|
if( dwIndex == 0 )
|
|
{
|
|
hkCurrentHive = HKEY_CURRENT_USER;
|
|
}
|
|
else
|
|
{
|
|
hkCurrentHive = HKEY_LOCAL_MACHINE;
|
|
}
|
|
|
|
if (!RegistryEntry.Open(hkCurrentHive,DPL_REG_LOCAL_APPL_SUBKEY,TRUE,FALSE,TRUE,DPL_REGISTRY_READ_ACCESS))
|
|
{
|
|
DPFX( DPFPREP, 1, "Entry not found in user hive on pass %i", dwIndex );
|
|
continue;
|
|
}
|
|
|
|
// Get Application name and GUID from each sub key
|
|
if (!SubEntry.Open(RegistryEntry,pGuidApplication,TRUE,FALSE,TRUE,DPL_REGISTRY_READ_ACCESS))
|
|
{
|
|
DPFX( DPFPREP, 1, "Entry not found in user hive on pass %i", dwIndex );
|
|
continue;
|
|
}
|
|
|
|
fFound = TRUE;
|
|
break;
|
|
|
|
}
|
|
|
|
if( !fFound )
|
|
{
|
|
DPFERR("Entry not found");
|
|
hResultCode = DPNERR_DOESNOTEXIST;
|
|
goto EXIT_DPLGetProgramDesc;
|
|
}
|
|
|
|
// Calculate total entry size (structure + data)
|
|
dwEntrySize = sizeof(DPL_PROGRAM_DESC);
|
|
dwRegValueLengths = 0;
|
|
if (SubEntry.GetValueLength(DPL_REG_KEYNAME_APPLICATIONNAME,&dwValueSize))
|
|
{
|
|
dwRegValueLengths += dwValueSize;
|
|
}
|
|
if (SubEntry.GetValueLength(DPL_REG_KEYNAME_COMMANDLINE,&dwValueSize))
|
|
{
|
|
dwRegValueLengths += dwValueSize;
|
|
}
|
|
if (SubEntry.GetValueLength(DPL_REG_KEYNAME_CURRENTDIRECTORY,&dwValueSize))
|
|
{
|
|
dwRegValueLengths += dwValueSize;
|
|
}
|
|
if (SubEntry.GetValueLength(DPL_REG_KEYNAME_DESCRIPTION,&dwValueSize))
|
|
{
|
|
dwRegValueLengths += dwValueSize;
|
|
}
|
|
if (SubEntry.GetValueLength(DPL_REG_KEYNAME_EXECUTABLEFILENAME,&dwValueSize))
|
|
{
|
|
dwRegValueLengths += dwValueSize;
|
|
}
|
|
if (SubEntry.GetValueLength(DPL_REG_KEYNAME_EXECUTABLEPATH,&dwValueSize))
|
|
{
|
|
dwRegValueLengths += dwValueSize;
|
|
}
|
|
if (SubEntry.GetValueLength(DPL_REG_KEYNAME_LAUNCHERFILENAME,&dwValueSize))
|
|
{
|
|
dwRegValueLengths += dwValueSize;
|
|
}
|
|
if (SubEntry.GetValueLength(DPL_REG_KEYNAME_LAUNCHERPATH,&dwValueSize))
|
|
{
|
|
dwRegValueLengths += dwValueSize;
|
|
}
|
|
|
|
dwEntrySize += dwRegValueLengths * sizeof( WCHAR );
|
|
DPFX(DPFPREP, 7,"dwEntrySize [%ld]",dwEntrySize);
|
|
|
|
// If supplied buffer sufficient, use it
|
|
if (dwEntrySize <= *pdwBufferSize)
|
|
{
|
|
PackedBuffer.Initialize(pBuffer,*pdwBufferSize);
|
|
|
|
pdnProgramDesc = static_cast<DPL_PROGRAM_DESC*>(PackedBuffer.GetHeadAddress());
|
|
PackedBuffer.AddToFront(NULL,sizeof(DPL_PROGRAM_DESC));
|
|
|
|
dwValueSize = PackedBuffer.GetSpaceRemaining();
|
|
pdnProgramDesc->pwszApplicationName = static_cast<WCHAR*>(PackedBuffer.GetHeadAddress());
|
|
if (!SubEntry.ReadString(DPL_REG_KEYNAME_APPLICATIONNAME,
|
|
pdnProgramDesc->pwszApplicationName,&dwValueSize))
|
|
{
|
|
DPFERR( "Unable to get application name for entry" );
|
|
hResultCode = DPNERR_GENERIC;
|
|
goto EXIT_DPLGetProgramDesc;
|
|
}
|
|
if (dwValueSize > 1)
|
|
{
|
|
PackedBuffer.AddToFront(NULL,dwValueSize * sizeof(WCHAR));
|
|
}
|
|
else
|
|
{
|
|
pdnProgramDesc->pwszApplicationName = NULL;
|
|
}
|
|
|
|
dwValueSize = PackedBuffer.GetSpaceRemaining();
|
|
pdnProgramDesc->pwszCommandLine = static_cast<WCHAR*>(PackedBuffer.GetHeadAddress());
|
|
if (!SubEntry.ReadString(DPL_REG_KEYNAME_COMMANDLINE,
|
|
pdnProgramDesc->pwszCommandLine,&dwValueSize))
|
|
{
|
|
DPFERR( "Unable to get commandline for entry" );
|
|
hResultCode = DPNERR_GENERIC;
|
|
goto EXIT_DPLGetProgramDesc;
|
|
}
|
|
if (dwValueSize > 1)
|
|
{
|
|
PackedBuffer.AddToFront(NULL,dwValueSize * sizeof(WCHAR));
|
|
}
|
|
else
|
|
{
|
|
pdnProgramDesc->pwszCommandLine = NULL;
|
|
}
|
|
|
|
dwValueSize = PackedBuffer.GetSpaceRemaining();
|
|
pdnProgramDesc->pwszCurrentDirectory = static_cast<WCHAR*>(PackedBuffer.GetHeadAddress());
|
|
if (!SubEntry.ReadString(DPL_REG_KEYNAME_CURRENTDIRECTORY,
|
|
pdnProgramDesc->pwszCurrentDirectory,&dwValueSize))
|
|
{
|
|
DPFERR( "Unable to get current directory filename for entry" );
|
|
hResultCode = DPNERR_GENERIC;
|
|
goto EXIT_DPLGetProgramDesc;
|
|
}
|
|
if (dwValueSize > 1)
|
|
{
|
|
PackedBuffer.AddToFront(NULL,dwValueSize * sizeof(WCHAR));
|
|
}
|
|
else
|
|
{
|
|
pdnProgramDesc->pwszCurrentDirectory = NULL;
|
|
}
|
|
|
|
dwValueSize = PackedBuffer.GetSpaceRemaining();
|
|
pdnProgramDesc->pwszDescription = static_cast<WCHAR*>(PackedBuffer.GetHeadAddress());
|
|
if (!SubEntry.ReadString(DPL_REG_KEYNAME_DESCRIPTION,
|
|
pdnProgramDesc->pwszDescription,&dwValueSize))
|
|
{
|
|
DPFERR( "Unable to get description for entry" );
|
|
hResultCode = DPNERR_GENERIC;
|
|
goto EXIT_DPLGetProgramDesc;
|
|
}
|
|
if (dwValueSize > 1)
|
|
{
|
|
PackedBuffer.AddToFront(NULL,dwValueSize * sizeof(WCHAR));
|
|
}
|
|
else
|
|
{
|
|
pdnProgramDesc->pwszDescription = NULL;
|
|
}
|
|
|
|
dwValueSize = PackedBuffer.GetSpaceRemaining();
|
|
pdnProgramDesc->pwszExecutableFilename = static_cast<WCHAR*>(PackedBuffer.GetHeadAddress());
|
|
if (!SubEntry.ReadString(DPL_REG_KEYNAME_EXECUTABLEFILENAME,
|
|
pdnProgramDesc->pwszExecutableFilename,&dwValueSize))
|
|
{
|
|
DPFERR( "Unable to get executable filename for entry" );
|
|
hResultCode = DPNERR_GENERIC;
|
|
goto EXIT_DPLGetProgramDesc;
|
|
}
|
|
if (dwValueSize > 1)
|
|
{
|
|
PackedBuffer.AddToFront(NULL,dwValueSize * sizeof(WCHAR));
|
|
}
|
|
else
|
|
{
|
|
pdnProgramDesc->pwszExecutableFilename = NULL;
|
|
}
|
|
|
|
dwValueSize = PackedBuffer.GetSpaceRemaining();
|
|
pdnProgramDesc->pwszExecutablePath = static_cast<WCHAR*>(PackedBuffer.GetHeadAddress());
|
|
if (!SubEntry.ReadString(DPL_REG_KEYNAME_EXECUTABLEPATH,
|
|
pdnProgramDesc->pwszExecutablePath,&dwValueSize))
|
|
{
|
|
DPFERR( "Unable to get executable path for entry" );
|
|
hResultCode = DPNERR_GENERIC;
|
|
goto EXIT_DPLGetProgramDesc;
|
|
}
|
|
if (dwValueSize > 1)
|
|
{
|
|
PackedBuffer.AddToFront(NULL,dwValueSize * sizeof(WCHAR));
|
|
}
|
|
else
|
|
{
|
|
pdnProgramDesc->pwszExecutablePath = NULL;
|
|
}
|
|
|
|
dwValueSize = PackedBuffer.GetSpaceRemaining();
|
|
pdnProgramDesc->pwszLauncherFilename = static_cast<WCHAR*>(PackedBuffer.GetHeadAddress());
|
|
if (!SubEntry.ReadString(DPL_REG_KEYNAME_LAUNCHERFILENAME,
|
|
pdnProgramDesc->pwszLauncherFilename,&dwValueSize))
|
|
{
|
|
DPFERR( "Unable to get launcher filename for entry" );
|
|
hResultCode = DPNERR_GENERIC;
|
|
goto EXIT_DPLGetProgramDesc;
|
|
}
|
|
if (dwValueSize > 1)
|
|
{
|
|
PackedBuffer.AddToFront(NULL,dwValueSize * sizeof(WCHAR));
|
|
}
|
|
else
|
|
{
|
|
pdnProgramDesc->pwszLauncherFilename = NULL;
|
|
}
|
|
|
|
dwValueSize = PackedBuffer.GetSpaceRemaining();
|
|
pdnProgramDesc->pwszLauncherPath = static_cast<WCHAR*>(PackedBuffer.GetHeadAddress());
|
|
if (!SubEntry.ReadString(DPL_REG_KEYNAME_LAUNCHERPATH,
|
|
pdnProgramDesc->pwszLauncherPath,&dwValueSize))
|
|
{
|
|
DPFERR( "Unable to get launcher path for entry" );
|
|
hResultCode = DPNERR_GENERIC;
|
|
goto EXIT_DPLGetProgramDesc;
|
|
}
|
|
if (dwValueSize > 1)
|
|
{
|
|
PackedBuffer.AddToFront(NULL,dwValueSize * sizeof(WCHAR));
|
|
}
|
|
else
|
|
{
|
|
pdnProgramDesc->pwszLauncherPath = NULL;
|
|
}
|
|
|
|
pdnProgramDesc->dwSize = sizeof(DPL_PROGRAM_DESC);
|
|
pdnProgramDesc->dwFlags = 0;
|
|
pdnProgramDesc->guidApplication = *pGuidApplication;
|
|
|
|
hResultCode = DPN_OK;
|
|
}
|
|
else
|
|
{
|
|
hResultCode = DPNERR_BUFFERTOOSMALL;
|
|
}
|
|
|
|
SubEntry.Close();
|
|
RegistryEntry.Close();
|
|
|
|
if (hResultCode == DPN_OK || hResultCode == DPNERR_BUFFERTOOSMALL)
|
|
{
|
|
*pdwBufferSize = dwEntrySize;
|
|
}
|
|
|
|
EXIT_DPLGetProgramDesc:
|
|
|
|
DPFX(DPFPREP, 3,"Returning: [0x%lx]",hResultCode);
|
|
return(hResultCode);
|
|
}
|
|
|
|
|
|
|
|
// ------------------------------------------------------------------------------
|
|
|
|
#if 0
|
|
|
|
// HRESULT DnAddRegKey
|
|
// HKEY hBase Open key from which to start
|
|
// LPSTR lpszLocation Key path in Subkey1/Subkey2... format (ANSI string)
|
|
// LPSTR lpszName Name of key (ANSI string)
|
|
// LPWSTR lpwszValue Value of key (Unicode string)
|
|
//
|
|
// Returns
|
|
// DPN_OK If the key was added successfully
|
|
// DPNERR_GENERIC If there was a problem opening/creating/adding
|
|
// DPNERR_OUTOFMEMORY If it could not allocate memory
|
|
//
|
|
// Notes
|
|
// The key path and name are in ANSI CHAR format, and the key value to add is in
|
|
// Unicode WCHAR format. This function recursively calls itself to descend the
|
|
// registry tree staring from the open key, hBase, creating keys as required.
|
|
//
|
|
// Key names are limited to ANSI, whereas key values are in Unicode
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "DnAddRegKey"
|
|
|
|
HRESULT DnAddRegKey(HKEY hBase, LPSTR lpszLocation, LPSTR lpszName, LPWSTR lpwszValue)
|
|
{
|
|
LPSTR lpc;
|
|
LPSTR lpszCopy = NULL;
|
|
LPSTR lpszAnsiValue = NULL;
|
|
LPWSTR lpwszUnicodeName = NULL;
|
|
DWORD dwLen,dwDisposition;
|
|
int iLen;
|
|
HKEY h;
|
|
HRESULT hResultCode = DPN_OK;
|
|
LONG tmp;
|
|
|
|
DPFX(DPFPREP, 3,"Parameters: hBase [%p], lpszLocation [%p], lpszName [%p], lpwszValue [%p]",
|
|
hBase,lpszLocation,lpszName,lpwszValue);
|
|
|
|
if (strlen(lpszLocation) == 0)
|
|
{
|
|
DPFX(DPFPREP, 7,"RegSetValue");
|
|
// Add key here
|
|
iLen = wcslen(lpwszValue) + 1;
|
|
if (DN_RUNNING_NT)
|
|
{
|
|
// For WindowsNT, just place the Unicode key value into the key
|
|
DPFX(DPFPREP, 5,"WinNT - Use Unicode");
|
|
// Convert key name from ANSI to Unicode
|
|
if ((lpwszUnicodeName = (LPWSTR)GLOBALALLOC((strlen(lpszName)+1)*sizeof(WCHAR))) == NULL)
|
|
{
|
|
hResultCode = DPNERR_OUTOFMEMORY;
|
|
goto EXIT_DnAddRegKey;
|
|
}
|
|
AnsiToWide(lpwszUnicodeName,lpszName,strlen(lpszName)+1);
|
|
// Set key value
|
|
if (RegSetValueExW(hBase,lpwszUnicodeName,0,REG_EXPAND_SZ,(CONST BYTE *)lpwszValue,
|
|
iLen*sizeof(WCHAR)) != ERROR_SUCCESS)
|
|
{
|
|
hResultCode = DPNERR_GENERIC;
|
|
goto EXIT_DnAddRegKey;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// For Windows9x, convert Unicode key value to ANSI before placing in key
|
|
DPFX(DPFPREP, 5,"Win9x - Use ANSI");
|
|
// Convert key value from Unicode to ANSI first
|
|
if ((lpszAnsiValue = (LPSTR)GLOBALALLOC(iLen)) == NULL)
|
|
{
|
|
hResultCode = DPNERR_OUTOFMEMORY;
|
|
goto EXIT_DnAddRegKey;
|
|
}
|
|
WideToAnsi(lpszAnsiValue,lpwszValue,iLen);
|
|
// Set key value
|
|
if (RegSetValueExA(hBase,lpszName,0,REG_EXPAND_SZ,(CONST BYTE *)lpszAnsiValue,
|
|
iLen) != ERROR_SUCCESS)
|
|
{
|
|
hResultCode = DPNERR_GENERIC;
|
|
goto EXIT_DnAddRegKey;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for(lpc = lpszLocation ; *lpc != '/' && *lpc != '\0' ; lpc++)
|
|
;
|
|
dwLen = lpc-lpszLocation+1;
|
|
if ((lpszCopy = (LPSTR)GLOBALALLOC(dwLen)) == NULL)
|
|
{
|
|
hResultCode = DPNERR_OUTOFMEMORY;
|
|
goto EXIT_DnAddRegKey;
|
|
}
|
|
memcpy((void *)lpszCopy,(void *)lpszLocation,dwLen);
|
|
*((LPSTR)(lpszCopy+dwLen-1)) = '\0';
|
|
DPFX(DPFPREP, 5,"Calling RegCreateKeyExA() to create %s",lpszCopy);
|
|
if ((tmp = RegCreateKeyExA(hBase,lpszCopy,0,"None",REG_OPTION_NON_VOLATILE,
|
|
KEY_ALL_ACCESS,NULL,&h,&dwDisposition)) != ERROR_SUCCESS)
|
|
{
|
|
hResultCode = DPNERR_GENERIC;
|
|
goto EXIT_DnAddRegKey;
|
|
}
|
|
if (*lpc == '/')
|
|
lpc++;
|
|
hResultCode = DnAddRegKey(h,lpc,lpszName,lpwszValue);
|
|
RegCloseKey(h);
|
|
}
|
|
|
|
EXIT_DnAddRegKey: // Clean up
|
|
|
|
DPFX(DPFPREP, 3, "hResultCode = %ld",hResultCode);
|
|
|
|
if (lpszCopy != NULL)
|
|
GlobalFree(lpszCopy);
|
|
if (lpszAnsiValue != NULL)
|
|
GlobalFree(lpszAnsiValue);
|
|
if (lpwszUnicodeName != NULL)
|
|
GlobalFree(lpwszUnicodeName);
|
|
|
|
return(hResultCode);
|
|
}
|
|
|
|
|
|
// HRESULT DnOpenRegKey
|
|
// HKEY hBase Open key from which to start
|
|
// LPSTR lpszLocation Key path in Subkey1/Subkey2... format (ANSI string)
|
|
// HKEY * lpHkey Pointer to key handle
|
|
//
|
|
// Returns
|
|
// DPN_OK If the key was opened successfully
|
|
// DPNERR_DOESNOTEXIST If a key could not be opened
|
|
// DPNERR_OUTOFMEMORY If it could not allocate memory
|
|
// DPNERR_INVALIDPARAM If there was an invalid key pay (end in / or is NULL)
|
|
//
|
|
// Notes
|
|
// The key path is in ANSI CHAR format.
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "DnOpenRegKey"
|
|
|
|
HRESULT DnOpenRegKey(HKEY hBase, LPSTR lpszLocation, HKEY *lpHkey)
|
|
{
|
|
LPSTR lpc;
|
|
LPSTR lpszCopy = NULL;
|
|
DWORD dwLen;
|
|
HKEY h;
|
|
HRESULT hResultCode = DPN_OK;
|
|
|
|
DPFX(DPFPREP, 3,"Parameters: hBase [%p], lpszLocation [%p], lpHkey [%p]",
|
|
hBase,lpszLocation,lpHkey);
|
|
|
|
if (strlen(lpszLocation) == 0)
|
|
{
|
|
hResultCode = DPNERR_INVALIDPARAM;
|
|
goto EXIT_DnOpenRegKey;
|
|
}
|
|
else
|
|
{
|
|
for (lpc = lpszLocation ; *lpc != '/' && *lpc != '\0' ; lpc++)
|
|
;
|
|
dwLen = lpc-lpszLocation;
|
|
if ((lpszCopy = (LPSTR)GLOBALALLOC(dwLen+1)) == NULL)
|
|
{
|
|
hResultCode = DPNERR_OUTOFMEMORY;
|
|
goto EXIT_DnOpenRegKey;
|
|
}
|
|
memcpy(lpszCopy,lpszLocation,dwLen);
|
|
*(lpszCopy+dwLen) = '\0';
|
|
if (RegOpenKeyExA(hBase,lpszCopy,0,KEY_READ,&h) != ERROR_SUCCESS)
|
|
{
|
|
hResultCode = DPNERR_DOESNOTEXIST;
|
|
goto EXIT_DnOpenRegKey;
|
|
}
|
|
if (*lpc == '/') // More keys - open next sub key
|
|
{
|
|
lpc++;
|
|
hResultCode = DnOpenRegKey(h,lpc,lpHkey);
|
|
RegCloseKey(h);
|
|
}
|
|
else // Last key - set handle
|
|
{
|
|
*lpHkey = h;
|
|
goto EXIT_DnOpenRegKey;
|
|
}
|
|
}
|
|
EXIT_DnOpenRegKey:
|
|
|
|
if (lpszCopy != NULL)
|
|
GlobalFree(lpszCopy);
|
|
|
|
DPFX(DPFPREP, 3,"Returning: hResultCode = [%lx]",hResultCode);
|
|
return(hResultCode);
|
|
}
|
|
|
|
|
|
// HRESULT DnGetRegKeyValue
|
|
// HKEY hKey Open key from which to start
|
|
// LPSTR lpszKeyName Key name (ANSI string) to retrieve
|
|
// LPWSTR *lplpwszKeyValue Pointer to the address pointer to a Unicode string
|
|
//
|
|
// Returns
|
|
// DPN_OK If successfull
|
|
// DPNERR_DOESNOTEXIST If there was a problem opening/reading the key
|
|
// DPNERR_OUTOFMEMORY If it could not allocate memory
|
|
//
|
|
// Notes
|
|
// The key name is an Ansi string. The function gets the length of the key value,
|
|
// allocates a buffer for it, and then reads the key into the buffer.
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "DnGetRegKeyValue"
|
|
|
|
HRESULT DnGetRegKeyValue(HKEY hKey, LPSTR lpszKeyName, LPWSTR *lplpwszKeyValue)
|
|
{
|
|
HRESULT hResultCode = DPN_OK;
|
|
LPSTR lpszValue = NULL;
|
|
LPWSTR lpwszValue = NULL;
|
|
DWORD dwValueLen;
|
|
LONG lReturnValue;
|
|
|
|
DPFX(DPFPREP, 3,"Parameters: hKey [%p], lpszKeyName[%p], lplpwszKeyValue [%p]",
|
|
hKey,lpszKeyName,lplpwszKeyValue);
|
|
|
|
dwValueLen = 0;
|
|
lReturnValue = RegQueryValueExA(hKey,lpszKeyName,NULL,NULL,NULL,&dwValueLen);
|
|
if (lReturnValue == ERROR_SUCCESS)
|
|
{
|
|
if ((lpszValue = (LPSTR)GLOBALALLOC(dwValueLen)) == NULL)
|
|
{
|
|
hResultCode = DPNERR_OUTOFMEMORY;
|
|
goto EXIT_DnGetRegKeyValue;
|
|
}
|
|
if (RegQueryValueExA(hKey,lpszKeyName,NULL,NULL,(LPBYTE)lpszValue,&dwValueLen) != ERROR_SUCCESS)
|
|
{
|
|
hResultCode = DPNERR_DOESNOTEXIST;
|
|
goto EXIT_DnGetRegKeyValue;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
hResultCode = DPNERR_DOESNOTEXIST;
|
|
goto EXIT_DnGetRegKeyValue;
|
|
}
|
|
dwValueLen++; // \0 char
|
|
if ((lpwszValue = (LPWSTR)GLOBALALLOC(dwValueLen*sizeof(WCHAR))) == NULL)
|
|
{
|
|
hResultCode = DPNERR_OUTOFMEMORY;
|
|
goto EXIT_DnGetRegKeyValue;
|
|
}
|
|
AnsiToWide(lpwszValue,lpszValue,dwValueLen);
|
|
*lplpwszKeyValue = lpwszValue;
|
|
|
|
EXIT_DnGetRegKeyValue:
|
|
|
|
if (lpszValue != NULL)
|
|
GlobalFree(lpszValue);
|
|
|
|
DPFX(DPFPREP, 3,"Returning: hResultCode = [%lx]",hResultCode);
|
|
return(hResultCode);
|
|
}
|
|
|
|
|
|
// void DnFreeProgramDesc
|
|
// LPDNPROGRAMDESC lpdnProgramDesc Pointer to a program description structure
|
|
//
|
|
// Returns
|
|
// nothing
|
|
//
|
|
// Notes
|
|
// This function should be called to free program descriptions which were created
|
|
// using DnRegRegProgramDesc() or DnGetProgramDesc().
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "DnFreeProgramDesc"
|
|
|
|
void DnFreeProgramDesc(LPDNPROGRAMDESC lpdnProgramDesc)
|
|
{
|
|
DPFX(DPFPREP, 3,"Parameters: lpdnProgramDesc [%p]",lpdnProgramDesc);
|
|
|
|
if (lpdnProgramDesc->lpwszApplicationName != NULL)
|
|
GlobalFree(lpdnProgramDesc->lpwszApplicationName);
|
|
if (lpdnProgramDesc->lpwszApplicationLauncher != NULL)
|
|
GlobalFree(lpdnProgramDesc->lpwszApplicationLauncher);
|
|
if (lpdnProgramDesc->lpwszCommandLine != NULL)
|
|
GlobalFree(lpdnProgramDesc->lpwszCommandLine);
|
|
if (lpdnProgramDesc->lpwszCurrentDirectory != NULL)
|
|
GlobalFree(lpdnProgramDesc->lpwszCurrentDirectory);
|
|
if (lpdnProgramDesc->lpwszDescription != NULL)
|
|
GlobalFree(lpdnProgramDesc->lpwszDescription);
|
|
if (lpdnProgramDesc->lpwszFilename != NULL)
|
|
GlobalFree(lpdnProgramDesc->lpwszFilename);
|
|
if (lpdnProgramDesc->lpwszPath != NULL)
|
|
GlobalFree(lpdnProgramDesc->lpwszPath);
|
|
}
|
|
|
|
// HRESULT DnReadRegProgramDesc
|
|
// HKEY hKey Handle to open key containing program description
|
|
// LPDNPROGRAMDESC lpdnProgramDesc Pointer to a program description structure
|
|
//
|
|
// Returns
|
|
// DPN_OK If successfull
|
|
// DPNERR_DOESNOTEXIST If there was a problem opening/reading the entry
|
|
// DPNERR_OUTOFMEMORY If it could not allocate memory
|
|
//
|
|
// Notes
|
|
// This function reads the program description entry from the registry at hKey into the
|
|
// supplied structure. The function will call DnGetRegKeyValue, which allocates
|
|
// space for strings as needed. Use DnFreeProgramDesc() to free the program
|
|
// description structure.
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "DnReadRegProgramDesc"
|
|
|
|
HRESULT DnReadRegProgramDesc(HKEY hKey, LPDNPROGRAMDESC lpdnProgramDesc)
|
|
{
|
|
HRESULT hResultCode = DPN_OK;
|
|
|
|
DPFX(DPFPREP, 3,"Parameters: hKey [%p], lpdnProgramDesc [%p]",hKey,lpdnProgramDesc);
|
|
|
|
if ((hResultCode = DnGetRegKeyValue(hKey,DN_REG_KEYNAME_APPLICATIONLAUNCHER,
|
|
&(lpdnProgramDesc->lpwszApplicationLauncher))) != DPN_OK)
|
|
{
|
|
DnFreeProgramDesc(lpdnProgramDesc);
|
|
goto EXIT_DnReadRegProgramDesc;
|
|
}
|
|
|
|
if ((hResultCode = DnGetRegKeyValue(hKey,DN_REG_KEYNAME_APPLICATIONNAME,
|
|
&(lpdnProgramDesc->lpwszApplicationName))) != DPN_OK)
|
|
{
|
|
DnFreeProgramDesc(lpdnProgramDesc);
|
|
goto EXIT_DnReadRegProgramDesc;
|
|
}
|
|
|
|
if ((hResultCode = DnGetRegKeyValue(hKey,DN_REG_KEYNAME_COMMANDLINE,
|
|
&(lpdnProgramDesc->lpwszCommandLine))) != DPN_OK)
|
|
{
|
|
DnFreeProgramDesc(lpdnProgramDesc);
|
|
goto EXIT_DnReadRegProgramDesc;
|
|
}
|
|
|
|
if ((hResultCode = DnGetRegKeyValue(hKey,DN_REG_KEYNAME_CURRENTDIRECTORY,
|
|
&(lpdnProgramDesc->lpwszCurrentDirectory))) != DPN_OK)
|
|
{
|
|
DnFreeProgramDesc(lpdnProgramDesc);
|
|
goto EXIT_DnReadRegProgramDesc;
|
|
}
|
|
|
|
if ((hResultCode = DnGetRegKeyValue(hKey,DN_REG_KEYNAME_DESCRIPTION,
|
|
&(lpdnProgramDesc->lpwszDescription))) != DPN_OK)
|
|
{
|
|
DnFreeProgramDesc(lpdnProgramDesc);
|
|
goto EXIT_DnReadRegProgramDesc;
|
|
}
|
|
|
|
if ((hResultCode = DnGetRegKeyValue(hKey,DN_REG_KEYNAME_FILENAME,
|
|
&(lpdnProgramDesc->lpwszFilename))) != DPN_OK)
|
|
{
|
|
DnFreeProgramDesc(lpdnProgramDesc);
|
|
goto EXIT_DnReadRegProgramDesc;
|
|
}
|
|
|
|
if ((hResultCode = DnGetRegKeyValue(hKey,DN_REG_KEYNAME_PATH,
|
|
&(lpdnProgramDesc->lpwszPath))) != DPN_OK)
|
|
{
|
|
DnFreeProgramDesc(lpdnProgramDesc);
|
|
goto EXIT_DnReadRegProgramDesc;
|
|
}
|
|
|
|
EXIT_DnReadRegProgramDesc:
|
|
|
|
DPFX(DPFPREP, 3,"Returning: hResultCode = [%lx]",hResultCode);
|
|
return(hResultCode);
|
|
}
|
|
|
|
|
|
// HRESULT DnDelAppKey
|
|
// lpGuid lpGuid Pointer to GUID of program desired
|
|
//
|
|
// Returns
|
|
// DPN_OK If successfull
|
|
// DPNERR_OUTOFMEMORY If it could not allocate memory
|
|
// DPNERR_DOESNOTEXIST If the entry does not exist, or there was a problem opening/reading a key
|
|
// DPNERR_GENERIC If the application key could not be deleted
|
|
//
|
|
// Notes
|
|
// This function deletes a GUID specified application registry entry.
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "DnDelAppKey"
|
|
|
|
HRESULT DnDelAppKey(LPGUID lpGuid)
|
|
{
|
|
HRESULT hResultCode = DPN_OK;
|
|
HKEY hBaseKey = NULL;
|
|
HKEY hSubKey;
|
|
DWORD dwEnumIndex = 0;
|
|
BOOL bFound = FALSE;
|
|
DWORD dwMaxSubKeyLen;
|
|
LPSTR lpszSubKey = NULL;
|
|
DWORD dwSubKeyLen;
|
|
CHAR lpszGuid[DN_GUID_STR_LEN+1];
|
|
DWORD dwKeyValueLen;
|
|
GUID guidApplication;
|
|
|
|
DPFX(DPFPREP, 3,"Parameters: lpGuid [%p]",lpGuid);
|
|
|
|
// Open base key
|
|
if (DnOpenRegKey(HKEY_LOCAL_MACHINE,DN_REG_LOCAL_APPL_SUBKEY,&hBaseKey) != DPN_OK)
|
|
{
|
|
hResultCode = DPNERR_DOESNOTEXIST;
|
|
goto EXIT_DnDelAppKey;
|
|
}
|
|
|
|
// Create buffer to read each subkey (application) name into
|
|
if (RegQueryInfoKeyA(hBaseKey,NULL,NULL,NULL,NULL,&dwMaxSubKeyLen,NULL,NULL,NULL,NULL,NULL,NULL)
|
|
!= ERROR_SUCCESS)
|
|
{
|
|
DPFX(DPFPREP, 9,"RegQueryInfoKey() failed");
|
|
hResultCode = DPNERR_DOESNOTEXIST;
|
|
goto EXIT_DnDelAppKey;
|
|
}
|
|
dwMaxSubKeyLen++; // Space for null terminator
|
|
if ((lpszSubKey = (LPSTR)GLOBALALLOC(dwMaxSubKeyLen)) == NULL)
|
|
{
|
|
DPFX(DPFPREP, 9,"lpszSubKey = GLOBALALLOC(%d) failed",dwMaxSubKeyLen);
|
|
hResultCode = DPNERR_OUTOFMEMORY;
|
|
goto EXIT_DnDelAppKey;
|
|
}
|
|
|
|
// For each subkey (application) get guid and check against lpGuid
|
|
dwEnumIndex = 0;
|
|
dwSubKeyLen = dwMaxSubKeyLen;
|
|
while (RegEnumKeyExA(hBaseKey,dwEnumIndex++,lpszSubKey,&dwSubKeyLen,NULL,NULL,NULL,NULL) == ERROR_SUCCESS)
|
|
{
|
|
if (DnOpenRegKey(hBaseKey,lpszSubKey,&hSubKey) != DPN_OK)
|
|
{
|
|
hResultCode = DPNERR_DOESNOTEXIST;
|
|
goto EXIT_DnDelAppKey;
|
|
}
|
|
dwKeyValueLen = DN_GUID_STR_LEN+1;
|
|
if (RegQueryValueExA(hSubKey,DN_REG_KEYNAME_GUIDAPPLICATION,NULL,NULL,(LPBYTE)lpszGuid,&dwKeyValueLen) != DPN_OK)
|
|
{
|
|
RegCloseKey(hSubKey);
|
|
dwSubKeyLen = dwMaxSubKeyLen;
|
|
continue;
|
|
}
|
|
if (GUIDFromStringA(lpszGuid,&guidApplication) != DPN_OK)
|
|
{
|
|
RegCloseKey(hSubKey);
|
|
dwSubKeyLen = dwMaxSubKeyLen;
|
|
continue;
|
|
}
|
|
if (IsEqualGuid(lpGuid,&guidApplication))
|
|
{ // Found it !
|
|
if (RegDeleteKey(hBaseKey,lpszSubKey) != ERROR_SUCCESS)
|
|
{
|
|
hResultCode = DPNERR_GENERIC;
|
|
}
|
|
RegCloseKey(hSubKey);
|
|
bFound = TRUE;
|
|
break;
|
|
}
|
|
|
|
RegCloseKey(hSubKey);
|
|
dwSubKeyLen = dwMaxSubKeyLen;
|
|
}
|
|
|
|
if (!bFound)
|
|
hResultCode = DPNERR_DOESNOTEXIST;
|
|
|
|
EXIT_DnDelAppKey:
|
|
|
|
if (hBaseKey != NULL)
|
|
RegCloseKey(hBaseKey);
|
|
if (lpszSubKey != NULL)
|
|
GlobalFree(lpszSubKey);
|
|
|
|
DPFX(DPFPREP, 3,"Returning: hResultCode = [%lx]",hResultCode);
|
|
return(hResultCode);
|
|
}
|
|
|
|
|
|
// HRESULT DnGetProgramDesc
|
|
// lpGuid lpGuid Pointer to GUID of program desired
|
|
// LPDNPROGRAMDESC lpdnProgramDesc Pointer to a program description structure
|
|
//
|
|
// Returns
|
|
// DPN_OK If successfull
|
|
// DPNERR_OUTOFMEMORY If it could not allocate memory
|
|
// DPNERR_DOESNOTEXIST If the entry does not exist, or there was a problem opening/reading a key
|
|
//
|
|
// Notes
|
|
// This function gets the program description for a GUID specified program. The
|
|
// function will search for the program description entry in the registry, and the
|
|
// LPDNPROGRAMDESC structure will then be filled in. Any strings required will be
|
|
// allocated. When done with the structure, DnFreeProgramDesc() should be used to
|
|
// release it. The program description structure should be empty (string pointers
|
|
// invalid) when passed into this function.
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "DnGetProgramDesc"
|
|
|
|
HRESULT DnGetProgramDesc(LPGUID lpGuid, LPDNPROGRAMDESC lpdnProgramDesc)
|
|
{
|
|
HRESULT hResultCode = DPN_OK;
|
|
HKEY hBaseKey = NULL;
|
|
HKEY hSubKey;
|
|
DWORD dwEnumIndex = 0;
|
|
BOOL bFound = FALSE;
|
|
DWORD dwMaxSubKeyLen;
|
|
LPSTR lpszSubKey = NULL;
|
|
DWORD dwSubKeyLen;
|
|
CHAR lpszGuid[DN_GUID_STR_LEN+1];
|
|
DWORD dwKeyValueLen;
|
|
GUID guidApplication;
|
|
|
|
DPFX(DPFPREP, 3,"Parameters: lpGuid [%p], lpdnProgramDesc [%p]",lpGuid,lpdnProgramDesc);
|
|
|
|
// Clean up structure
|
|
lpdnProgramDesc->lpwszApplicationLauncher = NULL;
|
|
lpdnProgramDesc->lpwszApplicationName = NULL;
|
|
lpdnProgramDesc->lpwszCommandLine = NULL;
|
|
lpdnProgramDesc->lpwszCurrentDirectory = NULL;
|
|
lpdnProgramDesc->lpwszDescription = NULL;
|
|
lpdnProgramDesc->lpwszFilename = NULL;
|
|
lpdnProgramDesc->lpwszPath = NULL;
|
|
|
|
// Open base key
|
|
if (DnOpenRegKey(HKEY_LOCAL_MACHINE,DN_REG_LOCAL_APPL_SUBKEY,&hBaseKey) != DPN_OK)
|
|
{
|
|
hResultCode = DPNERR_DOESNOTEXIST;
|
|
goto EXIT_DnGetProgramDesc;
|
|
}
|
|
|
|
// Create buffer to read each subkey (application) name into
|
|
if (RegQueryInfoKeyA(hBaseKey,NULL,NULL,NULL,NULL,&dwMaxSubKeyLen,NULL,NULL,NULL,NULL,NULL,NULL)
|
|
!= ERROR_SUCCESS)
|
|
{
|
|
DPFX(DPFPREP, 9,"RegQueryInfoKey() failed");
|
|
hResultCode = DPNERR_DOESNOTEXIST;
|
|
goto EXIT_DnGetProgramDesc;
|
|
}
|
|
dwMaxSubKeyLen++; // Space for null terminator
|
|
if ((lpszSubKey = (LPSTR)GLOBALALLOC(dwMaxSubKeyLen)) == NULL)
|
|
{
|
|
DPFX(DPFPREP, 9,"lpszSubKey = GLOBALALLOC(%d) failed",dwMaxSubKeyLen);
|
|
hResultCode = DPNERR_OUTOFMEMORY;
|
|
goto EXIT_DnGetProgramDesc;
|
|
}
|
|
|
|
// For each subkey (application) get guid and check against lpGuid
|
|
dwEnumIndex = 0;
|
|
dwSubKeyLen = dwMaxSubKeyLen;
|
|
while (RegEnumKeyExA(hBaseKey,dwEnumIndex++,lpszSubKey,&dwSubKeyLen,NULL,NULL,NULL,NULL) == ERROR_SUCCESS)
|
|
{
|
|
if (DnOpenRegKey(hBaseKey,lpszSubKey,&hSubKey) != DPN_OK)
|
|
{
|
|
hResultCode = DPNERR_DOESNOTEXIST;
|
|
goto EXIT_DnGetProgramDesc;
|
|
}
|
|
dwKeyValueLen = DN_GUID_STR_LEN+1;
|
|
if (RegQueryValueExA(hSubKey,DN_REG_KEYNAME_GUIDAPPLICATION,NULL,NULL,(LPBYTE)lpszGuid,&dwKeyValueLen) != DPN_OK)
|
|
{
|
|
RegCloseKey(hSubKey);
|
|
dwSubKeyLen = dwMaxSubKeyLen;
|
|
continue;
|
|
}
|
|
if (GUIDFromStringA(lpszGuid,&guidApplication) != DPN_OK)
|
|
{
|
|
RegCloseKey(hSubKey);
|
|
dwSubKeyLen = dwMaxSubKeyLen;
|
|
continue;
|
|
}
|
|
if (IsEqualGuid(lpGuid,&guidApplication))
|
|
{ // Found it !
|
|
CopyGuid(&(lpdnProgramDesc->guidApplication),&guidApplication);
|
|
hResultCode = DnReadRegProgramDesc(hSubKey,lpdnProgramDesc);
|
|
RegCloseKey(hSubKey);
|
|
bFound = TRUE;
|
|
break;
|
|
}
|
|
|
|
RegCloseKey(hSubKey);
|
|
dwSubKeyLen = dwMaxSubKeyLen;
|
|
}
|
|
|
|
if (!bFound)
|
|
hResultCode = DPNERR_DOESNOTEXIST;
|
|
|
|
EXIT_DnGetProgramDesc:
|
|
|
|
if (hBaseKey != NULL)
|
|
RegCloseKey(hBaseKey);
|
|
if (lpszSubKey != NULL)
|
|
GlobalFree(lpszSubKey);
|
|
|
|
DPFX(DPFPREP, 3,"Returning: hResultCode = [%lx]",hResultCode);
|
|
return(hResultCode);
|
|
}
|
|
|
|
|
|
// HRESULT DnExpandEnvStringA
|
|
// LPSTR lpszOrig Orginal string, including environment variables
|
|
// LPSTR *lplpszResult Resulting string, after expanding environemnt variables
|
|
//
|
|
// Returns
|
|
// DPN_OK If successfull
|
|
// DPNERR_OUTOFMEMORY If it could not allocate memory
|
|
//
|
|
// Notes
|
|
// This function expands embedded environment strings. It calculates the expected size of the
|
|
// required expanded string, allocates it, expands environment variables and returns a pointer
|
|
// to the new string to the caller.
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "DnExpandEnvStringA"
|
|
|
|
HRESULT DnExpandEnvStringA(LPSTR lpszOrig, LPSTR *lplpszResult)
|
|
{
|
|
HRESULT hResultCode = DPN_OK;
|
|
LPSTR lpszResult;
|
|
DWORD dwStrLen;
|
|
|
|
DPFX(DPFPREP, 3,"Parameters: lpszOrig [%p], lplpszRestul [%p]",lpszOrig,lplpszResult);
|
|
|
|
// Expand environment strings
|
|
if ((dwStrLen = ExpandEnvironmentStringsA(lpszOrig,NULL,0)) == 0)
|
|
{
|
|
hResultCode = DPNERR_OUTOFMEMORY;
|
|
goto EXIT_DnExpandEnvStringA;
|
|
}
|
|
if ((lpszResult = (LPSTR)GLOBALALLOC(dwStrLen)) == NULL)
|
|
{
|
|
hResultCode = DPNERR_OUTOFMEMORY;
|
|
goto EXIT_DnExpandEnvStringA;
|
|
}
|
|
if (ExpandEnvironmentStringsA(lpszOrig,lpszResult,dwStrLen) == 0)
|
|
{
|
|
GlobalFree(lpszResult);
|
|
hResultCode = DPNERR_OUTOFMEMORY;
|
|
goto EXIT_DnExpandEnvStringA;
|
|
}
|
|
|
|
*lplpszResult = lpszResult;
|
|
|
|
EXIT_DnExpandEnvStringA:
|
|
|
|
DPFX(DPFPREP, 3,"Returning: hResultCode = [%lx]",hResultCode);
|
|
return(hResultCode);
|
|
}
|
|
|
|
|
|
// HRESULT DnExpandEnvStringW
|
|
// LPWSTR lpwszOrig Orginal string, including environment variables
|
|
// LPWSTR *lplpwszResult Resulting string, after expanding environemnt variables
|
|
//
|
|
// Returns
|
|
// DPN_OK If successfull
|
|
// DPNERR_OUTOFMEMORY If it could not allocate memory
|
|
//
|
|
// Notes
|
|
// This function expands embedded environment strings. It calculates the expected size of the
|
|
// required expanded string, allocates it, expands environment variables and returns a pointer
|
|
// to the new string to the caller.
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "DnExpandEnvStringW"
|
|
|
|
HRESULT DnExpandEnvStringW(LPWSTR lpwszOrig, LPWSTR *lplpwszResult)
|
|
{
|
|
HRESULT hResultCode = DPN_OK;
|
|
LPWSTR lpwszResult;
|
|
DWORD dwStrLen;
|
|
|
|
DPFX(DPFPREP, 3,"Parameters: lpwszOrig [%p], lplpwszRestul [%p]",lpwszOrig,lplpwszResult);
|
|
|
|
// Expand environment strings
|
|
if ((dwStrLen = ExpandEnvironmentStringsW(lpwszOrig,NULL,0)) == 0)
|
|
{
|
|
hResultCode = DPNERR_OUTOFMEMORY;
|
|
goto EXIT_DnExpandEnvStringW;
|
|
}
|
|
if ((lpwszResult = (LPWSTR)GLOBALALLOC(dwStrLen*sizeof(WCHAR))) == NULL)
|
|
{
|
|
hResultCode = DPNERR_OUTOFMEMORY;
|
|
goto EXIT_DnExpandEnvStringW;
|
|
}
|
|
if (ExpandEnvironmentStringsW(lpwszOrig,lpwszResult,dwStrLen) == 0)
|
|
{
|
|
GlobalFree(lpwszResult);
|
|
hResultCode = DPNERR_OUTOFMEMORY;
|
|
goto EXIT_DnExpandEnvStringW;
|
|
}
|
|
|
|
*lplpwszResult = lpwszResult;
|
|
|
|
EXIT_DnExpandEnvStringW:
|
|
|
|
DPFX(DPFPREP, 3,"Returning: hResultCode = [%lx]",hResultCode);
|
|
return(hResultCode);
|
|
}
|
|
|
|
|
|
// HRESULT DnGetOsPlatformId
|
|
//
|
|
// Returns
|
|
// DPN_OK If successfull
|
|
// DPNERR_GENERIC If not
|
|
//
|
|
// Notes
|
|
// This function determines the version of the operating system being run
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "DnGetOsPlatformId"
|
|
|
|
HRESULT DnGetOsPlatformId(void)
|
|
{
|
|
OSVERSIONINFO osv;
|
|
|
|
DPFX(DPFPREP, 3,"Parameters: (none)");
|
|
|
|
// Set Global
|
|
osv.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
|
|
if (GetVersionEx(&osv) == FALSE)
|
|
return(DPNERR_GENERIC);
|
|
|
|
DnOsPlatformId = osv.dwPlatformId;
|
|
return(DPN_OK);
|
|
}
|
|
|
|
#endif
|