Merge pull request #2394 from Mailaender/patch-1
[mono.git] / mcs / class / Mono.Data.Tds / Mono.Data.Tds.Protocol / Tds.cs
index 6865df9adbed27a38fcc7d789b427bc682938cb4..5cb0ae8a4ce2ab27e74207542e28e31427e4efe8 100644 (file)
@@ -41,7 +41,9 @@ using System.ComponentModel;
 using System.Diagnostics;
 using System.Net.Sockets;
 using System.Globalization;
+using System.Security;
 using System.Text;
+using System.Runtime.InteropServices;
 
 namespace Mono.Data.Tds.Protocol
 {
@@ -238,13 +240,9 @@ namespace Mono.Data.Tds.Protocol
                                throw new Exception ("Cannot Skip to a colindex less than the curr index");
 
                        while (colIndex != StreamColumnIndex) {
-#if NET_2_0
                                TdsColumnType? colType = Columns[StreamColumnIndex].ColumnType;
                                if (colType == null)
                                        throw new Exception ("Column type unset.");
-#else
-                               TdsColumnType colType = (TdsColumnType) Columns [StreamColumnIndex]["ColumnType"];
-#endif
                                if (!(colType == TdsColumnType.Image ||
                                        colType == TdsColumnType.Text ||
                                        colType == TdsColumnType.NText)) {
@@ -271,11 +269,7 @@ namespace Mono.Data.Tds.Protocol
                        if (colIndex != StreamColumnIndex)
                                SkipToColumnIndex (colIndex);
 
-#if NET_2_0
                        object o = GetColumnValue (Columns[colIndex].ColumnType, false, colIndex);
-#else
-                       object o = GetColumnValue ((TdsColumnType)Columns[colIndex]["ColumnType"], false, colIndex);
-#endif
                        StreamColumnIndex++;
                        return o;
                }
@@ -289,11 +283,7 @@ namespace Mono.Data.Tds.Protocol
                                        SkipToColumnIndex (colIndex);
 
                                if (!LoadInProgress) {
-#if NET_2_0
                                        BeginLoad (Columns[colIndex].ColumnType);
-#else
-                                       BeginLoad ((TdsColumnType)Columns[colIndex]["ColumnType"]);
-#endif
                                }
 
                                if (buffer == null)
@@ -306,11 +296,7 @@ namespace Mono.Data.Tds.Protocol
                }
 
                private void BeginLoad (
-#if NET_2_0
                        TdsColumnType? colType
-#else
-                       TdsColumnType colType
-#endif
                ) 
                {
                        if (LoadInProgress)
@@ -318,10 +304,8 @@ namespace Mono.Data.Tds.Protocol
 
                        StreamLength = 0;
 
-#if NET_2_0
                        if (colType == null)
                                throw new ArgumentNullException ("colType");
-#endif
 
                        switch (colType) {
                        case TdsColumnType.Text :
@@ -755,22 +739,14 @@ namespace Mono.Data.Tds.Protocol
                }
                
                protected object GetColumnValue (
-#if NET_2_0
                        TdsColumnType? colType,
-#else
-                       TdsColumnType colType,
-#endif
                        bool outParam)
                {
                        return GetColumnValue (colType, outParam, -1);
                }
 
                private object GetColumnValue (
-#if NET_2_0
                        TdsColumnType? colType,
-#else
-                       TdsColumnType colType,
-#endif
                        bool outParam, int ordinal)
                {
                        int len;
@@ -778,18 +754,11 @@ namespace Mono.Data.Tds.Protocol
                        Encoding enc = null;
                        int lcid = 0, sortId = 0;
 
-#if NET_2_0
                        if (colType == null)
                                throw new ArgumentNullException ("colType");
-#endif
                        if (ordinal > -1 && tdsVersion > TdsVersion.tds70) {
-#if NET_2_0
                                lcid = (int) columns[ordinal].LCID;
                                sortId = (int) columns[ordinal].SortOrder; 
-#else
-                               lcid = (int) columns[ordinal]["LCID"];
-                               sortId = (int) columns[ordinal]["SortOrder"];
-#endif                         
                        }
                        
                        switch (colType) {
@@ -895,13 +864,8 @@ namespace Mono.Data.Tds.Protocol
                                        scale = comm.GetByte ();
                                }
                                else {
-#if NET_2_0
                                        precision = (byte) columns[ordinal].NumericPrecision;
                                        scale = (byte) columns[ordinal].NumericScale;
-#else
-                                       precision = (byte) columns[ordinal]["NumericPrecision"];
-                                       scale = (byte) columns[ordinal]["NumericScale"];
-#endif
                                }
 
                                element = GetDecimalValue (precision, scale);
@@ -968,6 +932,11 @@ namespace Mono.Data.Tds.Protocol
                                        element = new Guid (guidBytes);
                                }
                                break;
+                       case TdsColumnType.Variant :
+                               if (outParam)
+                                       comm.Skip (4);
+                               element = GetVariantValue();
+                               break;
                        default :
                                return DBNull.Value;
                        }
@@ -992,21 +961,49 @@ namespace Mono.Data.Tds.Protocol
                        return result;
                }
 
+               private object GetVariantValue ()
+               {
+                       uint len = (uint)comm.GetTdsInt ();
+                       if (len == 0)
+                               return DBNull.Value;
+
+                       // VARIANT_BASETYPE
+                       TdsColumnType colType = (TdsColumnType)comm.GetByte ();
+                       // VARIANT_PROPBYTES
+                       byte propbytes = comm.GetByte ();
+                       if (propbytes != 0)
+                               // VARIANT_PROPERTIES
+                               comm.Skip (propbytes);
+
+                       len -= (uint)propbytes + 2;
+
+                       switch (colType)
+                       {
+                       case TdsColumnType.Int1 :
+                       case TdsColumnType.Int2 :
+                       case TdsColumnType.Int4 :
+                       case TdsColumnType.BigInt :
+                               return GetIntValue (colType);
+                       default:
+                               // The old code was ignoring variants
+                               // and returning null.  Should we
+                               // throw an exception?
+                               comm.Skip (len);
+                               break;
+                       }
+
+                       return DBNull.Value;
+               }
+
                private object GetDateTimeValue (
-#if NET_2_0
                        TdsColumnType? type
-#else
-                       TdsColumnType type
-#endif
                )
                {
                        int len = 0;
                        object result;
 
-#if NET_2_0
                        if (type == null)
                                throw new ArgumentNullException ("type");
-#endif
                        switch (type) {
                        case TdsColumnType.DateTime4:
                                len = 4;
@@ -1118,17 +1115,11 @@ namespace Mono.Data.Tds.Protocol
                }
 
                private object GetFloatValue (
-#if NET_2_0
                        TdsColumnType? columnType
-#else
-                       TdsColumnType columnType
-#endif
                )
                {
-#if NET_2_0
                        if (columnType == null)
                                throw new ArgumentNullException ("columnType");
-#endif
                        int columnSize = 0;
 
                        switch (columnType) {
@@ -1170,19 +1161,13 @@ namespace Mono.Data.Tds.Protocol
                }
 
                private object GetIntValue (
-#if NET_2_0
                        TdsColumnType? type
-#else
-                       TdsColumnType type
-#endif
                )
                {
                        int len;
 
-#if NET_2_0
                        if (type == null)
                                throw new ArgumentNullException ("type");
-#endif
                        switch (type) {
                        case TdsColumnType.BigInt :
                                len = 8;
@@ -1218,19 +1203,13 @@ namespace Mono.Data.Tds.Protocol
                }
 
                private object GetMoneyValue (
-#if NET_2_0
                        TdsColumnType? type
-#else
-                       TdsColumnType type
-#endif
                )
                {
                        int len;
 
-#if NET_2_0
                        if (type == null)
                                throw new ArgumentNullException ("type");
-#endif
                        switch (type) {
                        case TdsColumnType.SmallMoney :
                        case TdsColumnType.Money4 :
@@ -1271,11 +1250,7 @@ namespace Mono.Data.Tds.Protocol
                }
 
                protected object GetStringValue (
-#if NET_2_0
                        TdsColumnType? colType,
-#else
-                       TdsColumnType colType,
-#endif
                    bool wideChars, bool outputParam, Encoding encoder)
                {
                        bool shortLen = false;
@@ -1355,7 +1330,7 @@ namespace Mono.Data.Tds.Protocol
                
                internal bool IsBlobType (TdsColumnType columnType)
                {
-                       return (columnType == TdsColumnType.Text || columnType == TdsColumnType.Image || columnType == TdsColumnType.NText);
+                       return (columnType == TdsColumnType.Text || columnType == TdsColumnType.Image || columnType == TdsColumnType.NText || columnType == TdsColumnType.Variant);
                }
 
                internal bool IsLargeType (TdsColumnType columnType)
@@ -1414,11 +1389,7 @@ namespace Mono.Data.Tds.Protocol
 
                        int i = 0;
                        foreach (TdsDataColumn column in columns) {
-#if NET_2_0
                                object o = GetColumnValue (column.ColumnType, false, i);
-#else
-                               object o = GetColumnValue ((TdsColumnType)column["ColumnType"], false, i);
-#endif
                                currentRow.Add (o);
                                if (doneProc)
                                        outputParameters.Add (o);
@@ -1468,7 +1439,7 @@ namespace Mono.Data.Tds.Protocol
                        t3.Domain = this.connectionParms.DefaultDomain;
                        t3.Host = this.connectionParms.Hostname;
                        t3.Username = this.connectionParms.User;
-                       t3.Password = this.connectionParms.Password;
+                       t3.Password = GetPlainPassword(this.connectionParms.Password);
 
                        Comm.StartPacket (TdsPacketType.SspAuth); // 0x11
                        Comm.Append (t3.GetBytes ());
@@ -1512,21 +1483,12 @@ namespace Mono.Data.Tds.Protocol
                                bool isExpression = ((values[2] & (byte) TdsColumnStatus.IsExpression) != 0);
 
                                TdsDataColumn column = columns [index];
-#if NET_2_0
                                column.IsHidden = ((values[2] & (byte) TdsColumnStatus.Hidden) != 0);
                                column.IsExpression = isExpression;
                                column.IsKey = ((values[2] & (byte) TdsColumnStatus.IsKey) != 0);
                                column.IsAliased = isAlias;
                                column.BaseColumnName = ((isAlias) ? baseColumnName : null);
                                column.BaseTableName = ((!isExpression) ? (string) tableNames [tableIndex] : null);
-#else
-                               column ["IsHidden"] = ((values [2] & (byte) TdsColumnStatus.Hidden) != 0);
-                               column ["IsExpression"] = isExpression;
-                               column ["IsKey"] = ((values [2] & (byte) TdsColumnStatus.IsKey) != 0);
-                               column ["IsAliased"] = isAlias;
-                               column ["BaseColumnName"] = ((isAlias) ? baseColumnName : null);
-                               column ["BaseTableName"] = ((!isExpression) ? tableNames [tableIndex] : null);
-#endif
                        }
                }
 
@@ -1919,9 +1881,22 @@ namespace Mono.Data.Tds.Protocol
                        comm.Skip(4);
                }
 
+               public static string GetPlainPassword(SecureString secPass)
+               {
+                       IntPtr plainString = IntPtr.Zero;
+                       try
+                       {
+                               plainString = Marshal.SecureStringToGlobalAllocUnicode(secPass);
+                               return Marshal.PtrToStringUni(plainString);
+                       }
+                       finally
+                       {
+                               Marshal.ZeroFreeGlobalAllocUnicode(plainString);
+                       }
+               }
+
                #endregion // Private Methods
 
-#if NET_2_0
                 #region asynchronous methods
                 protected IAsyncResult BeginExecuteQueryInternal (string sql, bool wantResults, 
                                                           AsyncCallback callback, object state)
@@ -2032,7 +2007,6 @@ namespace Mono.Data.Tds.Protocol
                 }
 
                 #endregion // asynchronous methods
-#endif // NET_2_0
 
 
        }