/* $Id: registry.cpp,v 1.22 2004-10-08 08:41:13 cinc Exp $ */ /* * Win32 registry API functions for OS/2 * * 1998/06/12 * * Copyright 1998 Sander van Leeuwen * Copyright 1998 Patrick Haller * * * TODO: Many unicode apis are still wrong (missing unicode conversions and wrong sizes)!!!!! * * Project Odin Software License can be found in LICENSE.TXT * */ /***************************************************************************** * Includes * *****************************************************************************/ #include #include #include #include #include #include #include #include #include #include "unicode.h" #include #include #define DBG_LOCALLOG DBG_registry #include "dbglocal.h" ODINDEBUGCHANNEL(ADVAPI32-REGISTRY) /***************************************************************************** * Defines * *****************************************************************************/ /* this define enables certain less important debug messages */ //#define DEBUG_LOCAL 1 static HKEY hKeyClassesRoot = HKEY_CLASSES_ROOT_O32; static HKEY hKeyCurrentUser = HKEY_CURRENT_USER_O32; static HKEY hKeyLocalMachine = HKEY_LOCAL_MACHINE_O32; static HKEY hKeyUsers = HKEY_USERS_O32; /***************************************************************************** * Name : Convert Key * Purpose : convert key handle values between win32 and os/2 * Parameters: HKEY winkey - the win32 key handle value * Variables : * Result : the os/2 warp registry key handle value * Remark : * Status : UNTESTED STUB * * Author : Patrick Haller [Tue, 1998/06/16 23:00] *****************************************************************************/ static HKEY ConvertKey(HKEY winkey) { switch((DWORD)winkey) { case HKEY_CLASSES_ROOT: return hKeyClassesRoot; case HKEY_CURRENT_USER: return hKeyCurrentUser; case HKEY_LOCAL_MACHINE: return hKeyLocalMachine; case HKEY_USERS: return hKeyUsers; } return(winkey); } extern "C" { void WIN32API SetRegistryRootKey(HKEY hRootkey, HKEY hKey) { switch((DWORD)hRootkey) { case HKEY_CLASSES_ROOT: hKeyClassesRoot = hKey; break; case HKEY_CURRENT_USER: hKeyCurrentUser = hKey; break; case HKEY_LOCAL_MACHINE: hKeyLocalMachine = hKey; break; case HKEY_USERS: hKeyUsers = hKey; break; } } /***************************************************************************** * Name : * Purpose : * Parameters: * Variables : * Result : * Remark : * Status : CORRECTED UNTESTED * * Author : Patrick Haller [Tue, 1998/06/16 23:00] *****************************************************************************/ LONG WIN32API RegCloseKey(HKEY hKey) { switch(hKey) {//Closing a root key should just return success (matters for custom builds) case HKEY_CLASSES_ROOT: case HKEY_CURRENT_USER: case HKEY_LOCAL_MACHINE: case HKEY_USERS: return 0; } return O32_RegCloseKey(ConvertKey(hKey)); } /***************************************************************************** * Name : * Purpose : * Parameters: * Variables : * Result : * Remark : * Status : CORRECTED UNTESTED * * Author : Patrick Haller [Tue, 1998/06/16 23:00] *****************************************************************************/ LONG WIN32API RegCreateKeyA(HKEY hKey, LPCSTR lpszSubKey, PHKEY phkResult) { dprintf(("RegCreateKeyA %x %s", hKey, lpszSubKey)); return O32_RegCreateKey(ConvertKey(hKey), lpszSubKey, phkResult); } /***************************************************************************** * Name : * Purpose : * Parameters: * Variables : * Result : * Remark : * Status : CORRECTED UNTESTED * * Author : Patrick Haller [Tue, 1998/06/16 23:00] *****************************************************************************/ LONG WIN32API RegCreateKeyW(HKEY hKey, LPCWSTR lpszSubKey, PHKEY phkResult) { char *astring = UnicodeToAsciiString((LPWSTR)lpszSubKey); LONG rc; dprintf(("RegCreateKeyW %x %s", hKey, astring)); rc = O32_RegCreateKey(ConvertKey(hKey), astring, phkResult); if (NULL != astring) FreeAsciiString(astring); return(rc); } /***************************************************************************** * Name : * Purpose : * Parameters: * Variables : * Result : * Remark : * Status : CORRECTED UNTESTED * * Author : Patrick Haller [Tue, 1998/06/16 23:00] *****************************************************************************/ LONG WIN32API RegCreateKeyExA(HKEY hKey, LPCSTR lpszSubKey, DWORD dwReserved, LPSTR lpszClass, DWORD fdwOptions, REGSAM samDesired, LPSECURITY_ATTRIBUTES lpSecurityAttributes, PHKEY phkResult, LPDWORD lpdwDisposition) { dprintf(("RegCreateKeyExA %x %s", hKey, lpszSubKey)); return O32_RegCreateKeyEx(ConvertKey(hKey), lpszSubKey, dwReserved, lpszClass, fdwOptions, samDesired, // | KEY_READ lpSecurityAttributes, phkResult, lpdwDisposition); } /***************************************************************************** * Name : * Purpose : * Parameters: * Variables : * Result : * Remark : * Status : CORRECTED UNTESTED * * Author : Patrick Haller [Tue, 1998/06/16 23:00] *****************************************************************************/ LONG WIN32API RegCreateKeyExW(HKEY hKey, LPCWSTR lpszSubKey, DWORD dwReserved, LPWSTR lpszClass, DWORD fdwOptions, REGSAM samDesired, LPSECURITY_ATTRIBUTES lpSecurityAttributes, PHKEY phkResult, LPDWORD lpdwDisposition) { char *astring1 = UnicodeToAsciiString((LPWSTR)lpszSubKey); char *astring2 = UnicodeToAsciiString(lpszClass); LONG rc; dprintf(("RegCreateKeyExW %x %s", hKey, astring1)); rc = O32_RegCreateKeyEx(ConvertKey(hKey), astring1, dwReserved, astring2, fdwOptions, samDesired, // | KEY_READ lpSecurityAttributes, phkResult, lpdwDisposition); if (NULL != astring1) FreeAsciiString(astring1); if (NULL != astring2) FreeAsciiString(astring2); return(rc); } /***************************************************************************** * Name : * Purpose : * Parameters: * Variables : * Result : * Remark : * Status : CORRECTED UNTESTED * * Author : Patrick Haller [Tue, 1998/06/16 23:00] *****************************************************************************/ LONG WIN32API RegDeleteKeyW(HKEY hKey, LPCWSTR lpszSubKey) { char *astring = UnicodeToAsciiString(lpszSubKey); LONG rc; dprintf(("RegDeleteKeyW %s", astring)); rc = O32_RegDeleteKey(ConvertKey(hKey), astring); if (NULL != astring) FreeAsciiString(astring); return(rc); } /***************************************************************************** * Name : * Purpose : * Parameters: * Variables : * Result : * Remark : * Status : CORRECTED UNTESTED * * Author : Patrick Haller [Tue, 1998/06/16 23:00] *****************************************************************************/ LONG WIN32API RegDeleteKeyA(HKEY hKey, LPCSTR lpszSubKey) { dprintf(("RegDeleteKeyW %s", lpszSubKey)); return O32_RegDeleteKey(ConvertKey(hKey), lpszSubKey); } /***************************************************************************** * Name : * Purpose : * Parameters: * Variables : * Result : * Remark : * Status : CORRECTED UNTESTED * * Author : Patrick Haller [Tue, 1998/06/16 23:00] *****************************************************************************/ LONG WIN32API RegDeleteValueA(HKEY hKey, LPCSTR lpszValue) { return O32_RegDeleteValue(ConvertKey(hKey), lpszValue); } /***************************************************************************** * Name : * Purpose : * Parameters: * Variables : * Result : * Remark : * Status : CORRECTED UNTESTED * * Author : Patrick Haller [Tue, 1998/06/16 23:00] *****************************************************************************/ LONG WIN32API RegDeleteValueW(HKEY hKey, LPCWSTR lpszValue) { char *astring = UnicodeToAsciiString(lpszValue); LONG rc; rc = O32_RegDeleteValue(ConvertKey(hKey), astring); if (NULL != astring) FreeAsciiString(astring); return(rc); } /***************************************************************************** * Name : * Purpose : * Parameters: * Variables : * Result : * Remark : * Status : UNTESTED STUB * * Author : Patrick Haller [Tue, 1998/06/16 23:00] *****************************************************************************/ LONG WIN32API RegEnumKeyA(HKEY hKey, DWORD iSubKey, LPSTR lpszName, DWORD cchName) { return O32_RegEnumKey(ConvertKey(hKey), iSubKey, lpszName, cchName); } /***************************************************************************** * Name : * Purpose : * Parameters: * Variables : * Result : * Remark : * Status : UNTESTED STUB * * Author : Patrick Haller [Tue, 1998/06/16 23:00] *****************************************************************************/ LONG WIN32API RegEnumKeyW(HKEY hKey, DWORD iSubKey, LPWSTR lpszName, DWORD cchName) { char *astring; LONG rc; rc = O32_RegEnumKey(ConvertKey(hKey), iSubKey, (char *)lpszName, cchName); if(rc == ERROR_SUCCESS) { astring = (char *)malloc(cchName); strcpy(astring, (char *)lpszName); AsciiToUnicode(astring, lpszName); free(astring); } return(rc); } /***************************************************************************** * Name : * Purpose : * Parameters: * Variables : * Result : * Remark : * Status : UNTESTED STUB * * Author : Patrick Haller [Tue, 1998/06/16 23:00] *****************************************************************************/ LONG WIN32API RegEnumKeyExA(HKEY arg1, DWORD arg2, LPSTR arg3, LPDWORD arg4, LPDWORD arg5, LPSTR arg6, LPDWORD arg7, LPFILETIME arg8) { return O32_RegEnumKeyEx(ConvertKey(arg1), arg2, arg3, arg4, arg5, arg6, arg7, arg8); } /***************************************************************************** * Name : * Purpose : * Parameters: * Variables : * Result : * Remark : * Status : UNTESTED STUB * * Author : Patrick Haller [Tue, 1998/06/16 23:00] *****************************************************************************/ LONG WIN32API RegEnumKeyExW(HKEY hKey, DWORD iSubkey, LPWSTR lpszName, LPDWORD lpcchName, LPDWORD lpdwReserved, LPWSTR lpszClass, LPDWORD lpcchClass, LPFILETIME lpffLastWrite) { char *astring; LONG rc; rc = O32_RegEnumKeyEx(ConvertKey(hKey), iSubkey, (char *)lpszName, lpcchName, lpdwReserved, (char *)lpszClass, lpcchClass, lpffLastWrite); if(rc == ERROR_SUCCESS) { astring = (char *)malloc(max(*lpcchName+1, (lpcchClass) ? (*lpcchClass+1) : 0)); //class & keyname strcpy(astring, (char *)lpszName); AsciiToUnicode(astring, lpszName); if(lpszClass != NULL) { strcpy(astring, (char *)lpszClass); AsciiToUnicode(astring, lpszClass); } free(astring); } return(rc); } /***************************************************************************** * Name : * Purpose : * Parameters: * Variables : * Result : * Remark : * Status : UNTESTED STUB * * Author : Patrick Haller [Tue, 1998/06/16 23:00] *****************************************************************************/ LONG WIN32API RegEnumValueA(HKEY arg1, DWORD arg2, LPSTR arg3, LPDWORD arg4, LPDWORD arg5, LPDWORD arg6, LPBYTE arg7, LPDWORD arg8) { return O32_RegEnumValue(ConvertKey(arg1), arg2, arg3, arg4, arg5, arg6, arg7, arg8); } /***************************************************************************** * Name : * Purpose : * Parameters: * Variables : * Result : * Remark : * Status : UNTESTED STUB * * Author : Patrick Haller [Tue, 1998/06/16 23:00] *****************************************************************************/ LONG WIN32API RegEnumValueW(HKEY hkey, DWORD iValue, LPWSTR lpszValue, LPDWORD lpcchValue, LPDWORD lpdwReserved, LPDWORD lpdwType, LPBYTE lpbData, LPDWORD lpcbData) { char *astring; LONG rc, oldsize = 0; if(lpcbData) { oldsize = *lpcbData; } rc = O32_RegEnumValue(ConvertKey(hkey), iValue, (char *)lpszValue, lpcchValue, lpdwReserved, lpdwType, lpbData, lpcbData); if(rc == ERROR_SUCCESS) { astring = (char *)malloc(*lpcchValue+1); //+ 0 terminator strcpy(astring, (char *)lpszValue); AsciiToUnicode(astring, lpszValue); free(astring); if(lpcbData && lpbData) { switch(*lpdwType) { case REG_SZ: case REG_EXPAND_SZ: if(oldsize < *lpcbData*sizeof(WCHAR)) { *lpcbData = *lpcbData*sizeof(WCHAR); return ERROR_MORE_DATA; } astring = (char *)malloc(*lpcbData); strcpy(astring, (char *)lpbData); lstrcpyAtoW((LPWSTR)lpbData, astring); free(astring); break; case REG_MULTI_SZ: case REG_LINK: //??? dprintf(("ERROR: key data must be translated from Unicode to Ascii!!")); break; default: break; } } } return(rc); } /***************************************************************************** * Name : * Purpose : * Parameters: * Variables : * Result : * Remark : * Status : UNTESTED STUB * * Author : Patrick Haller [Tue, 1998/06/16 23:00] *****************************************************************************/ LONG WIN32API RegOpenKeyA(HKEY hKey, LPCSTR arg2, PHKEY arg3) { LONG rc; dprintf(("RegOpenKey %s", arg2)); rc = O32_RegOpenKey(ConvertKey(hKey), arg2, arg3); if(rc) *arg3 = 0; return(rc); } /***************************************************************************** * Name : * Purpose : * Parameters: * Variables : * Result : * Remark : * Status : UNTESTED STUB * * Author : Patrick Haller [Tue, 1998/06/16 23:00] *****************************************************************************/ LONG WIN32API RegOpenKeyW(HKEY hKey, LPCWSTR arg2, PHKEY arg3) { char *astring = UnicodeToAsciiString((LPWSTR)arg2); LONG rc; rc = RegOpenKeyA(hKey, astring, arg3); if(rc) *arg3 = 0; if (NULL != astring) FreeAsciiString(astring); return(rc); } /***************************************************************************** * Name : * Purpose : * Parameters: * Variables : * Result : * Remark : * Status : UNTESTED STUB * * Author : Patrick Haller [Tue, 1998/06/16 23:00] *****************************************************************************/ LONG WIN32API RegOpenKeyExA(HKEY hKey, LPCSTR arg2, DWORD arg3, REGSAM arg4, PHKEY arg5) { LONG rc; dprintf(("RegOpenKeyEx %s", arg2)); rc = O32_RegOpenKeyEx(ConvertKey(hKey), arg2, arg3, arg4, arg5); //SvL: This fixes crashes in pmwinx.dll. (if an app doesn't check the // return value and uses the whatever *arg5 contains) if(rc) *arg5 = 0; return(rc); } /***************************************************************************** * Name : * Purpose : * Parameters: * Variables : * Result : * Remark : * Status : UNTESTED STUB * * Author : Patrick Haller [Tue, 1998/06/16 23:00] *****************************************************************************/ LONG WIN32API RegOpenKeyExW(HKEY arg1, LPCWSTR arg2, DWORD arg3, REGSAM arg4, PHKEY arg5) { char *astring = UnicodeToAsciiString((LPWSTR)arg2); LONG rc; rc = RegOpenKeyExA(arg1, astring, arg3, arg4, arg5); //SvL: This fixes crashes in pmwinx.dll. (if an app doesn't check the // return value and uses the whatever *arg5 contains) if(rc) *arg5 = 0; if (NULL != astring) FreeAsciiString(astring); return(rc); } /***************************************************************************** * Name : * Purpose : * Parameters: * Variables : * Result : * Remark : * Status : UNTESTED STUB * * Author : Patrick Haller [Tue, 1998/06/16 23:00] *****************************************************************************/ LONG WIN32API RegQueryInfoKeyA(HKEY hkey, LPSTR lpszClass, LPDWORD lpcchClass, LPDWORD lpdwReserved, LPDWORD lpcSubKeys, LPDWORD lpcchMaxSubKey, LPDWORD lpcchMaxClass, LPDWORD lpcValues, LPDWORD lpcchMaxValueName, LPDWORD lpcbMaxValueData, LPDWORD lpcbSecurityDescriptor, LPFILETIME lpftLastWriteTime) { return O32_RegQueryInfoKey(ConvertKey(hkey), lpszClass, lpcchClass, lpdwReserved, lpcSubKeys, lpcchMaxSubKey, lpcchMaxClass, lpcValues, lpcchMaxValueName, lpcbMaxValueData, lpcbSecurityDescriptor,lpftLastWriteTime); } /***************************************************************************** * Name : * Purpose : * Parameters: * Variables : * Result : * Remark : * Status : UNTESTED STUB * * Author : Patrick Haller [Tue, 1998/06/16 23:00] *****************************************************************************/ LONG WIN32API RegQueryInfoKeyW(HKEY hkey, LPWSTR lpszClass, LPDWORD lpcchClass, LPDWORD lpdwReserved, LPDWORD lpcSubKeys, LPDWORD lpcchMaxSubKey, LPDWORD lpcchMaxClass, LPDWORD lpcValues, LPDWORD lpcchMaxValueName, LPDWORD lpcbMaxValueData, LPDWORD lpcbSecurityDescriptor, LPFILETIME lpftLastWriteTime) { LONG rc; rc = O32_RegQueryInfoKey(ConvertKey(hkey), (char *)lpszClass, lpcchClass, lpdwReserved, lpcSubKeys, lpcchMaxSubKey, lpcchMaxClass, lpcValues, lpcchMaxValueName, lpcbMaxValueData, lpcbSecurityDescriptor,lpftLastWriteTime); if(rc == ERROR_SUCCESS) { if(lpcchClass && *lpcchClass) { char *astring = (char *)malloc(*lpcchClass+1); //returned length does NOT include 0 terminator strcpy(astring, (char *)lpszClass); AsciiToUnicode(astring, lpszClass); free(astring); } else if(lpszClass) *lpszClass = 0; } //TODO: lpcbMaxValueData could be wrong for string key values!!! (as it's in bytes) return(rc); } /***************************************************************************** * Name : * Purpose : * Parameters: * Variables : * Result : * Remark : * Status : UNTESTED STUB * * Author : Patrick Haller [Tue, 1998/06/16 23:00] *****************************************************************************/ LONG WIN32API RegQueryValueA(HKEY arg1, LPCSTR arg2, LPSTR arg3, PLONG arg4) { dprintf(("ADVAPI32:Registry key=%s\n", arg2)); return O32_RegQueryValue(ConvertKey(arg1), arg2, arg3, arg4); } /***************************************************************************** * Name : * Purpose : * Parameters: * Variables : * Result : * Remark : * Status : UNTESTED STUB * * Author : Patrick Haller [Tue, 1998/06/16 23:00] *****************************************************************************/ LONG WIN32API RegQueryValueW(HKEY hkey, LPCWSTR lpszSubKey, LPWSTR lpszValue, PLONG pcbValue) { char *astring1 = UnicodeToAsciiString((LPWSTR)lpszSubKey); char *astring2; LONG rc; rc = RegQueryValueA(hkey, astring1, (char *)lpszValue, pcbValue); if(rc == ERROR_SUCCESS) { if(pcbValue) { astring2 = (char *)malloc(*pcbValue); //includes 0 terminator strcpy(astring2, (char *)lpszValue); AsciiToUnicode(astring2, lpszValue); free(astring2); } } if((rc == ERROR_SUCCESS || rc == ERROR_MORE_DATA) && pcbValue) { *pcbValue = *pcbValue * sizeof(WCHAR); //size in bytes!! } if (NULL != astring1) FreeAsciiString(astring1); return(rc); } /***************************************************************************** * Name : * Purpose : * Parameters: * Variables : * Result : * Remark : * Status : UNTESTED STUB * * Author : Patrick Haller [Tue, 1998/06/16 23:00] *****************************************************************************/ LONG WIN32API RegQueryValueExA(HKEY hkey, LPCSTR lpszValueName, LPDWORD lpdwReserved, LPDWORD lpdwType, LPBYTE lpbData, LPDWORD lpcbData) { LONG ret; DWORD dwType = 0; dprintf(("ADVAPI32:Registry key=%s", lpszValueName)); if(lpdwType == NULL) { lpdwType = &dwType; } ret = O32_RegQueryValueEx(ConvertKey(hkey), lpszValueName, lpdwReserved, lpdwType, lpbData, lpcbData); if(ret == 0) { if(lpdwType) dprintf(("key type: %x", *lpdwType)); if(lpcbData) dprintf(("key length: %d", *lpcbData)); } if(ret == 0 || ret == ERROR_MORE_DATA) { //TODO:!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // Probably the same bug for some other key types (binary, multi_sz, REG_EXPAND_SZ) if(*lpdwType == REG_SZ && (lpbData == NULL || ret == ERROR_MORE_DATA) && lpcbData) { dprintf(("Get the real size of the string key data")); //Get the real size of the string key data //not a nice fix; hope this is enough (there is no clear connection //between returned length and real string length (not linear for different //string sizes)) *lpcbData = 4096; lpbData = (LPBYTE)malloc(*lpcbData); if(lpcbData) { //don't overwrite return value (in case it was ERROR_MODE_DATA) O32_RegQueryValueEx(ConvertKey(hkey), lpszValueName, lpdwReserved, lpdwType, lpbData, lpcbData); if(lpcbData) dprintf(("real key length: %d", *lpcbData)); free(lpbData); } } } return ret; } /***************************************************************************** * Name : * Purpose : * Parameters: * Variables : * Result : * Remark : TODO: DOESN'T WORK FOR STRING DATA!! * Status : UNTESTED STUB * * Author : Patrick Haller [Tue, 1998/06/16 23:00] *****************************************************************************/ LONG WIN32API RegQueryValueExW(HKEY hkey, LPCWSTR lpszValueName, LPDWORD lpdwReserved, LPDWORD lpdwType, LPBYTE lpbData, LPDWORD lpcbData) { char *astring = UnicodeToAsciiString(lpszValueName); char *akeydata = NULL; LONG rc; DWORD dwType; if(lpbData && lpcbData) { akeydata = (char *)malloc(*lpcbData+1); akeydata[*lpcbData] = 0; } if(lpdwType == NULL) { lpdwType = &dwType; } rc = RegQueryValueExA(hkey, astring, lpdwReserved, lpdwType, (LPBYTE)akeydata, lpcbData); //could also query key type (without returning data), call it again and only allocate translation //buffer if string type if(rc == ERROR_SUCCESS && lpbData && lpcbData) { switch(*lpdwType) { case REG_SZ: case REG_EXPAND_SZ: lstrcpyAtoW((LPWSTR)lpbData, akeydata); break; case REG_MULTI_SZ: case REG_LINK: //??? dprintf(("ERROR: key data must be translated from Unicode to Ascii!!")); break; default: memcpy(lpbData, akeydata, *lpcbData); break; } } if((rc == ERROR_SUCCESS || rc == ERROR_MORE_DATA) && lpcbData) { switch(*lpdwType) { case REG_SZ: case REG_EXPAND_SZ: case REG_MULTI_SZ: case REG_LINK: //??? *lpcbData = *lpcbData * sizeof(WCHAR); //size in bytes!! break; } } if (NULL != astring) FreeAsciiString(astring); if(akeydata) free(akeydata); return(rc); } /***************************************************************************** * Name : * Purpose : * Parameters: * Variables : * Result : * Remark : * Status : UNTESTED STUB * * Author : Patrick Haller [Tue, 1998/06/16 23:00] *****************************************************************************/ LONG WIN32API RegSetValueA(HKEY hkey, LPCSTR lpSubKey, DWORD dwType, LPCSTR lpData, DWORD cbData) { LONG rc; //SvL: 8-11-'97: Bugfix: crash in pmwinx if size == 0 and string is large if(cbData == 0) cbData = strlen(lpData); rc = O32_RegSetValue(ConvertKey(hkey), lpSubKey, dwType, lpData, cbData); if(rc == ERROR_NOT_ENOUGH_MEMORY && cbData == 0 && dwType == REG_SZ) { char regdata = 0; //SvL: Netscape sets an empty string key this way; Open32 doesn't like it rc = O32_RegSetValue(ConvertKey(hkey), lpSubKey, dwType, ®data, 1); } return rc; } /***************************************************************************** * Name : * Purpose : * Parameters: * Variables : * Result : * Remark : * Status : UNTESTED STUB * * Author : Patrick Haller [Tue, 1998/06/16 23:00] *****************************************************************************/ LONG WIN32API RegSetValueW(HKEY hkey, LPCWSTR lpSubKey, DWORD dwType, LPCWSTR lpData, DWORD cbData) { char *astring1 = UnicodeToAsciiString((LPWSTR)lpSubKey); char *astring2 = UnicodeToAsciiString((LPWSTR)lpData); LONG rc; rc = RegSetValueA(hkey, astring1, dwType, astring2, cbData); if (NULL != astring1) FreeAsciiString(astring1); if (NULL != astring2) FreeAsciiString(astring2); return(rc); } /***************************************************************************** * Name : * Purpose : * Parameters: * Variables : * Result : * Remark : TODO:Check for string length here too? * Status : UNTESTED STUB * * Author : Patrick Haller [Tue, 1998/06/16 23:00] *****************************************************************************/ LONG WIN32API RegSetValueExA(HKEY hkey, LPCSTR lpszValueName, DWORD dwReserved, DWORD fdwType, const BYTE *lpbData, DWORD cbData) { LPSTR lpszExpandedString = NULL; LONG ret; if(fdwType == REG_SZ || fdwType == REG_EXPAND_SZ) { dprintf(("ADVAPI32: RegSetValueExA)%08xh,%s,%08xh,%08xh,%s,%08xh)", hkey, lpszValueName, dwReserved, fdwType, lpbData, cbData)); } else { dprintf(("ADVAPI32: RegSetValueExA)%08xh,%s,%08xh,%08xh,%08xh,%08xh)", hkey, lpszValueName, dwReserved, fdwType, lpbData, cbData)); } if(fdwType == REG_EXPAND_SZ) { dprintf(("!WARNING!: REG_EXPAND_SZ converted to REG_SZ")); fdwType = REG_SZ; //registry.dll doesn't like this type //Expand string lpszExpandedString = (LPSTR)malloc(cbData); if(lpszExpandedString == NULL) { DebugInt3(); return ERROR_NOT_ENOUGH_MEMORY; } ExpandEnvironmentStringsA((LPSTR)lpbData, lpszExpandedString, cbData); lpbData = (BYTE *)lpszExpandedString; cbData = strlen(lpszExpandedString)+1; dprintf(("Expanded to: %s", lpszExpandedString)); } ret = O32_RegSetValueEx(ConvertKey(hkey), lpszValueName, dwReserved, fdwType, lpbData, cbData); if(lpszExpandedString) free(lpszExpandedString); return ret; } /***************************************************************************** * Name : * Purpose : * Parameters: * Variables : * Result : * Remark : TODO:Check for string length here too? * Status : UNTESTED STUB * * Author : Patrick Haller [Tue, 1998/06/16 23:00] *****************************************************************************/ LONG WIN32API RegSetValueExW(HKEY hkey, LPCWSTR lpszValueName, DWORD dwReserved, DWORD fdwType, const BYTE *lpbData, DWORD cbData) { char *astring = UnicodeToAsciiString(lpszValueName); char *akeydata = NULL; LONG rc; switch(fdwType) { case REG_SZ: case REG_EXPAND_SZ: akeydata = UnicodeToAsciiString((LPWSTR)lpbData); lpbData = (BYTE *)akeydata; break; case REG_MULTI_SZ: case REG_LINK: //??? dprintf(("ERROR: key data must be translated from Unicode to Ascii!!")); break; } rc = RegSetValueExA(hkey, astring, dwReserved, fdwType, lpbData, cbData); if(akeydata) FreeAsciiString(akeydata); if (NULL != astring) FreeAsciiString(astring); return(rc); } /***************************************************************************** * Name : * Purpose : * Parameters: * Variables : * Result : * Remark : * Status : UNTESTED STUB * * Author : Patrick Haller [Tue, 1998/06/16 23:00] *****************************************************************************/ LONG WIN32API RegFlushKey(HKEY hkey) { dprintf(("ADVAPI32: RegFlushKey not implemented yet.")); return(ERROR_SUCCESS); } /***************************************************************************** * Name : RegConnectRegistryA * Purpose : The RegConnectRegistry function establishes a connection to a * predefined registry handle on another computer. * Parameters: LPTSTR lpszComputerName address of name of remote computer * HKEY hKey predefined registry handle * PHKEY phkResult address of buffer for remote registry handle * Variables : * Result : * Remark : * Status : UNTESTED STUB * * Author : Patrick Haller [Tue, 1998/06/16 23:00] *****************************************************************************/ LONG WIN32API RegConnectRegistryA(LPCSTR lpszComputerName, HKEY hKey, PHKEY phkResult) { char szLocalName[256]; DWORD dwNameLength = sizeof(szLocalName)-2; szLocalName[0] = '\\'; szLocalName[1] = '\\'; GetComputerNameA(szLocalName+2, &dwNameLength); dprintf(("ADVAPI32: RegConnectRegistryA(%s,local %s) not implemented yet.\n", lpszComputerName, szLocalName)); /* local registry ? */ if ( ( lpszComputerName == NULL) || (strcmp(szLocalName, lpszComputerName) == 0 ) ) { /* @@@PH experimental !!! */ *phkResult = hKey; return (NO_ERROR); } return (ERROR_ACCESS_DENIED); } /***************************************************************************** * Name : RegConnectRegistryW * Purpose : The RegConnectRegistry function establishes a connection to a * predefined registry handle on another computer. * Parameters: LPWSTR lpszComputerName address of name of remote computer * HKEY hKey predefined registry handle * PHKEY phkResult address of buffer for remote registry handle * Variables : * Result : * Remark : * Status : UNTESTED STUB * * Author : Patrick Haller [Tue, 1998/06/16 23:00] *****************************************************************************/ LONG WIN32API RegConnectRegistryW(LPCWSTR lpszComputerName, HKEY hKey, PHKEY phkResult) { /* corresponding ascii string */ LPSTR pszAscii; LONG rc; /* returncode from call to ascii version of this function */ dprintf(("ADVAPI32: RegConnectRegistryW not implemented yet.")); if (lpszComputerName != NULL) pszAscii = UnicodeToAsciiString((LPWSTR)lpszComputerName); else pszAscii = NULL; rc = RegConnectRegistryA(pszAscii, hKey, phkResult); if (pszAscii != NULL) FreeAsciiString(pszAscii); return (rc); /* OK */ } /***************************************************************************** * Name : RegGetKeySecurity * Purpose : The RegGetKeySecurity function retrieves a copy of the security * descriptor protecting the specified open registry key. * Parameters: HKEY hKey open handle of key to set * SECURITY_INFORMATION SecInf descriptor contents * PSECURITY_DESCRIPTOR pSecDesc address of descriptor for key * LPDWORD lpcbSecDesc address of size of buffer and descriptor * Variables : * Result : * Remark : * Status : UNTESTED STUB * * Author : Patrick Haller [Tue, 1998/06/16 23:00] *****************************************************************************/ LONG WIN32API RegGetKeySecurity(HKEY hKey, SECURITY_INFORMATION SecInf, PSECURITY_DESCRIPTOR pSecDesc, LPDWORD lpcbSecDesc) { dprintf(("ADVAPI32: RegGetKeySecurity not implemented.\n")); return (ERROR_ACCESS_DENIED); /* signal failure */ } /***************************************************************************** * Name : RegLoadKeyA * Purpose : The RegLoadKey function creates a subkey under HKEY_USER or * HKEY_LOCAL_MACHINE and stores registration information from a * specified file into that subkey. This registration information * is in the form of a hive. A hive is a discrete body of keys, * subkeys, and values that is rooted at the top of the registry * hierarchy. A hive is backed by a single file and .LOG file. * Parameters: HKEY hKey handle of open key * LPCSTR lpszSubKey address of name of subkey * LPCSTR lpszFile address of filename for registry information * Variables : * Result : * Remark : * Status : UNTESTED STUB * * Author : Patrick Haller [Tue, 1998/06/16 23:00] *****************************************************************************/ LONG WIN32API RegLoadKeyA(HKEY hKey, LPCSTR lpszSubKey, LPCSTR lpszFile) { dprintf(("ADVAPI32: RegLoadKeyA not implemented.\n")); return (ERROR_ACCESS_DENIED); /* signal failure */ } /***************************************************************************** * Name : RegLoadKeyW * Purpose : The RegLoadKey function creates a subkey under HKEY_USER or * HKEY_LOCAL_MACHINE and stores registration information from a * specified file into that subkey. This registration information * is in the form of a hive. A hive is a discrete body of keys, * subkeys, and values that is rooted at the top of the registry * hierarchy. A hive is backed by a single file and .LOG file. * Parameters: HKEY hKey handle of open key * LPCWSTR lpszSubKey address of name of subkey * LPCWSTR lpszFile address of filename for registry information * Variables : * Result : * Remark : * Status : UNTESTED STUB * * Author : Patrick Haller [Tue, 1998/06/16 23:00] *****************************************************************************/ LONG WIN32API RegLoadKeyW(HKEY hKey, LPCWSTR lpszSubKey, LPCWSTR lpszFile) { dprintf(("ADVAPI32: RegLoadKeyW not implemented.\n")); return (ERROR_ACCESS_DENIED); /* signal failure */ } /***************************************************************************** * Name : RegQueryMultipleValuesA * Purpose : The RegQueryMultipleValues function retrieves the type and data * for a list of value names associated with an open registry key. * Parameters: HKEY hKey handle of key to query * PVALENT val_list address of array of value entry structures * DWORD num_vals size of array of value entry structures * LPTSTR lpValueBuf address of buffer for value information * LPDWORD ldwTotsize address of size of value buffer * Variables : * Result : * Remark : * Status : UNTESTED STUB * * Author : Patrick Haller [Tue, 1998/06/16 23:00] *****************************************************************************/ LONG WIN32API RegQueryMultipleValuesA(HKEY hKey, PVALENTA val_list, DWORD num_vals, LPTSTR lpValueBuf, LPDWORD ldwTotsize) { dprintf(("ADVAPI32: RegQueryMultipleValuesA not implemented.\n")); return (ERROR_ACCESS_DENIED); /* signal failure */ } /***************************************************************************** * Name : RegQueryMultipleValuesW * Purpose : The RegQueryMultipleValues function retrieves the type and data * for a list of value names associated with an open registry key. * Parameters: HKEY hKey handle of key to query * PVALENT val_list address of array of value entry structures * DWORD num_vals size of array of value entry structures * LPWSTR lpValueBuf address of buffer for value information * LPDWORD ldwTotsize address of size of value buffer * Variables : * Result : * Remark : * Status : UNTESTED STUB * * Author : Patrick Haller [Tue, 1998/06/16 23:00] *****************************************************************************/ LONG WIN32API RegQueryMultipleValuesW(HKEY hKey, PVALENTW val_list, DWORD num_vals, LPWSTR lpValueBuf, LPDWORD ldwTotsize) { dprintf(("ADVAPI32: RegQueryMultipleValuesW not implemented.\n")); return (ERROR_ACCESS_DENIED); /* signal failure */ } /***************************************************************************** * Name : RegRemapPreDefKey * Purpose : * Parameters: * Variables : * Result : * Remark : * Status : UNTESTED STUB * * Author : Patrick Haller [Tue, 1998/06/16 23:00] *****************************************************************************/ #if 0 LONG WIN32API RegRemapPreDefKey(HKEY hKey) { dprintf(("ADVAPI32: RegRemapPreDefKey not implemented.\n")); return (ERROR_ACCESS_DENIED); /* signal failure */ } #endif /***************************************************************************** * Name : RegReplaceKeyA * Purpose : The RegReplaceKey function replaces the file backing a key and * all its subkeys with another file, so that when the system is * next started, the key and subkeys will have the values stored in the new file. * Parameters: HKEY hKey handle of open key * LPCSTR lpSubKey address of name of subkey * LPCSTR lpNewFile address of filename for file with new data * LPCSTR lpOldFile address of filename for backup file * Variables : * Result : * Remark : * Status : UNTESTED STUB * * Author : Patrick Haller [Tue, 1998/06/16 23:00] *****************************************************************************/ LONG WIN32API RegReplaceKeyA(HKEY hKey, LPCSTR lpSubKey, LPCSTR lpNewFile, LPCSTR lpOldFile) { dprintf(("ADVAPI32: RegReplaceKeyA not implemented.\n")); return (ERROR_ACCESS_DENIED); /* signal failure */ } /***************************************************************************** * Name : RegReplaceKeyW * Purpose : The RegReplaceKey function replaces the file backing a key and * all its subkeys with another file, so that when the system is * next started, the key and subkeys will have the values stored in the new file. * Parameters: HKEY hKey handle of open key * LPCWSTR lpSubKey address of name of subkey * LPCWSTR lpNewFile address of filename for file with new data * LPCWSTR lpOldFile address of filename for backup file * Variables : * Result : * Remark : * Status : UNTESTED STUB * * Author : Patrick Haller [Tue, 1998/06/16 23:00] *****************************************************************************/ LONG WIN32API RegReplaceKeyW(HKEY hKey, LPCWSTR lpSubKey, LPCWSTR lpNewFile, LPCWSTR lpOldFile) { dprintf(("ADVAPI32: RegReplaceKeyW not implemented.\n")); return (ERROR_ACCESS_DENIED); /* signal failure */ } /***************************************************************************** * Name : RegRestoreKeyA * Purpose : The RegRestoreKey function reads the registry information in a * specified file and copies it over the specified key. This * registry information may be in the form of a key and multiple * levels of subkeys. * Parameters: HKEY hKey handle of key where restore begins * LPCSTR lpszFile address of filename containing saved tree * DWORD fdw optional flags * Variables : * Result : * Remark : * Status : UNTESTED STUB * * Author : Patrick Haller [Tue, 1998/06/16 23:00] *****************************************************************************/ LONG WIN32API RegRestoreKeyA(HKEY hKey, LPCSTR lpszFile, DWORD fdw) { dprintf(("ADVAPI32: RegRestoreKeyA not implemented.\n")); return (ERROR_ACCESS_DENIED); /* signal failure */ } /***************************************************************************** * Name : RegRestoreKeyW * Purpose : The RegRestoreKey function reads the registry information in a * specified file and copies it over the specified key. This * registry information may be in the form of a key and multiple * levels of subkeys. * Parameters: HKEY hKey handle of key where restore begins * LPCWSTR lpszFile address of filename containing saved tree * DWORD fdw optional flags * Variables : * Result : * Remark : * Status : UNTESTED STUB * * Author : Patrick Haller [Tue, 1998/06/16 23:00] *****************************************************************************/ LONG WIN32API RegRestoreKeyW(HKEY hKey, LPCWSTR lpszFile, DWORD fdw) { dprintf(("ADVAPI32: RegRestoreKeyW not implemented.\n")); return (ERROR_ACCESS_DENIED); /* signal failure */ } /***************************************************************************** * Name : RegSaveKeyA * Purpose : The RegSaveKey function saves the specified key and all of its * subkeys and values to a new file. * Parameters: HKEY hKey handle of key where save begins * LPCSTR lpszFile address of filename to save to * LPSECURITY_ATTRIBUTES lpsa address of security structure * Variables : * Result : * Remark : * Status : UNTESTED STUB * * Author : Patrick Haller [Tue, 1998/06/16 23:00] *****************************************************************************/ LONG WIN32API RegSaveKeyA(HKEY hKey, LPCSTR lpszFile, LPSECURITY_ATTRIBUTES lpsa) { dprintf(("ADVAPI32: RegSaveKeyA not implemented.\n")); return (ERROR_ACCESS_DENIED); /* signal failure */ } /***************************************************************************** * Name : RegSaveKeyW * Purpose : The RegSaveKey function saves the specified key and all of its * subkeys and values to a new file. * Parameters: HKEY hKey handle of key where save begins * LPCWSTR lpszFile address of filename to save to * LPSECURITY_ATTRIBUTES lpsa address of security structure * Variables : * Result : * Remark : * Status : UNTESTED STUB * * Author : Patrick Haller [Tue, 1998/06/16 23:00] *****************************************************************************/ LONG WIN32API RegSaveKeyW(HKEY hKey, LPCWSTR lpszFile, LPSECURITY_ATTRIBUTES lpsa) { dprintf(("ADVAPI32: RegSaveKeyW not implemented.\n")); return (ERROR_ACCESS_DENIED); /* signal failure */ } /***************************************************************************** * Name : RegSetKeySecurity * Purpose : The RegSetKeySecurity function sets the security of an open registry key. * Parameters: HKEY hKey open handle of key to set * SECURITY_INFORMATION si descriptor contents * PSECURITY_DESCRIPTOR psd address of descriptor for key * Variables : * Result : * Remark : * Status : UNTESTED STUB * * Author : Patrick Haller [Tue, 1998/06/16 23:00] *****************************************************************************/ LONG WIN32API RegSetKeySecurity(HKEY hKey, SECURITY_INFORMATION si, PSECURITY_DESCRIPTOR psd) { dprintf(("ADVAPI32: RegSetKeySecurity not implemented.\n")); return (ERROR_ACCESS_DENIED); /* signal failure */ } /***************************************************************************** * Name : RegUnLoadKeyA * Purpose : The RegUnLoadKey function unloads the specified key and subkeys from the registry. * Parameters: HKEY hKey handle of open key * LPCSTR lpszSubKey address of name of subkey to unload * Variables : * Result : * Remark : * Status : UNTESTED STUB * * Author : Patrick Haller [Tue, 1998/06/16 23:00] *****************************************************************************/ LONG WIN32API RegUnLoadKeyA(HKEY hKey, LPCSTR lpszSubKey) { dprintf(("ADVAPI32: RegUnLoadKeyA not implemented.\n")); return (ERROR_ACCESS_DENIED); /* signal failure */ } /***************************************************************************** * Name : RegUnLoadKeyW * Purpose : The RegUnLoadKey function unloads the specified key and subkeys from the registry. * Parameters: HKEY hKey handle of open key * LPCWSTR lpszSubKey address of name of subkey to unload * Variables : * Result : * Remark : * Status : UNTESTED STUB * * Author : Patrick Haller [Tue, 1998/06/16 23:00] *****************************************************************************/ LONG WIN32API RegUnLoadKeyW(HKEY hKey, LPCWSTR lpszSubKey) { dprintf(("ADVAPI32: RegUnLoadKeyW not implemented.\n")); return (ERROR_ACCESS_DENIED); /* signal failure */ } /***************************************************************************** * Name : RegNotifyChangeKeyValue * Purpose : * Parameters: HKEY hKey handle of open key * LPCWSTR lpszSubKey address of name of subkey to unload * Variables : * Result : * Remark : * Status : UNTESTED STUB * * Author : Patrick Haller [Tue, 1998/06/16 23:00] *****************************************************************************/ LONG WIN32API RegNotifyChangeKeyValue(HKEY hKey, BOOL bWatchSubtree, DWORD dwNotifyFilter, HANDLE hEvent, BOOL fAsynchronus) { dprintf(("ADVAPI32: RegNotifyChangeKeyValue() not implemented.\n")); return ERROR_ACCESS_DENIED; } } // extern "C"