2 // Mono.Data.TdsClient.Internal.Tds42.cs
5 // Tim Coleman (tim@timcoleman.com)
7 // Copyright (C) 2002 Tim Coleman
11 using System.Data.Common;
13 namespace Mono.Data.TdsClient.Internal {
14 internal class Tds42 : Tds, ITds
18 public static readonly TdsVersion Version = TdsVersion.tds42;
24 public Tds42 (string server, int port)
25 : this (server, port, 512)
29 public Tds42 (string server, int port, int packetSize)
30 : base (server, port, packetSize, Version)
34 #endregion // Constructors
38 public override bool Connect (TdsConnectionParameters connectionParameters)
41 throw new InvalidOperationException ("The connection is already open.");
43 SetCharset (connectionParameters.Charset);
44 SetLanguage (connectionParameters.Language);
47 byte[] empty = new byte[0];
50 Comm.StartPacket (TdsPacketType.Logon);
52 // hostname (offset 0)
53 byte[] tmp = Comm.Append (connectionParameters.Hostname, 30, pad);
54 Comm.Append ((byte) (tmp.Length < 30 ? tmp.Length : 30));
56 // username (offset 31 0x1f)
57 tmp = Comm.Append (connectionParameters.User, 30, pad);
58 Comm.Append ((byte) (tmp.Length < 30 ? tmp.Length : 30));
60 // password (offset 62 0x3e)
61 tmp = Comm.Append (connectionParameters.Password, 30, pad);
62 Comm.Append ((byte) (tmp.Length < 30 ? tmp.Length : 30));
64 // hostproc (offset 93 0x5d)
65 Comm.Append ("00000116", 8, pad);
67 // unused (offset 109 0x6d)
68 Comm.Append (empty, (30-14), pad);
71 Comm.Append ((byte) 0x0);
72 Comm.Append ((byte) 0xa0);
73 Comm.Append ((byte) 0x24);
74 Comm.Append ((byte) 0xcc);
75 Comm.Append ((byte) 0x50);
76 Comm.Append ((byte) 0x12);
79 Comm.Append ((byte) 8);
81 // Byte order of 2 byte ints
82 // 2 = <MSB, LSB>, 3 = <LSB, MSB>
83 Comm.Append ((byte) 3);
85 // Byte order of 4 byte ints
86 // 0 = <MSB, LSB>, 1 = <LSB, MSB>
87 Comm.Append ((byte) 1);
89 // Character representation
90 // (6 = ASCII, 7 = EBCDIC)
91 Comm.Append ((byte) 6);
93 // Eight byte floating point representation
94 // 4 = IEEE <MSB, ..., LSB>
96 // 10 = IEEE <LSB, ..., MSB>
98 Comm.Append ((byte) 10);
100 // Eight byte date format
101 // 8 = <MSB, ..., LSB>
102 Comm.Append ((byte) 9);
105 Comm.Append ((byte) 1);
107 // disallow dump/load and bulk insert
108 Comm.Append ((byte) 1);
110 // sql interface type
111 Comm.Append ((byte) 0);
113 // type of network connection
114 Comm.Append ((byte) 0);
118 Comm.Append (empty, 7, pad);
120 tmp = Comm.Append (connectionParameters.ApplicationName, 30, pad);
121 Comm.Append ((byte) (tmp.Length < 30 ? tmp.Length : 30));
124 tmp = Comm.Append (DataSource, 30, pad);
125 Comm.Append ((byte) (tmp.Length < 30 ? tmp.Length : 30));
128 Comm.Append (empty, 2, pad);
129 tmp = Comm.Append (connectionParameters.Password, 253, pad);
130 Comm.Append ((byte) (tmp.Length < 253 ? tmp.Length + 2 : 253 + 2));
133 Comm.Append ((byte) (((byte) Version) / 10));
134 Comm.Append ((byte) (((byte) Version) % 10));
135 Comm.Append ((byte) 0);
136 Comm.Append ((byte) 0);
139 tmp = Comm.Append (connectionParameters.ProgName, 10, pad);
140 Comm.Append ((byte) (tmp.Length < 10 ? tmp.Length : 10));
143 Comm.Append ((byte) 6);
145 // Tell the server we can handle SQLServer version 6
146 Comm.Append ((byte) 0);
148 // Send zero to tell the server we can't handle any other version
149 Comm.Append ((byte) 0);
150 Comm.Append ((byte) 0);
152 // auto convert short
153 Comm.Append ((byte) 0);
156 Comm.Append ((byte) 0x0d);
159 Comm.Append ((byte) 0x11);
162 tmp = Comm.Append (Language, 30, pad);
163 Comm.Append ((byte) (tmp.Length < 30 ? tmp.Length : 30));
165 // notify on lang change
166 Comm.Append ((byte) 1);
168 // security label hierarchy
169 Comm.Append ((short) 0);
171 // security components
172 Comm.Append (empty, 8, pad);
175 Comm.Append ((short) 0);
177 // security login role
178 Comm.Append ((byte) 0);
181 tmp = Comm.Append (Charset, 30, pad);
182 Comm.Append ((byte) (tmp.Length < 30 ? tmp.Length : 30));
184 // notify on charset change
185 Comm.Append ((byte) 1);
187 // length of tds packets
188 tmp = Comm.Append (PacketSize.ToString (), 6, pad);
189 Comm.Append ((byte) 3);
191 // pad out to a longword
192 Comm.Append (empty, 8, pad);
196 TdsPacketResult result;
198 while (!((result = ProcessSubPacket()) is TdsPacketEndTokenResult)) {
199 if (result is TdsPacketErrorResult) {
203 // XXX Should really process some more types of packets.
206 // XXX Possible bug. What happend if this is cancelled before the logon
207 // takes place? Should isOkay be false?
209 IsConnected = isOkay;
213 protected override TdsPacketColumnInfoResult ProcessColumnInfo ()
217 int totalLength = Comm.GetTdsShort ();
220 TdsPacketColumnInfoResult result = new TdsPacketColumnInfoResult ();
222 while (bytesRead < totalLength) {
228 byte[] flagData = new byte[4];
229 for (int i = 0; i < 4; i += 1) {
230 flagData[i] = Comm.GetByte ();
233 bool nullable = (flagData[2] & 0x01) > 0;
234 bool caseSensitive = (flagData[2] & 0x02) > 0;
235 bool writable = (flagData[2] & 0x0c) > 0;
236 bool autoIncrement = (flagData[2] & 0x10) > 0;
238 string tableName = String.Empty;
239 TdsColumnType columnType = (TdsColumnType) Comm.GetByte ();
243 if (columnType == TdsColumnType.Text || columnType == TdsColumnType.Image) {
247 int tableNameLength = Comm.GetTdsShort ();
249 tableName = Comm.GetString (tableNameLength);
250 bytesRead += tableNameLength;
251 bufLength = 2 << 31 - 1;
253 else if (columnType == TdsColumnType.Decimal || columnType == TdsColumnType.Numeric) {
254 bufLength = Comm.GetByte ();
256 precision = Comm.GetByte ();
258 scale = Comm.GetByte ();
261 else if (IsFixedSizeColumn (columnType))
262 bufLength = LookupBufferSize (columnType);
264 bufLength = (int) Comm.GetByte () & 0xff;
268 int index = result.Add (new TdsSchemaInfo ());
269 result[index].NumericPrecision = precision;
270 result[index].NumericScale = scale;
271 result[index].ColumnSize = bufLength;
272 result[index].ColumnName = ColumnNames[index];
273 result[index].ColumnType = columnType;
274 result[index].BaseTableName = tableName;
275 result[index].AllowDBNull = nullable;
276 result[index].IsReadOnly = !writable;
279 //int skipLength = totalLength - bytesRead;
280 //if (skipLength != 0)
281 //throw new TdsException ("skipping");
286 #endregion // Methods