1 //------------------------------------------------------------------------------ 2 // <copyright file="TdsEnums.cs" company="Microsoft"> 3 // Copyright (c) Microsoft Corporation. All rights reserved. 4 // </copyright> 5 // <owner current="true" primary="true">Microsoft</owner> 6 // <owner current="true" primary="false">Microsoft</owner> 7 //------------------------------------------------------------------------------ 8 9 namespace System.Data.SqlClient { 10 using System; 11 using System.Diagnostics; 12 13 /// <devdoc> Class of variables for the Tds connection. 14 /// </devdoc> 15 internal static class TdsEnums { 16 17 // internal tdsparser constants 18 19 public const short SQL_SERVER_VERSION_SEVEN = 7; 20 21 public const string SQL_PROVIDER_NAME = Common.DbConnectionStringDefaults.ApplicationName; 22 23 public static readonly Decimal SQL_SMALL_MONEY_MIN = new Decimal(-214748.3648); 24 public static readonly Decimal SQL_SMALL_MONEY_MAX = new Decimal(214748.3647); 25 26 // sql debugging constants, sdci is the structure passed in 27 public const string SDCI_MAPFILENAME = "SqlClientSSDebug"; 28 public const byte SDCI_MAX_MACHINENAME = 32; 29 public const byte SDCI_MAX_DLLNAME = 16; 30 public const byte SDCI_MAX_DATA = 255; 31 public const int SQLDEBUG_OFF = 0; 32 public const int SQLDEBUG_ON = 1; 33 public const int SQLDEBUG_CONTEXT = 2; 34 public const string SP_SDIDEBUG = "sp_sdidebug"; 35 public static readonly string[] SQLDEBUG_MODE_NAMES = new string[3] { 36 "off", 37 "on", 38 "context" 39 }; 40 41 // HACK!!! 42 // Constant for SqlDbType.SmallVarBinary... store internal variable here instead of on 43 // SqlDbType so that it is not surfaced to the user!!! Related to dtc and the fact that 44 // the TransactionManager TDS stream is the only token left that uses VarBinarys instead of 45 // BigVarBinarys. 46 public const SqlDbType SmallVarBinary = (SqlDbType) (SqlDbType.Variant)+1; 47 48 // network protocol string constants 49 public const string TCP = "tcp"; 50 public const string NP = "np"; 51 public const string RPC = "rpc"; 52 public const string BV = "bv"; 53 public const string ADSP = "adsp"; 54 public const string SPX = "spx"; 55 public const string VIA = "via"; 56 public const string LPC = "lpc"; 57 58 // network function string contants 59 public const string INIT_SSPI_PACKAGE = "InitSSPIPackage"; 60 public const string INIT_ADAL_PACKAGE = "InitADALPackage"; 61 public const string INIT_SESSION = "InitSession"; 62 public const string CONNECTION_GET_SVR_USER = "ConnectionGetSvrUser"; 63 public const string GEN_CLIENT_CONTEXT = "GenClientContext"; 64 65 // tdsparser packet handling constants 66 public const byte SOFTFLUSH = 0; 67 public const byte HARDFLUSH = 1; 68 public const byte IGNORE = 2; 69 70 // header constants 71 public const int HEADER_LEN = 8; 72 public const int HEADER_LEN_FIELD_OFFSET = 2; 73 public const int YUKON_HEADER_LEN = 12; //Yukon headers also include a MARS session id 74 public const int MARS_ID_OFFSET = 8; 75 public const int HEADERTYPE_QNOTIFICATION = 1; 76 public const int HEADERTYPE_MARS = 2; 77 public const int HEADERTYPE_TRACE = 3; 78 79 // other various constants 80 public const int SUCCEED = 1; 81 public const int FAIL = 0; 82 public const short TYPE_SIZE_LIMIT = 8000; 83 public const int MIN_PACKET_SIZE = 512; 84 // Login packet can be no greater than 4k until server sends us env-change 85 // increasing packet size. 86 public const int DEFAULT_LOGIN_PACKET_SIZE = 4096; 87 public const int MAX_PRELOGIN_PAYLOAD_LENGTH = 1024; 88 public const int MAX_PACKET_SIZE = 32768; 89 public const int MAX_SERVER_USER_NAME = 256; // obtained from luxor 90 91 // Severity 0 - 10 indicates informational (non-error) messages 92 // Severity 11 - 16 indicates errors that can be corrected by user (syntax errors, etc...) 93 // Severity 17 - 19 indicates failure due to insufficient resources in the server 94 // (max locks exceeded, not enough memory, other internal server limits reached, etc..) 95 // Severity 20 - 25 Severe problems with the server, connection terminated. 96 public const byte MIN_ERROR_CLASS = 11; // webdata 100667: This should actually be 11 97 public const byte MAX_USER_CORRECTABLE_ERROR_CLASS = 16; 98 public const byte FATAL_ERROR_CLASS = 20; 99 100 // Message types 101 public const byte MT_SQL = 1; // SQL command batch 102 public const byte MT_LOGIN = 2; // Login message for pre-Sphinx (before version 7.0) 103 public const byte MT_RPC = 3; // Remote procedure call 104 public const byte MT_TOKENS = 4; // Table response data stream 105 public const byte MT_BINARY = 5; // Unformatted binary response data (UNUSED) 106 public const byte MT_ATTN = 6; // Attention (break) signal 107 public const byte MT_BULK = 7; // Bulk load data 108 public const byte MT_FEDAUTH = 8; // Authentication token for federated authentication 109 public const byte MT_CLOSE = 9; // Close subchannel (UNUSED) 110 public const byte MT_ERROR = 10; // Protocol error detected 111 public const byte MT_ACK = 11; // Protocol acknowledgement (UNUSED) 112 public const byte MT_ECHO = 12; // Echo data (UNUSED) 113 public const byte MT_LOGOUT = 13; // Logout message (UNUSED) 114 public const byte MT_TRANS = 14; // Transaction Manager Interface 115 public const byte MT_OLEDB = 15; // ? (UNUSED) 116 public const byte MT_LOGIN7 = 16; // Login message for Sphinx (version 7) or later 117 public const byte MT_SSPI = 17; // SSPI message 118 public const byte MT_PRELOGIN = 18; // Pre-login handshake 119 120 // Message status bits 121 public const byte ST_EOM = 0x1; // Packet is end-of-message 122 public const byte ST_AACK = 0x2; // Packet acknowledges attention (server to client) 123 public const byte ST_IGNORE = 0x2; // Ignore this event (client to server) 124 public const byte ST_BATCH = 0x4; // Message is part of a batch. 125 public const byte ST_RESET_CONNECTION = 0x8; // Exec sp_reset_connection prior to processing message 126 public const byte ST_RESET_CONNECTION_PRESERVE_TRANSACTION = 0x10; // reset prior to processing, with preserving local tx 127 128 // TDS control tokens 129 public const byte SQLCOLFMT = 0xa1; 130 public const byte SQLPROCID = 0x7c; 131 public const byte SQLCOLNAME = 0xa0; 132 public const byte SQLTABNAME = 0xa4; 133 public const byte SQLCOLINFO = 0xa5; 134 public const byte SQLALTNAME = 0xa7; 135 public const byte SQLALTFMT = 0xa8; 136 public const byte SQLERROR = 0xaa; 137 public const byte SQLINFO = 0xab; 138 public const byte SQLRETURNVALUE = 0xac; 139 public const byte SQLRETURNSTATUS = 0x79; 140 public const byte SQLRETURNTOK = 0xdb; 141 public const byte SQLALTCONTROL = 0xaf; 142 public const byte SQLROW = 0xd1; 143 public const byte SQLNBCROW = 0xd2; // same as ROW with null-bit-compression support 144 public const byte SQLALTROW = 0xd3; 145 public const byte SQLDONE = 0xfd; 146 public const byte SQLDONEPROC = 0xfe; 147 public const byte SQLDONEINPROC = 0xff; 148 public const byte SQLOFFSET = 0x78; 149 public const byte SQLORDER = 0xa9; 150 public const byte SQLDEBUG_CMD = 0x60; 151 public const byte SQLLOGINACK = 0xad; 152 public const byte SQLFEATUREEXTACK= 0xae; // TDS 7.4 - feature ack 153 public const byte SQLSESSIONSTATE = 0xe4; // TDS 7.4 - connection resiliency session state 154 public const byte SQLENVCHANGE = 0xe3; // Environment change notification 155 public const byte SQLSECLEVEL = 0xed; // Security level token ??? 156 public const byte SQLROWCRC = 0x39; // ROWCRC datastream??? 157 public const byte SQLCOLMETADATA = 0x81; // Column metadata including name 158 public const byte SQLALTMETADATA = 0x88; // Alt column metadata including name 159 public const byte SQLSSPI = 0xed; // SSPI data 160 public const byte SQLFEDAUTHINFO = 0xee; // Info for client to generate fed auth token 161 162 // Environment change notification streams 163 // TYPE on TDS ENVCHANGE token stream (from sql\ntdbms\include\odsapi.h) 164 // 165 public const byte ENV_DATABASE = 1; // Database changed 166 public const byte ENV_LANG = 2; // Language changed 167 public const byte ENV_CHARSET = 3; // Character set changed 168 public const byte ENV_PACKETSIZE = 4; // Packet size changed 169 public const byte ENV_LOCALEID = 5; // Unicode data sorting locale id 170 public const byte ENV_COMPFLAGS = 6; // Unicode data sorting comparison flags 171 public const byte ENV_COLLATION = 7; // SQL Collation 172 // The following are environment change tokens valid for Yukon or later. 173 public const byte ENV_BEGINTRAN = 8; // Transaction began 174 public const byte ENV_COMMITTRAN = 9; // Transaction committed 175 public const byte ENV_ROLLBACKTRAN = 10; // Transaction rolled back 176 public const byte ENV_ENLISTDTC = 11; // Enlisted in Distributed Transaction 177 public const byte ENV_DEFECTDTC = 12; // Defected from Distributed Transaction 178 public const byte ENV_LOGSHIPNODE = 13; // Realtime Log shipping primary node 179 public const byte ENV_PROMOTETRANSACTION = 15; // Promote Transaction 180 public const byte ENV_TRANSACTIONMANAGERADDRESS = 16; // Transaction Manager Address 181 public const byte ENV_TRANSACTIONENDED = 17; // Transaction Ended 182 public const byte ENV_SPRESETCONNECTIONACK = 18; // SP_Reset_Connection ack 183 public const byte ENV_USERINSTANCE = 19; // User Instance 184 public const byte ENV_ROUTING = 20; // Routing (ROR) information 185 186 // done status stream bit masks 187 public const int DONE_MORE = 0x0001; // more command results coming 188 public const int DONE_ERROR = 0x0002; // error in command batch 189 public const int DONE_INXACT = 0x0004; // transaction in progress 190 public const int DONE_PROC = 0x0008; // done from stored proc 191 public const int DONE_COUNT = 0x0010; // count in done info 192 public const int DONE_ATTN = 0x0020; // oob ack 193 public const int DONE_INPROC = 0x0040; // like DONE_PROC except proc had error 194 public const int DONE_RPCINBATCH = 0x0080; // Done from RPC in batch 195 public const int DONE_SRVERROR = 0x0100; // Severe error in which resultset should be discarded 196 public const int DONE_FMTSENT = 0x8000; // fmt message sent, done_inproc req'd 197 198 // Feature Extension 199 public const byte FEATUREEXT_TERMINATOR = 0xFF; 200 public const byte FEATUREEXT_SRECOVERY = 0x01; 201 public const byte FEATUREEXT_FEDAUTH = 0x02; 202 public const byte FEATUREEXT_TCE = 0x04; 203 public const byte FEATUREEXT_GLOBALTRANSACTIONS = 0x05; 204 205 [Flags] 206 public enum FeatureExtension:uint { 207 None=0, 208 SessionRecovery=1, 209 FedAuth=2, 210 Tce=4, 211 GlobalTransactions = 8, 212 } 213 214 public const byte FEDAUTHLIB_LIVEID = 0X00; 215 public const byte FEDAUTHLIB_SECURITYTOKEN = 0x01; 216 public const byte FEDAUTHLIB_ADAL = 0x02; 217 public const byte FEDAUTHLIB_RESERVED = 0X7F; 218 219 public enum FedAuthLibrary:byte { 220 LiveId=FEDAUTHLIB_LIVEID, 221 SecurityToken=FEDAUTHLIB_SECURITYTOKEN, 222 ADAL=FEDAUTHLIB_ADAL, 223 Default=FEDAUTHLIB_RESERVED 224 } 225 226 public const byte ADALWORKFLOW_ACTIVEDIRECTORYPASSWORD = 0x01; 227 public const byte ADALWORKFLOW_ACTIVEDIRECTORYINTEGRATED = 0x02; 228 229 public enum ActiveDirectoryWorkflow : byte { 230 Password=ADALWORKFLOW_ACTIVEDIRECTORYPASSWORD, 231 Integrated=ADALWORKFLOW_ACTIVEDIRECTORYINTEGRATED, 232 } 233 234 // The string used for username in the error message when Authentication = Active Directory Integrated with FedAuth is used, if authentication fails. 235 public const string NTAUTHORITYANONYMOUSLOGON = @"NT Authority\Anonymous Logon"; 236 237 // Loginrec defines 238 public const byte MAX_LOG_NAME = 30; // TDS 4.2 login rec max name length 239 public const byte MAX_PROG_NAME = 10; // max length of loginrec progran name 240 public const byte SEC_COMP_LEN = 8; // length of security compartments 241 public const byte MAX_PK_LEN = 6; // max length of TDS packet size 242 public const byte MAX_NIC_SIZE = 6; // The size of a MAC or client address 243 public const byte SQLVARIANT_SIZE = 2; // size of the fixed portion of a sql variant (type, cbPropBytes) 244 public const byte VERSION_SIZE = 4; // size of the tds version (4 unsigned bytes) 245 public const int CLIENT_PROG_VER = 0x06000000; // Client interface version 246 public const int YUKON_LOG_REC_FIXED_LEN = 0x5e; 247 // misc 248 public const int TEXT_TIME_STAMP_LEN = 8; 249 public const int COLLATION_INFO_LEN = 4; 250 251 /* 252 public const byte INT4_LSB_HI = 0; // lsb is low byte (eg 68000) 253 // public const byte INT4_LSB_LO = 1; // lsb is low byte (eg VAX) 254 public const byte INT2_LSB_HI = 2; // lsb is low byte (eg 68000) 255 // public const byte INT2_LSB_LO = 3; // lsb is low byte (eg VAX) 256 public const byte FLT_IEEE_HI = 4; // lsb is low byte (eg 68000) 257 public const byte CHAR_ASCII = 6; // ASCII character set 258 public const byte TWO_I4_LSB_HI = 8; // lsb is low byte (eg 68000 259 // public const byte TWO_I4_LSB_LO = 9; // lsb is low byte (eg VAX) 260 // public const byte FLT_IEEE_LO = 10; // lsb is low byte (eg MSDOS) 261 public const byte FLT4_IEEE_HI = 12; // IEEE 4-byte floating point -lsb is high byte 262 // public const byte FLT4_IEEE_LO = 13; // IEEE 4-byte floating point -lsb is low byte 263 public const byte TWO_I2_LSB_HI = 16; // lsb is high byte 264 // public const byte TWO_I2_LSB_LO = 17; // lsb is low byte 265 266 public const byte LDEFSQL = 0; // server sends its default 267 public const byte LDEFUSER = 0; // regular old user 268 public const byte LINTEGRATED = 8; // integrated security login 269 */ 270 271 /* Versioning scheme table: 272 273 Client sends: 274 0x70000000 -> Sphinx 275 0x71000000 -> Shiloh RTM 276 0x71000001 -> Shiloh SP1 277 0x72xx0002 -> Yukon RTM 278 279 Server responds: 280 0x07000000 -> Sphinx // Notice server response format is different for bwd compat 281 0x07010000 -> Shiloh RTM // Notice server response format is different for bwd compat 282 0x71000001 -> Shiloh SP1 283 0x72xx0002 -> Yukon RTM 284 */ 285 286 // Pre Shiloh SP1 versioning scheme: 287 public const int SPHINXORSHILOH_MAJOR = 0x07; // The high byte (b3) is not sufficient to distinguish 288 public const int SPHINX_INCREMENT = 0x00; // Sphinx and Shiloh 289 public const int SHILOH_INCREMENT = 0x01; // So we need to look at the high-mid byte (b2) as well 290 public const int DEFAULT_MINOR = 0x0000; 291 292 // Shiloh SP1 and beyond versioning scheme: 293 294 // Majors: 295 public const int SHILOHSP1_MAJOR = 0x71; // For Shiloh SP1 and later the versioning schema changed and 296 public const int YUKON_MAJOR = 0x72; // the high-byte is sufficient to distinguish later versions 297 public const int KATMAI_MAJOR = 0x73; 298 public const int DENALI_MAJOR = 0x74; 299 300 // Increments: 301 public const int SHILOHSP1_INCREMENT = 0x00; 302 public const int YUKON_INCREMENT = 0x09; 303 public const int KATMAI_INCREMENT = 0x0b; 304 public const int DENALI_INCREMENT = 0x00; 305 306 // Minors: 307 public const int SHILOHSP1_MINOR = 0x0001; 308 public const int YUKON_RTM_MINOR = 0x0002; 309 public const int KATMAI_MINOR = 0x0003; 310 public const int DENALI_MINOR = 0x0004; 311 312 public const int ORDER_68000 = 1; 313 public const int USE_DB_ON = 1; 314 public const int INIT_DB_FATAL = 1; 315 public const int SET_LANG_ON = 1; 316 public const int INIT_LANG_FATAL = 1; 317 public const int ODBC_ON = 1; 318 public const int SSPI_ON = 1; 319 public const int REPL_ON = 3; 320 321 322 // send the read-only intent to the server 323 public const int READONLY_INTENT_ON = 1; 324 325 // Token masks 326 public const byte SQLLenMask = 0x30; // mask to check for length tokens 327 public const byte SQLFixedLen = 0x30; // Mask to check for fixed token 328 public const byte SQLVarLen = 0x20; // Value to check for variable length token 329 public const byte SQLZeroLen = 0x10; // Value to check for zero length token 330 public const byte SQLVarCnt = 0x00; // Value to check for variable count token 331 332 // Token masks for COLINFO status 333 public const byte SQLDifferentName = 0x20; // column name different than select list name 334 public const byte SQLExpression = 0x4; // column was result of an expression 335 public const byte SQLKey = 0x8; // column is part of the key for the table 336 public const byte SQLHidden = 0x10; // column not part of select list but added because part of key 337 338 // Token masks for COLMETADATA flags 339 // first byte 340 public const byte Nullable = 0x1; 341 public const byte Identity = 0x10; 342 public const byte Updatability = 0xb; // mask off bits 3 and 4 343 // second byte 344 public const byte ClrFixedLen = 0x1; // Fixed length CLR type 345 public const byte IsColumnSet = 0x4; // Column is an XML representation of an aggregation of other columns 346 public const byte IsEncrypted = 0x8; // Column is encrypted using TCE 347 348 // null values 349 public const uint VARLONGNULL = 0xffffffff; // null value for text and image types 350 public const int VARNULL = 0xffff; // null value for character and binary types 351 public const int MAXSIZE = 8000; // max size for any column 352 public const byte FIXEDNULL = 0; 353 public const UInt64 UDTNULL = 0xffffffffffffffff; 354 355 // SQL Server Data Type Tokens. 356 public const int SQLVOID = 0x1f; 357 public const int SQLTEXT = 0x23; 358 public const int SQLVARBINARY = 0x25; 359 public const int SQLINTN = 0x26; 360 public const int SQLVARCHAR = 0x27; 361 public const int SQLBINARY = 0x2d; 362 public const int SQLIMAGE = 0x22; 363 public const int SQLCHAR = 0x2f; 364 public const int SQLINT1 = 0x30; 365 public const int SQLBIT = 0x32; 366 public const int SQLINT2 = 0x34; 367 public const int SQLINT4 = 0x38; 368 public const int SQLMONEY = 0x3c; 369 public const int SQLDATETIME = 0x3d; 370 public const int SQLFLT8 = 0x3e; 371 public const int SQLFLTN = 0x6d; 372 public const int SQLMONEYN = 0x6e; 373 public const int SQLDATETIMN = 0x6f; 374 public const int SQLFLT4 = 0x3b; 375 public const int SQLMONEY4 = 0x7a; 376 public const int SQLDATETIM4 = 0x3a; 377 public const int SQLDECIMALN = 0x6a; 378 public const int SQLNUMERICN = 0x6c; 379 public const int SQLUNIQUEID = 0x24; 380 public const int SQLBIGCHAR = 0xaf; 381 public const int SQLBIGVARCHAR = 0xa7; 382 public const int SQLBIGBINARY = 0xad; 383 public const int SQLBIGVARBINARY = 0xa5; 384 public const int SQLBITN = 0x68; 385 public const int SQLNCHAR = 0xef; 386 public const int SQLNVARCHAR = 0xe7; 387 public const int SQLNTEXT = 0x63; 388 public const int SQLUDT = 0xF0; 389 390 // aggregate operator type TDS tokens, used by compute statements: 391 public const int AOPCNTB = 0x09; 392 public const int AOPSTDEV = 0x30; 393 public const int AOPSTDEVP = 0x31; 394 public const int AOPVAR = 0x32; 395 public const int AOPVARP = 0x33; 396 397 public const int AOPCNT = 0x4b; 398 public const int AOPSUM = 0x4d; 399 public const int AOPAVG = 0x4f; 400 public const int AOPMIN = 0x51; 401 public const int AOPMAX = 0x52; 402 public const int AOPANY = 0x53; 403 public const int AOPNOOP = 0x56; 404 405 // SQL Server user-defined type tokens we care about 406 public const int SQLTIMESTAMP = 0x50; 407 408 public const int MAX_NUMERIC_LEN = 0x11; // 17 bytes of data for max numeric/decimal length 409 public const int DEFAULT_NUMERIC_PRECISION = 0x1D; // 29 is the default max numeric precision(Decimal.MaxValue) if not user set 410 public const int SPHINX_DEFAULT_NUMERIC_PRECISION = 0x1C; // 28 is the default max numeric precision for Sphinx(Decimal.MaxValue doesn't work for sphinx) 411 public const int MAX_NUMERIC_PRECISION = 0x26; // 38 is max numeric precision; 412 public const byte UNKNOWN_PRECISION_SCALE = 0xff; // -1 is value for unknown precision or scale 413 414 // The following datatypes are specific to SHILOH (version 8) and later. 415 public const int SQLINT8 = 0x7f; 416 public const int SQLVARIANT = 0x62; 417 418 // The following datatypes are specific to Yukon (version 9) or later 419 public const int SQLXMLTYPE = 0xf1; 420 public const int XMLUNICODEBOM = 0xfeff; 421 public static readonly byte[] XMLUNICODEBOMBYTES = { 0xff, 0xfe }; 422 423 // The following datatypes are specific to Katmai (version 10) or later 424 public const int SQLTABLE = 0xf3; 425 public const int SQLDATE = 0x28; 426 public const int SQLTIME = 0x29; 427 public const int SQLDATETIME2 = 0x2a; 428 public const int SQLDATETIMEOFFSET = 0x2b; 429 430 public const int DEFAULT_VARTIME_SCALE = 7; 431 432 //Partially length prefixed datatypes constants. These apply to XMLTYPE, BIGVARCHRTYPE, 433 // NVARCHARTYPE, and BIGVARBINTYPE. Valid for Yukon or later 434 435 public const ulong SQL_PLP_NULL = 0xffffffffffffffff; // Represents null value 436 public const ulong SQL_PLP_UNKNOWNLEN = 0xfffffffffffffffe; // Data coming in chunks, total length unknown 437 public const int SQL_PLP_CHUNK_TERMINATOR = 0x00000000; // Represents end of chunked data. 438 public const ushort SQL_USHORTVARMAXLEN = 0xffff; // Second ushort in TDS stream is this value if one of max types 439 440 // TVPs require some new in-value control tokens: 441 public const byte TVP_ROWCOUNT_ESTIMATE = 0x12; 442 public const byte TVP_ROW_TOKEN = 0x01; 443 public const byte TVP_END_TOKEN = 0x00; 444 public const ushort TVP_NOMETADATA_TOKEN = 0xFFFF; 445 public const byte TVP_ORDER_UNIQUE_TOKEN = 0x10; 446 447 // TvpColumnMetaData flags 448 public const int TVP_DEFAULT_COLUMN = 0x200; 449 450 // TVP_ORDER_UNIQUE_TOKEN flags 451 public const byte TVP_ORDERASC_FLAG = 0x1; 452 public const byte TVP_ORDERDESC_FLAG = 0x2; 453 public const byte TVP_UNIQUE_FLAG = 0x4; 454 455 public const bool Is68K = false; 456 public const bool TraceTDS = false; 457 458 // RPC function names 459 public const string SP_EXECUTESQL = "sp_executesql"; // used against 7.0 servers 460 public const string SP_PREPEXEC = "sp_prepexec"; // used against 7.5 servers 461 462 public const string SP_PREPARE = "sp_prepare"; // used against 7.0 servers 463 public const string SP_EXECUTE = "sp_execute"; 464 public const string SP_UNPREPARE = "sp_unprepare"; 465 public const string SP_PARAMS = "sp_procedure_params_rowset"; 466 public const string SP_PARAMS_MANAGED = "sp_procedure_params_managed"; 467 public const string SP_PARAMS_MGD10 = "sp_procedure_params_100_managed"; 468 469 // RPC ProcID's 470 // NOTE: It is more efficient to call these procs using ProcID's instead of names 471 public const ushort RPC_PROCID_CURSOR = 1; 472 public const ushort RPC_PROCID_CURSOROPEN = 2; 473 public const ushort RPC_PROCID_CURSORPREPARE = 3; 474 public const ushort RPC_PROCID_CURSOREXECUTE = 4; 475 public const ushort RPC_PROCID_CURSORPREPEXEC = 5; 476 public const ushort RPC_PROCID_CURSORUNPREPARE = 6; 477 public const ushort RPC_PROCID_CURSORFETCH = 7; 478 public const ushort RPC_PROCID_CURSOROPTION = 8; 479 public const ushort RPC_PROCID_CURSORCLOSE = 9; 480 public const ushort RPC_PROCID_EXECUTESQL = 10; 481 public const ushort RPC_PROCID_PREPARE = 11; 482 public const ushort RPC_PROCID_EXECUTE = 12; 483 public const ushort RPC_PROCID_PREPEXEC = 13; 484 public const ushort RPC_PROCID_PREPEXECRPC = 14; 485 public const ushort RPC_PROCID_UNPREPARE = 15; 486 487 // For Transactions 488 public const string TRANS_BEGIN = "BEGIN TRANSACTION"; 489 public const string TRANS_COMMIT = "COMMIT TRANSACTION"; 490 public const string TRANS_ROLLBACK = "ROLLBACK TRANSACTION"; 491 public const string TRANS_IF_ROLLBACK = "IF @@TRANCOUNT > 0 ROLLBACK TRANSACTION"; 492 public const string TRANS_SAVE = "SAVE TRANSACTION"; 493 494 // For Transactions - isolation levels 495 public const string TRANS_READ_COMMITTED = "SET TRANSACTION ISOLATION LEVEL READ COMMITTED"; 496 public const string TRANS_READ_UNCOMMITTED = "SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED"; 497 public const string TRANS_REPEATABLE_READ = "SET TRANSACTION ISOLATION LEVEL REPEATABLE READ"; 498 public const string TRANS_SERIALIZABLE = "SET TRANSACTION ISOLATION LEVEL SERIALIZABLE"; 499 public const string TRANS_SNAPSHOT = "SET TRANSACTION ISOLATION LEVEL SNAPSHOT"; 500 501 // Batch RPC flags 502 public const byte SHILOH_RPCBATCHFLAG = 0x80; 503 public const byte YUKON_RPCBATCHFLAG = 0xFF; 504 505 // RPC flags 506 public const byte RPC_RECOMPILE = 0x1; 507 public const byte RPC_NOMETADATA = 0x2; 508 509 // RPC parameter class 510 public const byte RPC_PARAM_BYREF = 0x1; 511 public const byte RPC_PARAM_DEFAULT = 0x2; 512 public const byte RPC_PARAM_ENCRYPTED = 0x8; 513 514 // SQL parameter list text 515 public const string PARAM_OUTPUT = "output"; 516 517 // SQL Parameter constants 518 public const int MAX_PARAMETER_NAME_LENGTH = 128; 519 520 // metadata options (added around an existing sql statement) 521 522 // prefixes 523 public const string FMTONLY_ON = " SET FMTONLY ON;"; 524 public const string FMTONLY_OFF = " SET FMTONLY OFF;"; 525 // suffixes 526 public const string BROWSE_ON = " SET NO_BROWSETABLE ON;"; 527 public const string BROWSE_OFF = " SET NO_BROWSETABLE OFF;"; 528 529 // generic table name 530 public const string TABLE = "Table"; 531 532 public const int EXEC_THRESHOLD = 0x3; // if the number of commands we execute is > than this threshold, than do prep/exec/unprep instead 533 // of executesql. 534 535 // dbnetlib error values 536 public const short TIMEOUT_EXPIRED = -2; 537 public const short ENCRYPTION_NOT_SUPPORTED = 20; 538 // CAUTION: These are not error codes returned by SNI. This is used for backward compatibility 539 // since netlib (now removed from sqlclient) returned these codes. 540 541 // SQL error values (from sqlerrorcodes.h) 542 public const int LOGON_FAILED = 18456; 543 public const int PASSWORD_EXPIRED = 18488; 544 public const int IMPERSONATION_FAILED = 1346; 545 public const int P_TOKENTOOLONG = 103; 546 547 // SQL error that indicates retry for Always Encrypted 548 public const int TCE_CONVERSION_ERROR_CLIENT_RETRY = 33514; 549 550 // SNI\Win32 error values 551 // NOTE: these are simply windows system error codes, not SNI specific 552 public const uint SNI_UNINITIALIZED = unchecked((uint)-1); 553 public const uint SNI_SUCCESS = 0; // The operation completed successfully. 554 public const uint SNI_WAIT_TIMEOUT = 258; // The wait operation timed out. 555 public const uint SNI_SUCCESS_IO_PENDING = 997; // Overlapped I/O operation is in progress. 556 557 // Windows Sockets Error Codes 558 public const short SNI_WSAECONNRESET = 10054; // An existing connection was forcibly closed by the remote host. 559 560 // SNI flags 561 public const UInt32 SNI_SSL_VALIDATE_CERTIFICATE = 1; // This enables validation of server certificate 562 public const UInt32 SNI_SSL_USE_SCHANNEL_CACHE = 2; // This enables schannel session cache 563 public const UInt32 SNI_SSL_IGNORE_CHANNEL_BINDINGS = 0x10; // Used with SSL Provider, sent to SNIAddProvider in case of SQL Authentication & Encrypt. 564 565 public const string DEFAULT_ENGLISH_CODE_PAGE_STRING = "iso_1"; 566 public const short DEFAULT_ENGLISH_CODE_PAGE_VALUE = 1252; 567 public const short CHARSET_CODE_PAGE_OFFSET = 2; 568 internal const int MAX_SERVERNAME = 255; 569 570 // Sql Statement Tokens in the DONE packet 571 // (see ntdbms\ntinc\tokens.h) 572 // 573 internal const ushort SELECT = 0xc1; 574 internal const ushort INSERT = 0xc3; 575 internal const ushort DELETE = 0xc4; 576 internal const ushort UPDATE = 0xc5; 577 internal const ushort ABORT = 0xd2; 578 internal const ushort BEGINXACT = 0xd4; 579 internal const ushort ENDXACT = 0xd5; 580 internal const ushort BULKINSERT = 0xf0; 581 internal const ushort OPENCURSOR = 0x20; 582 internal const ushort MERGE = 0x117; 583 584 585 // Login data validation Rules 586 // 587 internal const ushort MAXLEN_HOSTNAME = 128; // the client machine name 588 internal const ushort MAXLEN_USERNAME = 128; // the client user id 589 internal const ushort MAXLEN_PASSWORD = 128; // the password supplied by the client 590 internal const ushort MAXLEN_APPNAME = 128; // the client application name 591 internal const ushort MAXLEN_SERVERNAME = 128; // the server name 592 internal const ushort MAXLEN_CLIENTINTERFACE = 128; // the interface library name 593 internal const ushort MAXLEN_LANGUAGE = 128; // the initial language 594 internal const ushort MAXLEN_DATABASE = 128; // the initial database 595 internal const ushort MAXLEN_ATTACHDBFILE = 260; // the filename for a database that is to be attached during the connection process 596 internal const ushort MAXLEN_NEWPASSWORD = 128; // new password for the specified login. 597 598 599 // array copied directly from tdssort.h from luxor 600 public static readonly UInt16[] CODE_PAGE_FROM_SORT_ID = { 601 0, /* 0 */ 602 0, /* 1 */ 603 0, /* 2 */ 604 0, /* 3 */ 605 0, /* 4 */ 606 0, /* 5 */ 607 0, /* 6 */ 608 0, /* 7 */ 609 0, /* 8 */ 610 0, /* 9 */ 611 0, /* 10 */ 612 0, /* 11 */ 613 0, /* 12 */ 614 0, /* 13 */ 615 0, /* 14 */ 616 0, /* 15 */ 617 0, /* 16 */ 618 0, /* 17 */ 619 0, /* 18 */ 620 0, /* 19 */ 621 0, /* 20 */ 622 0, /* 21 */ 623 0, /* 22 */ 624 0, /* 23 */ 625 0, /* 24 */ 626 0, /* 25 */ 627 0, /* 26 */ 628 0, /* 27 */ 629 0, /* 28 */ 630 0, /* 29 */ 631 437, /* 30 */ 632 437, /* 31 */ 633 437, /* 32 */ 634 437, /* 33 */ 635 437, /* 34 */ 636 0, /* 35 */ 637 0, /* 36 */ 638 0, /* 37 */ 639 0, /* 38 */ 640 0, /* 39 */ 641 850, /* 40 */ 642 850, /* 41 */ 643 850, /* 42 */ 644 850, /* 43 */ 645 850, /* 44 */ 646 0, /* 45 */ 647 0, /* 46 */ 648 0, /* 47 */ 649 0, /* 48 */ 650 850, /* 49 */ 651 1252, /* 50 */ 652 1252, /* 51 */ 653 1252, /* 52 */ 654 1252, /* 53 */ 655 1252, /* 54 */ 656 850, /* 55 */ 657 850, /* 56 */ 658 850, /* 57 */ 659 850, /* 58 */ 660 850, /* 59 */ 661 850, /* 60 */ 662 850, /* 61 */ 663 0, /* 62 */ 664 0, /* 63 */ 665 0, /* 64 */ 666 0, /* 65 */ 667 0, /* 66 */ 668 0, /* 67 */ 669 0, /* 68 */ 670 0, /* 69 */ 671 0, /* 70 */ 672 1252, /* 71 */ 673 1252, /* 72 */ 674 1252, /* 73 */ 675 1252, /* 74 */ 676 1252, /* 75 */ 677 0, /* 76 */ 678 0, /* 77 */ 679 0, /* 78 */ 680 0, /* 79 */ 681 1250, /* 80 */ 682 1250, /* 81 */ 683 1250, /* 82 */ 684 1250, /* 83 */ 685 1250, /* 84 */ 686 1250, /* 85 */ 687 1250, /* 86 */ 688 1250, /* 87 */ 689 1250, /* 88 */ 690 1250, /* 89 */ 691 1250, /* 90 */ 692 1250, /* 91 */ 693 1250, /* 92 */ 694 1250, /* 93 */ 695 1250, /* 94 */ 696 1250, /* 95 */ 697 1250, /* 96 */ 698 1250, /* 97 */ 699 1250, /* 98 */ 700 0, /* 99 */ 701 0, /* 100 */ 702 0, /* 101 */ 703 0, /* 102 */ 704 0, /* 103 */ 705 1251, /* 104 */ 706 1251, /* 105 */ 707 1251, /* 106 */ 708 1251, /* 107 */ 709 1251, /* 108 */ 710 0, /* 109 */ 711 0, /* 110 */ 712 0, /* 111 */ 713 1253, /* 112 */ 714 1253, /* 113 */ 715 1253, /* 114 */ 716 0, /* 115 */ 717 0, /* 116 */ 718 0, /* 117 */ 719 0, /* 118 */ 720 0, /* 119 */ 721 1253, /* 120 */ 722 1253, /* 121 */ 723 1253, /* 122 */ 724 0, /* 123 */ 725 1253, /* 124 */ 726 0, /* 125 */ 727 0, /* 126 */ 728 0, /* 127 */ 729 1254, /* 128 */ 730 1254, /* 129 */ 731 1254, /* 130 */ 732 0, /* 131 */ 733 0, /* 132 */ 734 0, /* 133 */ 735 0, /* 134 */ 736 0, /* 135 */ 737 1255, /* 136 */ 738 1255, /* 137 */ 739 1255, /* 138 */ 740 0, /* 139 */ 741 0, /* 140 */ 742 0, /* 141 */ 743 0, /* 142 */ 744 0, /* 143 */ 745 1256, /* 144 */ 746 1256, /* 145 */ 747 1256, /* 146 */ 748 0, /* 147 */ 749 0, /* 148 */ 750 0, /* 149 */ 751 0, /* 150 */ 752 0, /* 151 */ 753 1257, /* 152 */ 754 1257, /* 153 */ 755 1257, /* 154 */ 756 1257, /* 155 */ 757 1257, /* 156 */ 758 1257, /* 157 */ 759 1257, /* 158 */ 760 1257, /* 159 */ 761 1257, /* 160 */ 762 0, /* 161 */ 763 0, /* 162 */ 764 0, /* 163 */ 765 0, /* 164 */ 766 0, /* 165 */ 767 0, /* 166 */ 768 0, /* 167 */ 769 0, /* 168 */ 770 0, /* 169 */ 771 0, /* 170 */ 772 0, /* 171 */ 773 0, /* 172 */ 774 0, /* 173 */ 775 0, /* 174 */ 776 0, /* 175 */ 777 0, /* 176 */ 778 0, /* 177 */ 779 0, /* 178 */ 780 0, /* 179 */ 781 0, /* 180 */ 782 0, /* 181 */ 783 0, /* 182 */ 784 1252, /* 183 */ 785 1252, /* 184 */ 786 1252, /* 185 */ 787 1252, /* 186 */ 788 0, /* 187 */ 789 0, /* 188 */ 790 0, /* 189 */ 791 0, /* 190 */ 792 0, /* 191 */ 793 932, /* 192 */ 794 932, /* 193 */ 795 949, /* 194 */ 796 949, /* 195 */ 797 950, /* 196 */ 798 950, /* 197 */ 799 936, /* 198 */ 800 936, /* 199 */ 801 932, /* 200 */ 802 949, /* 201 */ 803 950, /* 202 */ 804 936, /* 203 */ 805 874, /* 204 */ 806 874, /* 205 */ 807 874, /* 206 */ 808 0, /* 207 */ 809 0, /* 208 */ 810 0, /* 209 */ 811 1252, /* 210 */ 812 1252, /* 211 */ 813 1252, /* 212 */ 814 1252, /* 213 */ 815 1252, /* 214 */ 816 1252, /* 215 */ 817 1252, /* 216 */ 818 1252, /* 217 */ 819 0, /* 218 */ 820 0, /* 219 */ 821 0, /* 220 */ 822 0, /* 221 */ 823 0, /* 222 */ 824 0, /* 223 */ 825 0, /* 224 */ 826 0, /* 225 */ 827 0, /* 226 */ 828 0, /* 227 */ 829 0, /* 228 */ 830 0, /* 229 */ 831 0, /* 230 */ 832 0, /* 231 */ 833 0, /* 232 */ 834 0, /* 233 */ 835 0, /* 234 */ 836 0, /* 235 */ 837 0, /* 236 */ 838 0, /* 237 */ 839 0, /* 238 */ 840 0, /* 239 */ 841 0, /* 240 */ 842 0, /* 241 */ 843 0, /* 242 */ 844 0, /* 243 */ 845 0, /* 244 */ 846 0, /* 245 */ 847 0, /* 246 */ 848 0, /* 247 */ 849 0, /* 248 */ 850 0, /* 249 */ 851 0, /* 250 */ 852 0, /* 251 */ 853 0, /* 252 */ 854 0, /* 253 */ 855 0, /* 254 */ 856 0, /* 255 */ 857 }; 858 859 internal enum UDTFormatType { 860 Native = 1, 861 UserDefined = 2 862 } 863 864 internal enum TransactionManagerRequestType { 865 GetDTCAddress = 0, 866 Propagate = 1, 867 Begin = 5, 868 Promote = 6, 869 Commit = 7, 870 Rollback = 8, 871 Save = 9 872 }; 873 874 internal enum TransactionManagerIsolationLevel { 875 Unspecified = 0x00, 876 ReadUncommitted = 0x01, 877 ReadCommitted = 0x02, 878 RepeatableRead = 0x03, 879 Serializable = 0x04, 880 Snapshot = 0x05 881 } 882 883 internal enum GenericType { 884 MultiSet = 131, 885 }; 886 887 // Date, Time, DateTime2, DateTimeOffset specific constants 888 internal static readonly Int64[] TICKS_FROM_SCALE = { 889 10000000, 890 1000000, 891 100000, 892 10000, 893 1000, 894 100, 895 10, 896 1, 897 }; 898 899 internal const int MAX_TIME_SCALE = 7; // Maximum scale for time-related types 900 internal const int MAX_TIME_LENGTH = 5; // Maximum length for time 901 internal const int MAX_DATETIME2_LENGTH = 8; // Maximum length for datetime2 902 internal const int WHIDBEY_DATE_LENGTH = 10; 903 internal static readonly int[] WHIDBEY_TIME_LENGTH = { 8, 10, 11, 12, 13, 14, 15, 16 }; 904 internal static readonly int[] WHIDBEY_DATETIME2_LENGTH = { 19, 21, 22, 23, 24, 25, 26, 27 }; 905 internal static readonly int[] WHIDBEY_DATETIMEOFFSET_LENGTH = {26, 28, 29, 30, 31, 32, 33, 34 }; 906 907 internal enum FedAuthInfoId:byte { 908 Stsurl = 0x01, // FedAuthInfoData is token endpoint URL from which to acquire fed auth token 909 Spn = 0x02, // FedAuthInfoData is the SPN to use for acquiring fed auth token 910 } 911 912 // TCE Related constants 913 internal const byte MAX_SUPPORTED_TCE_VERSION = 0x01; // max version 914 internal const ushort MAX_TCE_CIPHERINFO_SIZE = 2048; // max size of cipherinfo blob 915 internal const long MAX_TCE_CIPHERTEXT_SIZE = 2147483648; // max size of encrypted blob- currently 2GB. 916 internal const byte CustomCipherAlgorithmId = 0; // Id used for custom encryption algorithm. 917 918 internal const int AES_256_CBC = 1; 919 internal const int AEAD_AES_256_CBC_HMAC_SHA256 = 2; 920 921 // TCE Param names for exec handling 922 internal const string TCE_PARAM_CIPHERTEXT = "cipherText"; 923 internal const string TCE_PARAM_CIPHER_ALGORITHM_ID="cipherAlgorithmId"; 924 internal const string TCE_PARAM_COLUMNENCRYPTION_KEY="columnEncryptionKey"; 925 internal const string TCE_PARAM_ENCRYPTION_ALGORITHM="encryptionAlgorithm"; 926 internal const string TCE_PARAM_ENCRYPTIONTYPE = "encryptionType"; 927 internal const string TCE_PARAM_ENCRYPTIONKEY = "encryptionKey"; 928 internal const string TCE_PARAM_MASTERKEY_PATH = "masterKeyPath"; 929 internal const string TCE_PARAM_ENCRYPTED_CEK = "encryptedColumnEncryptionKey"; 930 internal const string TCE_PARAM_CLIENT_KEYSTORE_PROVIDERS="clientKeyStoreProviders"; 931 internal const string TCE_PARAM_FORCE_COLUMN_ENCRYPTION="ForceColumnEncryption(true)"; 932 } 933 934 internal enum ParsingErrorState { 935 Undefined = 0, 936 FedAuthInfoLengthTooShortForCountOfInfoIds = 1, 937 FedAuthInfoLengthTooShortForData = 2, 938 FedAuthInfoFailedToReadCountOfInfoIds = 3, 939 FedAuthInfoFailedToReadTokenStream = 4, 940 FedAuthInfoInvalidOffset = 5, 941 FedAuthInfoFailedToReadData = 6, 942 FedAuthInfoDataNotUnicode = 7, 943 FedAuthInfoDoesNotContainStsurlAndSpn = 8, 944 FedAuthInfoNotReceived = 9, 945 FedAuthNotAcknowledged = 10, 946 FedAuthFeatureAckContainsExtraData = 11, 947 FedAuthFeatureAckUnknownLibraryType = 12, 948 UnrequestedFeatureAckReceived = 13, 949 UnknownFeatureAck = 14, 950 InvalidTdsTokenReceived = 15, 951 SessionStateLengthTooShort = 16, 952 SessionStateInvalidStatus = 17, 953 CorruptedTdsStream = 18, 954 ProcessSniPacketFailed = 19, 955 FedAuthRequiredPreLoginResponseInvalidValue = 20, 956 TceUnknownVersion = 21, 957 TceInvalidVersion = 22, 958 TceInvalidOrdinalIntoCipherInfoTable = 23, 959 } 960 961 internal enum SniContext { 962 Undefined = 0, 963 Snix_Connect, 964 Snix_PreLoginBeforeSuccessfullWrite, 965 Snix_PreLogin, 966 Snix_LoginSspi, 967 Snix_ProcessSspi, 968 Snix_Login, 969 Snix_EnableMars, 970 Snix_AutoEnlist, 971 Snix_GetMarsSession, 972 Snix_Execute, 973 Snix_Read, 974 Snix_Close, 975 Snix_SendRows, 976 } 977 978 /// <summary> 979 /// Column Encryption Setting to be used for the SqlConnection. 980 /// </summary> 981 public enum SqlConnectionColumnEncryptionSetting { 982 /// <summary> 983 /// Disables column encryption by default on all commands on this connection. 984 /// </summary> 985 Disabled = 0, 986 987 /// <summary> 988 /// Enables column encryption by default on all commands on this connection. 989 /// </summary> 990 Enabled, 991 } 992 993 /// <summary> 994 /// Column Encryption Setting to be used for the SqlCommand. 995 /// </summary> 996 public enum SqlCommandColumnEncryptionSetting { 997 /// <summary> 998 /// if �Column Encryption Setting=Enabled� in the connection string, use Enabled. Otherwise, maps to Disabled. 999 /// </summary> 1000 UseConnectionSetting = 0, 1001 1002 /// <summary> 1003 /// Enables TCE for the command. Overrides the connection level setting for this command. 1004 /// </summary> 1005 Enabled, 1006 1007 /// <summary> 1008 /// Parameters will not be encrypted, only the ResultSet will be decrypted. This is an optimization for queries that do not pass any encrypted input parameters. 1009 /// Overrides the connection level setting for this command. 1010 /// </summary> 1011 ResultSetOnly, 1012 1013 /// <summary> 1014 /// Disables TCE for the command.Overrides the connection level setting for this command. 1015 /// </summary> 1016 Disabled, 1017 } 1018 1019 public enum SqlAuthenticationMethod { 1020 NotSpecified = 0, 1021 SqlPassword, 1022 ActiveDirectoryPassword, 1023 ActiveDirectoryIntegrated, 1024 } 1025 // This enum indicates the state of TransparentNetworkIPResolution 1026 // The first attempt when TNIR is on should be sequential. If the first attempt failes next attempts should be parallel. 1027 internal enum TransparentNetworkResolutionState { 1028 DisabledMode = 0, 1029 SequentialMode, 1030 ParallelMode 1031 }; 1032 1033 internal class ActiveDirectoryAuthentication 1034 { 1035 internal const string AdoClientId = "4d079b4c-cab7-4b7c-a115-8fd51b6f8239"; 1036 internal const string AdalGetAccessTokenFunctionName = "ADALGetAccessToken"; 1037 internal const int GetAccessTokenSuccess = 0; 1038 internal const int GetAccessTokenInvalidGrant = 1; 1039 internal const int GetAccessTokenTansisentError = 2; 1040 internal const int GetAccessTokenOtherError = 3; 1041 } 1042 1043 // Fields in the first resultset of "sp_describe_parameter_encryption". 1044 // We expect the server to return the fields in the resultset in the same order as mentioned below. 1045 // If the server changes the below order, then transparent parameter encryption will break. 1046 internal enum DescribeParameterEncryptionResultSet1 { 1047 KeyOrdinal = 0, 1048 DbId, 1049 KeyId, 1050 KeyVersion, 1051 KeyMdVersion, 1052 EncryptedKey, 1053 ProviderName, 1054 KeyPath, 1055 KeyEncryptionAlgorithm, 1056 } 1057 1058 // Fields in the second resultset of "sp_describe_parameter_encryption" 1059 // We expect the server to return the fields in the resultset in the same order as mentioned below. 1060 // If the server changes the below order, then transparent parameter encryption will break. 1061 internal enum DescribeParameterEncryptionResultSet2 { 1062 ParameterOrdinal = 0, 1063 ParameterName, 1064 ColumnEncryptionAlgorithm, 1065 ColumnEncrytionType, 1066 ColumnEncryptionKeyOrdinal, 1067 NormalizationRuleVersion, 1068 } 1069 } 1070