// private MorphicResult <GetValueAndTypeAsObjectResult, RegistryValueError> GetValueAndTypeAsObject(string?name) { var handleAsUIntPtr = (UIntPtr)(_handle.DangerousGetHandle().ToInt64()); // pass 1: set dataSize to zero (so that RegQueryValueEx returns the size of the value uint dataSize = 0; ExtendedPInvoke.RegistryValueType valueType; var queryValueErrorCode = ExtendedPInvoke.RegQueryValueEx(handleAsUIntPtr, name, IntPtr.Zero, out valueType, IntPtr.Zero, ref dataSize); switch (queryValueErrorCode) { case PInvoke.Win32ErrorCode.ERROR_SUCCESS: break; case PInvoke.Win32ErrorCode.ERROR_FILE_NOT_FOUND: return(MorphicResult.ErrorResult(RegistryValueError.ValueDoesNotExist)); default: // NOTE: in the future, we may want to consider returning a specific result (i.e. "could not open for write access" etc.) return(MorphicResult.ErrorResult(RegistryValueError.Win32Error((int)queryValueErrorCode))); } // pass 2: capture the actual data var getValueResult = RegistryKey.GetValueForHandleAsUInt32(handleAsUIntPtr, name, dataSize); if (getValueResult.IsError) { return(MorphicResult.ErrorResult(getValueResult.Error !)); } var data = getValueResult.Value; return(MorphicResult.OkResult(new GetValueAndTypeAsObjectResult(data, valueType))); }
private static MorphicResult <uint, RegistryValueError> GetValueForHandleAsUInt32(UIntPtr handle, string?name, uint dataSize) { var ptrToData = Marshal.AllocHGlobal((int)dataSize); try { var mutableDataSize = dataSize; ExtendedPInvoke.RegistryValueType valueType; var queryValueErrorCode = ExtendedPInvoke.RegQueryValueEx(handle, name, IntPtr.Zero, out valueType, ptrToData, ref mutableDataSize); switch (queryValueErrorCode) { case PInvoke.Win32ErrorCode.ERROR_SUCCESS: break; default: // NOTE: in the future, we may want to consider returning a specific result (i.e. "could not open for write access" etc.) return(MorphicResult.ErrorResult(RegistryValueError.Win32Error((int)queryValueErrorCode))); } // validate value type and data size if (valueType != ExtendedPInvoke.RegistryValueType.REG_DWORD) { return(MorphicResult.ErrorResult(RegistryValueError.TypeMismatch)); } // if (mutableDataSize != dataSize) { return(MorphicResult.ErrorResult(RegistryValueError.TypeMismatch)); } // capture and return result var data = Marshal.PtrToStructure <uint>(ptrToData); return(MorphicResult.OkResult(data)); } finally { Marshal.FreeHGlobal(ptrToData); } }