|
|
/*++
Copyright (c) 1997 Microsoft Corporation
Module Name:
regutil.c
Abstract:
Utilities for accessing the system registry.
Author:
Mike Massa (mikemas) May 19, 1997
Revision History:
Who When What -------- -------- ---------------------------------------------- mikemas 05-19-97 created
--*/ #include <nt.h>
#include <ntrtl.h>
#include <nturtl.h>
#include <windows.h>
LPCWSTR ClRtlMultiSzEnum( IN LPCWSTR MszString, IN DWORD MszStringLength, IN DWORD StringIndex )
/*++
Routine Description:
Parses a REG_MULTI_SZ string and returns the specified substring.
Arguments:
MszString - A pointer to the REG_MULTI_SZ string.
MszStringLength - The length of the REG_MULTI_SZ string in characters, including the terminating null character.
StringIndex - Index number of the substring to return. Specifiying index 0 retrieves the first substring.
Return Value:
A pointer to the specified substring.
--*/ { LPCWSTR string = MszString;
if ( MszStringLength < 2 ) { return(NULL); }
//
// Find the start of the desired string.
//
while (StringIndex) {
while (MszStringLength >= 1) { MszStringLength -= 1;
if (*string++ == UNICODE_NULL) { break; } }
//
// Check for index out of range.
//
if ( MszStringLength < 2 ) { return(NULL); }
StringIndex--; }
if ( MszStringLength < 2 ) { return(NULL); }
return(string); }
DWORD ClRtlMultiSzRemove( IN LPWSTR lpszMultiSz, IN OUT LPDWORD StringLength, IN LPCWSTR lpString ) /*++
Routine Description:
Removes the specified string from the supplied REG_MULTI_SZ. The MULTI_SZ is edited in place.
Arguments:
lpszMultiSz - Supplies the REG_MULTI_SZ string that lpString should be removed from.
StringLength - Supplies the length (in characters) of lpszMultiSz Returns the new length (in characters) of lpszMultiSz
lpString - Supplies the string to be removed from lpszMultiSz
Return Value:
ERROR_SUCCESS if successful
ERROR_FILE_NOT_FOUND if the string was not found in the MULTI_SZ
Win32 error code otherwise
--*/
{ PCHAR Dest, Src; DWORD CurrentLength; DWORD i; LPCWSTR Next; DWORD NextLength;
//
// Scan through the strings in the returned MULTI_SZ looking
// for a match.
//
CurrentLength = *StringLength; for (i=0; ;i++) { Next = ClRtlMultiSzEnum(lpszMultiSz, *StringLength, i); if (Next == NULL) { //
// The value was not in the specified multi-sz
//
break; } NextLength = lstrlenW(Next)+1; CurrentLength -= NextLength; if (lstrcmpiW(Next, lpString)==0) { //
// Found the string, delete it and return
//
Dest = (PCHAR)Next; Src = (PCHAR)Next + (NextLength*sizeof(WCHAR)); CopyMemory(Dest, Src, CurrentLength*sizeof(WCHAR)); *StringLength -= NextLength; return(ERROR_SUCCESS); } }
return(ERROR_FILE_NOT_FOUND); }
DWORD ClRtlMultiSzAppend( IN OUT LPWSTR *MultiSz, IN OUT LPDWORD StringLength, IN LPCWSTR lpString ) /*++
Routine Description:
Appends the specified string to the supplied REG_MULTI_SZ. The passed in MultiSz will be freed with LocalFree. A new MultiSz large enough to hold the new value will be allocated with LocalAlloc and returned in *MultiSz
Arguments:
lpszMultiSz - Supplies the REG_MULTI_SZ string that lpString should be appended to. Returns the new REG_MULTI_SZ string with lpString appended
StringLength - Supplies the length (in characters) of lpszMultiSz Returns the new length (in characters) of lpszMultiSz
lpString - Supplies the string to be appended to lpszMultiSz
Return Value:
ERROR_SUCCESS if successful
Win32 error code otherwise
--*/
{ LPWSTR NewMultiSz; DWORD Length; DWORD NewLength;
if (*MultiSz == NULL) {
//
// There is no multi-sz, create a new multi-sz with lpString as the
// only entry.
//
NewLength = lstrlenW(lpString)+2; NewMultiSz = LocalAlloc(LMEM_FIXED, NewLength*sizeof(WCHAR)); if (NewMultiSz == NULL) { return(ERROR_NOT_ENOUGH_MEMORY); } CopyMemory(NewMultiSz, lpString, (NewLength-1)*sizeof(WCHAR)); } else { //
// Append this string to the existing MULTI_SZ
//
Length = lstrlenW(lpString) + 1; NewLength = *StringLength + Length; NewMultiSz = LocalAlloc(LMEM_FIXED, NewLength * sizeof(WCHAR)); if (NewMultiSz == NULL) { return(ERROR_NOT_ENOUGH_MEMORY); } CopyMemory(NewMultiSz, *MultiSz, *StringLength * sizeof(WCHAR)); CopyMemory(NewMultiSz + *StringLength - 1, lpString, Length * sizeof(WCHAR)); NewMultiSz[NewLength-1] = L'\0'; //Free the passed in MultiSz
LocalFree(*MultiSz); }
NewMultiSz[NewLength-1] = L'\0'; *MultiSz = NewMultiSz; *StringLength = NewLength; return(ERROR_SUCCESS);
}
DWORD ClRtlMultiSzLength( IN LPCWSTR lpszMultiSz ) /*++
Routine Description:
Determines the length (in characters) of a multi-sz. The calculated length includes all trailing NULLs.
Arguments:
lpszMultiSz - Supplies the multi-sz
Return Value:
The length (in characters) of the supplied multi-sz
--*/
{ LPCWSTR p; DWORD Length=0;
if(!lpszMultiSz) return 0; if (*lpszMultiSz == UNICODE_NULL) return 1; p=lpszMultiSz; do { while (p[Length++] != L'\0') { } } while ( p[Length++] != L'\0' );
return(Length); }
LPCWSTR ClRtlMultiSzScan( IN LPCWSTR lpszMultiSz, IN LPCWSTR lpszString ) /*++
Routine Description:
Scans a multi-sz looking for an entry that matches the specified string. The match is done case-insensitive.
Arguments:
lpszMultiSz - Supplies the multi-sz to scan.
lpszString - Supplies the string to look for
Return Value:
A pointer to the string in the supplied multi-sz if found.
NULL if not found.
--*/
{ DWORD dwLength; DWORD i; LPCWSTR sz;
dwLength = ClRtlMultiSzLength(lpszMultiSz); for (i=0; ; i++) { sz = ClRtlMultiSzEnum(lpszMultiSz, dwLength, i); if (sz == NULL) { break; } if (lstrcmpiW(sz, lpszString) == 0) { break; } }
return(sz); }
DWORD ClRtlRegQueryDword( IN HKEY hKey, IN LPWSTR lpValueName, OUT LPDWORD lpValue, IN LPDWORD lpDefaultValue OPTIONAL )
/*++
Routine Description:
Reads a REG_DWORD registry value. If the value is not present, then default to the value supplied in lpDefaultValue (if present).
Arguments:
hKey - Open key for the value to be read.
lpValueName - Unicode name of the value to be read.
lpValue - Pointer to the DWORD into which to read the value.
lpDefaultValue - Optional pointer to a DWORD to use as a default value.
Return Value:
ERROR_SUCCESS if successful
Win32 error code otherwise
--*/
{ HKEY Key; DWORD Status; DWORD ValueType; DWORD ValueSize = sizeof(DWORD);
Status = RegQueryValueExW( hKey, lpValueName, NULL, &ValueType, (LPBYTE)lpValue, &ValueSize );
if ( Status == ERROR_SUCCESS ) { if ( ValueType != REG_DWORD ) { Status = ERROR_INVALID_PARAMETER; } } else { if ( ARGUMENT_PRESENT( lpDefaultValue ) ) { *lpValue = *lpDefaultValue; Status = ERROR_SUCCESS; } }
return(Status);
} // ClRtlRegQueryDword
DWORD ClRtlRegQueryString( IN HKEY Key, IN LPWSTR ValueName, IN DWORD ValueType, IN LPWSTR *StringBuffer, IN OUT LPDWORD StringBufferSize, OUT LPDWORD StringSize )
/*++
Routine Description:
Reads a REG_SZ or REG_MULTI_SZ registry value. If the StringBuffer is not large enough to hold the data, it is reallocated.
Arguments:
Key - Open key for the value to be read.
ValueName - Unicode name of the value to be read.
ValueType - REG_SZ or REG_MULTI_SZ.
StringBuffer - Buffer into which to place the value data.
StringBufferSize - Pointer to the size of the StringBuffer. This parameter is updated if StringBuffer is reallocated.
StringSize - The size of the data returned in StringBuffer, including the terminating null character.
Return Value:
The status of the registry query.
--*/ { DWORD status; DWORD valueType; WCHAR *temp; DWORD oldBufferSize = *StringBufferSize; BOOL noBuffer = FALSE;
if (*StringBufferSize == 0) { noBuffer = TRUE; }
*StringSize = *StringBufferSize;
status = RegQueryValueExW( Key, ValueName, NULL, &valueType, (LPBYTE) *StringBuffer, StringSize );
if (status == NO_ERROR) { if (!noBuffer ) { if (valueType == ValueType) { return(NO_ERROR); } else { return(ERROR_INVALID_PARAMETER); } }
status = ERROR_MORE_DATA; }
if (status == ERROR_MORE_DATA) { temp = LocalAlloc(LMEM_FIXED, *StringSize);
if (temp == NULL) { *StringSize = 0; return(ERROR_NOT_ENOUGH_MEMORY); }
if (!noBuffer) { LocalFree(*StringBuffer); }
*StringBuffer = temp; *StringBufferSize = *StringSize;
status = RegQueryValueExW( Key, ValueName, NULL, &valueType, (LPBYTE) *StringBuffer, StringSize );
if (status == NO_ERROR) { if (valueType == ValueType) { return(NO_ERROR); } else { *StringSize = 0; return(ERROR_INVALID_PARAMETER); } } }
return(status);
} // ClRtlRegQueryString
|