Add SqlCredential support -
[mono-project.git] / mcs / class / Mono.Data.Tds / Mono.Data.Tds.Protocol / Tds42.cs
blobfb517d013d55841d99f8602154b2826e0e793fc9
1 //
2 // Mono.Data.Tds.Protocol.Tds42.cs
3 //
4 // Author:
5 // Tim Coleman (tim@timcoleman.com)
6 //
7 // Copyright (C) 2002 Tim Coleman
8 //
11 // Permission is hereby granted, free of charge, to any person obtaining
12 // a copy of this software and associated documentation files (the
13 // "Software"), to deal in the Software without restriction, including
14 // without limitation the rights to use, copy, modify, merge, publish,
15 // distribute, sublicense, and/or sell copies of the Software, and to
16 // permit persons to whom the Software is furnished to do so, subject to
17 // the following conditions:
18 //
19 // The above copyright notice and this permission notice shall be
20 // included in all copies or substantial portions of the Software.
21 //
22 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
26 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31 using System;
32 using System.Security;
34 namespace Mono.Data.Tds.Protocol {
35 public sealed class Tds42 : Tds
37 #region Fields
39 public static readonly TdsVersion Version = TdsVersion.tds42;
41 #endregion // Fields
43 #region Constructors
45 public Tds42 (string server, int port)
46 : this (server, port, 512, 15)
50 public Tds42 (string server, int port, int packetSize, int timeout)
51 : base (server, port, packetSize, timeout, Version)
55 #endregion // Constructors
57 #region Methods
59 public override bool Connect (TdsConnectionParameters connectionParameters)
61 if (IsConnected)
62 throw new InvalidOperationException ("The connection is already open.");
64 SetCharset (connectionParameters.Charset);
65 SetLanguage (connectionParameters.Language);
67 byte pad = (byte) 0;
68 byte[] empty = new byte[0];
70 Comm.StartPacket (TdsPacketType.Logon);
72 // hostname (offset 0)
73 byte[] tmp = Comm.Append (connectionParameters.Hostname, 30, pad);
74 Comm.Append ((byte) (tmp.Length < 30 ? tmp.Length : 30));
76 // username (offset 31 0x1f)
77 tmp = Comm.Append (connectionParameters.User, 30, pad);
78 Comm.Append ((byte) (tmp.Length < 30 ? tmp.Length : 30));
80 // password (offset 62 0x3e)
81 tmp = Comm.Append (GetPlainPassword(connectionParameters.Password), 30, pad);
82 Comm.Append ((byte) (tmp.Length < 30 ? tmp.Length : 30));
84 // hostproc (offset 93 0x5d)
85 Comm.Append ("00000116", 8, pad);
87 // unused (offset 109 0x6d)
88 Comm.Append (empty, (30-14), pad);
90 // apptype
91 Comm.Append ((byte) 0x0);
92 Comm.Append ((byte) 0xa0);
93 Comm.Append ((byte) 0x24);
94 Comm.Append ((byte) 0xcc);
95 Comm.Append ((byte) 0x50);
96 Comm.Append ((byte) 0x12);
98 // hostproc length
99 Comm.Append ((byte) 8);
101 // Byte order of 2 byte ints
102 // 2 = <MSB, LSB>, 3 = <LSB, MSB>
103 Comm.Append ((byte) 3);
105 // Byte order of 4 byte ints
106 // 0 = <MSB, LSB>, 1 = <LSB, MSB>
107 Comm.Append ((byte) 1);
109 // Character representation
110 // (6 = ASCII, 7 = EBCDIC)
111 Comm.Append ((byte) 6);
113 // Eight byte floating point representation
114 // 4 = IEEE <MSB, ..., LSB>
115 // 5 = VAX 'D'
116 // 10 = IEEE <LSB, ..., MSB>
117 // 11 = ND5000
118 Comm.Append ((byte) 10);
120 // Eight byte date format
121 // 8 = <MSB, ..., LSB>
122 Comm.Append ((byte) 9);
124 // notify of use db
125 Comm.Append ((byte) 1);
127 // disallow dump/load and bulk insert
128 Comm.Append ((byte) 1);
130 // sql interface type
131 Comm.Append ((byte) 0);
133 // type of network connection
134 Comm.Append ((byte) 0);
137 // spare [7]
138 Comm.Append (empty, 7, pad);
139 // appname
140 tmp = Comm.Append (connectionParameters.ApplicationName, 30, pad);
141 Comm.Append ((byte) (tmp.Length < 30 ? tmp.Length : 30));
143 // server name
144 tmp = Comm.Append (DataSource, 30, pad);
145 Comm.Append ((byte) (tmp.Length < 30 ? tmp.Length : 30));
147 // remote passwords
148 Comm.Append (empty, 2, pad);
149 tmp = Comm.Append (GetPlainPassword(connectionParameters.Password), 253, pad);
150 Comm.Append ((byte) (tmp.Length < 253 ? tmp.Length + 2 : 253 + 2));
152 // tds version
153 Comm.Append ((byte) (((byte) Version) / 10));
154 Comm.Append ((byte) (((byte) Version) % 10));
155 Comm.Append ((byte) 0);
156 Comm.Append ((byte) 0);
158 // prog name
159 tmp = Comm.Append (connectionParameters.ProgName, 10, pad);
160 Comm.Append ((byte) (tmp.Length < 10 ? tmp.Length : 10));
162 // prog version
163 Comm.Append ((byte) 6);
165 // Tell the server we can handle SQLServer version 6
166 Comm.Append ((byte) 0);
168 // Send zero to tell the server we can't handle any other version
169 Comm.Append ((byte) 0);
170 Comm.Append ((byte) 0);
172 // auto convert short
173 Comm.Append ((byte) 0);
175 // type of flt4
176 Comm.Append ((byte) 0x0d);
178 // type of date4
179 Comm.Append ((byte) 0x11);
181 // language
182 tmp = Comm.Append (Language, 30, pad);
183 Comm.Append ((byte) (tmp.Length < 30 ? tmp.Length : 30));
185 // notify on lang change
186 Comm.Append ((byte) 1);
188 // security label hierarchy
189 Comm.Append ((short) 0);
191 // security components
192 Comm.Append (empty, 8, pad);
194 // security spare
195 Comm.Append ((short) 0);
197 // security login role
198 Comm.Append ((byte) 0);
200 // charset
201 tmp = Comm.Append (Charset, 30, pad);
202 Comm.Append ((byte) (tmp.Length < 30 ? tmp.Length : 30));
204 // notify on charset change
205 Comm.Append ((byte) 1);
207 // length of tds packets
208 tmp = Comm.Append (PacketSize.ToString (), 6, pad);
209 Comm.Append ((byte) 3);
211 // pad out to a longword
212 Comm.Append (empty, 8, pad);
214 Comm.SendPacket ();
216 MoreResults = true;
217 SkipToEnd ();
219 return IsConnected;
222 protected override void ProcessColumnInfo ()
224 byte precision;
225 byte scale;
226 int totalLength = Comm.GetTdsShort ();
227 int bytesRead = 0;
229 while (bytesRead < totalLength) {
230 scale = 0;
231 precision = 0;
233 int bufLength = -1;
234 byte[] flagData = new byte[4];
235 for (int i = 0; i < 4; i += 1) {
236 flagData[i] = Comm.GetByte ();
237 bytesRead += 1;
239 bool nullable = (flagData[2] & 0x01) > 0;
240 //bool caseSensitive = (flagData[2] & 0x02) > 0;
241 bool writable = (flagData[2] & 0x0c) > 0;
242 //bool autoIncrement = (flagData[2] & 0x10) > 0;
244 string tableName = String.Empty;
245 TdsColumnType columnType = (TdsColumnType) Comm.GetByte ();
247 bytesRead += 1;
249 if (columnType == TdsColumnType.Text || columnType == TdsColumnType.Image) {
250 Comm.Skip (4);
251 bytesRead += 4;
253 int tableNameLength = Comm.GetTdsShort ();
254 bytesRead += 2;
255 tableName = Comm.GetString (tableNameLength);
256 bytesRead += tableNameLength;
257 bufLength = 2 << 31 - 1;
259 else if (columnType == TdsColumnType.Decimal || columnType == TdsColumnType.Numeric) {
260 bufLength = Comm.GetByte ();
261 bytesRead += 1;
262 precision = Comm.GetByte ();
263 bytesRead += 1;
264 scale = Comm.GetByte ();
265 bytesRead += 1;
267 else if (IsFixedSizeColumn (columnType))
268 bufLength = LookupBufferSize (columnType);
269 else {
270 bufLength = (int) Comm.GetByte () & 0xff;
271 bytesRead += 1;
274 TdsDataColumn col = new TdsDataColumn ();
275 int index = Columns.Add (col);
276 #if NET_2_0
277 col.ColumnType = columnType;
278 col.ColumnSize = bufLength;
279 col.ColumnName = ColumnNames[index] as string;
280 col.NumericPrecision = precision;
281 col.NumericScale = scale;
282 col.IsReadOnly = !writable;
283 col.BaseTableName = tableName;
284 col.AllowDBNull = nullable;
285 #else
286 col["ColumnType"] = columnType;
287 col["ColumnSize"] = bufLength;
288 col["ColumnName"] = ColumnNames[index];
289 col["NumericPrecision"] = precision;
290 col["NumericScale"] = scale;
291 col["IsReadOnly"] = !writable;
292 col["BaseTableName"] = tableName;
293 col["AllowDBNull"] = nullable;
294 #endif
298 #endregion // Methods