windows-nt/Source/XPSP1/NT/multimedia/directx/dplay/dnet/lobby/dplreg.cpp

1323 lines
36 KiB
C++
Raw Permalink Normal View History

2020-09-26 03:20:57 -05:00
/*==========================================================================
*
* 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