main
cs 181 lines 5.96 KB
Raw
1 // 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.
2
3 namespace WixToolset.Core.Native.Msi
4 {
5 using System;
6 using System.ComponentModel;
7 using System.Text;
8
9 /// <summary>
10 /// Wrapper class around msi.dll interop for a record.
11 /// </summary>
12 public sealed class Record : MsiHandle
13 {
14 /// <summary>
15 /// Creates a record with the specified number of fields.
16 /// </summary>
17 /// <param name="fieldCount">Number of fields in record.</param>
18 public Record(int fieldCount)
19 {
20 this.Handle = MsiInterop.MsiCreateRecord(fieldCount);
21 if (IntPtr.Zero == this.Handle)
22 {
23 throw new OutOfMemoryException();
24 }
25 }
26
27 /// <summary>
28 /// Creates a record from a handle.
29 /// </summary>
30 /// <param name="handle">Handle to create record from.</param>
31 internal Record(IntPtr handle)
32 {
33 this.Handle = handle;
34 }
35
36 /// <summary>
37 /// Gets a string value at specified location.
38 /// </summary>
39 /// <param name="field">Index into record to get string.</param>
40 public string this[int field]
41 {
42 get => this.GetString(field);
43 set => this.SetString(field, value);
44 }
45
46 /// <summary>
47 /// Determines if the value is null at the specified location.
48 /// </summary>
49 /// <param name="field">Index into record of the field to query.</param>
50 /// <returns>true if the value is null, false otherwise.</returns>
51 public bool IsNull(int field)
52 {
53 var error = MsiInterop.MsiRecordIsNull(this.Handle, field);
54
55 switch (error)
56 {
57 case 0:
58 return false;
59 case 1:
60 return true;
61 default:
62 throw new Win32Exception(error);
63 }
64 }
65
66 /// <summary>
67 /// Gets integer value at specified location.
68 /// </summary>
69 /// <param name="field">Index into record to get integer</param>
70 /// <returns>Integer value</returns>
71 public int GetInteger(int field)
72 {
73 return MsiInterop.MsiRecordGetInteger(this.Handle, field);
74 }
75
76 /// <summary>
77 /// Sets integer value at specified location.
78 /// </summary>
79 /// <param name="field">Index into record to set integer.</param>
80 /// <param name="value">Value to set into record.</param>
81 public void SetInteger(int field, int value)
82 {
83 var error = MsiInterop.MsiRecordSetInteger(this.Handle, field, value);
84 if (0 != error)
85 {
86 throw new Win32Exception(error);
87 }
88 }
89
90 /// <summary>
91 /// Gets string value at specified location.
92 /// </summary>
93 /// <param name="field">Index into record to get string.</param>
94 /// <returns>String value</returns>
95 public string GetString(int field)
96 {
97 var bufferSize = 256;
98 var buffer = new StringBuilder(bufferSize);
99 var error = MsiInterop.MsiRecordGetString(this.Handle, field, buffer, ref bufferSize);
100 if (234 == error)
101 {
102 buffer.EnsureCapacity(++bufferSize);
103 error = MsiInterop.MsiRecordGetString(this.Handle, field, buffer, ref bufferSize);
104 }
105
106 if (0 != error)
107 {
108 throw new Win32Exception(error);
109 }
110
111 return (0 < buffer.Length ? buffer.ToString() : null);
112 }
113
114 /// <summary>
115 /// Set string value at specified location
116 /// </summary>
117 /// <param name="field">Index into record to set string.</param>
118 /// <param name="value">Value to set into record</param>
119 public void SetString(int field, string value)
120 {
121 var error = MsiInterop.MsiRecordSetString(this.Handle, field, value);
122 if (0 != error)
123 {
124 throw new Win32Exception(error);
125 }
126 }
127
128 /// <summary>
129 /// Get stream at specified location.
130 /// </summary>
131 /// <param name="field">Index into record to get stream.</param>
132 /// <param name="buffer">buffer to receive bytes from stream.</param>
133 /// <param name="requestedBufferSize">Buffer size to read.</param>
134 /// <returns>Stream read into string.</returns>
135 public int GetStream(int field, byte[] buffer, int requestedBufferSize)
136 {
137 var bufferSize = buffer.Length;
138 if (requestedBufferSize > 0)
139 {
140 bufferSize = requestedBufferSize;
141 }
142
143 var error = MsiInterop.MsiRecordReadStream(this.Handle, field, buffer, ref bufferSize);
144 if (0 != error)
145 {
146 throw new Win32Exception(error);
147 }
148
149 return bufferSize;
150 }
151
152 /// <summary>
153 /// Sets a stream at a specified location.
154 /// </summary>
155 /// <param name="field">Index into record to set stream.</param>
156 /// <param name="path">Path to file to read into stream.</param>
157 public void SetStream(int field, string path)
158 {
159 var error = MsiInterop.MsiRecordSetStream(this.Handle, field, path);
160 if (0 != error)
161 {
162 throw new Win32Exception(error);
163 }
164 }
165
166 /// <summary>
167 /// Gets the number of fields in record.
168 /// </summary>
169 /// <returns>Count of fields in record.</returns>
170 public int GetFieldCount()
171 {
172 var size = MsiInterop.MsiRecordGetFieldCount(this.Handle);
173 if (0 > size)
174 {
175 throw new Win32Exception();
176 }
177
178 return size;
179 }
180 }
181 }