bool FRegistryKey::Read(HKEY hKey) { // Enumerate all the child key names TArray<FString> KeyNames; EnumerateRegistryKeys(hKey, KeyNames); // Read all the child keys for (int32 Idx = 0; Idx < KeyNames.Num(); Idx++) { FRegistryKey *Key = FindOrAddKey(KeyNames[Idx]); if (!Key->Read(hKey, KeyNames[Idx])) { return false; } } // Enumerate all the child values TArray<FString> ValueNames; EnumerateRegistryValues(hKey, ValueNames); // Read all the values for (int32 Idx = 0; Idx < ValueNames.Num(); Idx++) { FRegistryValue *Value = FindOrAddValue(ValueNames[Idx]); if (!Value->Read(hKey, ValueNames[Idx])) { return false; } } return true; }
bool FRegistryKey::Write(HKEY hKey, bool bRemoveDifferences) const { // Remove all the differences from the current content if (bRemoveDifferences) { // Get all the existing value names TArray<FString> ValueNames; EnumerateRegistryValues(hKey, ValueNames); // Remove any values that don't exist any more for (int32 Idx = 0; Idx < ValueNames.Num(); Idx++) { if (!Values.Contains(ValueNames[Idx]) && RegDeleteValue(hKey, *ValueNames[Idx]) != ERROR_SUCCESS) { return false; } } // Get all the existing key names TArray<FString> KeyNames; EnumerateRegistryKeys(hKey, KeyNames); // Remove any keys that don't exist any more for (int32 Idx = 0; Idx < KeyNames.Num(); Idx++) { #if WINVER == 0x0502 if (!Keys.Contains(KeyNames[Idx]) && SHDeleteKey(hKey, *KeyNames[Idx]) != ERROR_SUCCESS) #else if (!Keys.Contains(KeyNames[Idx]) && RegDeleteTree(hKey, *KeyNames[Idx]) != ERROR_SUCCESS) #endif // WINVER == 0x0502 { return false; } } } // Write all the child keys for (TMap<FString, FRegistryKey*>::TConstIterator ChildKeyIter(Keys); ChildKeyIter; ++ChildKeyIter) { if (!ChildKeyIter.Value()->Write(hKey, ChildKeyIter.Key(), bRemoveDifferences)) { return false; } } // Write all the child values for (TMap<FString, FRegistryValue*>::TConstIterator ChildValueIter(Values); ChildValueIter; ++ChildValueIter) { if (RegSetValueEx(hKey, *ChildValueIter.Key(), 0, ChildValueIter.Value()->Type, ChildValueIter.Value()->Data.GetData(), (DWORD)ChildValueIter.Value()->Data.Num()) != ERROR_SUCCESS) { return false; } } return true; }
bool FRegistryKey::IsUpToDate(HKEY hKey, bool bRemoveDifferences) const { // Remove all the differences from the current content if (bRemoveDifferences) { // Get all the existing value names TArray<FString> ValueNames; EnumerateRegistryValues(hKey, ValueNames); // Check there aren't any extra values for (int32 Idx = 0; Idx < ValueNames.Num(); Idx++) { if (!Values.Contains(ValueNames[Idx])) { return false; } } // Get all the existing key names TArray<FString> KeyNames; EnumerateRegistryKeys(hKey, KeyNames); // Check there aren't any extra keys for (int32 Idx = 0; Idx < KeyNames.Num(); Idx++) { if (!Keys.Contains(KeyNames[Idx])) { return false; } } } // Write all the child keys for (TMap<FString, FRegistryKey*>::TConstIterator Iter(Keys); Iter; ++Iter) { if (!Iter.Value()->IsUpToDate(hKey, Iter.Key(), bRemoveDifferences)) { return false; } } // Write all the child values for (TMap<FString, FRegistryValue*>::TConstIterator Iter(Values); Iter; ++Iter) { if (!Iter.Value()->IsUpToDate(hKey, Iter.Key())) { return false; } } return true; }
/* * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= ** * * * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= ** */ NTSTATUS DriverEntry( IN PDRIVER_OBJECT theDriverObject, IN PUNICODE_STRING theRegistryPath ) { NTSTATUS Status; PSECURITY_DESCRIPTOR SecurityDescriptor; OBJECT_ATTRIBUTES ObjectAttributes; UNICODE_STRING uPortName; // Open the registry and read in all the setting we will use in kernel mode EnumerateRegistryValues( theRegistryPath ); // DDK : "...Add itself to the global list of registered minifilters and to provide // the Filter Manager with a list of callback functions and other information // about the minifilter." Status = FltRegisterFilter( theDriverObject, &cfsd_FilterRegistration, &gFilterPointer ); if ( NT_SUCCESS( Status ) ) { #if ENABLE_USER_INTERFACE Status = FltBuildDefaultSecurityDescriptor( &SecurityDescriptor, FLT_PORT_ALL_ACCESS ); if ( NT_SUCCESS( Status ) ) { RtlInitUnicodeString( &uPortName, USER_COMMUNICATION_PORT_NAME ); InitializeObjectAttributes( &ObjectAttributes, &uPortName, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, SecurityDescriptor ); KdPrint( (PRINT_TAG "Attempting to create Communication Port for user mode access\n") ); Status = FltCreateCommunicationPort( gFilterPointer, // Filter &gUserModeConnection.ServerPort,// *ServerPort &ObjectAttributes, // ObjectAttributes NULL, // ServerPortCookie cfsd_UserModeConnect, // ConnectNotifyCallback cfsd_UserModeDisconnect, // DisconnectNotifyCallback cfsd_UserModeCommunication, // MessageNotifyCallback 1 ); // MaxConnections FltFreeSecurityDescriptor( SecurityDescriptor ); // If we failed to create a communications port then we are going to fail the driver if ( !NT_SUCCESS( Status ) ) { KdPrint( (PRINT_TAG "Failed FltCreateCommunicationPort() with NTSTATUS 0x%x\n",Status ) ); // Release our hidden data memory ExFreePoolWithTag( gHiddenData, 'parC' ); return Status; } KdPrint( (PRINT_TAG "Created ServerPort 0x%X\n", gUserModeConnection.ServerPort ) ); } #endif // DDK : "...Notifies the Filter Manager that the minifilter is ready to // begin attaching to volumes and filtering I/O requests" Status = FltStartFiltering( gFilterPointer ); if ( !NT_SUCCESS( Status )) { #if ENABLE_USER_INTERFACE FltCloseCommunicationPort( gUserModeConnection.ServerPort ); #endif // If we failed FltStartFiltering() then we unregister ourself with the Filter Manager // so that we no longer recieve calls to process I/O operations. FltUnregisterFilter( gFilterPointer ); // Release our hidden data memory ExFreePoolWithTag( gHiddenData, 'parC' ); } } return Status; }