mirror of
https://github.com/reactos/reactos.git
synced 2024-08-20 02:13:29 +00:00
202 lines
5.4 KiB
C
202 lines
5.4 KiB
C
/*
|
|
* PROJECT: ReactOS Service Host
|
|
* LICENSE: BSD - See COPYING.ARM in the top level directory
|
|
* FILE: base/services/svchost/registry.c
|
|
* PURPOSE: Helper functions for accessing the registry
|
|
* PROGRAMMERS: ReactOS Portable Systems Group
|
|
*/
|
|
|
|
/* INCLUDES ******************************************************************/
|
|
|
|
#include "svchost.h"
|
|
|
|
/* FUNCTIONS *****************************************************************/
|
|
|
|
DWORD
|
|
WINAPI
|
|
RegQueryValueWithAlloc (
|
|
_In_ HKEY hKey,
|
|
_In_ LPCWSTR pszValueName,
|
|
_In_ DWORD dwExpectedType,
|
|
_Out_ PBYTE* ppbData,
|
|
_Out_ PDWORD pdwSize
|
|
)
|
|
{
|
|
DWORD dwError, dwType, dwBytes;
|
|
PBYTE pbData;
|
|
ASSERT(hKey);
|
|
ASSERT(pszValueName);
|
|
ASSERT(ppbData);
|
|
ASSERT(pdwSize);
|
|
|
|
/* Assume failure */
|
|
*ppbData = NULL;
|
|
*pdwSize = 0;
|
|
|
|
/* Query how big and what type the registry data is */
|
|
dwBytes = 0;
|
|
dwError = RegQueryValueExW(hKey,
|
|
pszValueName,
|
|
NULL,
|
|
&dwType,
|
|
NULL,
|
|
&dwBytes);
|
|
if (dwError != ERROR_SUCCESS) return dwError;
|
|
|
|
/* It if's not the right type, or it's sero bytes, fail*/
|
|
if ((dwType != dwExpectedType) || (dwBytes == 0)) return ERROR_INVALID_DATA;
|
|
|
|
/* Allocate space to hold the data */
|
|
pbData = MemAlloc(0, dwBytes);
|
|
if (pbData == NULL) return ERROR_OUTOFMEMORY;
|
|
|
|
/* Now get the real registry data */
|
|
dwError = RegQueryValueExW(hKey,
|
|
pszValueName,
|
|
NULL,
|
|
&dwType,
|
|
pbData,
|
|
&dwBytes);
|
|
if (dwError != ERROR_SUCCESS)
|
|
{
|
|
/* We failed, free the data since it won't be needed */
|
|
MemFree(pbData);
|
|
}
|
|
else
|
|
{
|
|
/* It worked, return the data and size back to the caller */
|
|
*ppbData = pbData;
|
|
*pdwSize = dwBytes;
|
|
}
|
|
|
|
/* All done */
|
|
return dwError;
|
|
}
|
|
|
|
DWORD
|
|
WINAPI
|
|
RegQueryDword (
|
|
_In_ HKEY hKey,
|
|
_In_ LPCWSTR pszValueName,
|
|
_Out_ PDWORD pdwValue
|
|
)
|
|
{
|
|
DWORD dwError, cbData, dwType;
|
|
ASSERT(hKey);
|
|
ASSERT(pszValueName);
|
|
ASSERT(pdwValue);
|
|
|
|
/* Attempt to read 4 bytes */
|
|
cbData = sizeof(DWORD);
|
|
dwError = RegQueryValueExW(hKey, pszValueName, 0, &dwType, 0, &cbData);
|
|
|
|
/* If we didn't get back a DWORD... */
|
|
if ((dwError == ERROR_SUCCESS) && (dwType != REG_DWORD))
|
|
{
|
|
/* Zero out the output and fail */
|
|
*pdwValue = 0;
|
|
dwError = ERROR_INVALID_DATATYPE;
|
|
}
|
|
|
|
/* All done! */
|
|
return dwError;
|
|
}
|
|
|
|
DWORD
|
|
WINAPI
|
|
RegQueryString (
|
|
_In_ HKEY hKey,
|
|
_In_ LPCWSTR pszValueName,
|
|
_In_ DWORD dwExpectedType,
|
|
_Out_ PBYTE* ppbData
|
|
)
|
|
{
|
|
DWORD dwSize;
|
|
ASSERT(hKey);
|
|
ASSERT(pszValueName);
|
|
|
|
/* Call the helper function */
|
|
return RegQueryValueWithAlloc(hKey,
|
|
pszValueName,
|
|
dwExpectedType,
|
|
ppbData,
|
|
&dwSize);
|
|
}
|
|
|
|
DWORD
|
|
WINAPI
|
|
RegQueryStringA (
|
|
_In_ HKEY hKey,
|
|
_In_ LPCWSTR pszValueName,
|
|
_In_ DWORD dwExpectedType,
|
|
_Out_ LPCSTR* ppszData
|
|
)
|
|
{
|
|
DWORD dwError;
|
|
LPWSTR pbLocalData;
|
|
DWORD cchValueName, cbMultiByte;
|
|
LPSTR pszData;
|
|
ASSERT(hKey);
|
|
ASSERT(pszValueName);
|
|
ASSERT(ppszData);
|
|
|
|
/* Assume failure */
|
|
*ppszData = NULL;
|
|
|
|
/* Query the string in Unicode first */
|
|
dwError = RegQueryString(hKey,
|
|
pszValueName,
|
|
dwExpectedType,
|
|
(PBYTE*)&pbLocalData);
|
|
if (dwError != ERROR_SUCCESS) return dwError;
|
|
|
|
/* Get the length of the Unicode string */
|
|
cchValueName = lstrlenW(pbLocalData);
|
|
|
|
/* See how much space it would take to convert to ANSI */
|
|
cbMultiByte = WideCharToMultiByte(CP_ACP,
|
|
0,
|
|
pbLocalData,
|
|
cchValueName + 1,
|
|
NULL,
|
|
0,
|
|
NULL,
|
|
NULL);
|
|
if (cbMultiByte != 0)
|
|
{
|
|
/* Allocate the space, assuming failure */
|
|
dwError = ERROR_OUTOFMEMORY;
|
|
pszData = MemAlloc(0, cbMultiByte);
|
|
if (pszData != NULL)
|
|
{
|
|
/* What do you know, it worked! */
|
|
dwError = ERROR_SUCCESS;
|
|
|
|
/* Now do the real conversion */
|
|
if (WideCharToMultiByte(CP_ACP,
|
|
0,
|
|
pbLocalData,
|
|
cchValueName + 1,
|
|
pszData,
|
|
cbMultiByte,
|
|
NULL,
|
|
NULL) != 0)
|
|
{
|
|
/* It worked, return the data back to the caller */
|
|
*ppszData = pszData;
|
|
}
|
|
else
|
|
{
|
|
/* It failed, free our buffer and get the error code */
|
|
MemFree(pszData);
|
|
dwError = GetLastError();
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Free the original Unicode string and return the error */
|
|
MemFree(pbLocalData);
|
|
return dwError;
|
|
}
|
|
|