2 // Mono.Data.Tds.Protocol.Tds42.cs
5 // Tim Coleman (tim@timcoleman.com)
7 // Copyright (C) 2002 Tim Coleman
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:
19 // The above copyright notice and this permission notice shall be
20 // included in all copies or substantial portions of the Software.
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.
32 using System
.Security
;
34 namespace Mono
.Data
.Tds
.Protocol
{
35 public sealed class Tds42
: Tds
39 public static readonly TdsVersion Version
= TdsVersion
.tds42
;
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
59 public override bool Connect (TdsConnectionParameters connectionParameters
)
62 throw new InvalidOperationException ("The connection is already open.");
64 SetCharset (connectionParameters
.Charset
);
65 SetLanguage (connectionParameters
.Language
);
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
);
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);
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>
116 // 10 = IEEE <LSB, ..., MSB>
118 Comm
.Append ((byte) 10);
120 // Eight byte date format
121 // 8 = <MSB, ..., LSB>
122 Comm
.Append ((byte) 9);
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);
138 Comm
.Append (empty
, 7, pad
);
140 tmp
= Comm
.Append (connectionParameters
.ApplicationName
, 30, pad
);
141 Comm
.Append ((byte) (tmp
.Length
< 30 ? tmp
.Length
: 30));
144 tmp
= Comm
.Append (DataSource
, 30, pad
);
145 Comm
.Append ((byte) (tmp
.Length
< 30 ? tmp
.Length
: 30));
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));
153 Comm
.Append ((byte) (((byte) Version
) / 10));
154 Comm
.Append ((byte) (((byte) Version
) % 10));
155 Comm
.Append ((byte) 0);
156 Comm
.Append ((byte) 0);
159 tmp
= Comm
.Append (connectionParameters
.ProgName
, 10, pad
);
160 Comm
.Append ((byte) (tmp
.Length
< 10 ? tmp
.Length
: 10));
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);
176 Comm
.Append ((byte) 0x0d);
179 Comm
.Append ((byte) 0x11);
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
);
195 Comm
.Append ((short) 0);
197 // security login role
198 Comm
.Append ((byte) 0);
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
);
222 protected override void ProcessColumnInfo ()
226 int totalLength
= Comm
.GetTdsShort ();
229 while (bytesRead
< totalLength
) {
234 byte[] flagData
= new byte[4];
235 for (int i
= 0; i
< 4; i
+= 1) {
236 flagData
[i
] = Comm
.GetByte ();
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 ();
249 if (columnType
== TdsColumnType
.Text
|| columnType
== TdsColumnType
.Image
) {
253 int tableNameLength
= Comm
.GetTdsShort ();
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 ();
262 precision
= Comm
.GetByte ();
264 scale
= Comm
.GetByte ();
267 else if (IsFixedSizeColumn (columnType
))
268 bufLength
= LookupBufferSize (columnType
);
270 bufLength
= (int) Comm
.GetByte () & 0xff;
274 TdsDataColumn col
= new TdsDataColumn ();
275 int index
= Columns
.Add (col
);
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
;
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
;
298 #endregion // Methods