You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
2528 lines
58 KiB
2528 lines
58 KiB
// Copyright (c) 2001 Microsoft Corporation, All Rights Reserved
|
|
|
|
#include "precomp.h"
|
|
|
|
#include <nt.h>
|
|
#include <ntrtl.h>
|
|
#include <nturtl.h>
|
|
|
|
#include <windows.h>
|
|
#include <objbase.h>
|
|
|
|
#include "profilestring.h"
|
|
#include "profilestringimpl.h"
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////
|
|
// TOOLS
|
|
/////////////////////////////////////////////////////////////////////////////////////////
|
|
DWORD WMIREG_GetBaseFileName ( IN LPCWSTR FileName, OUT LPWSTR* BaseFileName )
|
|
{
|
|
DWORD Status = ERROR_INVALID_PARAMETER;
|
|
|
|
if ( FileName && BaseFileName )
|
|
{
|
|
*BaseFileName = NULL;
|
|
|
|
LPWSTR wsz = NULL;
|
|
wsz = const_cast < LPWSTR > ( FileName ) + wcslen ( FileName );
|
|
|
|
while ( --wsz > FileName )
|
|
{
|
|
if ( *wsz == OBJ_NAME_PATH_SEPARATOR || *wsz == L'/' || *wsz == L':' )
|
|
{
|
|
wsz++;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if ( wsz )
|
|
{
|
|
try
|
|
{
|
|
if ( ( *BaseFileName = new WCHAR [ wcslen ( wsz ) + 1 ] ) != NULL )
|
|
{
|
|
wcscpy ( *BaseFileName, wsz );
|
|
Status = ERROR_SUCCESS;
|
|
}
|
|
else
|
|
{
|
|
Status = ERROR_NOT_ENOUGH_MEMORY;
|
|
}
|
|
}
|
|
catch ( ... )
|
|
{
|
|
if ( *BaseFileName )
|
|
{
|
|
delete [] *BaseFileName;
|
|
*BaseFileName = NULL;
|
|
}
|
|
|
|
Status = ERROR_GEN_FAILURE;
|
|
}
|
|
}
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
BOOLEAN WMIREG_GetApplicationName (
|
|
IN PREGISTRY_PARAMETERS a,
|
|
OUT LPCWSTR *ApplicationNameU
|
|
)
|
|
{
|
|
if ( ApplicationNameU )
|
|
{
|
|
*ApplicationNameU = a->ApplicationName;
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
BOOLEAN WMIREG_GetVariableName (
|
|
IN PREGISTRY_PARAMETERS a,
|
|
OUT LPCWSTR *VariableNameU
|
|
)
|
|
{
|
|
if ( VariableNameU )
|
|
{
|
|
*VariableNameU = a->VariableName;
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
// get appname mapping
|
|
PREGISTRY_MAPPING_NAME WMIREG_FindMapping (
|
|
IN PREGISTRY_MAPPING_NAME NameMapping,
|
|
IN LPCWSTR MappingName
|
|
)
|
|
{
|
|
PREGISTRY_MAPPING_NAME Mapping = NULL;
|
|
Mapping = NameMapping;
|
|
|
|
while ( Mapping != NULL )
|
|
{
|
|
try
|
|
{
|
|
if ( wcslen( Mapping->Name ) == wcslen( MappingName ) )
|
|
{
|
|
if ( _wcsnicmp ( Mapping->Name, MappingName, wcslen( MappingName ) ) == 0 )
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
Mapping = (PREGISTRY_MAPPING_NAME)Mapping->Next;
|
|
}
|
|
catch ( ... )
|
|
{
|
|
Mapping = NULL;
|
|
}
|
|
}
|
|
|
|
return Mapping;
|
|
}
|
|
|
|
// get appname mapping
|
|
PREGISTRY_MAPPING_APPNAME WMIREG_FindAppNameMapping (
|
|
IN PREGISTRY_MAPPING_NAME NameMapping,
|
|
IN LPCWSTR ApplicationName
|
|
)
|
|
{
|
|
PREGISTRY_MAPPING_APPNAME AppNameMapping = NULL;
|
|
AppNameMapping = (PREGISTRY_MAPPING_APPNAME)NameMapping->ApplicationNames;
|
|
|
|
while ( AppNameMapping != NULL )
|
|
{
|
|
try
|
|
{
|
|
if ( wcslen( AppNameMapping->Name ) == wcslen( ApplicationName ) )
|
|
{
|
|
if ( _wcsnicmp ( AppNameMapping->Name, ApplicationName, wcslen( ApplicationName ) ) == 0 )
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
AppNameMapping = (PREGISTRY_MAPPING_APPNAME)AppNameMapping->Next;
|
|
}
|
|
catch ( ... )
|
|
{
|
|
AppNameMapping = NULL;
|
|
}
|
|
}
|
|
|
|
if ( !AppNameMapping )
|
|
{
|
|
AppNameMapping = (PREGISTRY_MAPPING_APPNAME)NameMapping->DefaultAppNameMapping;
|
|
}
|
|
|
|
return AppNameMapping;
|
|
}
|
|
|
|
//get varname mapping
|
|
PREGISTRY_MAPPING_VARNAME WMIREG_FindVarNameMapping (
|
|
IN PREGISTRY_MAPPING_APPNAME AppNameMapping,
|
|
IN LPCWSTR VariableName
|
|
)
|
|
{
|
|
PREGISTRY_MAPPING_VARNAME VarNameMapping = NULL;
|
|
VarNameMapping = (PREGISTRY_MAPPING_VARNAME)AppNameMapping->VariableNames;
|
|
|
|
while ( VarNameMapping != NULL )
|
|
{
|
|
try
|
|
{
|
|
if ( wcslen ( VarNameMapping->Name ) == wcslen( VariableName ) )
|
|
{
|
|
if ( _wcsnicmp ( VarNameMapping->Name, VariableName, wcslen( VariableName ) ) == 0 )
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
VarNameMapping = (PREGISTRY_MAPPING_VARNAME)VarNameMapping->Next;
|
|
}
|
|
catch ( ... )
|
|
{
|
|
VarNameMapping = NULL;
|
|
}
|
|
}
|
|
|
|
if ( !VarNameMapping )
|
|
{
|
|
VarNameMapping = (PREGISTRY_MAPPING_VARNAME)AppNameMapping->DefaultVarNameMapping;
|
|
}
|
|
|
|
return VarNameMapping;
|
|
}
|
|
|
|
// get string representing user's registry
|
|
BOOL WMIREG_UserPROFILE ( UNICODE_STRING * UserKeyPath )
|
|
{
|
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
|
HANDLE Key = NULL;
|
|
|
|
if ( NT_SUCCESS ( RtlFormatCurrentUserKeyPath( UserKeyPath ) ) )
|
|
{
|
|
InitializeObjectAttributes ( &ObjectAttributes,
|
|
UserKeyPath,
|
|
OBJ_CASE_INSENSITIVE,
|
|
NULL,
|
|
NULL
|
|
);
|
|
|
|
if ( NT_SUCCESS ( NtOpenKey( &Key, GENERIC_READ, &ObjectAttributes ) ) )
|
|
{
|
|
NtClose( Key );
|
|
}
|
|
else
|
|
{
|
|
RtlFreeUnicodeString( UserKeyPath );
|
|
RtlInitUnicodeString( UserKeyPath, NULL );
|
|
}
|
|
}
|
|
|
|
if ( UserKeyPath->Length == 0)
|
|
{
|
|
if ( !RtlCreateUnicodeString ( UserKeyPath, L"\\REGISTRY\\USER\\.DEFAULT" ) )
|
|
{
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
// open registry key
|
|
DWORD WMIREG_OpenMappingTarget (
|
|
IN PREGISTRY_PARAMETERS a,
|
|
IN PREGISTRY_MAPPING_VARNAME VarNameMapping,
|
|
IN LPCWSTR ApplicationName,
|
|
OUT PHANDLE Key
|
|
)
|
|
{
|
|
DWORD Status = ERROR_INVALID_PARAMETER;
|
|
|
|
PREGISTRY_MAPPING_TARGET MappingTarget = NULL;
|
|
ULONG MappingFlags = 0L;
|
|
|
|
BOOLEAN AppendApplicationName = FALSE;
|
|
|
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
|
|
|
PUNICODE_STRING RegistryPathPrefix = NULL;
|
|
UNICODE_STRING RegistryPath;
|
|
|
|
UNICODE_STRING UserKeyPath;
|
|
UNICODE_STRING SoftwareKeyPath;
|
|
|
|
// initialization of strings
|
|
RtlInitUnicodeString( &UserKeyPath, NULL );
|
|
RtlInitUnicodeString( &SoftwareKeyPath, L"\\Registry\\Machine\\Software" );
|
|
|
|
// temporary unicode_string
|
|
UNICODE_STRING temp;
|
|
|
|
ULONG n = 0L; // size of reg key
|
|
|
|
// init key
|
|
*Key = INVALID_HANDLE_VALUE;
|
|
|
|
// get mapping
|
|
MappingTarget = (PREGISTRY_MAPPING_TARGET)VarNameMapping->MappingTarget;
|
|
MappingFlags = VarNameMapping->MappingFlags & ( REGISTRY_MAPPING_APPEND_BASE_NAME |
|
|
REGISTRY_MAPPING_APPEND_APPLICATION_NAME |
|
|
REGISTRY_MAPPING_SOFTWARE_RELATIVE |
|
|
REGISTRY_MAPPING_USER_RELATIVE
|
|
);
|
|
|
|
if ( MappingTarget != NULL && MappingTarget->RegistryPath )
|
|
{
|
|
// everything's ok
|
|
Status = ERROR_SUCCESS;
|
|
|
|
if ( ApplicationName && ( MappingFlags & REGISTRY_MAPPING_APPEND_APPLICATION_NAME ) )
|
|
{
|
|
AppendApplicationName = TRUE;
|
|
}
|
|
else
|
|
{
|
|
AppendApplicationName = FALSE;
|
|
}
|
|
|
|
if ( MappingFlags & REGISTRY_MAPPING_USER_RELATIVE )
|
|
{
|
|
if ( WMIREG_UserPROFILE ( &UserKeyPath ) )
|
|
{
|
|
if ( UserKeyPath.Length == 0 )
|
|
{
|
|
Status = ERROR_ACCESS_DENIED;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Status = ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
if ( Status == ERROR_SUCCESS )
|
|
{
|
|
RegistryPathPrefix = &UserKeyPath;
|
|
}
|
|
}
|
|
else
|
|
if ( MappingFlags & REGISTRY_MAPPING_SOFTWARE_RELATIVE )
|
|
{
|
|
RegistryPathPrefix = &SoftwareKeyPath;
|
|
}
|
|
else
|
|
{
|
|
RegistryPathPrefix = NULL;
|
|
}
|
|
|
|
if ( Status == ERROR_SUCCESS )
|
|
{
|
|
LPWSTR BaseFileName = NULL;
|
|
|
|
if ( MappingFlags & REGISTRY_MAPPING_APPEND_BASE_NAME )
|
|
{
|
|
Status = WMIREG_GetBaseFileName ( a->FileName, &BaseFileName );
|
|
}
|
|
|
|
if ( Status == ERROR_SUCCESS )
|
|
{
|
|
if ( RegistryPathPrefix )
|
|
{
|
|
n = RegistryPathPrefix->Length + sizeof( WCHAR );
|
|
}
|
|
|
|
n += sizeof( WCHAR ) + wcslen ( MappingTarget->RegistryPath ) * sizeof ( WCHAR );
|
|
if ( MappingFlags & REGISTRY_MAPPING_APPEND_BASE_NAME )
|
|
{
|
|
n += sizeof( WCHAR ) + wcslen ( BaseFileName ) * sizeof ( WCHAR );
|
|
}
|
|
|
|
if (AppendApplicationName)
|
|
{
|
|
n += sizeof( WCHAR ) + wcslen ( ApplicationName ) * sizeof ( WCHAR );
|
|
}
|
|
|
|
n += sizeof( UNICODE_NULL );
|
|
|
|
RegistryPath.Buffer = reinterpret_cast < LPWSTR > ( RtlAllocateHeap( RtlProcessHeap(), 0, n ) );
|
|
if (RegistryPath.Buffer == NULL)
|
|
{
|
|
Status = ERROR_NOT_ENOUGH_MEMORY;
|
|
}
|
|
|
|
if ( Status == ERROR_SUCCESS )
|
|
{
|
|
RegistryPath.Length = 0;
|
|
RegistryPath.MaximumLength = (USHORT)n;
|
|
|
|
if (RegistryPathPrefix != NULL)
|
|
{
|
|
RtlAppendUnicodeStringToString( &RegistryPath, RegistryPathPrefix );
|
|
RtlAppendUnicodeToString( &RegistryPath, L"\\" );
|
|
}
|
|
|
|
RtlInitUnicodeString( &temp, MappingTarget->RegistryPath );
|
|
RtlAppendUnicodeStringToString( &RegistryPath, &temp );
|
|
RtlInitUnicodeString( &temp, NULL );
|
|
|
|
if (MappingFlags & REGISTRY_MAPPING_APPEND_BASE_NAME)
|
|
{
|
|
RtlAppendUnicodeToString( &RegistryPath, L"\\" );
|
|
|
|
RtlInitUnicodeString( &temp, BaseFileName );
|
|
RtlAppendUnicodeStringToString( &RegistryPath, &temp );
|
|
RtlInitUnicodeString( &temp, NULL );
|
|
}
|
|
|
|
if (AppendApplicationName)
|
|
{
|
|
RtlAppendUnicodeToString( &RegistryPath, L"\\" );
|
|
|
|
RtlInitUnicodeString( &temp, ApplicationName );
|
|
RtlAppendUnicodeStringToString( &RegistryPath, &temp );
|
|
RtlInitUnicodeString( &temp, NULL );
|
|
}
|
|
|
|
// open real registry
|
|
InitializeObjectAttributes ( &ObjectAttributes,
|
|
&RegistryPath,
|
|
OBJ_CASE_INSENSITIVE | OBJ_OPENIF,
|
|
NULL,
|
|
NULL
|
|
);
|
|
|
|
Status = NtOpenKey ( Key, GENERIC_READ, &ObjectAttributes );
|
|
|
|
// clear registry path
|
|
RtlFreeHeap( RtlProcessHeap(), 0, RegistryPath.Buffer );
|
|
}
|
|
}
|
|
|
|
// clear use string
|
|
if ( UserKeyPath.Length )
|
|
{
|
|
RtlFreeUnicodeString ( &UserKeyPath );
|
|
}
|
|
|
|
if ( BaseFileName )
|
|
{
|
|
delete [] BaseFileName;
|
|
}
|
|
}
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
// append string to result buffer
|
|
DWORD REGISTRY_AppendBufferToResultBuffer (
|
|
IN PREGISTRY_PARAMETERS a,
|
|
IN PUNICODE_STRING Buffer,
|
|
IN BOOLEAN IncludeNull
|
|
)
|
|
{
|
|
DWORD OverflowStatus = ERROR_INVALID_PARAMETER;
|
|
|
|
if ( Buffer )
|
|
{
|
|
ULONG Chars = Buffer->Length / sizeof( WCHAR );
|
|
|
|
if ( a->ResultChars + Chars >= a->ResultMaxChars )
|
|
{
|
|
OverflowStatus = ERROR_MORE_DATA;
|
|
|
|
Chars = a->ResultMaxChars - a->ResultChars;
|
|
if ( Chars )
|
|
{
|
|
Chars -= 1;
|
|
}
|
|
}
|
|
|
|
if ( Chars )
|
|
{
|
|
memcpy( reinterpret_cast < PBYTE > ( a->ResultBuffer ) + ( a->ResultChars * sizeof( WCHAR ) ), Buffer->Buffer, Chars * sizeof( WCHAR ) );
|
|
a->ResultChars += Chars;
|
|
}
|
|
|
|
if ( OverflowStatus != ERROR_MORE_DATA )
|
|
{
|
|
OverflowStatus = ERROR_SUCCESS;
|
|
}
|
|
}
|
|
|
|
if (IncludeNull)
|
|
{
|
|
if ( a->ResultChars + 1 >= a->ResultMaxChars )
|
|
{
|
|
OverflowStatus = ERROR_MORE_DATA;
|
|
}
|
|
else
|
|
{
|
|
a->ResultBuffer[ a->ResultChars ] = L'\0';
|
|
a->ResultChars += 1;
|
|
}
|
|
}
|
|
|
|
return OverflowStatus;
|
|
}
|
|
|
|
DWORD REGISTRY_AppendNULLToResultBuffer ( IN PREGISTRY_PARAMETERS a )
|
|
{
|
|
return REGISTRY_AppendBufferToResultBuffer( a, NULL, TRUE );
|
|
}
|
|
|
|
NTSTATUS REGISTRY_CheckSubKeyNotEmpty ( IN HANDLE Key, IN PUNICODE_STRING SubKeyName )
|
|
{
|
|
NTSTATUS Status = STATUS_SUCCESS;
|
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
|
HANDLE SubKey = INVALID_HANDLE_VALUE;
|
|
KEY_VALUE_BASIC_INFORMATION KeyValueInformation;
|
|
ULONG ResultLength;
|
|
|
|
InitializeObjectAttributes( &ObjectAttributes,
|
|
SubKeyName,
|
|
OBJ_CASE_INSENSITIVE,
|
|
Key,
|
|
NULL
|
|
);
|
|
|
|
Status = NtOpenKey( &SubKey, GENERIC_READ, &ObjectAttributes );
|
|
if ( NT_SUCCESS ( Status ) )
|
|
{
|
|
Status = NtEnumerateValueKey ( SubKey,
|
|
0,
|
|
KeyValueBasicInformation,
|
|
&KeyValueInformation,
|
|
sizeof( KeyValueInformation ),
|
|
&ResultLength
|
|
);
|
|
|
|
if ( Status == STATUS_BUFFER_OVERFLOW )
|
|
{
|
|
Status = STATUS_SUCCESS;
|
|
}
|
|
|
|
NtClose( SubKey );
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////
|
|
// REAL REGISTRY FUNCTIONALITY
|
|
/////////////////////////////////////////////////////////////////////////////////////////
|
|
DWORD REGISTRY_ReadVariableValue (
|
|
IN PREGISTRY_PARAMETERS a,
|
|
PREGISTRY_MAPPING_APPNAME AppNameMapping,
|
|
PREGISTRY_MAPPING_VARNAME VarNameMapping,
|
|
LPCWSTR VariableName
|
|
)
|
|
{
|
|
DWORD Status = ERROR_INVALID_PARAMETER;
|
|
LPCWSTR ApplicationName = NULL;
|
|
|
|
BOOLEAN OutputVariableName = FALSE;
|
|
|
|
UNICODE_STRING EqualSign;
|
|
|
|
if ( VariableName )
|
|
{
|
|
RtlInitUnicodeString ( &EqualSign, L"=" );
|
|
OutputVariableName = TRUE;
|
|
}
|
|
|
|
if ( !VariableName )
|
|
{
|
|
if ( ! WMIREG_GetVariableName ( a, &VariableName ) )
|
|
{
|
|
VariableName = NULL;
|
|
}
|
|
}
|
|
|
|
if ( VariableName != NULL )
|
|
{
|
|
if ( ! VarNameMapping )
|
|
{
|
|
VarNameMapping = WMIREG_FindVarNameMapping ( AppNameMapping, VariableName );
|
|
}
|
|
|
|
if ( VarNameMapping != NULL )
|
|
{
|
|
if ( WMIREG_GetApplicationName ( a, &ApplicationName ) )
|
|
{
|
|
HANDLE Key = INVALID_HANDLE_VALUE;
|
|
|
|
Status = WMIREG_OpenMappingTarget ( a,
|
|
VarNameMapping,
|
|
ApplicationName,
|
|
&Key
|
|
);
|
|
|
|
if ( Status == ERROR_SUCCESS && Key != INVALID_HANDLE_VALUE )
|
|
{
|
|
NTSTATUS NtStatus;
|
|
|
|
KEY_VALUE_PARTIAL_INFORMATION KeyValueInformation;
|
|
PKEY_VALUE_PARTIAL_INFORMATION p = NULL;
|
|
|
|
DWORD ResultLength = 0L;
|
|
|
|
UNICODE_STRING temp;
|
|
RtlInitUnicodeString ( &temp, VariableName );
|
|
|
|
NtStatus = NtQueryValueKey ( Key,
|
|
&temp,
|
|
KeyValuePartialInformation,
|
|
&KeyValueInformation,
|
|
sizeof( KeyValueInformation ),
|
|
&ResultLength
|
|
);
|
|
|
|
if ( ! NT_SUCCESS ( NtStatus ) )
|
|
{
|
|
if ( NtStatus == STATUS_BUFFER_OVERFLOW )
|
|
{
|
|
p = reinterpret_cast < PKEY_VALUE_PARTIAL_INFORMATION > ( RtlAllocateHeap ( RtlProcessHeap(), HEAP_ZERO_MEMORY, ResultLength ) );
|
|
if ( p != NULL )
|
|
{
|
|
NtStatus = NtQueryValueKey ( Key,
|
|
&temp,
|
|
KeyValuePartialInformation,
|
|
p,
|
|
ResultLength,
|
|
&ResultLength
|
|
);
|
|
|
|
Status = NtStatus;
|
|
}
|
|
else
|
|
{
|
|
Status = ERROR_NOT_ENOUGH_MEMORY;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Status = NtStatus;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
p = &KeyValueInformation;
|
|
}
|
|
|
|
// create results
|
|
if ( Status == ERROR_SUCCESS )
|
|
{
|
|
if ( OutputVariableName )
|
|
{
|
|
Status = REGISTRY_AppendBufferToResultBuffer( a, &temp, FALSE );
|
|
if ( Status == ERROR_SUCCESS )
|
|
{
|
|
Status = REGISTRY_AppendBufferToResultBuffer( a, &EqualSign, FALSE );
|
|
}
|
|
}
|
|
|
|
if ( Status == ERROR_SUCCESS )
|
|
{
|
|
if ( p->Type == REG_SZ )
|
|
{
|
|
UNICODE_STRING Value;
|
|
LPWSTR s = NULL;
|
|
|
|
Value.Buffer = reinterpret_cast < LPWSTR > ( &p->Data[ 0 ] );
|
|
if ( p->DataLength >= sizeof( UNICODE_NULL ) )
|
|
{
|
|
Value.Length = static_cast< USHORT > ( p->DataLength - sizeof ( UNICODE_NULL ) );
|
|
}
|
|
else
|
|
{
|
|
Value.Length = 0;
|
|
}
|
|
|
|
Value.MaximumLength = static_cast < USHORT > (p->DataLength);
|
|
s = reinterpret_cast < LPWSTR > ( Value.Buffer );
|
|
|
|
if ( a->Operation == Registry_ReadKeyValue &&
|
|
Value.Length >= ( 2 * sizeof( WCHAR ) ) &&
|
|
( s[ 0 ] == s[ ( Value.Length - sizeof( WCHAR ) ) / sizeof( WCHAR ) ] ) &&
|
|
( s[ 0 ] == L'"' || s[ 0 ] == L'\'' )
|
|
)
|
|
{
|
|
Value.Buffer += 1;
|
|
Value.Length -= (2 * sizeof( WCHAR ));
|
|
}
|
|
|
|
Status = REGISTRY_AppendBufferToResultBuffer( a, &Value, TRUE );
|
|
}
|
|
else
|
|
{
|
|
Status = STATUS_OBJECT_TYPE_MISMATCH;
|
|
}
|
|
}
|
|
}
|
|
|
|
// clear buffer
|
|
if ( p && p != &KeyValueInformation )
|
|
{
|
|
RtlFreeHeap( RtlProcessHeap(), 0, p );
|
|
}
|
|
|
|
NtClose ( Key );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
DWORD REGISTRY_ReadVariableName ( IN PREGISTRY_PARAMETERS a, PREGISTRY_MAPPING_APPNAME AppNameMapping )
|
|
{
|
|
DWORD Status = ERROR_SUCCESS;
|
|
|
|
PREGISTRY_MAPPING_VARNAME VarNameMapping = NULL;
|
|
LPCWSTR ApplicationName = NULL;
|
|
|
|
HANDLE Key = INVALID_HANDLE_VALUE;
|
|
|
|
WCHAR Buffer[ 256 ];
|
|
PKEY_VALUE_BASIC_INFORMATION KeyValueInformation = NULL;
|
|
|
|
// temporary unicode strings
|
|
UNICODE_STRING temp;
|
|
|
|
VarNameMapping = (PREGISTRY_MAPPING_VARNAME)AppNameMapping->VariableNames;
|
|
while ( VarNameMapping != NULL && Status == ERROR_SUCCESS )
|
|
{
|
|
RtlInitUnicodeString ( &temp, VarNameMapping->Name );
|
|
Status = REGISTRY_AppendBufferToResultBuffer( a, &temp, TRUE );
|
|
|
|
if ( Status == ERROR_SUCCESS )
|
|
{
|
|
VarNameMapping = (PREGISTRY_MAPPING_VARNAME)VarNameMapping->Next;
|
|
}
|
|
}
|
|
|
|
if ( Status == ERROR_SUCCESS )
|
|
{
|
|
VarNameMapping = (PREGISTRY_MAPPING_VARNAME)AppNameMapping->DefaultVarNameMapping;
|
|
if ( VarNameMapping != NULL )
|
|
{
|
|
if ( WMIREG_GetApplicationName ( a, &ApplicationName ) )
|
|
{
|
|
Status = WMIREG_OpenMappingTarget ( a,
|
|
VarNameMapping,
|
|
ApplicationName,
|
|
&Key
|
|
);
|
|
|
|
if ( Status == ERROR_SUCCESS && Key != INVALID_HANDLE_VALUE )
|
|
{
|
|
KeyValueInformation = (PKEY_VALUE_BASIC_INFORMATION)Buffer;
|
|
for ( ULONG ValueIndex = 0; Status == ERROR_SUCCESS; ValueIndex++ )
|
|
{
|
|
ULONG ResultLength = 0L;
|
|
|
|
Status = NtEnumerateValueKey( Key,
|
|
ValueIndex,
|
|
KeyValueBasicInformation,
|
|
KeyValueInformation,
|
|
sizeof( Buffer ),
|
|
&ResultLength
|
|
);
|
|
|
|
if ( Status == STATUS_NO_MORE_ENTRIES )
|
|
{
|
|
break;
|
|
}
|
|
|
|
if ( NT_SUCCESS ( Status ) )
|
|
{
|
|
temp.Buffer = KeyValueInformation->Name;
|
|
temp.Length = (USHORT)KeyValueInformation->NameLength;
|
|
temp.MaximumLength = (USHORT)KeyValueInformation->NameLength;
|
|
|
|
Status = REGISTRY_AppendBufferToResultBuffer( a, &temp, TRUE );
|
|
}
|
|
}
|
|
|
|
if ( Status == STATUS_NO_MORE_ENTRIES )
|
|
{
|
|
Status = ERROR_SUCCESS;
|
|
}
|
|
|
|
NtClose ( Key );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Status = ERROR_INVALID_PARAMETER;
|
|
}
|
|
}
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
DWORD REGISTRY_ReadSectionValue ( IN PREGISTRY_PARAMETERS a, PREGISTRY_MAPPING_APPNAME AppNameMapping )
|
|
{
|
|
DWORD Status = ERROR_SUCCESS;
|
|
|
|
PREGISTRY_MAPPING_VARNAME VarNameMapping = NULL;
|
|
LPCWSTR ApplicationName= NULL;
|
|
|
|
WCHAR Buffer[ 256 ];
|
|
PKEY_VALUE_BASIC_INFORMATION KeyValueInformation = NULL;
|
|
|
|
HANDLE Key = INVALID_HANDLE_VALUE;
|
|
|
|
VarNameMapping = (PREGISTRY_MAPPING_VARNAME)AppNameMapping->VariableNames;
|
|
while ( VarNameMapping != NULL && Status == ERROR_SUCCESS )
|
|
{
|
|
if ( VarNameMapping->Name )
|
|
{
|
|
Status = REGISTRY_ReadVariableValue ( a, AppNameMapping, VarNameMapping, VarNameMapping->Name );
|
|
if ( Status != ERROR_SUCCESS )
|
|
{
|
|
if ( Status == STATUS_OBJECT_TYPE_MISMATCH )
|
|
{
|
|
Status = STATUS_SUCCESS;
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( Status == ERROR_SUCCESS )
|
|
{
|
|
VarNameMapping = (PREGISTRY_MAPPING_VARNAME)VarNameMapping->Next;
|
|
}
|
|
}
|
|
|
|
if ( Status == ERROR_SUCCESS )
|
|
{
|
|
VarNameMapping = (PREGISTRY_MAPPING_VARNAME)AppNameMapping->DefaultVarNameMapping;
|
|
if ( VarNameMapping != NULL)
|
|
{
|
|
if ( WMIREG_GetApplicationName ( a, &ApplicationName ) )
|
|
{
|
|
Status = WMIREG_OpenMappingTarget ( a,
|
|
VarNameMapping,
|
|
ApplicationName,
|
|
&Key
|
|
);
|
|
|
|
if ( Status == ERROR_SUCCESS && Key != INVALID_HANDLE_VALUE )
|
|
{
|
|
KeyValueInformation = (PKEY_VALUE_BASIC_INFORMATION)Buffer;
|
|
for ( ULONG ValueIndex = 0; Status == ERROR_SUCCESS; ValueIndex++ )
|
|
{
|
|
ULONG ResultLength = 0L;
|
|
|
|
Status = NtEnumerateValueKey( Key,
|
|
ValueIndex,
|
|
KeyValueBasicInformation,
|
|
KeyValueInformation,
|
|
sizeof( Buffer ),
|
|
&ResultLength
|
|
);
|
|
|
|
if ( Status == STATUS_NO_MORE_ENTRIES )
|
|
{
|
|
break;
|
|
}
|
|
|
|
if ( NT_SUCCESS ( Status ) )
|
|
{
|
|
LPWSTR VariableName = NULL;
|
|
|
|
try
|
|
{
|
|
if ( ( VariableName = new WCHAR [ KeyValueInformation->NameLength / sizeof ( WCHAR ) + 1 ] ) != NULL )
|
|
{
|
|
wcsncpy ( VariableName, (LPWSTR)&(KeyValueInformation->Name[0]), KeyValueInformation->NameLength / sizeof ( WCHAR ) );
|
|
VariableName [ KeyValueInformation->NameLength / sizeof ( WCHAR ) ] = L'\0';
|
|
}
|
|
else
|
|
{
|
|
Status = ERROR_NOT_ENOUGH_MEMORY;
|
|
}
|
|
}
|
|
catch ( ... )
|
|
{
|
|
if ( VariableName )
|
|
{
|
|
delete [] VariableName;
|
|
VariableName = NULL;
|
|
}
|
|
|
|
Status = ERROR_GEN_FAILURE;
|
|
}
|
|
|
|
if ( Status == ERROR_SUCCESS )
|
|
{
|
|
Status = REGISTRY_ReadVariableValue( a, AppNameMapping, NULL, VariableName );
|
|
|
|
delete [] VariableName;
|
|
VariableName = NULL;
|
|
|
|
if ( Status != ERROR_SUCCESS )
|
|
{
|
|
if ( Status == STATUS_OBJECT_TYPE_MISMATCH )
|
|
{
|
|
Status = STATUS_SUCCESS;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( Status == STATUS_NO_MORE_ENTRIES )
|
|
{
|
|
Status = ERROR_SUCCESS;
|
|
}
|
|
|
|
NtClose ( Key );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
DWORD REGISTRY_ReadSectionName ( IN PREGISTRY_PARAMETERS a )
|
|
{
|
|
DWORD Status = ERROR_SUCCESS;
|
|
|
|
PREGISTRY_MAPPING_APPNAME AppNameMapping = NULL;
|
|
HANDLE Key = INVALID_HANDLE_VALUE;
|
|
|
|
WCHAR Buffer[ 256 ];
|
|
PKEY_BASIC_INFORMATION KeyInformation = NULL;
|
|
|
|
// temporary unicode strings
|
|
UNICODE_STRING temp;
|
|
|
|
PREGISTRY_MAPPING_NAME Mapping = NULL;
|
|
|
|
LPWSTR BaseFileName = NULL;
|
|
Status = WMIREG_GetBaseFileName ( a->FileName, &BaseFileName );
|
|
|
|
if ( Status == ERROR_SUCCESS && BaseFileName )
|
|
{
|
|
Mapping = WMIREG_FindMapping ( a->Mapping, BaseFileName );
|
|
|
|
delete [] BaseFileName;
|
|
BaseFileName = NULL;
|
|
}
|
|
|
|
if ( Mapping )
|
|
{
|
|
AppNameMapping = (PREGISTRY_MAPPING_APPNAME)Mapping->ApplicationNames;
|
|
while ( AppNameMapping != NULL && Status == ERROR_SUCCESS )
|
|
{
|
|
RtlInitUnicodeString ( &temp, AppNameMapping->Name );
|
|
Status = REGISTRY_AppendBufferToResultBuffer( a, &temp, TRUE );
|
|
|
|
if ( Status == ERROR_SUCCESS )
|
|
{
|
|
AppNameMapping = (PREGISTRY_MAPPING_APPNAME)AppNameMapping->Next;
|
|
}
|
|
}
|
|
|
|
if ( Status == ERROR_SUCCESS )
|
|
{
|
|
AppNameMapping = (PREGISTRY_MAPPING_APPNAME)a->Mapping->DefaultAppNameMapping;
|
|
if ( AppNameMapping != NULL )
|
|
{
|
|
Status = WMIREG_OpenMappingTarget ( a,
|
|
reinterpret_cast < PREGISTRY_MAPPING_VARNAME > ( AppNameMapping->DefaultVarNameMapping ),
|
|
NULL,
|
|
&Key
|
|
);
|
|
|
|
if ( Status == ERROR_SUCCESS && Key != INVALID_HANDLE_VALUE )
|
|
{
|
|
KeyInformation = (PKEY_BASIC_INFORMATION)Buffer;
|
|
for ( ULONG SubKeyIndex = 0; Status == ERROR_SUCCESS; SubKeyIndex++ )
|
|
{
|
|
ULONG ResultLength = 0L;
|
|
|
|
Status = NtEnumerateKey( Key,
|
|
SubKeyIndex,
|
|
KeyBasicInformation,
|
|
KeyInformation,
|
|
sizeof( Buffer ),
|
|
&ResultLength
|
|
);
|
|
|
|
if ( Status == STATUS_NO_MORE_ENTRIES )
|
|
{
|
|
break;
|
|
}
|
|
|
|
if ( NT_SUCCESS ( Status ) )
|
|
{
|
|
temp.Buffer = (PWSTR)&(KeyInformation->Name[0]);
|
|
temp.Length = (USHORT)KeyInformation->NameLength;
|
|
temp.MaximumLength = (USHORT)KeyInformation->NameLength;
|
|
|
|
Status = REGISTRY_CheckSubKeyNotEmpty( Key, &temp );
|
|
|
|
if ( NT_SUCCESS ( Status ) )
|
|
{
|
|
Status = REGISTRY_AppendBufferToResultBuffer( a, &temp, TRUE );
|
|
}
|
|
else
|
|
if ( Status != STATUS_NO_MORE_ENTRIES )
|
|
{
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
Status = STATUS_SUCCESS;
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( Status == STATUS_NO_MORE_ENTRIES )
|
|
{
|
|
Status = ERROR_SUCCESS;
|
|
}
|
|
|
|
NtClose ( Key );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////
|
|
// IMPLEMENTATION
|
|
/////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
DWORD WMIRegistry_Mapping ( IN PREGISTRY_PARAMETERS a )
|
|
{
|
|
DWORD Status = ERROR_INVALID_PARAMETER;
|
|
|
|
if ( a )
|
|
{
|
|
if ( a->Operation == Registry_ReadSectionName )
|
|
{
|
|
Status = REGISTRY_ReadSectionName ( a );
|
|
}
|
|
else
|
|
{
|
|
LPCWSTR ApplicationName = NULL;
|
|
if ( WMIREG_GetApplicationName ( a, &ApplicationName ) )
|
|
{
|
|
PREGISTRY_MAPPING_NAME Mapping = NULL;
|
|
|
|
LPWSTR BaseFileName = NULL;
|
|
Status = WMIREG_GetBaseFileName ( a->FileName, &BaseFileName );
|
|
|
|
if ( Status == ERROR_SUCCESS && BaseFileName )
|
|
{
|
|
Mapping = WMIREG_FindMapping ( a->Mapping, BaseFileName );
|
|
|
|
delete [] BaseFileName;
|
|
BaseFileName = NULL;
|
|
}
|
|
|
|
if ( Mapping )
|
|
{
|
|
PREGISTRY_MAPPING_APPNAME AppNameMapping = NULL;
|
|
AppNameMapping = WMIREG_FindAppNameMapping ( Mapping, ApplicationName );
|
|
|
|
if ( AppNameMapping )
|
|
{
|
|
if ( a->Operation == Registry_ReadKeyValue )
|
|
{
|
|
Status = REGISTRY_ReadVariableValue ( a, AppNameMapping, NULL, NULL );
|
|
}
|
|
else
|
|
if ( a->Operation == Registry_ReadKeyName )
|
|
{
|
|
Status = REGISTRY_ReadVariableName ( a, AppNameMapping );
|
|
}
|
|
else
|
|
if ( a->Operation == Registry_ReadSectionValue )
|
|
{
|
|
Status = REGISTRY_ReadSectionValue ( a, AppNameMapping );
|
|
}
|
|
else
|
|
{
|
|
// not supported operation
|
|
// possible write ?
|
|
Status = ERROR_INVALID_PARAMETER;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// no registry for this section
|
|
// you should use file function
|
|
|
|
Status = STATUS_MORE_PROCESSING_REQUIRED;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
// ALLOCATION of reg structures
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
PREGISTRY_MAPPING_TARGET MappingTargetAlloc (
|
|
IN LPCWSTR RegistryPath,
|
|
OUT PULONG MappingFlags
|
|
)
|
|
{
|
|
BOOLEAN RelativePath = FALSE;
|
|
UNICODE_STRING RegistryPathString;
|
|
|
|
PREGISTRY_MAPPING_TARGET MappingTarget = NULL;
|
|
|
|
LPCWSTR SaveRegistryPath = RegistryPath;
|
|
ULONG Flags = 0L;
|
|
|
|
// simulate result
|
|
*MappingFlags = Flags;
|
|
|
|
BOOLEAN Continue = TRUE;
|
|
|
|
while ( Continue )
|
|
{
|
|
try
|
|
{
|
|
if ( *RegistryPath == L'!' )
|
|
{
|
|
Flags |= REGISTRY_MAPPING_WRITE_TO_INIFILE_TOO;
|
|
RegistryPath += 1;
|
|
}
|
|
else
|
|
if ( *RegistryPath == L'#' )
|
|
{
|
|
Flags |= REGISTRY_MAPPING_INIT_FROM_INIFILE;
|
|
RegistryPath += 1;
|
|
}
|
|
else
|
|
if ( *RegistryPath == L'@' )
|
|
{
|
|
Flags |= REGISTRY_MAPPING_READ_FROM_REGISTRY_ONLY;
|
|
RegistryPath += 1;
|
|
}
|
|
else
|
|
if ( !_wcsnicmp ( RegistryPath, L"USR:", 4 ) )
|
|
{
|
|
Flags |= REGISTRY_MAPPING_USER_RELATIVE;
|
|
RegistryPath += 4;
|
|
break;
|
|
}
|
|
else
|
|
if ( !_wcsnicmp ( RegistryPath, L"SYS:", 4 ) )
|
|
{
|
|
Flags |= REGISTRY_MAPPING_SOFTWARE_RELATIVE;
|
|
RegistryPath += 4;
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
catch ( ... )
|
|
{
|
|
Continue = FALSE;
|
|
}
|
|
}
|
|
|
|
if ( Continue )
|
|
{
|
|
if ( Flags & ( REGISTRY_MAPPING_USER_RELATIVE | REGISTRY_MAPPING_SOFTWARE_RELATIVE ) )
|
|
{
|
|
RelativePath = TRUE;
|
|
}
|
|
|
|
if ( ( RelativePath && *RegistryPath != OBJ_NAME_PATH_SEPARATOR ) ||
|
|
( !RelativePath && *RegistryPath == OBJ_NAME_PATH_SEPARATOR )
|
|
)
|
|
{
|
|
RtlInitUnicodeString( &RegistryPathString, RegistryPath );
|
|
}
|
|
else
|
|
if ( !RelativePath && *RegistryPath == UNICODE_NULL )
|
|
{
|
|
RtlInitUnicodeString( &RegistryPathString, NULL );
|
|
}
|
|
else
|
|
{
|
|
Continue = FALSE;
|
|
}
|
|
|
|
if ( Continue )
|
|
{
|
|
MappingTarget = reinterpret_cast < PREGISTRY_MAPPING_TARGET > ( RtlAllocateHeap( RtlProcessHeap (), HEAP_ZERO_MEMORY, sizeof( REGISTRY_MAPPING_TARGET ) ) );
|
|
if ( MappingTarget != NULL )
|
|
{
|
|
*MappingFlags = Flags;
|
|
|
|
MappingTarget->RegistryPath = NULL;
|
|
if ( RegistryPathString.Length != 0 )
|
|
{
|
|
try
|
|
{
|
|
if ( ( MappingTarget->RegistryPath = new WCHAR [ RegistryPathString.Length / sizeof ( WCHAR ) + 1 ] ) != NULL )
|
|
{
|
|
wcsncpy ( MappingTarget->RegistryPath, RegistryPathString.Buffer, RegistryPathString.Length / sizeof ( WCHAR ) );
|
|
MappingTarget->RegistryPath [RegistryPathString.Length / sizeof ( WCHAR )] = L'\0';
|
|
}
|
|
}
|
|
catch ( ... )
|
|
{
|
|
if ( MappingTarget->RegistryPath )
|
|
{
|
|
delete [] MappingTarget->RegistryPath;
|
|
MappingTarget->RegistryPath = NULL;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return MappingTarget;
|
|
}
|
|
|
|
DWORD MappingTargetFree ( IN PREGISTRY_MAPPING_TARGET MappingTarget )
|
|
{
|
|
DWORD Status = ERROR_INVALID_PARAMETER;
|
|
|
|
if ( MappingTarget )
|
|
{
|
|
PREGISTRY_MAPPING_TARGET MappingTargetNext = NULL;
|
|
MappingTargetNext = reinterpret_cast < PREGISTRY_MAPPING_TARGET > ( MappingTarget->Next );
|
|
|
|
if ( MappingTargetNext )
|
|
{
|
|
MappingTargetFree ( MappingTargetNext );
|
|
}
|
|
if ( MappingTarget->RegistryPath )
|
|
{
|
|
delete [] MappingTarget->RegistryPath;
|
|
MappingTarget->RegistryPath = NULL;
|
|
}
|
|
|
|
RtlFreeHeap( RtlProcessHeap(), 0, MappingTarget );
|
|
|
|
// success
|
|
Status = ERROR_SUCCESS;
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
DWORD MappingVarNameFree ( IN PREGISTRY_MAPPING_VARNAME VarNameMapping );
|
|
BOOLEAN MappingVarNameAlloc (
|
|
PREGISTRY_MAPPING_NAME FileNameMapping,
|
|
PREGISTRY_MAPPING_APPNAME AppNameMapping,
|
|
PUNICODE_STRING VariableName,
|
|
LPCWSTR RegistryPath,
|
|
PREGISTRY_MAPPING_VARNAME *ReturnedVarNameMapping
|
|
)
|
|
{
|
|
PREGISTRY_MAPPING_TARGET MappingTarget = NULL;;
|
|
PREGISTRY_MAPPING_VARNAME VarNameMapping = NULL;
|
|
PREGISTRY_MAPPING_VARNAME *pp;
|
|
|
|
ULONG MappingFlags = 0L;
|
|
|
|
BOOLEAN Result = FALSE;
|
|
BOOLEAN Continue = TRUE;
|
|
|
|
if ( VariableName->Length != 0 )
|
|
{
|
|
pp = reinterpret_cast < PREGISTRY_MAPPING_VARNAME* > ( &AppNameMapping->VariableNames );
|
|
while ( VarNameMapping = *pp )
|
|
{
|
|
try
|
|
{
|
|
if ( VarNameMapping->Name )
|
|
{
|
|
if ( ! _wcsnicmp ( VariableName->Buffer, VarNameMapping->Name, VariableName->Length ) )
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
catch ( ... )
|
|
{
|
|
Continue = FALSE;
|
|
break;
|
|
}
|
|
|
|
pp = reinterpret_cast < PREGISTRY_MAPPING_VARNAME* > ( &VarNameMapping->Next );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
pp = reinterpret_cast < PREGISTRY_MAPPING_VARNAME* > ( &AppNameMapping->DefaultVarNameMapping );
|
|
VarNameMapping = *pp;
|
|
}
|
|
|
|
if ( Continue && VarNameMapping == NULL )
|
|
{
|
|
MappingTarget = MappingTargetAlloc ( RegistryPath, &MappingFlags );
|
|
if (MappingTarget != NULL)
|
|
{
|
|
VarNameMapping = reinterpret_cast < PREGISTRY_MAPPING_VARNAME > ( RtlAllocateHeap( RtlProcessHeap (), HEAP_ZERO_MEMORY, sizeof( REGISTRY_MAPPING_VARNAME ) ) );
|
|
if (VarNameMapping != NULL)
|
|
{
|
|
VarNameMapping->MappingFlags = MappingFlags;
|
|
VarNameMapping->MappingTarget = reinterpret_cast < ULONG_PTR > ( MappingTarget );
|
|
|
|
if ( VariableName->Length != 0 )
|
|
{
|
|
try
|
|
{
|
|
if ( ( VarNameMapping->Name = new WCHAR [ VariableName->Length / sizeof ( WCHAR ) + 1 ] ) != NULL )
|
|
{
|
|
wcsncpy ( VarNameMapping->Name, VariableName->Buffer, VariableName->Length / sizeof ( WCHAR ) );
|
|
VarNameMapping->Name [VariableName->Length / sizeof ( WCHAR )] = L'\0';
|
|
|
|
Result = TRUE;
|
|
}
|
|
}
|
|
catch ( ... )
|
|
{
|
|
if ( VarNameMapping->Name )
|
|
{
|
|
delete [] VarNameMapping->Name;
|
|
VarNameMapping->Name = NULL;
|
|
}
|
|
|
|
MappingVarNameFree ( VarNameMapping );
|
|
throw;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Result = TRUE;
|
|
}
|
|
|
|
*pp = VarNameMapping;
|
|
|
|
// return value
|
|
*ReturnedVarNameMapping = VarNameMapping;
|
|
}
|
|
}
|
|
}
|
|
|
|
return Result;
|
|
}
|
|
|
|
DWORD MappingVarNameFree ( IN PREGISTRY_MAPPING_VARNAME VarNameMapping )
|
|
{
|
|
DWORD Status = ERROR_INVALID_PARAMETER;
|
|
|
|
if ( VarNameMapping )
|
|
{
|
|
PREGISTRY_MAPPING_VARNAME VarNameMappingNext = NULL;
|
|
VarNameMappingNext = reinterpret_cast < PREGISTRY_MAPPING_VARNAME > ( VarNameMapping->Next );
|
|
|
|
if ( VarNameMappingNext )
|
|
{
|
|
MappingVarNameFree ( VarNameMappingNext );
|
|
}
|
|
|
|
// return status from helper ?
|
|
Status = MappingTargetFree ( reinterpret_cast < PREGISTRY_MAPPING_TARGET > ( VarNameMapping->MappingTarget ) );
|
|
|
|
if ( VarNameMapping->Name )
|
|
{
|
|
delete [] VarNameMapping->Name;
|
|
VarNameMapping->Name = NULL;
|
|
}
|
|
|
|
RtlFreeHeap( RtlProcessHeap(), 0, VarNameMapping );
|
|
VarNameMapping = NULL;
|
|
|
|
// success
|
|
Status = ERROR_SUCCESS;
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
DWORD MappingAppNameFree ( IN PREGISTRY_MAPPING_APPNAME AppNameMapping );
|
|
BOOLEAN MappingAppNameAlloc (
|
|
PREGISTRY_MAPPING_NAME FileNameMapping,
|
|
PUNICODE_STRING ApplicationName,
|
|
PREGISTRY_MAPPING_APPNAME *ReturnedAppNameMapping
|
|
)
|
|
{
|
|
PREGISTRY_MAPPING_APPNAME AppNameMapping = NULL;
|
|
PREGISTRY_MAPPING_APPNAME *pp;
|
|
|
|
BOOLEAN Result = FALSE;
|
|
BOOLEAN Continue = TRUE;
|
|
|
|
if ( ApplicationName->Length != 0 )
|
|
{
|
|
pp = reinterpret_cast < PREGISTRY_MAPPING_APPNAME* > ( &FileNameMapping->ApplicationNames );
|
|
while ( AppNameMapping = *pp )
|
|
{
|
|
try
|
|
{
|
|
if ( AppNameMapping->Name )
|
|
{
|
|
if ( ! _wcsnicmp ( ApplicationName->Buffer, AppNameMapping->Name, ApplicationName->Length ) )
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
catch ( ... )
|
|
{
|
|
Continue = FALSE;
|
|
break;
|
|
}
|
|
|
|
pp = reinterpret_cast < PREGISTRY_MAPPING_APPNAME* > ( &AppNameMapping->Next );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
pp = reinterpret_cast < PREGISTRY_MAPPING_APPNAME* > ( &FileNameMapping->DefaultAppNameMapping );
|
|
AppNameMapping = *pp;
|
|
}
|
|
|
|
if ( Continue && AppNameMapping == NULL)
|
|
{
|
|
AppNameMapping = reinterpret_cast < PREGISTRY_MAPPING_APPNAME > ( RtlAllocateHeap( RtlProcessHeap(), HEAP_ZERO_MEMORY, sizeof( REGISTRY_MAPPING_APPNAME ) ) );
|
|
if (AppNameMapping != NULL)
|
|
{
|
|
if (ApplicationName->Length != 0)
|
|
{
|
|
try
|
|
{
|
|
if ( ( AppNameMapping->Name = new WCHAR [ ApplicationName->Length / sizeof ( WCHAR ) + 1 ] ) != NULL )
|
|
{
|
|
wcsncpy ( AppNameMapping->Name, ApplicationName->Buffer, ApplicationName->Length / sizeof ( WCHAR ) );
|
|
AppNameMapping->Name [ApplicationName->Length / sizeof ( WCHAR )] = L'\0';
|
|
|
|
Result = TRUE;
|
|
}
|
|
}
|
|
catch ( ... )
|
|
{
|
|
if ( AppNameMapping->Name )
|
|
{
|
|
delete [] AppNameMapping->Name;
|
|
AppNameMapping->Name = NULL;
|
|
}
|
|
|
|
MappingAppNameFree ( AppNameMapping );
|
|
throw;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Result = TRUE;
|
|
}
|
|
|
|
*pp = AppNameMapping;
|
|
|
|
// return value
|
|
*ReturnedAppNameMapping = AppNameMapping;
|
|
}
|
|
}
|
|
|
|
return Result;
|
|
}
|
|
|
|
DWORD MappingAppNameFree ( IN PREGISTRY_MAPPING_APPNAME AppNameMapping )
|
|
{
|
|
DWORD Status = ERROR_INVALID_PARAMETER;
|
|
|
|
if ( AppNameMapping )
|
|
{
|
|
PREGISTRY_MAPPING_APPNAME AppNameMappingNext = NULL;
|
|
AppNameMappingNext = reinterpret_cast < PREGISTRY_MAPPING_APPNAME > ( AppNameMapping->Next );
|
|
|
|
if ( AppNameMappingNext )
|
|
{
|
|
MappingAppNameFree ( AppNameMappingNext );
|
|
}
|
|
|
|
MappingVarNameFree( reinterpret_cast < PREGISTRY_MAPPING_VARNAME > ( AppNameMapping->VariableNames ) );
|
|
MappingVarNameFree( reinterpret_cast < PREGISTRY_MAPPING_VARNAME > ( AppNameMapping->DefaultVarNameMapping ) );
|
|
|
|
if ( AppNameMapping->Name )
|
|
{
|
|
delete [] AppNameMapping->Name;
|
|
AppNameMapping->Name = NULL;
|
|
}
|
|
|
|
RtlFreeHeap( RtlProcessHeap(), 0, AppNameMapping );
|
|
AppNameMapping = NULL;
|
|
|
|
// success
|
|
Status = ERROR_SUCCESS;
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
BOOLEAN MappingNameAlloc (
|
|
IN PUNICODE_STRING FileName,
|
|
OUT PREGISTRY_MAPPING_NAME *ReturnedFileNameMapping
|
|
)
|
|
{
|
|
PREGISTRY_MAPPING_NAME FileNameMapping = NULL;
|
|
|
|
BOOLEAN Result = FALSE;
|
|
|
|
FileNameMapping = reinterpret_cast < PREGISTRY_MAPPING_NAME > ( RtlAllocateHeap( RtlProcessHeap (), HEAP_ZERO_MEMORY, sizeof( REGISTRY_MAPPING_NAME ) ) );
|
|
if ( FileNameMapping != NULL)
|
|
{
|
|
if (FileName->Length != 0)
|
|
{
|
|
try
|
|
{
|
|
if ( ( FileNameMapping->Name = new WCHAR [ FileName->Length / sizeof ( WCHAR ) + 1 ] ) != NULL )
|
|
{
|
|
wcsncpy ( FileNameMapping->Name, FileName->Buffer, FileName->Length / sizeof ( WCHAR ) );
|
|
FileNameMapping->Name [FileName->Length / sizeof ( WCHAR )] = L'\0';
|
|
|
|
Result = TRUE;
|
|
}
|
|
}
|
|
catch ( ... )
|
|
{
|
|
if ( FileNameMapping->Name )
|
|
{
|
|
delete [] FileNameMapping->Name;
|
|
FileNameMapping->Name = NULL;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Result = TRUE;
|
|
}
|
|
|
|
// return value
|
|
*ReturnedFileNameMapping = FileNameMapping;
|
|
}
|
|
|
|
return Result;
|
|
}
|
|
|
|
DWORD MappingNameFree ( IN PREGISTRY_MAPPING_NAME FileNameMapping )
|
|
{
|
|
DWORD Status = ERROR_INVALID_PARAMETER;
|
|
|
|
if ( FileNameMapping )
|
|
{
|
|
PREGISTRY_MAPPING_NAME FileNameMappingNext = NULL;
|
|
FileNameMappingNext = reinterpret_cast < PREGISTRY_MAPPING_NAME > ( FileNameMapping->Next );
|
|
|
|
if ( FileNameMappingNext )
|
|
{
|
|
MappingNameFree ( FileNameMappingNext );
|
|
}
|
|
|
|
MappingAppNameFree( reinterpret_cast < PREGISTRY_MAPPING_APPNAME > ( FileNameMapping->ApplicationNames ) );
|
|
MappingAppNameFree( reinterpret_cast < PREGISTRY_MAPPING_APPNAME > ( FileNameMapping->DefaultAppNameMapping ) );
|
|
|
|
if ( FileNameMapping->Name )
|
|
{
|
|
delete [] FileNameMapping->Name;
|
|
FileNameMapping->Name = NULL;
|
|
}
|
|
|
|
RtlFreeHeap( RtlProcessHeap(), 0, FileNameMapping );
|
|
FileNameMapping = NULL;
|
|
|
|
// success
|
|
Status = ERROR_SUCCESS;
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
NTSTATUS IniFileMapping (
|
|
IN PREGISTRY_MAPPING_NAME FileNameMapping,
|
|
IN HANDLE Key,
|
|
|
|
IN LPCWSTR MyApplicationName,
|
|
IN LPCWSTR MyVariableName
|
|
)
|
|
{
|
|
NTSTATUS Status = STATUS_SUCCESS;
|
|
WCHAR Buffer[ 512 ];
|
|
PKEY_BASIC_INFORMATION KeyInformation = NULL;
|
|
PKEY_VALUE_FULL_INFORMATION KeyValueInformation = NULL;
|
|
|
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
|
|
|
PREGISTRY_MAPPING_APPNAME AppNameMapping = NULL;
|
|
PREGISTRY_MAPPING_VARNAME VarNameMapping = NULL;
|
|
|
|
HANDLE SubKeyHandle = INVALID_HANDLE_VALUE;
|
|
ULONG SubKeyIndex;
|
|
UNICODE_STRING ValueName;
|
|
UNICODE_STRING SubKeyName;
|
|
|
|
UNICODE_STRING NullString;
|
|
RtlInitUnicodeString( &NullString, NULL );
|
|
|
|
//
|
|
// Enumerate node
|
|
//
|
|
|
|
KeyValueInformation = (PKEY_VALUE_FULL_INFORMATION)Buffer;
|
|
for ( ULONG ValueIndex = 0; TRUE; ValueIndex++ )
|
|
{
|
|
ULONG ResultLength = 0L;
|
|
Status = NtEnumerateValueKey ( Key,
|
|
ValueIndex,
|
|
KeyValueFullInformation,
|
|
KeyValueInformation,
|
|
sizeof( Buffer ),
|
|
&ResultLength
|
|
);
|
|
|
|
if ( Status == STATUS_NO_MORE_ENTRIES )
|
|
{
|
|
Status = STATUS_SUCCESS;
|
|
break;
|
|
}
|
|
else
|
|
if ( !NT_SUCCESS( Status ) )
|
|
{
|
|
break;
|
|
}
|
|
|
|
ValueName.Buffer = (PWSTR)&(KeyValueInformation->Name[0]);
|
|
ValueName.Length = (USHORT)KeyValueInformation->NameLength;
|
|
ValueName.MaximumLength = (USHORT)KeyValueInformation->NameLength;
|
|
|
|
if ( KeyValueInformation->Type == REG_SZ )
|
|
{
|
|
BOOL Continue = TRUE;
|
|
if ( MyApplicationName && MyVariableName )
|
|
{
|
|
if ( _wcsnicmp ( ValueName.Buffer, MyVariableName, ValueName.Length / sizeof ( WCHAR ) ) )
|
|
{
|
|
Continue = FALSE;
|
|
}
|
|
}
|
|
|
|
if ( Continue )
|
|
{
|
|
if ( MappingAppNameAlloc ( FileNameMapping, &ValueName, &AppNameMapping ) )
|
|
{
|
|
if ( MappingVarNameAlloc ( FileNameMapping,
|
|
AppNameMapping,
|
|
&NullString,
|
|
(PWSTR)((PCHAR)KeyValueInformation + KeyValueInformation->DataOffset),
|
|
&VarNameMapping
|
|
)
|
|
)
|
|
{
|
|
if (ValueName.Length == 0)
|
|
{
|
|
VarNameMapping->MappingFlags |= REGISTRY_MAPPING_APPEND_APPLICATION_NAME;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Enumerate node's children and apply ourselves to each one
|
|
//
|
|
|
|
KeyInformation = (PKEY_BASIC_INFORMATION)Buffer;
|
|
for ( ULONG SubKeyIndex = 0; TRUE; SubKeyIndex++ )
|
|
{
|
|
ULONG ResultLength = 0L;
|
|
Status = NtEnumerateKey ( Key,
|
|
SubKeyIndex,
|
|
KeyBasicInformation,
|
|
KeyInformation,
|
|
sizeof( Buffer ),
|
|
&ResultLength
|
|
);
|
|
|
|
if ( Status == STATUS_NO_MORE_ENTRIES)
|
|
{
|
|
Status = STATUS_SUCCESS;
|
|
break;
|
|
}
|
|
else
|
|
if ( !NT_SUCCESS ( Status ) )
|
|
{
|
|
break;
|
|
}
|
|
|
|
SubKeyName.Buffer = (PWSTR)&(KeyInformation->Name[0]);
|
|
SubKeyName.Length = (USHORT)KeyInformation->NameLength;
|
|
SubKeyName.MaximumLength = (USHORT)KeyInformation->NameLength;
|
|
|
|
InitializeObjectAttributes ( &ObjectAttributes,
|
|
&SubKeyName,
|
|
OBJ_CASE_INSENSITIVE,
|
|
Key,
|
|
NULL
|
|
);
|
|
|
|
BOOL Continue = TRUE;
|
|
if ( MyApplicationName )
|
|
{
|
|
if ( _wcsnicmp ( SubKeyName.Buffer, MyApplicationName, SubKeyName.Length / sizeof ( WCHAR ) ) )
|
|
{
|
|
Continue = FALSE;
|
|
}
|
|
}
|
|
|
|
if ( Continue )
|
|
{
|
|
Status = NtOpenKey( &SubKeyHandle, GENERIC_READ, &ObjectAttributes );
|
|
|
|
try
|
|
{
|
|
if ( NT_SUCCESS( Status ) && SubKeyHandle != INVALID_HANDLE_VALUE && MappingAppNameAlloc( FileNameMapping, &SubKeyName, &AppNameMapping ) )
|
|
{
|
|
KeyValueInformation = (PKEY_VALUE_FULL_INFORMATION)Buffer;
|
|
for ( ULONG ValueIndex = 0; AppNameMapping != NULL; ValueIndex++ )
|
|
{
|
|
Status = NtEnumerateValueKey ( SubKeyHandle,
|
|
ValueIndex,
|
|
KeyValueFullInformation,
|
|
KeyValueInformation,
|
|
sizeof( Buffer ),
|
|
&ResultLength
|
|
);
|
|
|
|
if ( Status == STATUS_NO_MORE_ENTRIES )
|
|
{
|
|
Status = STATUS_SUCCESS;
|
|
break;
|
|
}
|
|
else
|
|
if ( !NT_SUCCESS ( Status ) )
|
|
{
|
|
break;
|
|
}
|
|
|
|
ValueName.Buffer = (PWSTR)&(KeyValueInformation->Name[0]);
|
|
ValueName.Length = (USHORT)KeyValueInformation->NameLength;
|
|
ValueName.MaximumLength = (USHORT)KeyValueInformation->NameLength;
|
|
|
|
BOOL ContinueValue = TRUE;
|
|
if ( MyApplicationName && MyVariableName )
|
|
{
|
|
if ( _wcsnicmp ( ValueName.Buffer, MyVariableName, ValueName.Length / sizeof ( WCHAR ) ) )
|
|
{
|
|
ContinueValue = FALSE;
|
|
}
|
|
}
|
|
|
|
if ( ContinueValue )
|
|
{
|
|
if ( KeyValueInformation->Type == REG_SZ )
|
|
{
|
|
MappingVarNameAlloc ( FileNameMapping,
|
|
AppNameMapping,
|
|
&ValueName,
|
|
(PWSTR)((PCHAR)KeyValueInformation + KeyValueInformation->DataOffset),
|
|
&VarNameMapping
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
NtClose( SubKeyHandle );
|
|
SubKeyHandle = INVALID_HANDLE_VALUE;
|
|
}
|
|
}
|
|
catch ( ... )
|
|
{
|
|
if ( SubKeyHandle && SubKeyHandle != INVALID_HANDLE_VALUE )
|
|
{
|
|
NtClose( SubKeyHandle );
|
|
SubKeyHandle = INVALID_HANDLE_VALUE;
|
|
}
|
|
|
|
throw;
|
|
}
|
|
}
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
DWORD WMIRegistry_InitMapping ( PREGISTRY_PARAMETERS a )
|
|
{
|
|
DWORD Status = ERROR_INVALID_PARAMETER;
|
|
PREGISTRY_MAPPING_NAME RegistryMapping = NULL;
|
|
|
|
if ( a )
|
|
{
|
|
// prepare mapping
|
|
a->Mapping = NULL;
|
|
|
|
NTSTATUS NtStatus = STATUS_SUCCESS;
|
|
|
|
PREGISTRY_MAPPING_NAME DefaultFileNameMapping = NULL;
|
|
PREGISTRY_MAPPING_NAME FileNames = NULL;
|
|
|
|
PREGISTRY_MAPPING_APPNAME AppNameMapping = NULL;
|
|
PREGISTRY_MAPPING_VARNAME VarNameMapping = NULL;
|
|
|
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
|
|
|
HANDLE IniFileMappingRoot = INVALID_HANDLE_VALUE;
|
|
|
|
PKEY_VALUE_PARTIAL_INFORMATION KeyValueInformation = NULL;
|
|
PKEY_BASIC_INFORMATION KeyInformation = NULL;
|
|
|
|
WCHAR Buffer[ 512 ];
|
|
|
|
LPWSTR BaseFileName = NULL;
|
|
Status = WMIREG_GetBaseFileName ( a->FileName, &BaseFileName );
|
|
|
|
if ( Status == ERROR_SUCCESS && BaseFileName )
|
|
{
|
|
UNICODE_STRING FullKeyName;
|
|
|
|
FullKeyName.Length = 0;
|
|
FullKeyName.MaximumLength = ( wcslen ( L"\\REGISTRY\\MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\IniFileMapping\\" ) + wcslen ( BaseFileName ) + 1 ) * sizeof ( WCHAR );
|
|
FullKeyName.Buffer = reinterpret_cast < PWSTR > ( RtlAllocateHeap( RtlProcessHeap(), 0, FullKeyName.MaximumLength ) );
|
|
|
|
if ( FullKeyName.Buffer != NULL )
|
|
{
|
|
RtlAppendUnicodeToString ( &FullKeyName, L"\\REGISTRY\\MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\IniFileMapping\\" );
|
|
RtlAppendUnicodeToString ( &FullKeyName, BaseFileName );
|
|
|
|
InitializeObjectAttributes ( &ObjectAttributes,
|
|
&FullKeyName,
|
|
OBJ_CASE_INSENSITIVE,
|
|
NULL,
|
|
NULL
|
|
);
|
|
|
|
NtStatus = NtOpenKey ( &IniFileMappingRoot,
|
|
GENERIC_READ,
|
|
&ObjectAttributes
|
|
);
|
|
|
|
if ( NT_SUCCESS ( NtStatus ) && IniFileMappingRoot != INVALID_HANDLE_VALUE )
|
|
{
|
|
UNICODE_STRING BaseFile;
|
|
RtlInitUnicodeString ( &BaseFile, BaseFileName );
|
|
|
|
if ( ! MappingNameAlloc( &BaseFile, &FileNames ) )
|
|
{
|
|
NtStatus = STATUS_NO_MEMORY;
|
|
}
|
|
else
|
|
{
|
|
try
|
|
{
|
|
NtStatus = IniFileMapping( FileNames, IniFileMappingRoot, a->ApplicationName, a->VariableName );
|
|
}
|
|
catch ( ... )
|
|
{
|
|
MappingNameFree ( FileNames );
|
|
FileNames = NULL;
|
|
|
|
NtStatus = STATUS_NO_MEMORY;
|
|
}
|
|
|
|
if ( ! NT_SUCCESS ( NtStatus ) )
|
|
{
|
|
if ( FileNames )
|
|
{
|
|
RtlFreeHeap( RtlProcessHeap(), 0, FileNames );
|
|
FileNames = NULL;
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( NT_SUCCESS ( NtStatus ) )
|
|
{
|
|
a->Mapping = FileNames;
|
|
}
|
|
|
|
// close main root
|
|
if ( IniFileMappingRoot && IniFileMappingRoot != INVALID_HANDLE_VALUE )
|
|
{
|
|
NtClose ( IniFileMappingRoot );
|
|
IniFileMappingRoot = NULL;
|
|
}
|
|
}
|
|
|
|
// clear buffer
|
|
RtlFreeHeap ( RtlProcessHeap (), 0, FullKeyName.Buffer );
|
|
}
|
|
else
|
|
{
|
|
NtStatus = STATUS_NO_MEMORY;
|
|
}
|
|
|
|
// we are done with looking for
|
|
delete [] BaseFileName;
|
|
BaseFileName = NULL;
|
|
}
|
|
|
|
// name has not found ( get ready for default )
|
|
if ( NT_SUCCESS ( NtStatus ) && a->Mapping == NULL )
|
|
{
|
|
UNICODE_STRING KeyName;
|
|
RtlInitUnicodeString ( &KeyName,
|
|
L"\\REGISTRY\\MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\IniFileMapping"
|
|
);
|
|
|
|
InitializeObjectAttributes ( &ObjectAttributes,
|
|
&KeyName,
|
|
OBJ_CASE_INSENSITIVE,
|
|
NULL,
|
|
NULL
|
|
);
|
|
|
|
NtStatus = NtOpenKey ( &IniFileMappingRoot,
|
|
GENERIC_READ,
|
|
&ObjectAttributes
|
|
);
|
|
|
|
if ( NT_SUCCESS ( NtStatus ) && IniFileMappingRoot != INVALID_HANDLE_VALUE )
|
|
{
|
|
ULONG ResultLength = 0L;
|
|
|
|
UNICODE_STRING NullString;
|
|
RtlInitUnicodeString( &NullString, NULL );
|
|
|
|
UNICODE_STRING ValueName;
|
|
RtlInitUnicodeString( &ValueName, NULL );
|
|
|
|
NtStatus = NtQueryValueKey ( IniFileMappingRoot,
|
|
&ValueName,
|
|
KeyValuePartialInformation,
|
|
KeyValueInformation,
|
|
sizeof( Buffer ),
|
|
&ResultLength
|
|
);
|
|
|
|
try
|
|
{
|
|
if ( NT_SUCCESS ( NtStatus ) )
|
|
{
|
|
if ( MappingNameAlloc( &NullString, &DefaultFileNameMapping ) )
|
|
{
|
|
if ( MappingAppNameAlloc ( DefaultFileNameMapping, &NullString, &AppNameMapping ) )
|
|
{
|
|
if ( MappingVarNameAlloc ( DefaultFileNameMapping, AppNameMapping, &NullString, (PWSTR)(KeyValueInformation->Data), &VarNameMapping ) )
|
|
{
|
|
VarNameMapping->MappingFlags |= REGISTRY_MAPPING_APPEND_BASE_NAME | REGISTRY_MAPPING_APPEND_APPLICATION_NAME;
|
|
|
|
// assign proper mapping
|
|
a->Mapping = DefaultFileNameMapping;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
catch ( ... )
|
|
{
|
|
MappingNameFree ( DefaultFileNameMapping );
|
|
DefaultFileNameMapping = NULL;
|
|
|
|
a->Mapping = NULL;
|
|
|
|
NtStatus = STATUS_NO_MEMORY;
|
|
}
|
|
|
|
// close main root
|
|
if ( IniFileMappingRoot && IniFileMappingRoot != INVALID_HANDLE_VALUE )
|
|
{
|
|
NtClose ( IniFileMappingRoot );
|
|
IniFileMappingRoot = NULL;
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( a->Mapping )
|
|
{
|
|
// return success
|
|
Status = ERROR_SUCCESS;
|
|
}
|
|
else
|
|
{
|
|
if ( NT_SUCCESS ( NtStatus ) )
|
|
{
|
|
// we do not have mapping
|
|
Status = STATUS_MORE_PROCESSING_REQUIRED;
|
|
}
|
|
else
|
|
{
|
|
Status = NtStatus;
|
|
}
|
|
}
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
DWORD WMIRegistry_ParametersInit (
|
|
#ifdef WRITE_OPERATION
|
|
BOOLEAN WriteOperation,
|
|
#endif WRITE_OPERATION
|
|
|
|
REGISTRY_OPERATION Operation,
|
|
BOOLEAN MultiValueStrings,
|
|
|
|
LPCWSTR FileName,
|
|
LPCWSTR ApplicationName,
|
|
LPCWSTR VariableName,
|
|
LPWSTR VariableValue,
|
|
PULONG ResultMaxChars,
|
|
|
|
PREGISTRY_PARAMETERS *ReturnedParameterBlock
|
|
)
|
|
{
|
|
DWORD Status = ERROR_SUCCESS;
|
|
PREGISTRY_PARAMETERS a = NULL;
|
|
|
|
if ( ! ReturnedParameterBlock )
|
|
{
|
|
Status = ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
if ( Status == ERROR_SUCCESS )
|
|
{
|
|
try
|
|
{
|
|
a = new REGISTRY_PARAMETERS();
|
|
if ( a== NULL )
|
|
{
|
|
Status = ERROR_NOT_ENOUGH_MEMORY;
|
|
}
|
|
}
|
|
catch ( ... )
|
|
{
|
|
if ( a )
|
|
{
|
|
delete a;
|
|
a = NULL;
|
|
}
|
|
|
|
Status = ERROR_NOT_ENOUGH_MEMORY;
|
|
}
|
|
}
|
|
|
|
if ( Status == ERROR_SUCCESS )
|
|
{
|
|
#ifdef WRITE_OPERATION
|
|
a->WriteOperation = WriteOperation;
|
|
#endif WRITE_OPERATION
|
|
|
|
a->ValueBufferAllocated = FALSE;
|
|
|
|
a->Operation = Operation;
|
|
a->MultiValueStrings = MultiValueStrings;
|
|
|
|
if ( FileName )
|
|
{
|
|
a->FileName = FileName;
|
|
}
|
|
else
|
|
{
|
|
a->FileName = L"win.ini";
|
|
}
|
|
|
|
// section name
|
|
if ( ApplicationName )
|
|
{
|
|
a->ApplicationName = ApplicationName;
|
|
}
|
|
else
|
|
{
|
|
a->ApplicationName = NULL;
|
|
}
|
|
|
|
// key name
|
|
if ( VariableName )
|
|
{
|
|
a->VariableName= VariableName;
|
|
}
|
|
else
|
|
{
|
|
a->VariableName= NULL;
|
|
}
|
|
|
|
Status = WMIRegistry_InitMapping ( a );
|
|
if ( Status != ERROR_SUCCESS )
|
|
{
|
|
delete a;
|
|
a = NULL;
|
|
}
|
|
else
|
|
{
|
|
// key value
|
|
if ( VariableValue )
|
|
{
|
|
#ifdef WRITE_OPERATION
|
|
if (a->WriteOperation)
|
|
{
|
|
a->ValueBuffer = VariableValue;
|
|
a->ValueLength = wcslen ( VariableValue );
|
|
}
|
|
else
|
|
#endif WRITE_OPERATION
|
|
{
|
|
if ( ResultMaxChars )
|
|
{
|
|
a->ResultMaxChars = *ResultMaxChars;
|
|
}
|
|
else
|
|
{
|
|
a->ResultMaxChars = 0;
|
|
}
|
|
|
|
a->ResultChars = 0;
|
|
a->ResultBuffer = VariableValue;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
#ifdef WRITE_OPERATION
|
|
if ( a->WriteOperation )
|
|
{
|
|
a->ValueBuffer = NULL;
|
|
a->ValueLength = 0;
|
|
}
|
|
else
|
|
#endif WRITE_OPERATION
|
|
{
|
|
a->ResultMaxChars = 0;
|
|
a->ResultChars = 0;
|
|
a->ResultBuffer = NULL;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( ReturnedParameterBlock )
|
|
{
|
|
*ReturnedParameterBlock = a;
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
DWORD WMIRegistry_ParametersClear (
|
|
PREGISTRY_PARAMETERS ParameterBlock
|
|
)
|
|
{
|
|
DWORD Status = ERROR_SUCCESS;
|
|
|
|
if ( ! ParameterBlock )
|
|
{
|
|
Status = ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
if ( Status == ERROR_SUCCESS )
|
|
{
|
|
if ( ParameterBlock->Mapping )
|
|
{
|
|
MappingNameFree ( ParameterBlock->Mapping );
|
|
ParameterBlock->Mapping = NULL;
|
|
}
|
|
|
|
delete ParameterBlock;
|
|
ParameterBlock = NULL;
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
// read function
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
DWORD WMIRegistry (
|
|
#ifdef WRITE_OPERATION
|
|
IN BOOLEAN WriteOperation,
|
|
#endif WRITE_OPERATION
|
|
|
|
IN BOOLEAN SectionOperation,
|
|
IN LPCWSTR FileName,
|
|
IN LPCWSTR ApplicationName,
|
|
IN LPCWSTR VariableName,
|
|
IN OUT LPWSTR VariableValue,
|
|
IN OUT PULONG VariableValueLength
|
|
)
|
|
{
|
|
// variables
|
|
DWORD Status = ERROR_INVALID_PARAMETER;
|
|
REGISTRY_OPERATION Operation = Registry_None;
|
|
BOOLEAN MultiValueStrings = FALSE;
|
|
|
|
if ( SectionOperation )
|
|
{
|
|
VariableName = NULL;
|
|
}
|
|
|
|
if ( ApplicationName )
|
|
{
|
|
if ( VariableValue )
|
|
{
|
|
if ( VariableName )
|
|
{
|
|
Operation = Registry_ReadKeyValue;
|
|
}
|
|
else
|
|
{
|
|
if ( SectionOperation )
|
|
{
|
|
Operation = Registry_ReadSectionValue;
|
|
MultiValueStrings = TRUE;
|
|
}
|
|
else
|
|
{
|
|
Operation = Registry_ReadKeyName;
|
|
MultiValueStrings = TRUE;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if ( ! ( SectionOperation || ! VariableValue ) )
|
|
{
|
|
Operation = Registry_ReadSectionName;
|
|
MultiValueStrings = TRUE;
|
|
}
|
|
}
|
|
|
|
// real operation
|
|
if ( Operation != Registry_None )
|
|
{
|
|
PREGISTRY_PARAMETERS a = NULL;
|
|
|
|
Status = WMIRegistry_ParametersInit (
|
|
#ifdef WRITE_OPERATION
|
|
WriteOperation,
|
|
#endif WRITE_OPERATION
|
|
|
|
Operation,
|
|
MultiValueStrings,
|
|
FileName,
|
|
ApplicationName,
|
|
VariableName,
|
|
VariableValue,
|
|
VariableValueLength,
|
|
&a
|
|
);
|
|
|
|
if ( Status == ERROR_SUCCESS )
|
|
{
|
|
if ( a->Mapping != NULL )
|
|
{
|
|
Status = WMIRegistry_Mapping( a );
|
|
|
|
if ( Status == ERROR_SUCCESS || Status == ERROR_MORE_DATA )
|
|
{
|
|
if ( a->Operation == Registry_ReadKeyName ||
|
|
a->Operation == Registry_ReadSectionName ||
|
|
a->Operation == Registry_ReadSectionValue
|
|
)
|
|
{
|
|
REGISTRY_AppendNULLToResultBuffer ( a );
|
|
}
|
|
|
|
if ( VariableValueLength )
|
|
{
|
|
*VariableValueLength = a->ResultChars;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Status = ERROR_INVALID_PARAMETER;
|
|
|
|
if ( VariableValueLength )
|
|
{
|
|
*VariableValueLength = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
WMIRegistry_ParametersClear ( a );
|
|
}
|
|
|
|
::SetLastError ( Status );
|
|
return Status;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
// get profile string
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
DWORD APIENTRY WMIRegistry_PrivateProfileString (
|
|
LPCWSTR lpAppName,
|
|
LPCWSTR lpKeyName,
|
|
LPCWSTR lpDefault,
|
|
LPWSTR lpReturnedString,
|
|
DWORD nSize,
|
|
LPCWSTR lpFileName
|
|
)
|
|
{
|
|
DWORD Status = ERROR_SUCCESS;
|
|
ULONG n = nSize;
|
|
|
|
if ( lpDefault == NULL )
|
|
{
|
|
lpDefault = L"";
|
|
}
|
|
|
|
Status = WMIRegistry (
|
|
#ifdef WRITE_OPERATION
|
|
FALSE, // Write operation
|
|
#endif WRITE_OPERATION
|
|
|
|
FALSE, // SectionOperation
|
|
lpFileName,
|
|
lpAppName,
|
|
lpKeyName,
|
|
lpReturnedString,
|
|
&n
|
|
);
|
|
|
|
if ( n && ( Status == ERROR_SUCCESS || Status == STATUS_BUFFER_OVERFLOW ) )
|
|
{
|
|
if ( Status == ERROR_SUCCESS )
|
|
{
|
|
n--;
|
|
}
|
|
else
|
|
{
|
|
if ( !lpAppName || !lpKeyName )
|
|
{
|
|
if ( nSize >= 2 )
|
|
{
|
|
n = nSize - 2;
|
|
lpReturnedString[ n+1 ] = L'\0';
|
|
}
|
|
else
|
|
{
|
|
n = 0;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if ( nSize >= 1 )
|
|
{
|
|
n = nSize - 1;
|
|
}
|
|
else
|
|
{
|
|
n = 0;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
n = wcslen( lpDefault );
|
|
while ( n > 0 && lpDefault[n-1] == L' ')
|
|
{
|
|
n -= 1;
|
|
}
|
|
|
|
if (n >= nSize)
|
|
{
|
|
n = nSize;
|
|
}
|
|
|
|
wcsncpy ( lpReturnedString, lpDefault, n );
|
|
}
|
|
|
|
if ( n < nSize )
|
|
{
|
|
lpReturnedString[ n ] = L'\0';
|
|
}
|
|
else
|
|
{
|
|
if ( nSize > 0 )
|
|
{
|
|
lpReturnedString[ nSize-1 ] = L'\0';
|
|
}
|
|
}
|
|
|
|
return n;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
// get profile section
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
DWORD APIENTRY WMIRegistry_PrivateProfileSection (
|
|
LPCWSTR lpAppName,
|
|
LPWSTR lpReturnedString,
|
|
DWORD nSize,
|
|
LPCWSTR lpFileName
|
|
)
|
|
{
|
|
NTSTATUS Status;
|
|
ULONG n;
|
|
|
|
n = nSize;
|
|
Status = WMIRegistry (
|
|
#ifdef WRITE_OPERATION
|
|
FALSE, // Write operation
|
|
#endif WRITE_OPERATION
|
|
|
|
TRUE, // SectionOperation
|
|
lpFileName,
|
|
lpAppName,
|
|
NULL,
|
|
lpReturnedString,
|
|
&n
|
|
);
|
|
|
|
if ( Status == ERROR_SUCCESS || Status == STATUS_BUFFER_OVERFLOW )
|
|
{
|
|
if ( Status == ERROR_SUCCESS )
|
|
{
|
|
n--;
|
|
}
|
|
else
|
|
{
|
|
if ( nSize >= 2 )
|
|
{
|
|
n = nSize - 2;
|
|
lpReturnedString[ n+1 ] = L'\0';
|
|
}
|
|
else
|
|
{
|
|
n = 0;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
n = 0;
|
|
}
|
|
|
|
if ( n < nSize )
|
|
{
|
|
lpReturnedString[ n ] = L'\0';
|
|
}
|
|
else
|
|
{
|
|
if ( nSize > 0 )
|
|
{
|
|
lpReturnedString[ nSize-1 ] = L'\0';
|
|
}
|
|
}
|
|
|
|
return n;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
// get profile integer
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
UINT APIENTRY WMIRegistry_PrivateProfileInt (
|
|
LPCWSTR lpAppName,
|
|
LPCWSTR lpKeyName,
|
|
INT nDefault
|
|
)
|
|
{
|
|
WCHAR ValueBuffer[ 256 ];
|
|
|
|
ULONG ReturnValue = nDefault;
|
|
ULONG cb = 0;
|
|
|
|
cb = WMIRegistry_PrivateProfileString ( lpAppName,
|
|
lpKeyName,
|
|
NULL,
|
|
ValueBuffer,
|
|
sizeof( ValueBuffer ) / sizeof( WCHAR ),
|
|
NULL
|
|
);
|
|
if ( cb )
|
|
{
|
|
// convert value to integer
|
|
_wtoi ( ValueBuffer );
|
|
}
|
|
|
|
return ReturnValue;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
// get profile integer caller
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
UINT APIENTRY WMIRegistry_ProfileInt (
|
|
LPCWSTR lpAppName,
|
|
LPCWSTR lpKeyName,
|
|
INT nDefault
|
|
)
|
|
{
|
|
return( WMIRegistry_PrivateProfileInt ( lpAppName,
|
|
lpKeyName,
|
|
nDefault
|
|
)
|
|
);
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
// get profile section caller
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
DWORD APIENTRY WMIRegistry_ProfileSection (
|
|
LPCWSTR lpAppName,
|
|
LPWSTR lpReturnedString,
|
|
DWORD nSize
|
|
)
|
|
{
|
|
return( WMIRegistry_PrivateProfileSection ( lpAppName,
|
|
lpReturnedString,
|
|
nSize,
|
|
NULL
|
|
)
|
|
);
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
// get profile string caller
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
DWORD APIENTRY WMIRegistry_ProfileString (
|
|
LPCWSTR lpAppName,
|
|
LPCWSTR lpKeyName,
|
|
LPCWSTR lpDefault,
|
|
LPWSTR lpReturnedString,
|
|
DWORD nSize
|
|
)
|
|
{
|
|
return( WMIRegistry_PrivateProfileString ( lpAppName,
|
|
lpKeyName,
|
|
lpDefault,
|
|
lpReturnedString,
|
|
nSize,
|
|
NULL
|
|
)
|
|
);
|
|
}
|