📄 reg.c
字号:
/*
* SHLWAPI registry functions
*
* Copyright 1998 Juergen Schmied
* Copyright 2001 Guy Albertelli
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <stdarg.h>
#include <string.h>
#include "windef.h"
#include "winbase.h"
#include "winuser.h"
#include "winreg.h"
#include "wine/debug.h"
#define NO_SHLWAPI_STREAM
#include "shlwapi.h"
#include "wine/unicode.h"
WINE_DEFAULT_DEBUG_CHANNEL(shell);
/* Key/Value names for MIME content types */
static const char lpszContentTypeA[] = "Content Type";
static const WCHAR lpszContentTypeW[] = { 'C','o','n','t','e','n','t',' ','T','y','p','e','\0'};
static const char szMimeDbContentA[] = "MIME\\Database\\Content Type\\";
static const WCHAR szMimeDbContentW[] = { 'M', 'I', 'M','E','\\',
'D','a','t','a','b','a','s','e','\\','C','o','n','t','e','n','t',
' ','T','y','p','e','\\', 0 };
static const DWORD dwLenMimeDbContent = 27; /* strlen of szMimeDbContentA/W */
static const char szExtensionA[] = "Extension";
static const WCHAR szExtensionW[] = { 'E', 'x', 't','e','n','s','i','o','n','\0' };
/* internal structure of what the HUSKEY points to */
typedef struct {
HKEY HKCUstart; /* Start key in CU hive */
HKEY HKCUkey; /* Opened key in CU hive */
HKEY HKLMstart; /* Start key in LM hive */
HKEY HKLMkey; /* Opened key in LM hive */
WCHAR lpszPath[MAX_PATH];
} SHUSKEY, *LPSHUSKEY;
INT WINAPI SHStringFromGUIDW(REFGUID,LPWSTR,INT);
HRESULT WINAPI SHRegGetCLSIDKeyW(REFGUID,LPCWSTR,BOOL,BOOL,PHKEY);
#define REG_HKCU TRUE
#define REG_HKLM FALSE
/*************************************************************************
* REG_GetHKEYFromHUSKEY
*
* Function: Return the proper registry key from the HUSKEY structure
* also allow special predefined values.
*/
static HKEY WINAPI REG_GetHKEYFromHUSKEY(HUSKEY hUSKey, BOOL which)
{
HKEY test = (HKEY) hUSKey;
LPSHUSKEY mihk = (LPSHUSKEY) hUSKey;
if ((test == HKEY_CLASSES_ROOT) ||
(test == HKEY_CURRENT_CONFIG) ||
(test == HKEY_CURRENT_USER) ||
(test == HKEY_DYN_DATA) ||
(test == HKEY_LOCAL_MACHINE) ||
(test == HKEY_PERFORMANCE_DATA) ||
/* FIXME: need to define for Win2k, ME, XP
* (test == HKEY_PERFORMANCE_TEXT) ||
* (test == HKEY_PERFORMANCE_NLSTEXT) ||
*/
(test == HKEY_USERS)) return test;
if (which == REG_HKCU) return mihk->HKCUkey;
return mihk->HKLMkey;
}
/*************************************************************************
* SHRegOpenUSKeyA [SHLWAPI.@]
*
* Open a user-specific registry key.
*
* PARAMS
* Path [I] Key name to open
* AccessType [I] Access type
* hRelativeUSKey [I] Relative user key
* phNewUSKey [O] Destination for created key
* fIgnoreHKCU [I] TRUE=Don't check HKEY_CURRENT_USER
*
* RETURNS
* Success: ERROR_SUCCESS
* Failure: An error code from RegOpenKeyExA().
*/
LONG WINAPI SHRegOpenUSKeyA(LPCSTR Path, REGSAM AccessType, HUSKEY hRelativeUSKey,
PHUSKEY phNewUSKey, BOOL fIgnoreHKCU)
{
WCHAR szPath[MAX_PATH];
if (Path)
MultiByteToWideChar(CP_ACP, 0, Path, -1, szPath, MAX_PATH);
return SHRegOpenUSKeyW(Path ? szPath : NULL, AccessType, hRelativeUSKey,
phNewUSKey, fIgnoreHKCU);
}
/*************************************************************************
* SHRegOpenUSKeyW [SHLWAPI.@]
*
* See SHRegOpenUSKeyA.
*/
LONG WINAPI SHRegOpenUSKeyW(LPCWSTR Path, REGSAM AccessType, HUSKEY hRelativeUSKey,
PHUSKEY phNewUSKey, BOOL fIgnoreHKCU)
{
LONG ret2, ret1 = ~ERROR_SUCCESS;
LPSHUSKEY hKey;
TRACE("(%s,0x%x,%p,%p,%d)\n", debugstr_w(Path),(LONG)AccessType,
hRelativeUSKey, phNewUSKey, fIgnoreHKCU);
if (phNewUSKey)
*phNewUSKey = NULL;
/* Create internal HUSKEY */
hKey = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*hKey));
lstrcpynW(hKey->lpszPath, Path, sizeof(hKey->lpszPath)/sizeof(WCHAR));
if (hRelativeUSKey)
{
hKey->HKCUstart = SHRegDuplicateHKey(REG_GetHKEYFromHUSKEY(hRelativeUSKey, REG_HKCU));
hKey->HKLMstart = SHRegDuplicateHKey(REG_GetHKEYFromHUSKEY(hRelativeUSKey, REG_HKLM));
/* FIXME: if either of these keys is NULL, create the start key from
* the relative keys start+path
*/
}
else
{
hKey->HKCUstart = HKEY_CURRENT_USER;
hKey->HKLMstart = HKEY_LOCAL_MACHINE;
}
if (!fIgnoreHKCU)
{
ret1 = RegOpenKeyExW(hKey->HKCUstart, hKey->lpszPath, 0, AccessType, &hKey->HKCUkey);
if (ret1)
hKey->HKCUkey = 0;
}
ret2 = RegOpenKeyExW(hKey->HKLMstart, hKey->lpszPath, 0, AccessType, &hKey->HKLMkey);
if (ret2)
hKey->HKLMkey = 0;
if (ret1 || ret2)
TRACE("one or more opens failed: HKCU=%d HKLM=%d\n", ret1, ret2);
if (ret1 && ret2)
{
/* Neither open succeeded: fail */
SHRegCloseUSKey(hKey);
return ret2;
}
TRACE("HUSKEY=%p\n", hKey);
if (phNewUSKey)
*phNewUSKey = (HUSKEY)hKey;
return ERROR_SUCCESS;
}
/*************************************************************************
* SHRegCloseUSKey [SHLWAPI.@]
*
* Close a user-specific registry key
*
* RETURNS
* Success: ERROR_SUCCESS
* Failure: An error code from RegCloseKey().
*/
LONG WINAPI SHRegCloseUSKey(
HUSKEY hUSKey) /* [I] Key to close */
{
LPSHUSKEY hKey = (LPSHUSKEY)hUSKey;
LONG ret = ERROR_SUCCESS;
if (hKey->HKCUkey)
ret = RegCloseKey(hKey->HKCUkey);
if (hKey->HKCUstart && hKey->HKCUstart != HKEY_CURRENT_USER)
ret = RegCloseKey(hKey->HKCUstart);
if (hKey->HKLMkey)
ret = RegCloseKey(hKey->HKLMkey);
if (hKey->HKLMstart && hKey->HKLMstart != HKEY_LOCAL_MACHINE)
ret = RegCloseKey(hKey->HKCUstart);
HeapFree(GetProcessHeap(), 0, hKey);
return ret;
}
/*************************************************************************
* SHRegCreateUSKeyA [SHLWAPI.@]
*
* Create or open a user-specific registry key.
*
* PARAMS
* pszPath [I] Key name to create or open.
* samDesired [I] Wanted security access.
* hRelativeUSKey [I] Base path if pszPath is relative. NULL otherwise.
* phNewUSKey [O] Receives a handle to the new or openened key.
* dwFlags [I] Base key under which the key should be opened.
*
* RETURNS
* Success: ERROR_SUCCESS
* Failure: Nonzero error code from winerror.h
*/
LONG WINAPI SHRegCreateUSKeyA(LPCSTR pszPath, REGSAM samDesired, HUSKEY hRelativeUSKey,
PHUSKEY phNewUSKey, DWORD dwFlags)
{
FIXME("(%s, 0x%08x, %p, %p, 0x%08x) stub\n", debugstr_a(pszPath), samDesired,
hRelativeUSKey, phNewUSKey, dwFlags);
return ERROR_SUCCESS;
}
/*************************************************************************
* SHRegCreateUSKeyW [SHLWAPI.@]
*
* See SHRegCreateUSKeyA.
*/
LONG WINAPI SHRegCreateUSKeyW(LPCWSTR pszPath, REGSAM samDesired, HUSKEY hRelativeUSKey,
PHUSKEY phNewUSKey, DWORD dwFlags)
{
FIXME("(%s, 0x%08x, %p, %p, 0x%08x) stub\n", debugstr_w(pszPath), samDesired,
hRelativeUSKey, phNewUSKey, dwFlags);
return ERROR_SUCCESS;
}
/*************************************************************************
* SHRegDeleteEmptyUSKeyA [SHLWAPI.@]
*
* Delete an empty user-specific registry key.
*
* PARAMS
* hUSKey [I] Handle to an open registry key.
* pszValue [I] Empty key name.
* delRegFlags [I] Flag that specifies the base from which to delete
* the key.
*
* RETURNS
* Success: ERROR_SUCCESS
* Failure: Nonzero error code from winerror.h
*/
LONG WINAPI SHRegDeleteEmptyUSKeyA(HUSKEY hUSKey, LPCSTR pszValue, SHREGDEL_FLAGS delRegFlags)
{
FIXME("(%p, %s, 0x%08x) stub\n", hUSKey, debugstr_a(pszValue), delRegFlags);
return ERROR_SUCCESS;
}
/*************************************************************************
* SHRegDeleteEmptyUSKeyW [SHLWAPI.@]
*
* See SHRegDeleteEmptyUSKeyA.
*/
LONG WINAPI SHRegDeleteEmptyUSKeyW(HUSKEY hUSKey, LPCWSTR pszValue, SHREGDEL_FLAGS delRegFlags)
{
FIXME("(%p, %s, 0x%08x) stub\n", hUSKey, debugstr_w(pszValue), delRegFlags);
return ERROR_SUCCESS;
}
/*************************************************************************
* SHRegDeleteUSValueA [SHLWAPI.@]
*
* Delete a user-specific registry value.
*
* PARAMS
* hUSKey [I] Handle to an open registry key.
* pszValue [I] Specifies the value to delete.
* delRegFlags [I] Flag that specifies the base of the key from which to
* delete the value.
*
* RETURNS
* Success: ERROR_SUCCESS
* Failure: Nonzero error code from winerror.h
*/
LONG WINAPI SHRegDeleteUSValueA(HUSKEY hUSKey, LPCSTR pszValue, SHREGDEL_FLAGS delRegFlags)
{
FIXME("(%p, %s, 0x%08x) stub\n", hUSKey, debugstr_a(pszValue), delRegFlags);
return ERROR_SUCCESS;
}
/*************************************************************************
* SHRegDeleteUSValueW [SHLWAPI.@]
*
* See SHRegDeleteUSValueA.
*/
LONG WINAPI SHRegDeleteUSValueW(HUSKEY hUSKey, LPCWSTR pszValue, SHREGDEL_FLAGS delRegFlags)
{
FIXME("(%p, %s, 0x%08x) stub\n", hUSKey, debugstr_w(pszValue), delRegFlags);
return ERROR_SUCCESS;
}
/*************************************************************************
* SHRegEnumUSValueA [SHLWAPI.@]
*
* Enumerate values of a specified registry key.
*
* PARAMS
* hUSKey [I] Handle to an open registry key.
* dwIndex [I] Index of the value to be retrieved.
* pszValueName [O] Buffer to receive the value name.
* pcchValueNameLen [I] Size of pszValueName in characters.
* pdwType [O] Receives data type of the value.
* pvData [O] Receives value data. May be NULL.
* pcbData [I/O] Size of pvData in bytes.
* enumRegFlags [I] Flag that specifies the base key under which to
* enumerate values.
*
* RETURNS
* Success: ERROR_SUCCESS
* Failure: Nonzero error code from winerror.h
*/
LONG WINAPI SHRegEnumUSValueA(HUSKEY hUSKey, DWORD dwIndex, LPSTR pszValueName,
LPDWORD pcchValueNameLen, LPDWORD pdwType, LPVOID pvData,
LPDWORD pcbData, SHREGENUM_FLAGS enumRegFlags)
{
FIXME("(%p, 0x%08x, %s, %p, %p, %p, %p, 0x%08x) stub\n", hUSKey, dwIndex,
debugstr_a(pszValueName), pcchValueNameLen, pdwType, pvData, pcbData, enumRegFlags);
return ERROR_INVALID_FUNCTION;
}
/*************************************************************************
* SHRegEnumUSValueW [SHLWAPI.@]
*
* See SHRegEnumUSValueA.
*/
LONG WINAPI SHRegEnumUSValueW(HUSKEY hUSKey, DWORD dwIndex, LPWSTR pszValueName,
LPDWORD pcchValueNameLen, LPDWORD pdwType, LPVOID pvData,
LPDWORD pcbData, SHREGENUM_FLAGS enumRegFlags)
{
FIXME("(%p, 0x%08x, %s, %p, %p, %p, %p, 0x%08x) stub\n", hUSKey, dwIndex,
debugstr_w(pszValueName), pcchValueNameLen, pdwType, pvData, pcbData, enumRegFlags);
return ERROR_INVALID_FUNCTION;
}
/*************************************************************************
* SHRegQueryUSValueA [SHLWAPI.@]
*
* Query a user-specific registry value.
*
* RETURNS
* Success: ERROR_SUCCESS
* Failure: An error code from RegQueryValueExA().
*/
LONG WINAPI SHRegQueryUSValueA(
HUSKEY hUSKey, /* [I] Key to query */
LPCSTR pszValue, /* [I] Value name under hUSKey */
LPDWORD pdwType, /* [O] Destination for value type */
LPVOID pvData, /* [O] Destination for value data */
LPDWORD pcbData, /* [O] Destination for value length */
BOOL fIgnoreHKCU, /* [I] TRUE=Don't check HKEY_CURRENT_USER */
LPVOID pvDefaultData, /* [I] Default data if pszValue does not exist */
DWORD dwDefaultDataSize) /* [I] Length of pvDefaultData */
{
LONG ret = ~ERROR_SUCCESS;
LONG i, maxmove;
HKEY dokey;
CHAR *src, *dst;
/* if user wants HKCU, and it exists, then try it */
if (!fIgnoreHKCU && (dokey = REG_GetHKEYFromHUSKEY(hUSKey,REG_HKCU))) {
ret = RegQueryValueExA(dokey,
pszValue, 0, pdwType, pvData, pcbData);
TRACE("HKCU RegQueryValue returned %08x\n", ret);
}
/* if HKCU did not work and HKLM exists, then try it */
if ((ret != ERROR_SUCCESS) &&
(dokey = REG_GetHKEYFromHUSKEY(hUSKey,REG_HKLM))) {
ret = RegQueryValueExA(dokey,
pszValue, 0, pdwType, pvData, pcbData);
TRACE("HKLM RegQueryValue returned %08x\n", ret);
}
/* if neither worked, and default data exists, then use it */
if (ret != ERROR_SUCCESS) {
if (pvDefaultData && (dwDefaultDataSize != 0)) {
maxmove = (dwDefaultDataSize >= *pcbData) ? *pcbData : dwDefaultDataSize;
src = (CHAR*)pvDefaultData;
dst = (CHAR*)pvData;
for(i=0; i<maxmove; i++) *dst++ = *src++;
*pcbData = maxmove;
TRACE("setting default data\n");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -