From dbde9e7104b907bbbaea17e21247d8cafc8b3a4c Mon Sep 17 00:00:00 2001 From: Rob Mensching Date: Sat, 14 Oct 2017 16:12:07 -0700 Subject: Massive refactoring to introduce the concept of IBackend --- src/WixToolset.Core.WindowsInstaller/Msi/Record.cs | 182 +++++++++++++++++++++ 1 file changed, 182 insertions(+) create mode 100644 src/WixToolset.Core.WindowsInstaller/Msi/Record.cs (limited to 'src/WixToolset.Core.WindowsInstaller/Msi/Record.cs') diff --git a/src/WixToolset.Core.WindowsInstaller/Msi/Record.cs b/src/WixToolset.Core.WindowsInstaller/Msi/Record.cs new file mode 100644 index 00000000..438aa3b0 --- /dev/null +++ b/src/WixToolset.Core.WindowsInstaller/Msi/Record.cs @@ -0,0 +1,182 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. + +namespace WixToolset.Msi +{ + using System; + using System.ComponentModel; + using System.Text; + using WixToolset.Core.Native; + + /// + /// Wrapper class around msi.dll interop for a record. + /// + public sealed class Record : MsiHandle + { + /// + /// Creates a record with the specified number of fields. + /// + /// Number of fields in record. + public Record(int fieldCount) + { + this.Handle = MsiInterop.MsiCreateRecord(fieldCount); + if (0 == this.Handle) + { + throw new OutOfMemoryException(); + } + } + + /// + /// Creates a record from a handle. + /// + /// Handle to create record from. + internal Record(uint handle) + { + this.Handle = handle; + } + + /// + /// Gets a string value at specified location. + /// + /// Index into record to get string. + public string this[int field] + { + get { return this.GetString(field); } + set { this.SetString(field, (string)value); } + } + + /// + /// Determines if the value is null at the specified location. + /// + /// Index into record of the field to query. + /// true if the value is null, false otherwise. + public bool IsNull(int field) + { + int error = MsiInterop.MsiRecordIsNull(this.Handle, field); + + switch (error) + { + case 0: + return false; + case 1: + return true; + default: + throw new Win32Exception(error); + } + } + + /// + /// Gets integer value at specified location. + /// + /// Index into record to get integer + /// Integer value + public int GetInteger(int field) + { + return MsiInterop.MsiRecordGetInteger(this.Handle, field); + } + + /// + /// Sets integer value at specified location. + /// + /// Index into record to set integer. + /// Value to set into record. + public void SetInteger(int field, int value) + { + int error = MsiInterop.MsiRecordSetInteger(this.Handle, field, value); + if (0 != error) + { + throw new Win32Exception(error); + } + } + + /// + /// Gets string value at specified location. + /// + /// Index into record to get string. + /// String value + public string GetString(int field) + { + int bufferSize = 255; + StringBuilder buffer = new StringBuilder(bufferSize); + int error = MsiInterop.MsiRecordGetString(this.Handle, field, buffer, ref bufferSize); + if (234 == error) + { + buffer.EnsureCapacity(++bufferSize); + error = MsiInterop.MsiRecordGetString(this.Handle, field, buffer, ref bufferSize); + } + + if (0 != error) + { + throw new Win32Exception(error); + } + + return (0 < buffer.Length ? buffer.ToString() : null); + } + + /// + /// Set string value at specified location + /// + /// Index into record to set string. + /// Value to set into record + public void SetString(int field, string value) + { + int error = MsiInterop.MsiRecordSetString(this.Handle, field, value); + if (0 != error) + { + throw new Win32Exception(error); + } + } + + /// + /// Get stream at specified location. + /// + /// Index into record to get stream. + /// buffer to receive bytes from stream. + /// Buffer size to read. + /// Stream read into string. + public int GetStream(int field, byte[] buffer, int requestedBufferSize) + { + int bufferSize = 255; + if (requestedBufferSize > 0) + { + bufferSize = requestedBufferSize; + } + + int error = MsiInterop.MsiRecordReadStream(this.Handle, field, buffer, ref bufferSize); + if (0 != error) + { + throw new Win32Exception(error); + } + + return bufferSize; + } + + /// + /// Sets a stream at a specified location. + /// + /// Index into record to set stream. + /// Path to file to read into stream. + public void SetStream(int field, string path) + { + int error = MsiInterop.MsiRecordSetStream(this.Handle, field, path); + if (0 != error) + { + throw new Win32Exception(error); + } + } + + /// + /// Gets the number of fields in record. + /// + /// Count of fields in record. + public int GetFieldCount() + { + int size = MsiInterop.MsiRecordGetFieldCount(this.Handle); + if (0 > size) + { + throw new Win32Exception(); + } + + return size; + } + } +} -- cgit v1.2.3-55-g6feb