📄 reg.c
字号:
return dwRet;
}
/*************************************************************************
* SHGetValueW [SHLWAPI.@]
*
* See SHGetValueA.
*/
DWORD WINAPI SHGetValueW(HKEY hKey, LPCWSTR lpszSubKey, LPCWSTR lpszValue,
LPDWORD pwType, LPVOID pvData, LPDWORD pcbData)
{
DWORD dwRet = 0;
HKEY hSubKey = 0;
TRACE("(hkey=%p,%s,%s,%p,%p,%p)\n", hKey, debugstr_w(lpszSubKey),
debugstr_w(lpszValue), pwType, pvData, pcbData);
if(lpszSubKey)
dwRet = RegOpenKeyExW(hKey, lpszSubKey, 0, KEY_QUERY_VALUE, &hSubKey);
if (! dwRet)
{
dwRet = SHQueryValueExW(hSubKey ? hSubKey : hKey, lpszValue, 0, pwType, pvData, pcbData);
if (hSubKey) RegCloseKey(hSubKey);
}
return dwRet;
}
/*************************************************************************
* SHSetValueA [SHLWAPI.@]
*
* Set a value in the registry.
*
* PARAMS
* hKey [I] Handle to registry key
* lpszSubKey [I] Name of sub key under hKey
* lpszValue [I] Name of value to set
* dwType [I] Type of the value
* pvData [I] Data of the value
* cbData [I] Size of the value
*
* RETURNS
* Success: ERROR_SUCCESS. The value is set with the data given.
* Failure: An error code from RegCreateKeyExA() or RegSetValueExA()
*
* NOTES
* If lpszSubKey does not exist, it is created before the value is set. If
* lpszSubKey is NULL or an empty string, then the value is added directly
* to hKey instead.
*/
DWORD WINAPI SHSetValueA(HKEY hKey, LPCSTR lpszSubKey, LPCSTR lpszValue,
DWORD dwType, LPCVOID pvData, DWORD cbData)
{
DWORD dwRet = ERROR_SUCCESS, dwDummy;
HKEY hSubKey;
TRACE("(hkey=%p,%s,%s,%d,%p,%d)\n", hKey, debugstr_a(lpszSubKey),
debugstr_a(lpszValue), dwType, pvData, cbData);
if (lpszSubKey && *lpszSubKey)
dwRet = RegCreateKeyExA(hKey, lpszSubKey, 0, NULL,
0, KEY_SET_VALUE, NULL, &hSubKey, &dwDummy);
else
hSubKey = hKey;
if (!dwRet)
{
dwRet = RegSetValueExA(hSubKey, lpszValue, 0, dwType, pvData, cbData);
if (hSubKey != hKey)
RegCloseKey(hSubKey);
}
return dwRet;
}
/*************************************************************************
* SHSetValueW [SHLWAPI.@]
*
* See SHSetValueA.
*/
DWORD WINAPI SHSetValueW(HKEY hKey, LPCWSTR lpszSubKey, LPCWSTR lpszValue,
DWORD dwType, LPCVOID pvData, DWORD cbData)
{
DWORD dwRet = ERROR_SUCCESS, dwDummy;
HKEY hSubKey;
TRACE("(hkey=%p,%s,%s,%d,%p,%d)\n", hKey, debugstr_w(lpszSubKey),
debugstr_w(lpszValue), dwType, pvData, cbData);
if (lpszSubKey && *lpszSubKey)
dwRet = RegCreateKeyExW(hKey, lpszSubKey, 0, NULL,
0, KEY_SET_VALUE, NULL, &hSubKey, &dwDummy);
else
hSubKey = hKey;
if (!dwRet)
{
dwRet = RegSetValueExW(hSubKey, lpszValue, 0, dwType, pvData, cbData);
if (hSubKey != hKey)
RegCloseKey(hSubKey);
}
return dwRet;
}
/*************************************************************************
* SHQueryInfoKeyA [SHLWAPI.@]
*
* Get information about a registry key. See RegQueryInfoKeyA().
*
* RETURNS
* The result of calling RegQueryInfoKeyA().
*/
LONG WINAPI SHQueryInfoKeyA(HKEY hKey, LPDWORD pwSubKeys, LPDWORD pwSubKeyMax,
LPDWORD pwValues, LPDWORD pwValueMax)
{
TRACE("(hkey=%p,%p,%p,%p,%p)\n", hKey, pwSubKeys, pwSubKeyMax,
pwValues, pwValueMax);
return RegQueryInfoKeyA(hKey, NULL, NULL, NULL, pwSubKeys, pwSubKeyMax,
NULL, pwValues, pwValueMax, NULL, NULL, NULL);
}
/*************************************************************************
* SHQueryInfoKeyW [SHLWAPI.@]
*
* See SHQueryInfoKeyA.
*/
LONG WINAPI SHQueryInfoKeyW(HKEY hKey, LPDWORD pwSubKeys, LPDWORD pwSubKeyMax,
LPDWORD pwValues, LPDWORD pwValueMax)
{
TRACE("(hkey=%p,%p,%p,%p,%p)\n", hKey, pwSubKeys, pwSubKeyMax,
pwValues, pwValueMax);
return RegQueryInfoKeyW(hKey, NULL, NULL, NULL, pwSubKeys, pwSubKeyMax,
NULL, pwValues, pwValueMax, NULL, NULL, NULL);
}
/*************************************************************************
* SHQueryValueExA [SHLWAPI.@]
*
* Get a value from the registry, expanding environment variable strings.
*
* PARAMS
* hKey [I] Handle to registry key
* lpszValue [I] Name of value to query
* lpReserved [O] Reserved for future use; must be NULL
* pwType [O] Optional pointer updated with the values type
* pvData [O] Optional pointer updated with the values data
* pcbData [O] Optional pointer updated with the values size
*
* RETURNS
* Success: ERROR_SUCCESS. Any non NULL output parameters are updated with
* information about the value.
* Failure: ERROR_OUTOFMEMORY if memory allocation fails, or the type of the
* data is REG_EXPAND_SZ and pcbData is NULL. Otherwise an error
* code from RegQueryValueExA() or ExpandEnvironmentStringsA().
*
* NOTES
* Either pwType, pvData or pcbData may be NULL if the caller doesn't want
* the type, data or size information for the value.
*
* If the type of the data is REG_EXPAND_SZ, it is expanded to REG_SZ. The
* value returned will be truncated if it is of type REG_SZ and bigger than
* the buffer given to store it.
*
* REG_EXPAND_SZ:
* case-1: the unexpanded string is smaller than the expanded one
* subcase-1: the buffer is too small to hold the unexpanded string:
* function fails and returns the size of the unexpanded string.
*
* subcase-2: buffer is too small to hold the expanded string:
* the function return success (!!) and the result is truncated
* *** This is clearly an error in the native implementation. ***
*
* case-2: the unexpanded string is bigger than the expanded one
* The buffer must have enough space to hold the unexpanded
* string even if the result is smaller.
*
*/
DWORD WINAPI SHQueryValueExA( HKEY hKey, LPCSTR lpszValue,
LPDWORD lpReserved, LPDWORD pwType,
LPVOID pvData, LPDWORD pcbData)
{
DWORD dwRet, dwType, dwUnExpDataLen = 0, dwExpDataLen;
TRACE("(hkey=%p,%s,%p,%p,%p,%p=%d)\n", hKey, debugstr_a(lpszValue),
lpReserved, pwType, pvData, pcbData, pcbData ? *pcbData : 0);
if (pcbData) dwUnExpDataLen = *pcbData;
dwRet = RegQueryValueExA(hKey, lpszValue, lpReserved, &dwType, pvData, &dwUnExpDataLen);
if (pcbData && (dwType == REG_EXPAND_SZ))
{
DWORD nBytesToAlloc;
/* Expand type REG_EXPAND_SZ into REG_SZ */
LPSTR szData;
/* If the caller didn't supply a buffer or the buffer is too small we have
* to allocate our own
*/
if ((!pvData) || (dwRet == ERROR_MORE_DATA) )
{
char cNull = '\0';
nBytesToAlloc = dwUnExpDataLen;
szData = (LPSTR) LocalAlloc(LMEM_ZEROINIT, nBytesToAlloc);
RegQueryValueExA (hKey, lpszValue, lpReserved, NULL, (LPBYTE)szData, &nBytesToAlloc);
dwExpDataLen = ExpandEnvironmentStringsA(szData, &cNull, 1);
dwUnExpDataLen = max(nBytesToAlloc, dwExpDataLen);
LocalFree((HLOCAL) szData);
}
else
{
nBytesToAlloc = (lstrlenA(pvData)+1) * sizeof (CHAR);
szData = (LPSTR) LocalAlloc(LMEM_ZEROINIT, nBytesToAlloc );
lstrcpyA(szData, pvData);
dwExpDataLen = ExpandEnvironmentStringsA(szData, pvData, *pcbData / sizeof(CHAR));
if (dwExpDataLen > *pcbData) dwRet = ERROR_MORE_DATA;
dwUnExpDataLen = max(nBytesToAlloc, dwExpDataLen);
LocalFree((HLOCAL) szData);
}
}
/* Update the type and data size if the caller wanted them */
if ( dwType == REG_EXPAND_SZ ) dwType = REG_SZ;
if ( pwType ) *pwType = dwType;
if ( pcbData ) *pcbData = dwUnExpDataLen;
return dwRet;
}
/*************************************************************************
* SHQueryValueExW [SHLWAPI.@]
*
* See SHQueryValueExA.
*/
DWORD WINAPI SHQueryValueExW(HKEY hKey, LPCWSTR lpszValue,
LPDWORD lpReserved, LPDWORD pwType,
LPVOID pvData, LPDWORD pcbData)
{
DWORD dwRet, dwType, dwUnExpDataLen = 0, dwExpDataLen;
TRACE("(hkey=%p,%s,%p,%p,%p,%p=%d)\n", hKey, debugstr_w(lpszValue),
lpReserved, pwType, pvData, pcbData, pcbData ? *pcbData : 0);
if (pcbData) dwUnExpDataLen = *pcbData;
dwRet = RegQueryValueExW(hKey, lpszValue, lpReserved, &dwType, pvData, &dwUnExpDataLen);
if (dwRet!=ERROR_SUCCESS && dwRet!=ERROR_MORE_DATA)
return dwRet;
if (pcbData && (dwType == REG_EXPAND_SZ))
{
DWORD nBytesToAlloc;
/* Expand type REG_EXPAND_SZ into REG_SZ */
LPWSTR szData;
/* If the caller didn't supply a buffer or the buffer is too small we have
* to allocate our own
*/
if ((!pvData) || (dwRet == ERROR_MORE_DATA) )
{
WCHAR cNull = '\0';
nBytesToAlloc = dwUnExpDataLen;
szData = (LPWSTR) LocalAlloc(LMEM_ZEROINIT, nBytesToAlloc);
RegQueryValueExW (hKey, lpszValue, lpReserved, NULL, (LPBYTE)szData, &nBytesToAlloc);
dwExpDataLen = ExpandEnvironmentStringsW(szData, &cNull, 1);
dwUnExpDataLen = max(nBytesToAlloc, dwExpDataLen);
LocalFree((HLOCAL) szData);
}
else
{
nBytesToAlloc = (lstrlenW(pvData) + 1) * sizeof(WCHAR);
szData = (LPWSTR) LocalAlloc(LMEM_ZEROINIT, nBytesToAlloc );
lstrcpyW(szData, pvData);
dwExpDataLen = ExpandEnvironmentStringsW(szData, pvData, *pcbData/sizeof(WCHAR) );
if (dwExpDataLen > *pcbData) dwRet = ERROR_MORE_DATA;
dwUnExpDataLen = max(nBytesToAlloc, dwExpDataLen);
LocalFree((HLOCAL) szData);
}
}
/* Update the type and data size if the caller wanted them */
if ( dwType == REG_EXPAND_SZ ) dwType = REG_SZ;
if ( pwType ) *pwType = dwType;
if ( pcbData ) *pcbData = dwUnExpDataLen;
return dwRet;
}
/*************************************************************************
* SHDeleteKeyA [SHLWAPI.@]
*
* Delete a registry key and any sub keys/values present
*
* This function forwards to the unicode version directly, to avoid
* handling subkeys that are not representable in ASCII.
*
* PARAMS
* hKey [I] Handle to registry key
* lpszSubKey [I] Name of sub key to delete
*
* RETURNS
* Success: ERROR_SUCCESS. The key is deleted.
* Failure: An error code from RegOpenKeyExA(), RegQueryInfoKeyA(),
* RegEnumKeyExA() or RegDeleteKeyA().
*/
DWORD WINAPI SHDeleteKeyA(HKEY hKey, LPCSTR lpszSubKey)
{
WCHAR subkeyW[MAX_PATH];
MultiByteToWideChar (CP_ACP, 0, lpszSubKey, -1, subkeyW, sizeof(subkeyW)/sizeof(WCHAR));
return SHDeleteKeyW(hKey, subkeyW);
}
/*************************************************************************
* SHDeleteKeyW [SHLWAPI.@]
*
* See SHDeleteKeyA.
*/
DWORD WINAPI SHDeleteKeyW(HKEY hKey, LPCWSTR lpszSubKey)
{
DWORD dwRet, dwMaxSubkeyLen = 0, dwSize;
WCHAR szNameBuf[MAX_PATH], *lpszName = szNameBuf;
HKEY hSubKey = 0;
TRACE("(hkey=%p,%s)\n", hKey, debugstr_w(lpszSubKey));
dwRet = RegOpenKeyExW(hKey, lpszSubKey, 0, KEY_READ, &hSubKey);
if(!dwRet)
{
/* Find the maximum subkey length so that we can allocate a buffer */
dwRet = RegQueryInfoKeyW(hSubKey, NULL, NULL, NULL, NULL,
&dwMaxSubkeyLen, NULL, NULL, NULL, NULL, NULL, NULL);
if(!dwRet)
{
dwMaxSubkeyLen++;
if (dwMaxSubkeyLen > sizeof(szNameBuf)/sizeof(WCHAR))
/* Name too big: alloc a buffer for it */
lpszName = HeapAlloc(GetProcessHeap(), 0, dwMaxSubkeyLen*sizeof(WCHAR));
if(!lpszName)
dwRet = ERROR_NOT_ENOUGH_MEMORY;
else
{
while (dwRet == ERROR_SUCCESS)
{
dwSize = dwMaxSubkeyLen;
dwRet = RegEnumKeyExW(hSubKey, 0, lpszName, &dwSize, NULL, NULL, NULL, NULL);
if (dwRet == ERROR_SUCCESS || dwRet == ERROR_MORE_DATA)
dwRet = SHDeleteKeyW(hSubKey, lpszName);
}
if (dwRet == ERROR_NO_MORE_ITEMS)
dwRet = ERROR_SUCCESS;
if (lpszName != szNameBuf)
HeapFree(GetProcessHeap(), 0, lpszName); /* Free buffer if allocated */
}
}
RegCloseKey(hSubKey);
if(!dwRet)
dwRet = RegDeleteKeyW(hKey, lpszSubKey);
}
return dwRet;
}
/*************************************************************************
* SHDeleteEmptyKeyA [SHLWAPI.@]
*
* Delete a registry key with no sub keys.
*
* PARAMS
* hKey [I] Handle to registry key
* lpszSubKey [I] Name of sub key to delete
*
* RETURNS
* Success: ERROR_SUCCESS. The key is deleted.
* Failure: If the key is not empty, returns ERROR_KEY_HAS_CHILDREN. Otherwise
* returns an error code from RegOpenKeyExA(), RegQueryInfoKeyA() or
* RegDeleteKeyA().
*/
DWORD WINAPI SHDeleteEmptyKeyA(HKEY hKey, LPCSTR lpszSubKey)
{
DWORD dwRet, dwKeyCount = 0;
HKEY hSubKey = 0;
TRACE("(hkey=%p,%s)\n", hKey, debugstr_a(lpszSubKey));
dwRet = RegOpenKeyExA(hKey, lpszSubKey, 0, KEY_READ, &hSubKey);
if(!dwRet)
{
dwRet = RegQueryInfoKeyA(hSubKey, NULL, NULL, NULL, &dwKeyCount,
NULL, NULL, NULL, NULL, NULL, NULL, NULL);
RegCloseKey(hSubKey);
if(!dwRet)
{
if (!dwKeyCount)
dwRet = RegDeleteKeyA(hKey, lpszSubKey);
else
dwRet = ERROR_KEY_HAS_CHILDREN;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -