/*========================================================================== * * 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(PackedBuffer.GetHeadAddress()); PackedBuffer.AddToFront(NULL,sizeof(DPL_PROGRAM_DESC)); dwValueSize = PackedBuffer.GetSpaceRemaining(); pdnProgramDesc->pwszApplicationName = static_cast(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(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(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(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(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(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(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(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