// 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; } } }