Merge pull request #3213 from henricm/fix-for-win-securestring-to-bstr
[mono.git] / mcs / class / referencesource / System / net / System / Net / UnsafeNativeMethods.cs
1 //------------------------------------------------------------------------------
2 // <copyright file="UnsafeNativeMethods.cs" company="Microsoft">
3 //     Copyright (c) Microsoft Corporation.  All rights reserved.
4 // </copyright>
5 //------------------------------------------------------------------------------
6
7 namespace System.Net {
8     using System.Runtime.InteropServices;
9     using System.Runtime.CompilerServices;
10     using System.Text;
11     using System.Net.Sockets;
12     using System.Net.Cache;
13     using System.Threading;
14     using System.ComponentModel;
15     using System.Collections;
16     using System.Runtime.ConstrainedExecution;
17     using System.Security;
18     using Microsoft.Win32.SafeHandles;
19     using System.Diagnostics;
20     using System.Diagnostics.CodeAnalysis;
21     using System.Security.Cryptography;
22     using System.Security.Cryptography.X509Certificates;
23     using System.IO;
24
25     [System.Security.SuppressUnmanagedCodeSecurityAttribute()]
26     internal static class UnsafeNclNativeMethods {
27
28 #if FEATURE_PAL
29  #if !PLATFORM_UNIX
30         internal const String DLLPREFIX = "";
31         internal const String DLLSUFFIX = ".dll";
32  #else // !PLATFORM_UNIX
33   #if __APPLE__
34         internal const String DLLPREFIX = "lib";
35         internal const String DLLSUFFIX = ".dylib";
36   #elif _AIX
37         internal const String DLLPREFIX = "lib";
38         internal const String DLLSUFFIX = ".a";
39   #elif __hppa__ || IA64
40         internal const String DLLPREFIX = "lib";
41         internal const String DLLSUFFIX = ".sl";
42   #else
43         internal const String DLLPREFIX = "lib";
44         internal const String DLLSUFFIX = ".so";
45   #endif
46  #endif // !PLATFORM_UNIX
47
48         internal const String ROTOR_PAL   = DLLPREFIX + "rotor_pal" + DLLSUFFIX;
49         internal const String ROTOR_PALRT = DLLPREFIX + "rotor_palrt" + DLLSUFFIX;
50         private const String KERNEL32 = ROTOR_PAL;
51 #else
52         private const string KERNEL32 = "kernel32.dll";
53 #endif // !FEATURE_PAL
54
55 #if !FEATURE_PAL
56         private const string WS2_32 = "ws2_32.dll";
57 #else
58         private const string WS2_32 = ExternDll.Kernel32; // Resolves to rotor_pal
59 #endif // !FEATURE_PAL
60
61         private const string SECUR32 = "secur32.dll";
62         private const string CRYPT32 = "crypt32.dll";
63         private const string ADVAPI32 = "advapi32.dll";
64         private const string HTTPAPI = "httpapi.dll";
65         private const string SCHANNEL = "schannel.dll";
66         private const string RASAPI32 = "rasapi32.dll";
67         private const string WININET = "wininet.dll";
68         private const string WINHTTP = "winhttp.dll";
69         private const string BCRYPT = "bcrypt.dll";
70         private const string USER32 = "user32.dll";
71         private const string TOKENBINDING = "tokenbinding.dll";
72
73 #if !FEATURE_PAL
74         private const string OLE32 = "ole32.dll";        
75 #endif       
76         [DllImport(KERNEL32)]
77         internal static extern IntPtr CreateSemaphore([In] IntPtr lpSemaphoreAttributes, [In] int lInitialCount, [In] int lMaximumCount, [In] IntPtr lpName);
78
79 #if DEBUG
80         [DllImport(KERNEL32)]
81         internal static extern bool ReleaseSemaphore([In] IntPtr hSemaphore, [In] int lReleaseCount, [Out] out int lpPreviousCount);
82
83 #else
84         [DllImport(KERNEL32)]
85         internal static extern bool ReleaseSemaphore([In] IntPtr hSemaphore, [In] int lReleaseCount, [In] IntPtr lpPreviousCount);
86 #endif
87
88         // 
89         internal static class ErrorCodes
90         {
91             internal const uint ERROR_SUCCESS               = 0;
92             internal const uint ERROR_HANDLE_EOF            = 38;
93             internal const uint ERROR_NOT_SUPPORTED         = 50;
94             internal const uint ERROR_INVALID_PARAMETER     = 87;
95             internal const uint ERROR_ALREADY_EXISTS        = 183;
96             internal const uint ERROR_MORE_DATA             = 234;
97             internal const uint ERROR_OPERATION_ABORTED     = 995;
98             internal const uint ERROR_IO_PENDING            = 997;
99             internal const uint ERROR_NOT_FOUND             = 1168;
100             internal const uint ERROR_CONNECTION_INVALID    = 1229;
101         }
102
103         internal static class NTStatus
104         {
105             internal const uint STATUS_SUCCESS               = 0x00000000;
106             internal const uint STATUS_OBJECT_NAME_NOT_FOUND = 0xC0000034;
107         }
108
109         [DllImport(KERNEL32, ExactSpelling=true, CallingConvention=CallingConvention.StdCall, SetLastError=true)]
110         internal static extern uint GetCurrentThreadId();
111
112
113         [DllImport(KERNEL32, ExactSpelling = true, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
114         internal static unsafe extern uint CancelIoEx(CriticalHandle handle, NativeOverlapped* overlapped);
115
116         [SuppressMessage("Microsoft.Security", "CA2118:ReviewSuppressUnmanagedCodeSecurityUsage", Justification = "Implementation requires unmanaged code usage")]
117         [DllImport(KERNEL32, ExactSpelling = true, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
118         internal static unsafe extern bool SetFileCompletionNotificationModes(CriticalHandle handle, FileCompletionNotificationModes modes);
119
120         [DllImport(KERNEL32, CallingConvention = CallingConvention.Winapi, SetLastError = true)]
121         internal static extern IntPtr GetProcessHeap();
122
123         [DllImport(KERNEL32, CallingConvention = CallingConvention.Winapi, SetLastError = true)]
124         internal static extern bool HeapFree([In] IntPtr hHeap, [In] uint dwFlags, [In] IntPtr lpMem);
125
126         [System.Security.SecurityCritical]
127         [DllImport(KERNEL32, CallingConvention = CallingConvention.Winapi, SetLastError = true)]
128         internal extern static IntPtr GetProcAddress(SafeLoadLibrary hModule, string entryPoint);
129
130         [Flags]
131         internal enum FileCompletionNotificationModes : byte
132         {
133             None = 0,
134             SkipCompletionPortOnSuccess = 1,
135             SkipSetEventOnHandle = 2
136         }
137
138 #if STRESS || !DEBUG
139         [DllImport(KERNEL32, ExactSpelling = true)]
140         internal static extern void DebugBreak();
141 #endif
142
143 #if FEATURE_PAL
144         [DllImport(ROTOR_PALRT, CharSet=CharSet.Unicode, SetLastError=true, EntryPoint="PAL_FetchConfigurationStringW")]
145         internal static extern bool FetchConfigurationString(bool perMachine, String parameterName, StringBuilder parameterValue, int parameterValueLength);
146 #endif // FEATURE_PAL
147
148 #if !FEATURE_PAL
149         [SuppressUnmanagedCodeSecurity]
150         internal unsafe static class RegistryHelper
151         {
152             internal const uint REG_NOTIFY_CHANGE_LAST_SET = 4;
153             internal const uint REG_BINARY = 3;
154             internal const uint KEY_READ = 0x00020019;
155
156             internal static readonly IntPtr HKEY_CURRENT_USER = (IntPtr) unchecked((int) 0x80000001L);
157             internal static readonly IntPtr HKEY_LOCAL_MACHINE = (IntPtr) unchecked((int) 0x80000002L);
158
159             // RELIABILITY:
160             // this out parameter in this API, resultSubKey, is an allocated handle to a registry sub-key.
161             // it must be a SafeHandle so we can guarantee that it is released correctly and never leaked.
162             [DllImport(ADVAPI32, BestFitMapping=false, ThrowOnUnmappableChar=true, ExactSpelling=false, CharSet=CharSet.Auto, SetLastError=true)]
163             internal static extern uint RegOpenKeyEx(IntPtr key, string subKey, uint ulOptions, uint samDesired, out SafeRegistryHandle resultSubKey);
164
165             [DllImport(ADVAPI32, BestFitMapping=false, ThrowOnUnmappableChar=true, ExactSpelling=false, CharSet=CharSet.Auto, SetLastError=true)]
166             internal static extern uint RegOpenKeyEx(SafeRegistryHandle key, string subKey, uint ulOptions, uint samDesired, out SafeRegistryHandle resultSubKey);
167
168             [DllImport(ADVAPI32, ExactSpelling=true, SetLastError=true)]
169             [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
170             internal static extern uint RegCloseKey(IntPtr key);
171
172             [DllImport(ADVAPI32, ExactSpelling=true, SetLastError=true)]
173             internal static extern uint RegNotifyChangeKeyValue(SafeRegistryHandle key, bool watchSubTree, uint notifyFilter, SafeWaitHandle regEvent, bool async);
174
175             [DllImport(ADVAPI32, ExactSpelling=true, SetLastError=true)]
176             internal static extern uint RegOpenCurrentUser(uint samDesired, out SafeRegistryHandle resultKey);
177
178             [DllImport(ADVAPI32, BestFitMapping=false, ThrowOnUnmappableChar=true, ExactSpelling=false, CharSet=CharSet.Auto, SetLastError=true)]
179             internal static extern uint RegQueryValueEx(SafeRegistryHandle key, string valueName, IntPtr reserved, out uint type, [Out] byte[] data, [In][Out] ref uint size);
180         }
181
182         [System.Security.SuppressUnmanagedCodeSecurityAttribute()]
183         internal unsafe class RasHelper
184         {
185             private static readonly bool s_RasSupported;
186
187             private ManualResetEvent m_RasEvent;
188             private bool m_Suppressed;
189
190             /* Consider removing
191             internal void Close()
192             {
193                 ManualResetEvent rasEvent = m_RasEvent;
194                 m_RasEvent = null;
195                 m_Suppressed = false;
196                 if (rasEvent != null)
197                 {
198                     rasEvent.Close();
199                 }
200             }
201             */
202
203             static RasHelper()
204             {
205                 if (ComNetOS.InstallationType == WindowsInstallationType.ServerCore)
206                 {
207                     // if InstallationType == WindowsSku.Unknown we'll support RAS, since older OS (like XP) 
208                     // don't have an "Installation Type" Registry value
209                     s_RasSupported = false;
210                 }
211                 else
212                 {
213                     s_RasSupported = true;
214                 }
215
216                 if (Logging.On)
217                     Logging.PrintInfo(Logging.Web, SR.GetString(SR.net_log_proxy_ras_supported, s_RasSupported));
218             }
219
220             internal RasHelper()
221             {
222                 if (!s_RasSupported) 
223                 {
224                     throw new InvalidOperationException(SR.GetString(SR.net_log_proxy_ras_notsupported_exception));
225                 }
226
227                 m_RasEvent = new ManualResetEvent(false);
228
229                 // Use -1 as a handle, to receive all RAS notifications for the local machine.
230                 uint statusCode = RasConnectionNotification((IntPtr)(-1), m_RasEvent.SafeWaitHandle, RASCN_Connection | RASCN_Disconnection);
231
232                 GlobalLog.Print("RasHelper::RasHelper() RasConnectionNotification() statusCode:" + statusCode);
233                 if (statusCode != 0) 
234                 {
235                     GlobalLog.Print("RasHelper::RasHelper() RasConnectionNotification() Marshal.GetLastWin32Error():" + Marshal.GetLastWin32Error());
236                     m_Suppressed = true;
237                     m_RasEvent.Close();
238                     m_RasEvent = null;
239                 }
240             }
241
242             internal static bool RasSupported
243             {
244                 get { return s_RasSupported; }
245             }
246
247             internal bool HasChanged
248             {
249                 get
250                 {
251                     if (m_Suppressed)
252                     {
253                         return false;
254                     }
255
256                     ManualResetEvent rasEvent = m_RasEvent;
257                     if (rasEvent == null)
258                     {
259                         throw new ObjectDisposedException(GetType().FullName);
260                     }
261                     return rasEvent.WaitOne(0, false);
262                 }
263             }
264
265             internal void Reset()
266             {
267                 if (!m_Suppressed)
268                 {
269                     ManualResetEvent rasEvent = m_RasEvent;
270                     if (rasEvent == null)
271                     {
272                         throw new ObjectDisposedException(GetType().FullName);
273                     }
274                     rasEvent.Reset();
275                 }
276             }
277
278             internal static string GetCurrentConnectoid()
279             {
280                 uint dwSize = (uint) Marshal.SizeOf(typeof(RASCONN));
281                 GlobalLog.Print("RasHelper::GetCurrentConnectoid() using struct size dwSize:" + dwSize);
282
283                 if (!s_RasSupported) 
284                 {
285                     // if RAS is not supported, behave as if no dial-up/VPN connection is in use
286                     // (which is actually the case, since without RAS dial-up/VPN doesn't work)
287                     return null;
288                 }
289
290                 uint count = 4;
291                 uint statusCode = 0;
292                 RASCONN[] connections = null;
293                 while (true)
294                 {
295                     uint cb = checked(dwSize * count);
296                     connections = new RASCONN[count];
297                     connections[0].dwSize = dwSize;
298                     statusCode = RasEnumConnections(connections, ref cb, ref count);
299                     GlobalLog.Print("RasHelper::GetCurrentConnectoid() called RasEnumConnections() count:" + count + " statusCode: " + statusCode + " cb:" + cb);
300                     if (statusCode != ERROR_BUFFER_TOO_SMALL)
301                     {
302                         break;
303                     }
304                     count = checked(cb + dwSize - 1) / dwSize;
305                 }
306
307                 if (count == 0 || statusCode != 0)
308                 {
309                     return null;
310                 }
311
312                 for (uint i=0; i < count; i++)
313                 {
314                     GlobalLog.Print("RasHelper::GetCurrentConnectoid() RASCONN[" + i + "]");
315                     GlobalLog.Print("RasHelper::GetCurrentConnectoid() RASCONN[" + i + "].dwSize: " + connections[i].dwSize);
316                     GlobalLog.Print("RasHelper::GetCurrentConnectoid() RASCONN[" + i + "].hrasconn: " + connections[i].hrasconn);
317                     GlobalLog.Print("RasHelper::GetCurrentConnectoid() RASCONN[" + i + "].szEntryName: " + connections[i].szEntryName);
318                     GlobalLog.Print("RasHelper::GetCurrentConnectoid() RASCONN[" + i + "].szDeviceType: " + connections[i].szDeviceType);
319                     GlobalLog.Print("RasHelper::GetCurrentConnectoid() RASCONN[" + i + "].szDeviceName: " + connections[i].szDeviceName);
320
321                     RASCONNSTATUS connectionStatus = new RASCONNSTATUS();
322                     connectionStatus.dwSize = (uint)Marshal.SizeOf(connectionStatus);
323                     // RELIABILITY:
324                     // the 'hrasconn' field is an IntPtr because it's defined as a handle
325                     // that said, its use is that of a opaque ID, so we're not
326                     // allocating anything that needs to be released for reliability.
327                     statusCode = RasGetConnectStatus(connections[i].hrasconn, ref connectionStatus);
328                     GlobalLog.Print("RasHelper::GetCurrentConnectoid() called RasGetConnectStatus() statusCode: " + statusCode + " dwSize: " + connectionStatus.dwSize);
329                     if (statusCode==0) {
330                         GlobalLog.Print("RasHelper::GetCurrentConnectoid() RASCONN[" + i + "].RASCONNSTATUS.dwSize: " + connectionStatus.dwSize);
331                         GlobalLog.Print("RasHelper::GetCurrentConnectoid() RASCONN[" + i + "].RASCONNSTATUS.rasconnstate: " + connectionStatus.rasconnstate);
332                         GlobalLog.Print("RasHelper::GetCurrentConnectoid() RASCONN[" + i + "].RASCONNSTATUS.dwError: " + connectionStatus.dwError);
333                         GlobalLog.Print("RasHelper::GetCurrentConnectoid() RASCONN[" + i + "].RASCONNSTATUS.szDeviceType: " + connectionStatus.szDeviceType);
334                         GlobalLog.Print("RasHelper::GetCurrentConnectoid() RASCONN[" + i + "].RASCONNSTATUS.szDeviceName: " + connectionStatus.szDeviceName);
335                         if (connectionStatus.rasconnstate==RASCONNSTATE.RASCS_Connected) {
336                             return connections[i].szEntryName;
337                         }
338                     }
339                 }
340
341                 return null;
342             }
343
344
345             [DllImport(RASAPI32, ExactSpelling = false, CharSet = CharSet.Auto, BestFitMapping = false, ThrowOnUnmappableChar = true, SetLastError = false)]
346             private static extern uint RasEnumConnections([In, Out] RASCONN[] lprasconn, ref uint lpcb, ref uint lpcConnections);
347
348             [DllImport(RASAPI32, ExactSpelling=false, CharSet=CharSet.Auto, BestFitMapping=false, ThrowOnUnmappableChar=true, SetLastError=false)]
349             private static extern uint RasGetConnectStatus([In] IntPtr hrasconn, [In, Out] ref RASCONNSTATUS lprasconnstatus);
350
351             [DllImport(RASAPI32, ExactSpelling=false, CharSet=CharSet.Auto, BestFitMapping=false, ThrowOnUnmappableChar=true, SetLastError=false)]
352             private static extern uint RasConnectionNotification([In] IntPtr hrasconn, [In] SafeWaitHandle hEvent, uint dwFlags);
353
354             const int RAS_MaxEntryName = 256;
355             const int RAS_MaxDeviceType = 16;
356             const int RAS_MaxDeviceName = 128;
357             const int RAS_MaxPhoneNumber = 128;
358             const int RAS_MaxCallbackNumber = 128;
359
360             const uint RASCN_Connection = 0x00000001;
361             const uint RASCN_Disconnection = 0x00000002;
362
363             const int UNLEN = 256;
364             const int PWLEN = 256;
365             const int DNLEN = 15;
366
367             const int MAX_PATH = 260;
368
369             const uint RASBASE = 600;
370             const uint ERROR_DIAL_ALREADY_IN_PROGRESS = (RASBASE+156);
371             const uint ERROR_BUFFER_TOO_SMALL = (RASBASE+3);
372
373             [StructLayout(LayoutKind.Sequential, Pack=4, CharSet=CharSet.Auto)]
374             struct RASCONN {
375                 internal uint dwSize;
376                 internal IntPtr hrasconn;
377                 [MarshalAs(UnmanagedType.ByValTStr, SizeConst=RAS_MaxEntryName + 1)]
378                 internal string szEntryName;
379                 [MarshalAs(UnmanagedType.ByValTStr, SizeConst=RAS_MaxDeviceType + 1)]
380                 internal string szDeviceType;
381                 [MarshalAs(UnmanagedType.ByValTStr, SizeConst=RAS_MaxDeviceName + 1)]
382                 internal string szDeviceName;
383
384 /* None of these are supported on Windows 98.
385    MSDN lies twice: there is no dwSessionId at all, and szPhonebook and dwSubEntry are not on Win98.
386                 [MarshalAs(UnmanagedType.ByValTStr, SizeConst=MAX_PATH)]
387                 internal string szPhonebook;
388                 internal uint dwSubEntry;
389                 internal Guid guidEntry;
390                 internal uint dwFlags;
391                 internal ulong luid;
392 */
393             }
394
395             [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Auto)]
396             struct RASCONNSTATUS {
397                 internal uint dwSize;
398                 internal RASCONNSTATE rasconnstate;
399                 internal uint dwError;
400                 [MarshalAs(UnmanagedType.ByValTStr, SizeConst=RAS_MaxDeviceType + 1)]
401                 internal string szDeviceType;
402                 [MarshalAs(UnmanagedType.ByValTStr, SizeConst=RAS_MaxDeviceName + 1)]
403                 internal string szDeviceName;
404 /* Not supported on Windows 98.
405                 [MarshalAs(UnmanagedType.ByValTStr, SizeConst=RAS_MaxPhoneNumber + 1)]
406                 internal string szPhoneNumber;
407 */
408             }
409
410             [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Auto)]
411             struct RASDIALPARAMS {
412                 internal uint dwSize;
413                 [MarshalAs(UnmanagedType.ByValTStr, SizeConst=RAS_MaxEntryName + 1)]
414                 internal string szEntryName;
415                 [MarshalAs(UnmanagedType.ByValTStr, SizeConst=RAS_MaxPhoneNumber + 1)]
416                 internal string szPhoneNumber;
417                 [MarshalAs(UnmanagedType.ByValTStr, SizeConst=RAS_MaxCallbackNumber + 1)]
418                 internal string szCallbackNumber;
419                 [MarshalAs(UnmanagedType.ByValTStr, SizeConst=UNLEN + 1)]
420                 internal string szUserName;
421                 [MarshalAs(UnmanagedType.ByValTStr, SizeConst=PWLEN + 1)]
422                 internal string szPassword;
423                 [MarshalAs(UnmanagedType.ByValTStr, SizeConst=DNLEN + 1)]
424                 internal string szDomain;
425 /* Not supported on Windows 98.
426                 internal uint dwSubEntry;
427                 internal uint dwCallbackId;
428 */
429             }
430
431             const int RASCS_PAUSED = 0x1000;
432             const int RASCS_DONE = 0x2000;
433
434             enum RASCONNSTATE {
435                 RASCS_OpenPort = 0,
436                 RASCS_PortOpened,
437                 RASCS_ConnectDevice,
438                 RASCS_DeviceConnected,
439                 RASCS_AllDevicesConnected,
440                 RASCS_Authenticate,
441                 RASCS_AuthNotify,
442                 RASCS_AuthRetry,
443                 RASCS_AuthCallback,
444                 RASCS_AuthChangePassword,
445                 RASCS_AuthProject,
446                 RASCS_AuthLinkSpeed,
447                 RASCS_AuthAck,
448                 RASCS_ReAuthenticate,
449                 RASCS_Authenticated,
450                 RASCS_PrepareForCallback,
451                 RASCS_WaitForModemReset,
452                 RASCS_WaitForCallback,
453                 RASCS_Projected,
454                 RASCS_StartAuthentication,    // Windows 95 only
455                 RASCS_CallbackComplete,       // Windows 95 only
456                 RASCS_LogonNetwork,           // Windows 95 only
457                 RASCS_SubEntryConnected,
458                 RASCS_SubEntryDisconnected,
459                 RASCS_Interactive = RASCS_PAUSED,
460                 RASCS_RetryAuthentication,
461                 RASCS_CallbackSetByCaller,
462                 RASCS_PasswordExpired,
463                 RASCS_InvokeEapUI,
464                 RASCS_Connected = RASCS_DONE,
465                 RASCS_Disconnected
466             }
467         }
468
469         [System.Security.SuppressUnmanagedCodeSecurityAttribute()]
470         internal static class SafeNetHandles_SECURITY {
471
472             [DllImport(SECUR32, ExactSpelling=true, SetLastError=true)]
473             [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
474             internal static extern int FreeContextBuffer(
475                 [In] IntPtr contextBuffer);
476
477
478             [DllImport(SECUR32, ExactSpelling=true, SetLastError=true)]
479             [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
480             internal static extern int FreeCredentialsHandle(
481                   ref  SSPIHandle handlePtr
482                   );
483
484             [DllImport(SECUR32, ExactSpelling=true, SetLastError=true)]
485             [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
486             internal static extern int DeleteSecurityContext(
487                   ref  SSPIHandle handlePtr
488                   );
489
490             [DllImport(SECUR32, ExactSpelling=true, SetLastError=true)]
491             [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
492             internal unsafe static extern int AcceptSecurityContext(
493                       ref  SSPIHandle       credentialHandle,
494                       [In] void*            inContextPtr,
495                       [In] SecurityBufferDescriptor inputBuffer,
496                       [In] ContextFlags     inFlags,
497                       [In] Endianness       endianness,
498                       ref  SSPIHandle       outContextPtr,
499                       [In, Out] SecurityBufferDescriptor outputBuffer,
500                       [In, Out] ref ContextFlags attributes,
501                       out  long timeStamp
502                       );
503
504             [DllImport(SECUR32, ExactSpelling=true, SetLastError=true)]
505             [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
506             internal unsafe static extern int QueryContextAttributesW(
507                 ref SSPIHandle contextHandle,
508                 [In] ContextAttribute attribute,
509                 [In] void* buffer);
510
511             [DllImport(SECUR32, ExactSpelling = true, SetLastError = true)]
512             [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
513             internal unsafe static extern int SetContextAttributesW(
514                 ref SSPIHandle contextHandle,
515                 [In] ContextAttribute attribute,
516                 [In] byte[] buffer,
517                 [In] int bufferSize);
518
519             [DllImport(SECUR32, ExactSpelling=true, SetLastError=true)]
520             internal static extern int EnumerateSecurityPackagesW(
521                 [Out] out int pkgnum,
522                 [Out] out SafeFreeContextBuffer_SECURITY handle);
523
524             [DllImport(SECUR32, ExactSpelling=true, CharSet=CharSet.Unicode, SetLastError=true)]
525             internal unsafe static extern int AcquireCredentialsHandleW(
526                       [In] string principal,
527                       [In] string moduleName,
528                       [In] int usage,
529                       [In] void* logonID,
530                       [In] ref AuthIdentity authdata,
531                       [In] void* keyCallback,
532                       [In] void* keyArgument,
533                       ref  SSPIHandle handlePtr,
534                       [Out] out long timeStamp
535                       );
536
537             [DllImport(SECUR32, ExactSpelling=true, CharSet=CharSet.Unicode, SetLastError=true)]
538             internal unsafe static extern int AcquireCredentialsHandleW(
539                       [In] string principal,
540                       [In] string moduleName,
541                       [In] int usage,
542                       [In] void* logonID,
543                       [In] IntPtr zero,
544                       [In] void* keyCallback,
545                       [In] void* keyArgument,
546                       ref  SSPIHandle handlePtr,
547                       [Out] out long timeStamp
548                       );
549
550             //  Win7+
551             [DllImport(SECUR32, ExactSpelling = true, CharSet = CharSet.Unicode, SetLastError = true)]
552             internal unsafe static extern int AcquireCredentialsHandleW(
553                       [In] string principal,
554                       [In] string moduleName,
555                       [In] int usage,
556                       [In] void* logonID,
557                       [In] SafeSspiAuthDataHandle authdata,
558                       [In] void* keyCallback,
559                       [In] void* keyArgument,
560                       ref  SSPIHandle handlePtr,
561                       [Out] out long timeStamp
562                       );
563
564             [DllImport(SECUR32, ExactSpelling=true, CharSet=CharSet.Unicode, SetLastError=true)]
565             internal unsafe  static extern int AcquireCredentialsHandleW(
566                       [In] string principal,
567                       [In] string moduleName,
568                       [In] int usage,
569                       [In] void* logonID,
570                       [In] ref SecureCredential authData,
571                       [In] void* keyCallback,
572                       [In] void* keyArgument,
573                       ref  SSPIHandle handlePtr,
574                       [Out] out long timeStamp
575                       );
576
577             [DllImport(SECUR32, ExactSpelling=true, SetLastError=true)]
578             [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
579             internal unsafe static extern int InitializeSecurityContextW(
580                       ref  SSPIHandle       credentialHandle,
581                       [In] void*            inContextPtr,
582                       [In] byte*            targetName,
583                       [In] ContextFlags     inFlags,
584                       [In] int              reservedI,
585                       [In] Endianness       endianness,
586                       [In] SecurityBufferDescriptor inputBuffer,
587                       [In] int              reservedII,
588                       ref  SSPIHandle       outContextPtr,
589                       [In, Out] SecurityBufferDescriptor outputBuffer,
590                       [In, Out] ref ContextFlags attributes,
591                       out  long timeStamp
592                       );
593
594             [DllImport(SECUR32, ExactSpelling=true, SetLastError=true)]
595             [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
596             internal unsafe static extern int CompleteAuthToken(
597                       [In] void*            inContextPtr,
598                       [In, Out] SecurityBufferDescriptor inputBuffers
599                       );
600
601         }
602         
603 #endif // !FEATURE_PAL
604
605         // Because the regular SafeNetHandles has a LocalAlloc with a different return type.
606         [System.Security.SuppressUnmanagedCodeSecurityAttribute()]
607         internal static class SafeNetHandlesSafeOverlappedFree {
608             [DllImport(ExternDll.Kernel32, ExactSpelling=true, SetLastError=true)]
609             internal static extern SafeOverlappedFree LocalAlloc(int uFlags, UIntPtr sizetdwBytes);
610         }
611
612 #if !FEATURE_PAL
613         // Because the regular SafeNetHandles tries to bind this MustRun method on type initialization, failing
614         // on legacy platforms.
615         [System.Security.SuppressUnmanagedCodeSecurityAttribute()]
616         internal static class SafeNetHandlesXPOrLater {
617             [DllImport(WS2_32, ExactSpelling = true, CharSet = CharSet.Unicode, BestFitMapping = false, ThrowOnUnmappableChar = true, SetLastError = true)]
618             internal static extern int GetAddrInfoW(
619                 [In] string nodename,
620                 [In] string servicename,
621                 [In] ref AddressInfo hints,
622                 [Out] out SafeFreeAddrInfo handle
623                 );
624
625             [DllImport(WS2_32, ExactSpelling = true, SetLastError = true)]
626             [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
627             internal static extern void freeaddrinfo([In] IntPtr info );
628         }
629 #endif
630
631         [System.Security.SuppressUnmanagedCodeSecurityAttribute()]
632         internal static class SafeNetHandles {
633
634     #if !FEATURE_PAL
635             [DllImport(SECUR32, ExactSpelling=true, SetLastError=true)]
636             internal static extern int QuerySecurityContextToken(ref SSPIHandle phContext, [Out] out SafeCloseHandle handle);
637
638             [SuppressMessage("Microsoft.Security", "CA2118:ReviewSuppressUnmanagedCodeSecurityUsage", Justification = "Implementation requires unmanaged code usage")]
639             [DllImport(HTTPAPI, ExactSpelling = true, CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode, SetLastError = true)]
640             internal static extern unsafe uint HttpCreateRequestQueue(HttpApi.HTTPAPI_VERSION version, string pName,
641                 Microsoft.Win32.NativeMethods.SECURITY_ATTRIBUTES pSecurityAttributes, uint flags, out HttpRequestQueueV2Handle pReqQueueHandle);
642
643             [DllImport(HTTPAPI, ExactSpelling = true, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
644             internal static extern unsafe uint HttpCloseRequestQueue(IntPtr pReqQueueHandle);
645
646     #endif
647
648             [DllImport(ExternDll.Kernel32, ExactSpelling=true, SetLastError=true)]
649             [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
650             internal static extern bool CloseHandle(IntPtr handle);
651
652             [DllImport(ExternDll.Kernel32, ExactSpelling=true, SetLastError=true)]
653             internal static extern SafeLocalFree LocalAlloc(int uFlags, UIntPtr sizetdwBytes);
654
655             [DllImport(ExternDll.Kernel32, EntryPoint = "LocalAlloc", SetLastError = true)]
656             internal static extern SafeLocalFreeChannelBinding LocalAllocChannelBinding(int uFlags, UIntPtr sizetdwBytes);
657
658             [DllImport(ExternDll.Kernel32, ExactSpelling=true, SetLastError=true)]
659             [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
660             internal static extern IntPtr LocalFree(IntPtr handle);
661
662 #if !FEATURE_PAL
663
664             [DllImport(KERNEL32, ExactSpelling=true, CharSet=CharSet.Unicode, SetLastError=true)]
665             internal static extern unsafe SafeLoadLibrary LoadLibraryExW([In] string lpwLibFileName, [In] void* hFile, [In] uint dwFlags);
666 #endif // !FEATURE_PAL
667
668
669             [DllImport(KERNEL32, ExactSpelling=true, SetLastError=true)]
670             [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
671             internal static extern unsafe bool FreeLibrary([In] IntPtr hModule);
672
673 #if !FEATURE_PAL
674
675             /*
676             // Consider removing.
677             [DllImport(CRYPT32, ExactSpelling=true, SetLastError=true)]
678             internal static extern  bool CertGetCertificateChain(
679                 [In] IntPtr                 chainEngine,
680                 [In] SafeFreeCertContext    certContext,
681                 [In] IntPtr                 time,
682                 [In] SafeCloseStore         additionalStore,
683                 [In] ref ChainParameters    certCP,
684                 [In] int                    flags,
685                 [In] IntPtr                 reserved,
686                 [Out] out SafeFreeCertChain  chainContext);
687             */
688
689             [DllImport(CRYPT32, ExactSpelling=true, SetLastError=true)]
690             [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
691             internal static extern void CertFreeCertificateChain(
692                 [In] IntPtr pChainContext);
693
694             [DllImport(CRYPT32, ExactSpelling = true, SetLastError = true)]
695             [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
696             internal static extern void CertFreeCertificateChainList(
697                 [In] IntPtr ppChainContext);
698
699             [DllImport(CRYPT32, ExactSpelling=true, SetLastError=true)]
700             [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
701             internal static extern bool CertFreeCertificateContext(      // Suppressing returned status check, it's always==TRUE,
702                 [In] IntPtr certContext);
703
704             /*
705             // Consider removing.
706             [DllImport(CRYPT32, ExactSpelling=true, SetLastError=true)]
707             [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
708             internal static extern bool CertCloseStore(
709                 [In] IntPtr hCertStore,
710                 [In] int dwFlags);
711             */
712
713 #endif // !FEATURE_PAL
714
715             [DllImport(ExternDll.Kernel32, ExactSpelling=true, SetLastError=true)]
716             [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
717             internal static extern IntPtr GlobalFree(IntPtr handle);
718
719             // Blocking call - requires IntPtr instead of SafeCloseSocket.
720             [DllImport(WS2_32, ExactSpelling=true, SetLastError=true)]
721             internal static extern SafeCloseSocket.InnerSafeCloseSocket accept(
722                                                   [In] IntPtr socketHandle,
723                                                   [Out] byte[] socketAddress,
724                                                   [In, Out] ref int socketAddressSize
725                                                   );
726
727             [DllImport(WS2_32, ExactSpelling=true, SetLastError=true)]
728             [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
729             internal static extern SocketError closesocket(
730                                                   [In] IntPtr socketHandle
731                                                   );
732
733             [DllImport(WS2_32, ExactSpelling=true, SetLastError=true)]
734             [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
735             internal static extern SocketError ioctlsocket(
736                                                 [In] IntPtr handle,
737                                                 [In] int cmd,
738                                                 [In, Out] ref int argp
739                                                 );
740
741             [DllImport(WS2_32, ExactSpelling=true, SetLastError=true)]
742             [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
743             internal static extern SocketError WSAEventSelect(
744                                                      [In] IntPtr handle,
745                                                      [In] IntPtr Event,
746                                                      [In] AsyncEventBits NetworkEvents
747                                                      );
748
749             [DllImport(WS2_32, ExactSpelling=true, SetLastError=true)]
750             [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
751             internal static extern SocketError setsockopt(
752                                                [In] IntPtr handle,
753                                                [In] SocketOptionLevel optionLevel,
754                                                [In] SocketOptionName optionName,
755                                                [In] ref Linger linger,
756                                                [In] int optionLength
757                                                );
758
759             /* Consider removing
760             [DllImport(WS2_32, ExactSpelling=true, SetLastError=true)]
761             [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
762             internal static extern SocketError setsockopt(
763                                                [In] IntPtr handle,
764                                                [In] SocketOptionLevel optionLevel,
765                                                [In] SocketOptionName optionName,
766                                                [In] ref int optionValue,
767                                                [In] int optionLength
768                                                );
769             */
770
771 #if !FEATURE_PAL
772             [DllImport(WININET, ExactSpelling=true, SetLastError = true)]
773             [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
774             unsafe internal static extern bool RetrieveUrlCacheEntryFileW(
775                                             [In]      char*     urlName,
776                                             [In]      byte*     entryPtr,               //was [Out]
777                                             [In, Out] ref int   entryBufSize,
778                                             [In]      int       dwReserved              //must be 0
779                                             );
780
781             [DllImport(WININET, ExactSpelling=true, SetLastError = true)]
782             [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
783             unsafe internal static extern bool UnlockUrlCacheEntryFileW(
784                                             [In]    char*       urlName,
785                                             [In]    int         dwReserved                  //must be 0
786                                             );
787 #endif // !FEATURE_PAL
788         }
789
790         //
791         // UnsafeNclNativeMethods.OSSOCK class contains all Unsafe() calls and should all be protected
792         // by the appropriate SocketPermission() to connect/accept to/from remote
793         // peers over the network and to perform name resolution.
794         // te following calls deal mainly with:
795         // 1) socket calls
796         // 2) DNS calls
797         //
798
799         //
800         // here's a brief explanation of all possible decorations we use for PInvoke.
801         // these are used in such a way that we hope to gain maximum performance from the
802         // unmanaged/managed/unmanaged transition we need to undergo when calling into winsock:
803         //
804         // [In] (Note: this is similar to what msdn will show)
805         // the managed data will be marshalled so that the unmanaged function can read it but even
806         // if it is changed in unmanaged world, the changes won't be propagated to the managed data
807         //
808         // [Out] (Note: this is similar to what msdn will show)
809         // the managed data will not be marshalled so that the unmanaged function will not see the
810         // managed data, if the data changes in unmanaged world, these changes will be propagated by
811         // the marshaller to the managed data
812         //
813         // objects are marshalled differently if they're:
814         //
815         // 1) structs
816         // for structs, by default, the whole layout is pushed on the stack as it is.
817         // in order to pass a pointer to the managed layout, we need to specify either the ref or out keyword.
818         //
819         //      a) for IN and OUT:
820         //      [In, Out] ref Struct ([In, Out] is optional here)
821         //
822         //      b) for IN only (the managed data will be marshalled so that the unmanaged
823         //      function can read it but even if it changes it the change won't be propagated
824         //      to the managed struct)
825         //      [In] ref Struct
826         //
827         //      c) for OUT only (the managed data will not be marshalled so that the
828         //      unmanaged function cannot read, the changes done in unmanaged code will be
829         //      propagated to the managed struct)
830         //      [Out] out Struct ([Out] is optional here)
831         //
832         // 2) array or classes
833         // for array or classes, by default, a pointer to the managed layout is passed.
834         // we don't need to specify neither the ref nor the out keyword.
835         //
836         //      a) for IN and OUT:
837         //      [In, Out] byte[]
838         //
839         //      b) for IN only (the managed data will be marshalled so that the unmanaged
840         //      function can read it but even if it changes it the change won't be propagated
841         //      to the managed struct)
842         //      [In] byte[] ([In] is optional here)
843         //
844         //      c) for OUT only (the managed data will not be marshalled so that the
845         //      unmanaged function cannot read, the changes done in unmanaged code will be
846         //      propagated to the managed struct)
847         //      [Out] byte[]
848         //
849         [System.Security.SuppressUnmanagedCodeSecurityAttribute()]
850         internal static class OSSOCK {
851
852 #if FEATURE_PAL
853             private const string WS2_32 = ROTOR_PAL;
854 #else
855             private const string WS2_32 = "ws2_32.dll";
856             private const string mswsock = "mswsock.dll";
857 #endif
858
859             //
860             // IPv6 Changes: These are initialized in InitializeSockets - don't set them here or
861             //               there will be an ordering problem with the call above that will
862             //               result in both being set to false !
863             //
864
865             [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Auto)]
866             internal struct WSAPROTOCOLCHAIN {
867                 internal int ChainLen;                                 /* the length of the chain,     */
868                 [MarshalAs(UnmanagedType.ByValArray, SizeConst=7)]
869                 internal uint[] ChainEntries;       /* a list of dwCatalogEntryIds */
870             }
871
872             [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Auto)]
873             internal struct WSAPROTOCOL_INFO {
874                 internal uint dwServiceFlags1;
875                 internal uint dwServiceFlags2;
876                 internal uint dwServiceFlags3;
877                 internal uint dwServiceFlags4;
878                 internal uint dwProviderFlags;
879                 Guid ProviderId;
880                 internal uint dwCatalogEntryId;
881                 WSAPROTOCOLCHAIN ProtocolChain;
882                 internal int iVersion;
883                 internal AddressFamily iAddressFamily;
884                 internal int iMaxSockAddr;
885                 internal int iMinSockAddr;
886                 internal int iSocketType;
887                 internal int iProtocol;
888                 internal int iProtocolMaxOffset;
889                 internal int iNetworkByteOrder;
890                 internal int iSecurityScheme;
891                 internal uint dwMessageSize;
892                 internal uint dwProviderReserved;
893                 [MarshalAs(UnmanagedType.ByValTStr, SizeConst=256)]
894                 internal string szProtocol;
895             }
896
897             [StructLayout(LayoutKind.Sequential)]
898             internal struct ControlData {
899                 internal UIntPtr length;
900                 internal uint level;
901                 internal uint type;
902                 internal uint address;
903                 internal uint index;
904             }
905
906             [StructLayout(LayoutKind.Sequential)]
907             internal struct ControlDataIPv6 {
908                 internal UIntPtr length;
909                 internal uint level;
910                 internal uint type;
911                 [MarshalAs(UnmanagedType.ByValArray,SizeConst=16)]
912                 internal byte[] address;
913                 internal uint index;
914             }
915
916             [StructLayout(LayoutKind.Sequential)]
917             internal struct WSAMsg {
918                 internal IntPtr socketAddress;
919                 internal uint addressLength;
920                 internal IntPtr buffers;
921                 internal uint count;
922                 internal WSABuffer controlBuffer;
923                 internal SocketFlags flags;
924             }
925             
926             //
927             // Flags equivalent to winsock TRANSMIT_PACKETS_ELEMENT flags
928             //    #define TP_ELEMENT_MEMORY   1
929             //    #define TP_ELEMENT_FILE     2
930             //    #define TP_ELEMENT_EOP      4
931             //
932             [Flags]
933             internal enum TransmitPacketsElementFlags : uint {
934                 None = 0x00,
935                 Memory = 0x01,
936                 File = 0x02,
937                 EndOfPacket = 0x04
938             }
939
940             // Structure equivalent to TRANSMIT_PACKETS_ELEMENT
941             //
942             // typedef struct _TRANSMIT_PACKETS_ELEMENT {
943             //     ULONG dwElFlags;  
944             //     ULONG cLength;  
945             //     union {    
946             //         struct {      
947             //             LARGE_INTEGER nFileOffset;      
948             //             HANDLE hFile;
949             //         };    
950             //         PVOID pBuffer;  
951             //     }
952             //  };
953             // } TRANSMIT_PACKETS_ELEMENT;
954             //
955             [StructLayout(LayoutKind.Explicit)]
956             internal struct TransmitPacketsElement {
957                 [System.Runtime.InteropServices.FieldOffset(0)]
958                 internal TransmitPacketsElementFlags flags;
959                 [System.Runtime.InteropServices.FieldOffset(4)]
960                 internal uint length;
961                 [System.Runtime.InteropServices.FieldOffset(8)]
962                 internal Int64 fileOffset;
963                 [System.Runtime.InteropServices.FieldOffset(8)]
964                 internal IntPtr buffer;
965                 [System.Runtime.InteropServices.FieldOffset(16)]
966                 internal IntPtr fileHandle;
967             }
968              
969             /*
970                typedef struct _SOCKET_ADDRESS {  
971                    PSOCKADDR lpSockaddr;  
972                    INT iSockaddrLength;
973                } SOCKET_ADDRESS, *PSOCKET_ADDRESS;                      
974             */
975             [StructLayout(LayoutKind.Sequential)]
976             internal struct SOCKET_ADDRESS {
977                 internal IntPtr lpSockAddr;
978                 internal int iSockaddrLength;
979             }
980
981             /*
982                typedef struct _SOCKET_ADDRESS_LIST {
983                    INT             iAddressCount;
984                    SOCKET_ADDRESS  Address[1];
985                } SOCKET_ADDRESS_LIST, *PSOCKET_ADDRESS_LIST, FAR *LPSOCKET_ADDRESS_LIST;
986             */
987             [StructLayout(LayoutKind.Sequential)]
988             internal struct SOCKET_ADDRESS_LIST {
989                 internal int iAddressCount;            
990                 internal SOCKET_ADDRESS Addresses;
991             }
992
993             [StructLayout(LayoutKind.Sequential)]
994             internal struct TransmitFileBuffersStruct {
995                 internal IntPtr preBuffer;// Pointer to Buffer
996                 internal int preBufferLength; // Length of Buffer
997                 internal IntPtr postBuffer;// Pointer to Buffer
998                 internal int postBufferLength; // Length of Buffer
999             }
1000
1001             // CharSet=Auto here since WSASocket has A and W versions. We can use Auto cause the method is not used under constrained execution region
1002             [DllImport(WS2_32, CharSet=CharSet.Auto, SetLastError=true)]
1003             internal static extern SafeCloseSocket.InnerSafeCloseSocket WSASocket(
1004                                                     [In] AddressFamily addressFamily,
1005                                                     [In] SocketType socketType,
1006                                                     [In] ProtocolType protocolType,
1007                                                     [In] IntPtr protocolInfo, // will be WSAProtcolInfo protocolInfo once we include QOS APIs
1008                                                     [In] uint group,
1009                                                     [In] SocketConstructorFlags flags
1010                                                     );
1011
1012             [DllImport(WS2_32, CharSet=CharSet.Auto, SetLastError=true)]
1013             internal unsafe static extern SafeCloseSocket.InnerSafeCloseSocket WSASocket(
1014                                         [In] AddressFamily addressFamily,
1015                                         [In] SocketType socketType,
1016                                         [In] ProtocolType protocolType,
1017                                         [In] byte* pinnedBuffer, // will be WSAProtcolInfo protocolInfo once we include QOS APIs
1018                                         [In] uint group,
1019                                         [In] SocketConstructorFlags flags
1020                                         );
1021
1022
1023             [DllImport(WS2_32, CharSet=CharSet.Ansi, BestFitMapping=false, ThrowOnUnmappableChar=true, SetLastError=true)]
1024             internal static extern SocketError WSAStartup(
1025                                                [In] short wVersionRequested,
1026                                                [Out] out WSAData lpWSAData
1027                                                );
1028
1029             [DllImport(WS2_32, SetLastError=true)]
1030             [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
1031             internal static extern SocketError ioctlsocket(
1032                                                 [In] SafeCloseSocket socketHandle,
1033                                                 [In] int cmd,
1034                                                 [In, Out] ref int argp
1035                                                 );
1036
1037             [DllImport(WS2_32, CharSet=CharSet.Ansi, BestFitMapping=false, ThrowOnUnmappableChar=true, SetLastError=true)]
1038             internal static extern IntPtr gethostbyname(
1039                                                   [In] string host
1040                                                   );
1041
1042             [DllImport(WS2_32, SetLastError=true)]
1043             internal static extern IntPtr gethostbyaddr(
1044                                                   [In] ref int addr,
1045                                                   [In] int len,
1046                                                   [In] ProtocolFamily type
1047                                                   );
1048
1049             [DllImport(WS2_32, CharSet=CharSet.Ansi, BestFitMapping=false, ThrowOnUnmappableChar=true, SetLastError=true)]
1050             internal static extern SocketError gethostname(
1051                                                 [Out] StringBuilder hostName,
1052                                                 [In] int bufferLength
1053                                                 );
1054
1055             [DllImport(WS2_32, SetLastError=true)]
1056             internal static extern SocketError getpeername(
1057                                                 [In] SafeCloseSocket socketHandle,
1058                                                 [Out] byte[] socketAddress,
1059                                                 [In, Out] ref int socketAddressSize
1060                                                 );
1061
1062             [DllImport(WS2_32, SetLastError=true)]
1063             internal static extern SocketError getsockopt(
1064                                                [In] SafeCloseSocket socketHandle,
1065                                                [In] SocketOptionLevel optionLevel,
1066                                                [In] SocketOptionName optionName,
1067                                                [Out] out int optionValue,
1068                                                [In, Out] ref int optionLength
1069                                                );
1070
1071             [DllImport(WS2_32, SetLastError=true)]
1072             internal static extern SocketError getsockopt(
1073                                                [In] SafeCloseSocket socketHandle,
1074                                                [In] SocketOptionLevel optionLevel,
1075                                                [In] SocketOptionName optionName,
1076                                                [Out] byte[] optionValue,
1077                                                [In, Out] ref int optionLength
1078                                                );
1079
1080             [DllImport(WS2_32, SetLastError=true)]
1081             internal static extern SocketError getsockopt(
1082                                                [In] SafeCloseSocket socketHandle,
1083                                                [In] SocketOptionLevel optionLevel,
1084                                                [In] SocketOptionName optionName,
1085                                                [Out] out Linger optionValue,
1086                                                [In, Out] ref int optionLength
1087                                                );
1088
1089             [DllImport(WS2_32, SetLastError=true)]
1090             internal static extern SocketError getsockopt(
1091                                                [In] SafeCloseSocket socketHandle,
1092                                                [In] SocketOptionLevel optionLevel,
1093                                                [In] SocketOptionName optionName,
1094                                                [Out] out IPMulticastRequest optionValue,
1095                                                [In, Out] ref int optionLength
1096                                                );
1097
1098             //
1099             // IPv6 Changes: need to receive and IPv6MulticastRequest from getsockopt
1100             //
1101             [DllImport(WS2_32, SetLastError=true)]
1102             internal static extern SocketError getsockopt(
1103                                                [In] SafeCloseSocket socketHandle,
1104                                                [In] SocketOptionLevel optionLevel,
1105                                                [In] SocketOptionName optionName,
1106                                                [Out] out IPv6MulticastRequest optionValue,
1107                                                [In, Out] ref int optionLength
1108                                                );
1109
1110             [DllImport(WS2_32, SetLastError=true)]
1111             internal static extern SocketError setsockopt(
1112                                                [In] SafeCloseSocket socketHandle,
1113                                                [In] SocketOptionLevel optionLevel,
1114                                                [In] SocketOptionName optionName,
1115                                                [In] ref int optionValue,
1116                                                [In] int optionLength
1117                                                );
1118
1119             [DllImport(WS2_32, SetLastError=true)]
1120             internal static extern SocketError setsockopt(
1121                                                [In] SafeCloseSocket socketHandle,
1122                                                [In] SocketOptionLevel optionLevel,
1123                                                [In] SocketOptionName optionName,
1124                                                [In] byte[] optionValue,
1125                                                [In] int optionLength
1126                                                );
1127
1128             [DllImport(WS2_32, SetLastError=true)]
1129             internal static extern SocketError setsockopt(
1130                                                [In] SafeCloseSocket socketHandle,
1131                                                [In] SocketOptionLevel optionLevel,
1132                                                [In] SocketOptionName optionName,
1133                                                [In] ref IntPtr pointer,
1134                                                [In] int optionLength
1135                                                );
1136
1137             [DllImport(WS2_32, SetLastError=true)]
1138             [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
1139             internal static extern SocketError setsockopt(
1140                                                [In] SafeCloseSocket socketHandle,
1141                                                [In] SocketOptionLevel optionLevel,
1142                                                [In] SocketOptionName optionName,
1143                                                [In] ref Linger linger,
1144                                                [In] int optionLength
1145                                                );
1146
1147             [DllImport(WS2_32, SetLastError=true)]
1148             internal static extern SocketError setsockopt(
1149                                                [In] SafeCloseSocket socketHandle,
1150                                                [In] SocketOptionLevel optionLevel,
1151                                                [In] SocketOptionName optionName,
1152                                                [In] ref IPMulticastRequest mreq,
1153                                                [In] int optionLength
1154                                                );
1155
1156             //
1157             // IPv6 Changes: need to pass an IPv6MulticastRequest to setsockopt
1158             //
1159             [DllImport(WS2_32, SetLastError=true)]
1160             internal static extern SocketError setsockopt(
1161                                                [In] SafeCloseSocket socketHandle,
1162                                                [In] SocketOptionLevel optionLevel,
1163                                                [In] SocketOptionName optionName,
1164                                                [In] ref IPv6MulticastRequest mreq,
1165                                                [In] int optionLength
1166                                                );
1167
1168 #if !FEATURE_PAL
1169
1170             [DllImport(mswsock, SetLastError=true)]
1171             internal static extern bool TransmitFile(
1172                                       [In] SafeCloseSocket socket,
1173                                       [In] SafeHandle fileHandle,
1174                                       [In] int numberOfBytesToWrite,
1175                                       [In] int numberOfBytesPerSend,
1176                                       [In] SafeHandle overlapped,
1177                                       [In] TransmitFileBuffers buffers,
1178                                       [In] TransmitFileOptions flags
1179                                       );
1180         
1181             [DllImport(mswsock, SetLastError=true, EntryPoint = "TransmitFile")]
1182             internal static extern bool TransmitFile2(
1183                                       [In] SafeCloseSocket socket,
1184                                       [In] IntPtr fileHandle,
1185                                       [In] int numberOfBytesToWrite,
1186                                       [In] int numberOfBytesPerSend,
1187                                       [In] SafeHandle overlapped,
1188                                       [In] TransmitFileBuffers buffers,
1189                                       [In] TransmitFileOptions flags
1190                                       );
1191
1192
1193             [DllImport(mswsock, SetLastError = true, EntryPoint = "TransmitFile")]
1194             internal static extern bool TransmitFile_Blocking(
1195                                       [In] IntPtr socket,
1196                                       [In] SafeHandle fileHandle,
1197                                       [In] int numberOfBytesToWrite,
1198                                       [In] int numberOfBytesPerSend,
1199                                       [In] SafeHandle overlapped,
1200                                       [In] TransmitFileBuffers buffers,
1201                                       [In] TransmitFileOptions flags
1202                                       );
1203
1204             [DllImport(mswsock, SetLastError = true, EntryPoint = "TransmitFile")]
1205             internal static extern bool TransmitFile_Blocking2(
1206                                       [In] IntPtr socket,
1207                                       [In] IntPtr fileHandle,
1208                                       [In] int numberOfBytesToWrite,
1209                                       [In] int numberOfBytesPerSend,
1210                                       [In] SafeHandle overlapped,
1211                                       [In] TransmitFileBuffers buffers,
1212                                       [In] TransmitFileOptions flags
1213                                       );
1214
1215 #endif // !FEATURE_PAL
1216
1217             // This method is always blocking, so it uses an IntPtr.
1218             [DllImport(WS2_32, SetLastError = true)]
1219             internal unsafe static extern int send(
1220                                          [In] IntPtr      socketHandle,
1221                                          [In] byte*       pinnedBuffer,
1222                                          [In] int         len,
1223                                          [In] SocketFlags socketFlags
1224                                          );
1225
1226             // This method is always blocking, so it uses an IntPtr.
1227             [DllImport(WS2_32, SetLastError = true)]
1228             internal unsafe static extern int recv(
1229                                          [In] IntPtr      socketHandle,
1230                                          [In] byte*       pinnedBuffer,
1231                                          [In] int         len,
1232                                          [In] SocketFlags socketFlags
1233                                          );
1234
1235             [DllImport(WS2_32, SetLastError=true)]
1236             internal static extern SocketError listen(
1237                                            [In] SafeCloseSocket socketHandle,
1238                                            [In] int backlog
1239                                            );
1240
1241             [DllImport(WS2_32, SetLastError=true)]
1242             internal static extern SocketError bind(
1243                                          [In] SafeCloseSocket socketHandle,
1244                                          [In] byte[] socketAddress,
1245                                          [In] int socketAddressSize
1246                                          );
1247
1248             [DllImport(WS2_32, SetLastError=true)]
1249             internal static extern SocketError shutdown(
1250                                              [In] SafeCloseSocket socketHandle,
1251                                              [In] int how
1252                                              );
1253
1254             // This method is always blocking, so it uses an IntPtr.
1255             [DllImport(WS2_32, SetLastError = true)]
1256             internal unsafe static extern int sendto(
1257                                            [In] IntPtr      socketHandle,
1258                                            [In] byte*       pinnedBuffer,
1259                                            [In] int         len,
1260                                            [In] SocketFlags socketFlags,
1261                                            [In] byte[]      socketAddress,
1262                                            [In] int         socketAddressSize
1263                                            );
1264
1265             // This method is always blocking, so it uses an IntPtr.
1266             [DllImport(WS2_32, SetLastError = true)]
1267             internal unsafe static extern int recvfrom(
1268                                              [In] IntPtr        socketHandle,
1269                                              [In] byte*         pinnedBuffer,
1270                                              [In] int           len,
1271                                              [In] SocketFlags   socketFlags,
1272                                              [Out] byte[]       socketAddress,
1273                                              [In, Out] ref int  socketAddressSize
1274                                              );
1275
1276             [DllImport(WS2_32, SetLastError=true)]
1277             internal static extern SocketError getsockname(
1278                                                 [In] SafeCloseSocket socketHandle,
1279                                                 [Out] byte[] socketAddress,
1280                                                 [In, Out] ref int socketAddressSize
1281                                                 );
1282
1283             [DllImport(WS2_32, SetLastError=true)]
1284             internal static extern int select(
1285                                            [In] int ignoredParameter,
1286                                            [In, Out] IntPtr[] readfds,
1287                                            [In, Out] IntPtr[] writefds,
1288                                            [In, Out] IntPtr[] exceptfds,
1289                                            [In] ref TimeValue timeout
1290                                            );
1291
1292             [DllImport(WS2_32, SetLastError=true)]
1293             internal static extern int select(
1294                                            [In] int ignoredParameter,
1295                                            [In, Out] IntPtr[] readfds,
1296                                            [In, Out] IntPtr[] writefds,
1297                                            [In, Out] IntPtr[] exceptfds,
1298                                            [In] IntPtr nullTimeout
1299                                            );
1300
1301             // This function is always potentially blocking so it uses an IntPtr.
1302             [DllImport(WS2_32, SetLastError = true)]
1303             internal static extern SocketError WSAConnect(
1304                                               [In] IntPtr socketHandle,
1305                                               [In] byte[] socketAddress,
1306                                               [In] int    socketAddressSize,
1307                                               [In] IntPtr inBuffer,
1308                                               [In] IntPtr outBuffer,
1309                                               [In] IntPtr sQOS,
1310                                               [In] IntPtr gQOS
1311                                               );
1312
1313
1314             [DllImport(WS2_32, SetLastError=true)]
1315             internal static extern SocketError WSASend(
1316                                               [In] SafeCloseSocket socketHandle,
1317                                               [In] ref WSABuffer buffer,
1318                                               [In] int bufferCount,
1319                                               [Out] out int bytesTransferred,
1320                                               [In] SocketFlags socketFlags,
1321                                               [In] SafeHandle overlapped,
1322                                               [In] IntPtr completionRoutine
1323                                               );
1324
1325             [DllImport(WS2_32, SetLastError=true)]
1326             internal static extern SocketError WSASend(
1327                                               [In] SafeCloseSocket socketHandle,
1328                                               [In] WSABuffer[] buffersArray,
1329                                               [In] int bufferCount,
1330                                               [Out] out int bytesTransferred,
1331                                               [In] SocketFlags socketFlags,
1332                                               [In] SafeHandle overlapped,
1333                                               [In] IntPtr completionRoutine
1334                                               );
1335
1336             [DllImport(WS2_32, SetLastError = true, EntryPoint = "WSASend")]
1337             internal static extern SocketError WSASend_Blocking(
1338                                               [In] IntPtr socketHandle,
1339                                               [In] WSABuffer[] buffersArray,
1340                                               [In] int bufferCount,
1341                                               [Out] out int bytesTransferred,
1342                                               [In] SocketFlags socketFlags,
1343                                               [In] SafeHandle overlapped,
1344                                               [In] IntPtr completionRoutine
1345                                               );
1346
1347             [DllImport(WS2_32, SetLastError = true)]
1348             internal static extern SocketError WSASendTo(
1349                                                 [In] SafeCloseSocket socketHandle,
1350                                                 [In] ref WSABuffer buffer,
1351                                                 [In] int bufferCount,
1352                                                 [Out] out int bytesTransferred,
1353                                                 [In] SocketFlags socketFlags,
1354                                                 [In] IntPtr socketAddress,
1355                                                 [In] int socketAddressSize,
1356                                                 [In] SafeHandle overlapped,
1357                                                 [In] IntPtr completionRoutine
1358                                                 );
1359             
1360             [DllImport(WS2_32, SetLastError = true)]
1361             internal static extern SocketError WSASendTo(
1362                                                 [In] SafeCloseSocket socketHandle,
1363                                                 [In] WSABuffer[] buffersArray,
1364                                                 [In] int bufferCount,
1365                                                 [Out] out int bytesTransferred,
1366                                                 [In] SocketFlags socketFlags,
1367                                                 [In] IntPtr socketAddress,
1368                                                 [In] int socketAddressSize,
1369                                                 [In] SafeNativeOverlapped overlapped,
1370                                                 [In] IntPtr completionRoutine
1371                                                 );
1372
1373             [DllImport(WS2_32, SetLastError=true)]
1374             internal static extern SocketError WSARecv(
1375                                               [In] SafeCloseSocket socketHandle,
1376                                               [In] ref WSABuffer buffer,
1377                                               [In] int bufferCount,
1378                                               [Out] out int bytesTransferred,
1379                                               [In, Out] ref SocketFlags socketFlags,
1380                                               [In] SafeHandle overlapped,
1381                                               [In] IntPtr completionRoutine
1382                                               );
1383
1384             [DllImport(WS2_32, SetLastError = true)]
1385             internal static extern SocketError WSARecv(
1386                                               [In] SafeCloseSocket socketHandle,
1387                                               [In, Out] WSABuffer[] buffers,
1388                                               [In] int bufferCount,
1389                                               [Out] out int bytesTransferred,
1390                                               [In, Out] ref SocketFlags socketFlags,
1391                                               [In] SafeHandle overlapped,
1392                                               [In] IntPtr completionRoutine
1393                                               );
1394
1395             [DllImport(WS2_32, SetLastError = true, EntryPoint = "WSARecv")]
1396             internal static extern SocketError WSARecv_Blocking(
1397                                               [In] IntPtr socketHandle,
1398                                               [In, Out] WSABuffer[] buffers,
1399                                               [In] int bufferCount,
1400                                               [Out] out int bytesTransferred,
1401                                               [In, Out] ref SocketFlags socketFlags,
1402                                               [In] SafeHandle overlapped,
1403                                               [In] IntPtr completionRoutine
1404                                               );
1405
1406             [DllImport(WS2_32, SetLastError=true)]
1407             internal static extern SocketError WSARecvFrom(
1408                                                   [In] SafeCloseSocket socketHandle,
1409                                                   [In] ref WSABuffer buffer,
1410                                                   [In] int bufferCount,
1411                                                   [Out] out int bytesTransferred,
1412                                                   [In, Out] ref SocketFlags socketFlags,
1413                                                   [In] IntPtr socketAddressPointer,
1414                                                   [In] IntPtr socketAddressSizePointer,
1415                                                   [In] SafeHandle overlapped,
1416                                                   [In] IntPtr completionRoutine
1417                                                   );
1418
1419             [DllImport(WS2_32, SetLastError = true)]
1420             internal static extern SocketError WSARecvFrom(
1421                                                   [In] SafeCloseSocket socketHandle,
1422                                                   [In, Out] WSABuffer[] buffers,
1423                                                   [In] int bufferCount,
1424                                                   [Out] out int bytesTransferred,
1425                                                   [In, Out] ref SocketFlags socketFlags,
1426                                                   [In] IntPtr socketAddressPointer,
1427                                                   [In] IntPtr socketAddressSizePointer,
1428                                                   [In] SafeNativeOverlapped overlapped,
1429                                                   [In] IntPtr completionRoutine
1430                                                   );
1431             
1432             [DllImport(WS2_32, SetLastError=true)]
1433             internal static extern SocketError WSAEventSelect(
1434                                                      [In] SafeCloseSocket socketHandle,
1435                                                      [In] SafeHandle Event,
1436                                                      [In] AsyncEventBits NetworkEvents
1437                                                      );
1438
1439             [DllImport(WS2_32, SetLastError=true)]
1440             internal static extern SocketError WSAEventSelect(
1441                                          [In] SafeCloseSocket socketHandle,
1442                                          [In] IntPtr Event,
1443                                          [In] AsyncEventBits NetworkEvents
1444                                          );
1445
1446
1447             // Used with SIOGETEXTENSIONFUNCTIONPOINTER - we're assuming that will never block.
1448             [DllImport(WS2_32, SetLastError=true)]
1449             internal static extern SocketError WSAIoctl(
1450                                                 [In] SafeCloseSocket socketHandle,
1451                                                 [In] int ioControlCode,
1452                                                 [In,Out] ref Guid guid,
1453                                                 [In] int guidSize,
1454                                                 [Out] out IntPtr funcPtr,
1455                                                 [In]  int funcPtrSize,
1456                                                 [Out] out int bytesTransferred,
1457                                                 [In] IntPtr shouldBeNull,
1458                                                 [In] IntPtr shouldBeNull2
1459                                                 );
1460
1461             [DllImport(WS2_32, SetLastError = true, EntryPoint = "WSAIoctl")]
1462             internal static extern SocketError WSAIoctl_Blocking(
1463                                                 [In] IntPtr socketHandle,
1464                                                 [In] int ioControlCode,
1465                                                 [In] byte[] inBuffer,
1466                                                 [In] int inBufferSize,
1467                                                 [Out] byte[] outBuffer,
1468                                                 [In] int outBufferSize,
1469                                                 [Out] out int bytesTransferred,
1470                                                 [In] SafeHandle overlapped,
1471                                                 [In] IntPtr completionRoutine
1472                                                 );
1473
1474             [DllImport(WS2_32, SetLastError = true, EntryPoint = "WSAIoctl")]
1475             internal static extern SocketError WSAIoctl_Blocking_Internal(
1476                                                 [In]  IntPtr socketHandle,
1477                                                 [In]  uint ioControlCode,
1478                                                 [In]  IntPtr inBuffer,
1479                                                 [In]  int inBufferSize,
1480                                                 [Out] IntPtr outBuffer,
1481                                                 [In]  int outBufferSize,
1482                                                 [Out] out int bytesTransferred,
1483                                                 [In]  SafeHandle overlapped,
1484                                                 [In]  IntPtr completionRoutine
1485                                                 );                  
1486
1487             [DllImport(WS2_32,SetLastError=true)]
1488             internal static extern SocketError WSAEnumNetworkEvents(
1489                                                      [In] SafeCloseSocket socketHandle,
1490                                                      [In] SafeWaitHandle Event,
1491                                                      [In, Out] ref NetworkEvents networkEvents
1492                                                      );
1493
1494 #if !FEATURE_PAL
1495             [DllImport(WS2_32, SetLastError=true)]
1496             internal unsafe static extern int WSADuplicateSocket(
1497                 [In] SafeCloseSocket socketHandle,
1498                 [In] uint targetProcessID,
1499                 [In] byte* pinnedBuffer
1500             );
1501 #endif // !FEATURE_PAL
1502
1503             [DllImport(WS2_32, SetLastError=true)]
1504             internal static extern bool WSAGetOverlappedResult(
1505                                                      [In] SafeCloseSocket socketHandle,
1506                                                      [In] SafeHandle overlapped,
1507                                                      [Out] out uint bytesTransferred,
1508                                                      [In] bool wait,
1509                                                      [Out] out SocketFlags socketFlags
1510                                                      );
1511 #if !FEATURE_PAL
1512             // Don't throw, it would crash IPAddress.TryParse
1513             [DllImport(WS2_32, CharSet=CharSet.Unicode, BestFitMapping=false, ThrowOnUnmappableChar=false, SetLastError=true)]
1514             internal static extern SocketError WSAStringToAddress(
1515                 [In] string addressString,
1516                 [In] AddressFamily addressFamily,
1517                 [In] IntPtr lpProtocolInfo, // always passing in a 0
1518                 [Out] byte[] socketAddress,
1519                 [In, Out] ref int socketAddressSize );
1520
1521             [DllImport(WS2_32, CharSet=CharSet.Ansi, BestFitMapping=false, ThrowOnUnmappableChar=true, SetLastError=true)]
1522             internal static extern SocketError WSAAddressToString(
1523                 [In] byte[] socketAddress,
1524                 [In] int socketAddressSize,
1525                 [In] IntPtr lpProtocolInfo,// always passing in a 0
1526                 [Out]StringBuilder addressString,
1527                 [In, Out] ref int addressStringLength);
1528
1529             [DllImport(WS2_32, CharSet=CharSet.Unicode, BestFitMapping=false, ThrowOnUnmappableChar=true, SetLastError=true)]
1530             internal static extern SocketError GetNameInfoW(
1531                 [In]         byte[]        sa,
1532                 [In]         int           salen,
1533                 [In,Out]     StringBuilder host,
1534                 [In]         int           hostlen,
1535                 [In,Out]     StringBuilder serv,
1536                 [In]         int           servlen,
1537                 [In]         int           flags);
1538
1539             //if we change this back to auto, we also have to change
1540             //WSAPROTOCOL_INFO and WSAPROTOCOLCHAIN
1541             [DllImport(WS2_32, SetLastError=true, CharSet=CharSet.Auto, ExactSpelling=false)]
1542             internal static extern int WSAEnumProtocols(
1543                                                         [MarshalAs(UnmanagedType.LPArray)]
1544                                                         [In] int[]     lpiProtocols,
1545                                                         [In] SafeLocalFree lpProtocolBuffer,
1546                                                         [In][Out] ref uint lpdwBufferLength
1547                                                        );
1548 #if SOCKETTHREADPOOL
1549             [DllImport("kernel32.dll", SetLastError = true)]
1550             public static extern bool BindIoCompletionCallback(
1551                 SafeCloseSocket socketHandle,
1552                 IOCompletionCallback function,
1553                 Int32 flags
1554             );
1555     
1556             [DllImport("kernel32.dll", SetLastError = true)]
1557             public static extern IntPtr CreateIoCompletionPort(
1558                 SafeCloseSocket socketHandle,
1559                 IntPtr ExistingCompletionPort,
1560                 Int32 CompletionKey,
1561                 Int32 NumberOfConcurrentThreads
1562             );
1563     
1564             [DllImport("kernel32.dll", SetLastError = true)]
1565             public static extern IntPtr CreateIoCompletionPort(
1566                 SafeHandle Handle,
1567                 IntPtr ExistingCompletionPort,
1568                 Int32 CompletionKey,
1569                 Int32 NumberOfConcurrentThreads
1570             );
1571             [DllImport("kernel32.dll", SetLastError = true)]
1572             public static extern IntPtr CreateIoCompletionPort(
1573                 IntPtr Handle,
1574                 IntPtr ExistingCompletionPort,
1575                 Int32 CompletionKey,
1576                 Int32 NumberOfConcurrentThreads
1577             );
1578     
1579             [DllImport("kernel32.dll", SetLastError = true)]
1580             public static extern unsafe bool GetQueuedCompletionStatus(
1581               IntPtr CompletionPort,
1582               out UInt32 lpNumberOfBytes,
1583               out Int32 lpCompletionKey,
1584               out NativeOverlapped* lpOverlapped,
1585               Int32 dwMilliseconds
1586             );
1587     
1588             [DllImport("kernel32.dll", SetLastError = true)]
1589             public static extern bool PostQueuedCompletionStatus(
1590                 IntPtr CompletionPort,
1591                 Int32 dwNumberOfBytesTransferred,
1592                 IntPtr dwCompletionKey,
1593                 IntPtr dwZero
1594             );
1595 #endif // SOCKETTHREADPOOL
1596 #endif // !FEATURE_PAL
1597
1598         }; // class UnsafeNclNativeMethods.OSSOCK
1599
1600 #if !FEATURE_PAL
1601         //
1602         // UnsafeNclNativeMethods.NativePKI class contains methods
1603         // imported from crypt32.dll.
1604         // They deal mainly with certificates handling when doing https://
1605         //
1606         [System.Security.SuppressUnmanagedCodeSecurityAttribute()]
1607         internal static class NativePKI {
1608
1609             [StructLayout(LayoutKind.Sequential)]
1610             internal struct CRYPT_OBJID_BLOB
1611             {
1612                 public UInt32 cbData;
1613                 public IntPtr pbData;
1614             }
1615
1616             [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)]
1617             internal struct CERT_EXTENSION
1618             {
1619                 public IntPtr pszObjId;
1620                 public UInt32 fCritical;
1621                 public CRYPT_OBJID_BLOB Value;
1622             }
1623
1624             [StructLayout(LayoutKind.Sequential)]
1625             internal struct CERT_SELECT_CRITERIA
1626             {
1627                 public UInt32 dwType;
1628                 public UInt32 cPara;
1629                 public IntPtr ppPara;
1630             }
1631
1632             [DllImport(CRYPT32, ExactSpelling=true, SetLastError=true)]
1633             internal static extern  int CertVerifyCertificateChainPolicy(
1634                 [In] IntPtr                     policy,
1635                 [In] SafeFreeCertChain          chainContext,
1636                 [In] ref ChainPolicyParameter   cpp,
1637                 [In, Out] ref ChainPolicyStatus ps);
1638
1639             // Win7+
1640             [DllImport(CRYPT32, ExactSpelling=true, SetLastError=true)]
1641             private static extern bool CertSelectCertificateChains(
1642                 [In] IntPtr pSelectionContext, // LPCGUID
1643                 [In] CertificateSelect flags, // DWORD
1644                 [In] IntPtr pChainParameters, // PCCERT_SELECT_CHAIN_PARA 
1645                 [In] int cCriteria, // DWORD
1646                 [In] SafeCertSelectCritera rgpCriteria, // PCCERT_SELECT_CRITERIA
1647                 [In] IntPtr hStore, // HCERTSTORE
1648                 [Out] out int pcSelection, // PDWORD
1649                 // **PCCERT_CHAIN_CONTEXT, Array of ptrs to contexts
1650                 [Out] out SafeFreeCertChainList pprgpSelection);
1651
1652             // See WinCrypt.h
1653             [Flags]
1654             private enum CertificateSelect : int
1655             {
1656                 None = 0,
1657                 AllowExpired = 0x00000001,
1658                 TrustedRoot = 0x00000002,
1659                 DisallowSelfsigned = 0x00000004,
1660                 HasPrivateKey = 0x00000008,
1661                 HasKeyForSignature = 0x00000010,
1662                 HasKeyForKeyExchange = 0x00000020,
1663                 HardwareOnly = 0x00000040,
1664                 AllowDuplicates = 0x00000080,
1665             }
1666
1667             // Discover available client certificates to send to the server.
1668             // SecureChannel will handle filtering by Issuer durring the request (AcquireClientCredentials).
1669             // See WinINet's implementation: //depot/winmain/inetcore/wininet/dll/CliauthCertselect.cxx
1670             [FriendAccessAllowed]
1671             [SuppressMessage("Microsoft.Reliability", "CA2001:AvoidCallingProblematicMethods",
1672                 Justification = "Marshalling requires DangerousGetHandle")]
1673             internal static X509CertificateCollection FindClientCertificates()
1674             {
1675                 if (!ComNetOS.IsWin7orLater)
1676                 {
1677                     throw new PlatformNotSupportedException();
1678                 }
1679
1680                 X509CertificateCollection certificates = new X509CertificateCollection();
1681
1682                 X509Store store = new X509Store(StoreName.My, StoreLocation.CurrentUser);
1683                 store.Open(OpenFlags.MaxAllowed);
1684
1685                 int chainCount = 0;
1686                 SafeFreeCertChainList chainList = null;
1687                 SafeCertSelectCritera criteria = new SafeCertSelectCritera();
1688                 try
1689                 {
1690                     bool success = CertSelectCertificateChains(
1691                         IntPtr.Zero,
1692                         CertificateSelect.HasPrivateKey, 
1693                         IntPtr.Zero,
1694                         criteria.Count,  // DWORD
1695                         criteria, // PCCERT_SELECT_CRITERIA
1696                         store.StoreHandle, 
1697                         out chainCount, 
1698                         out chainList);
1699
1700                     if (!success)
1701                     {
1702                         throw new Win32Exception(); // Calls GetLastError.
1703                     }
1704
1705                     Debug.Assert(chainCount == 0 || !chainList.IsInvalid);
1706
1707                     for (int i = 0; i < chainCount; i++)
1708                     {
1709                         // Resolve IntPtr in array.
1710                         using (SafeFreeCertChain chainRef = new SafeFreeCertChain(
1711                             Marshal.ReadIntPtr(chainList.DangerousGetHandle() 
1712                             + i * Marshal.SizeOf(typeof(IntPtr))), true))
1713                         {
1714                             Debug.Assert(!chainRef.IsInvalid);
1715
1716                             // X509Chain will duplicate the chain by increasing its ref-count.
1717                             X509Chain chain = new X509Chain(chainRef.DangerousGetHandle());
1718                             
1719                             // Copy base cert from chain.
1720                             if (chain.ChainElements.Count > 0)
1721                             {
1722                                 X509Certificate2 cert = chain.ChainElements[0].Certificate;
1723                                 certificates.Add(cert);
1724                             }
1725
1726                             // Remove the X509Chain's reference prior to releasing the Chain List.
1727                             chain.Reset();
1728                         }
1729                     }
1730                 }
1731                 finally
1732                 {
1733                     // Close store.
1734                     store.Close();
1735                     chainList.Dispose();
1736                     criteria.Dispose();
1737                 }
1738
1739                 return certificates;
1740             }
1741         }; // class UnsafeNclNativeMethods.NativePKI
1742
1743         [System.Security.SuppressUnmanagedCodeSecurityAttribute()]
1744         internal static class NativeNTSSPI {
1745
1746             [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
1747             [DllImport(SECUR32, ExactSpelling=true, SetLastError=true)]
1748             internal static extern int EncryptMessage(
1749                   ref SSPIHandle contextHandle,
1750                   [In] uint qualityOfProtection,
1751                   [In, Out] SecurityBufferDescriptor inputOutput,
1752                   [In] uint sequenceNumber
1753                   );
1754
1755             [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
1756             [DllImport(SECUR32, ExactSpelling = true, SetLastError = true)]
1757             internal static unsafe extern int DecryptMessage(
1758                   [In] ref SSPIHandle contextHandle,
1759                   [In, Out] SecurityBufferDescriptor inputOutput,
1760                   [In] uint sequenceNumber,
1761                        uint *qualityOfProtection
1762                   );
1763
1764         }; // class UnsafeNclNativeMethods.NativeNTSSPI
1765         
1766         // The replacement for WinInet, WinHttp is preferred where it's available.  We require version 5.1.
1767         [SuppressUnmanagedCodeSecurity]
1768         internal static class WinHttp
1769         {
1770             [DllImport(WINHTTP, ExactSpelling=true, SetLastError=true)]
1771             internal static extern bool WinHttpDetectAutoProxyConfigUrl(AutoDetectType autoDetectFlags, 
1772                 out SafeGlobalFree autoConfigUrl);
1773
1774             [DllImport(WINHTTP, SetLastError = true)]
1775             internal static extern bool WinHttpGetIEProxyConfigForCurrentUser(
1776                 ref WINHTTP_CURRENT_USER_IE_PROXY_CONFIG proxyConfig);
1777
1778             [SuppressMessage("Microsoft.Security", "CA2118:ReviewSuppressUnmanagedCodeSecurityUsage", Justification = "Implementation requires unmanaged code usage")]
1779             [DllImport(WINHTTP, CharSet = CharSet.Unicode, SetLastError = true)]
1780             internal static extern SafeInternetHandle WinHttpOpen(string userAgent, AccessType accessType,
1781                 string proxyName, string proxyBypass, int dwFlags);
1782
1783             [SuppressMessage("Microsoft.Security", "CA2118:ReviewSuppressUnmanagedCodeSecurityUsage", Justification = "Implementation requires unmanaged code usage")]
1784             [DllImport(WINHTTP, CharSet = CharSet.Unicode, SetLastError = true)]
1785             internal static extern bool WinHttpSetTimeouts(SafeInternetHandle session, int resolveTimeout,
1786                 int connectTimeout, int sendTimeout, int receiveTimeout);
1787
1788             [DllImport(WINHTTP, CharSet = CharSet.Unicode, SetLastError = true)]
1789             internal static extern bool WinHttpGetProxyForUrl(SafeInternetHandle session, string url,
1790                 [In] ref WINHTTP_AUTOPROXY_OPTIONS autoProxyOptions, out WINHTTP_PROXY_INFO proxyInfo);
1791
1792             [DllImport(WINHTTP, CharSet = CharSet.Unicode, SetLastError = true)]
1793             [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
1794             internal static extern bool WinHttpCloseHandle(IntPtr httpSession);
1795
1796             [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
1797             internal struct WINHTTP_CURRENT_USER_IE_PROXY_CONFIG
1798             {
1799                 public bool AutoDetect;
1800                 public IntPtr AutoConfigUrl;
1801                 public IntPtr Proxy;
1802                 public IntPtr ProxyBypass;
1803             }
1804
1805             [Flags]
1806             internal enum AutoProxyFlags
1807             {
1808                 AutoDetect = 0x00000001, // WINHTTP_AUTOPROXY_AUTO_DETECT
1809                 AutoProxyConfigUrl = 0x00000002, // WINHTTP_AUTOPROXY_CONFIG_URL
1810                 RunInProcess = 0x00010000, // WINHTTP_AUTOPROXY_RUN_INPROCESS
1811                 RunOutProcessOnly = 0x00020000 // WINHTTP_AUTOPROXY_RUN_OUTPROCESS_ONLY
1812             }
1813
1814             internal enum AccessType
1815             { 
1816                 DefaultProxy = 0,
1817                 NoProxy = 1,
1818                 NamedProxy = 3
1819             }
1820
1821             [Flags]
1822             internal enum AutoDetectType
1823             {
1824                 None = 0x0,
1825                 Dhcp = 0x1, // WINHTTP_AUTO_DETECT_TYPE_DHCP
1826                 DnsA = 0x2, // WINHTTP_AUTO_DETECT_TYPE_DNS_A
1827             }
1828
1829             [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
1830             internal struct WINHTTP_AUTOPROXY_OPTIONS
1831             {
1832                 public AutoProxyFlags Flags;
1833
1834                 public AutoDetectType AutoDetectFlags;
1835
1836                 [MarshalAs(UnmanagedType.LPWStr)]
1837                 public string AutoConfigUrl;
1838
1839                 private IntPtr lpvReserved;
1840
1841                 private int dwReserved;
1842
1843                 public bool AutoLogonIfChallenged;
1844             }
1845
1846             [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
1847             internal struct WINHTTP_PROXY_INFO
1848             {
1849                 public AccessType AccessType;
1850
1851                 public IntPtr Proxy;
1852
1853                 public IntPtr ProxyBypass;
1854             }
1855
1856             internal enum ErrorCodes
1857             {
1858                 Success = 0,
1859
1860                 OutOfHandles = 12001,                       // ERROR_WINHTTP_OUT_OF_HANDLES
1861                 Timeout = 12002,                            // ERROR_WINHTTP_TIMEOUT
1862                 InternalError = 12004,                      // ERROR_WINHTTP_INTERNAL_ERROR
1863                 InvalidUrl = 12005,                         // ERROR_WINHTTP_INVALID_URL
1864                 UnrecognizedScheme = 12006,                 // ERROR_WINHTTP_UNRECOGNIZED_SCHEME
1865                 NameNotResolved = 12007,                    // ERROR_WINHTTP_NAME_NOT_RESOLVED
1866                 InvalidOption = 12009,                      // ERROR_WINHTTP_INVALID_OPTION
1867                 OptionNotSettable = 12011,                  // ERROR_WINHTTP_OPTION_NOT_SETTABLE
1868                 Shutdown = 12012,                           // ERROR_WINHTTP_SHUTDOWN
1869
1870                 LoginFailure = 12015,                       // ERROR_WINHTTP_LOGIN_FAILURE
1871                 OperationCancelled = 12017,                 // ERROR_WINHTTP_OPERATION_CANCELLED
1872                 IncorrectHandleType = 12018,                // ERROR_WINHTTP_INCORRECT_HANDLE_TYPE
1873                 IncorrectHandleState = 12019,               // ERROR_WINHTTP_INCORRECT_HANDLE_STATE
1874                 CannotConnect = 12029,                      // ERROR_WINHTTP_CANNOT_CONNECT
1875                 ConnectionError = 12030,                    // ERROR_WINHTTP_CONNECTION_ERROR
1876                 ResendRequest = 12032,                      // ERROR_WINHTTP_RESEND_REQUEST
1877
1878                 AuthCertNeeded = 12044,                     // ERROR_WINHTTP_CLIENT_AUTH_CERT_NEEDED
1879
1880                 CannotCallBeforeOpen = 12100,               // ERROR_WINHTTP_CANNOT_CALL_BEFORE_OPEN
1881                 CannotCallBeforeSend = 12101,               // ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND
1882                 CannotCallAfterSend = 12102,                // ERROR_WINHTTP_CANNOT_CALL_AFTER_SEND
1883                 CannotCallAfterOpen = 12103,                // ERROR_WINHTTP_CANNOT_CALL_AFTER_OPEN
1884
1885                 HeaderNotFound = 12150,                     // ERROR_WINHTTP_HEADER_NOT_FOUND
1886                 InvalidServerResponse = 12152,              // ERROR_WINHTTP_INVALID_SERVER_RESPONSE
1887                 InvalidHeader = 12153,                      // ERROR_WINHTTP_INVALID_HEADER
1888                 InvalidQueryRequest = 12154,                // ERROR_WINHTTP_INVALID_QUERY_REQUEST
1889                 HeaderAlreadyExists = 12155,                // ERROR_WINHTTP_HEADER_ALREADY_EXISTS
1890                 RedirectFailed = 12156,                     // ERROR_WINHTTP_REDIRECT_FAILED
1891
1892                 AutoProxyServiceError = 12178,              // ERROR_WINHTTP_AUTO_PROXY_SERVICE_ERROR
1893                 BadAutoProxyScript = 12166,                 // ERROR_WINHTTP_BAD_AUTO_PROXY_SCRIPT
1894                 UnableToDownloadScript = 12167,             // ERROR_WINHTTP_UNABLE_TO_DOWNLOAD_SCRIPT
1895
1896                 NotInitialized = 12172,                     // ERROR_WINHTTP_NOT_INITIALIZED
1897                 SecureFailure = 12175,                      // ERROR_WINHTTP_SECURE_FAILURE
1898
1899                 SecureCertDateInvalid = 12037,              // ERROR_WINHTTP_SECURE_CERT_DATE_INVALID
1900                 SecureCertCNInvalid = 12038,                // ERROR_WINHTTP_SECURE_CERT_CN_INVALID
1901                 SecureInvalidCA = 12045,                    // ERROR_WINHTTP_SECURE_INVALID_CA
1902                 SecureCertRevFailed = 12057,                // ERROR_WINHTTP_SECURE_CERT_REV_FAILED
1903                 SecureChannelError = 12157,                 // ERROR_WINHTTP_SECURE_CHANNEL_ERROR
1904                 SecureInvalidCert = 12169,                  // ERROR_WINHTTP_SECURE_INVALID_CERT
1905                 SecureCertRevoked = 12170,                  // ERROR_WINHTTP_SECURE_CERT_REVOKED
1906                 SecureCertWrongUsage = 12179,               // ERROR_WINHTTP_SECURE_CERT_WRONG_USAGE
1907
1908                 AudodetectionFailed = 12180,                // ERROR_WINHTTP_AUTODETECTION_FAILED
1909                 HeaderCountExceeded = 12181,                // ERROR_WINHTTP_HEADER_COUNT_EXCEEDED
1910                 HeaderSizeOverflow = 12182,                 // ERROR_WINHTTP_HEADER_SIZE_OVERFLOW
1911                 ChunkedEncodingHeaderSizeOverflow = 12183,  // ERROR_WINHTTP_CHUNKED_ENCODING_HEADER_SIZE_OVERFLOW
1912                 ResponseDrainOverflow = 12184,              // ERROR_WINHTTP_RESPONSE_DRAIN_OVERFLOW
1913                 ClientCertNoPrivateKey = 12185,             // ERROR_WINHTTP_CLIENT_CERT_NO_PRIVATE_KEY
1914                 ClientCertNoAccessPrivateKey = 12186,       // ERROR_WINHTTP_CLIENT_CERT_NO_ACCESS_PRIVATE_KEY
1915             }
1916         }
1917
1918
1919         //
1920         // Caching (must use WinInet to cache).
1921         //
1922         [System.Security.SuppressUnmanagedCodeSecurityAttribute()]
1923         internal static class UnsafeWinInetCache {
1924             public  const int    MAX_PATH = 260;
1925
1926             [DllImport(WININET, CharSet = CharSet.Unicode, ExactSpelling=true, SetLastError = true)]
1927             internal static extern bool CreateUrlCacheEntryW(
1928                                             [In]  string        urlName,
1929                                             [In]  int           expectedFileSize,
1930                                             [In]  string        fileExtension,
1931                                             [Out] System.Text.StringBuilder fileName,
1932                                             [In]  int           dwReserved
1933         );
1934
1935             [DllImport(WININET, CharSet = CharSet.Unicode, ExactSpelling=true, SetLastError = true)]
1936             unsafe internal static extern bool CommitUrlCacheEntryW(
1937                                             [In] string                 urlName,
1938                                             [In] string                 localFileName,
1939                                             [In] _WinInetCache.FILETIME  expireTime,
1940                                             [In] _WinInetCache.FILETIME  lastModifiedTime,
1941                                             [In] _WinInetCache.EntryType EntryType,
1942                                             [In] byte*                  headerInfo,
1943                                             [In] int                    headerSizeTChars,
1944                                             [In] string                 fileExtension,
1945                                             [In] string                 originalUrl
1946         );
1947
1948             [DllImport(WININET, CharSet = CharSet.Unicode, ExactSpelling=true, SetLastError = true)]
1949             unsafe internal static extern bool GetUrlCacheEntryInfoW(
1950                                             [In]      string    urlName,
1951                                             [In]      byte*     entryPtr,                       //was [Out]
1952                                             [In, Out] ref int   bufferSz
1953                                             );
1954
1955             [DllImport(WININET, CharSet = CharSet.Unicode, ExactSpelling=true, SetLastError = true)]
1956             unsafe internal static extern bool SetUrlCacheEntryInfoW(
1957                                             [In] string                 lpszUrlName,
1958                                             [In] byte*                  EntryPtr,
1959                                             [In] _WinInetCache.Entry_FC  fieldControl
1960                                             );
1961
1962             [DllImport(WININET, CharSet = CharSet.Unicode, ExactSpelling=true, SetLastError = true)]
1963             internal static extern bool DeleteUrlCacheEntryW( [In] string urlName);
1964
1965             [DllImport(WININET, CharSet = CharSet.Unicode, ExactSpelling=true, SetLastError = true)]
1966             internal static extern bool UnlockUrlCacheEntryFileW(
1967                                             [In] string     urlName,
1968                                             [In] int        dwReserved                  //must be 0
1969                                             );
1970
1971     /*********
1972     NOT USED SO FAR
1973             unsafe private extern static SafeUnlockUrlCacheEntryStream RetrieveUrlCacheEntryStream(
1974                                             [In]      string    urlName,
1975                                             [In]      byte*     entryPtr,               //was [Out]
1976                                             [In, Out] ref int   entryBufSize,
1977                                             [In]      bool      randomRead,
1978                                             [In]      int       dwReserved
1979                                             );
1980
1981             unsafe internal static extern bool ReadUrlCacheEntryStream(
1982                                             [In]      SafeUnlockUrlCacheEntryStream  urlCacheStream,
1983                                             [In]      int       offset,
1984                                             [In]      byte*     bufferPtr,
1985                                             [In, Out] ref int   bufferSz,
1986                                             [In]      int       dwReserved                      //must be 0
1987                                             );
1988
1989             internal static extern bool UnlockUrlCacheEntryStream(
1990                                     [In] IntPtr         urlCacheStream,
1991                                     [In] int            dwReserved                      //mustbe 0
1992                                     );
1993
1994             unsafe internal static extern bool GetUrlCacheEntryInfoEx(
1995                                     [In]      string    url,
1996                                     [In]      byte*     entryPtr,                       //was [Out]
1997                                     [In, Out] ref int   entryBufSize,
1998                                     [In]      IntPtr    lpszReserved,                   //was[Out] must pass null
1999                                     [In]      IntPtr    lpdwReserved,                   //was[In, Out] must pass null
2000                                     [In]      IntPtr    lpReserved,                     //must pass null
2001                                     [In]      int       dwFlags                         //reserved must be 0
2002                                     );
2003
2004             internal static extern IntPtr  FindFirstUrlCacheGroup(
2005                                     [In]  _WinInetCache.GroupFlag     flags,
2006                                     [In]  _WinInetCache.GroupSrchType searchFilter,
2007                                     [In]  IntPtr                     searchConditionPtr, //must be null
2008                                     [In]  int                        searchConditionSz,  //must be 0
2009                                     [Out] out WinInet.GroupId        groupId,
2010                                     [In]  IntPtr                     lpReserved          //was [In,Out] must be IntPtr.Zero
2011                                     );
2012
2013             internal static extern bool FindNextUrlCacheGroup(
2014                                     [In]  IntPtr                    hFind,
2015                                     [Out] out _WinInetCache.GroupId  groupId,
2016                                     [In]  IntPtr                    lpReserved          //was [In,Out] must be IntPtr.Zero
2017                                     );
2018
2019             internal static extern bool GetUrlCacheGroupAttribute(
2020                                     [In]   _WinInetCache.GroupId     groupId,
2021                                     [In]   int                      flags,              //must 0
2022                                     [In]   _WinInetCache.GroupAttr   attr,
2023                                     [Out] out _WinInetCache.GroupInfo groupInfo,
2024                                     [In, Out] ref int               groupInfoSize,
2025                                     [In]  IntPtr                    lpReserved          //was [In,Out] must be IntPtr.Zero
2026                                     );
2027
2028             internal static extern bool SetUrlCacheGroupAttribute(
2029                                     [In]  _WinInetCache.GroupId      groupId,
2030                                     [In]  int                       flags,              //must be 0
2031                                     [In]  _WinInetCache.GroupAttr    attr,
2032                                     [In]  _WinInetCache.GroupInfo    groupInfo,
2033                                     [In]  IntPtr                    lpReserved          //was [In,Out] must be IntPtr.Zero
2034                                     );
2035
2036             internal static extern WinInet.GroupId CreateUrlCacheGroup(
2037                                     [In]  _WinInetCache.GroupFlag    flags,
2038                                     [In]  IntPtr                    lpReserved          //must be IntPtr.Zero
2039                                     );
2040
2041             internal static extern bool DeleteUrlCacheGroup(
2042                                     [In]  _WinInetCache.GroupId      groupId,
2043                                     [In]  _WinInetCache.GroupFlag    flags,
2044                                     [In]  IntPtr                    lpReserved          //must be IntPtr.Zero
2045                                     );
2046
2047
2048             internal static extern bool SetUrlCacheEntryGroup(
2049                                     [In] string                     urlName,
2050                                     [In] _WinInetCache.GroupSetFlag  flags,
2051                                     [In] _WinInetCache.GroupId       groupId,
2052                                     [In] IntPtr                     groupAttributes,    // must pass NULL
2053                                     [In] int                        groupAttrCount,     // must pass 0
2054                                     [In] IntPtr                     lpReserved          // must pass NULL
2055                                     );
2056
2057             unsafe internal static extern IntPtr FindFirstUrlCacheEntryEx(
2058                                     [In]      byte*             searchPattern,      //must be null
2059                                     [In]      int               dwFlags,            //must be 0
2060                                     [In]      CacheEntry.EntryType srchFilter,
2061                                     [In]      WinInet.GroupId   groupId,
2062                                     [In]      byte*             entryPtr,           //was [out]
2063                                     [In, Out] ref int           entryBufSize,
2064                                     [Out]     void*             lpReserved,         // must pass NULL
2065                                     [In]      void*             lpReserved2,        //was [In,Out] must be IntPtr.Zero
2066                                     [In]      void*             lpReserved3         // must pass NULL
2067                                     );
2068
2069             unsafe internal static extern bool FindNextUrlCacheEntryEx(
2070                                     [In]     IntPtr             enumHandle,
2071                                     [In]     byte*              entryPtr,           //was [Out]
2072                                     [In, Out]ref int            entryBufSize,
2073                                     [In]     void*              lpReserved,         // [Out] must pass NULL
2074                                     [In]     void*              lpReserved2,        // [In] [Out] must pass NULL
2075                                     [In]     void*              lpReserved3         // must pass NULL
2076                                     );
2077
2078             unsafe internal static extern IntPtr FindFirstUrlCacheEntry(
2079                                     [In]     string             searchPattern,
2080                                     [In]     byte*              entryPtr,           //was [Out]
2081                                     [In, Out]ref int            entryBufSize
2082                                     );
2083
2084
2085             unsafe internal static extern bool FindNextUrlCacheEntry(
2086                                     [In]     IntPtr             enumHandle,
2087                                     [In]     byte*              entryPtr,           //was [Out]
2088                                     [In, Out]ref int            entryBufSize
2089                                     );
2090
2091             internal static extern bool FindCloseUrlCache( [In] IntPtr enumHandle);
2092
2093     /**********/
2094         }
2095
2096         [SuppressUnmanagedCodeSecurityAttribute]
2097         internal static class SspiHelper
2098         {
2099             [DllImport(SECUR32, ExactSpelling = true, SetLastError = true)]
2100             [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
2101             internal unsafe static extern SecurityStatus SspiFreeAuthIdentity(
2102                 [In] IntPtr authData);
2103
2104             [SuppressMessage("Microsoft.Security", "CA2118:ReviewSuppressUnmanagedCodeSecurityUsage", Justification = "Implementation requires unmanaged code usage")]
2105             [DllImport(SECUR32, ExactSpelling = true, SetLastError = true, CharSet = CharSet.Unicode)]
2106             internal unsafe static extern SecurityStatus SspiEncodeStringsAsAuthIdentity(
2107                 [In] string userName,
2108                 [In] string domainName,
2109                 [In] string password,
2110                 [Out] out SafeSspiAuthDataHandle authData);
2111         }
2112
2113 #endif // !FEATURE_PAL
2114
2115 #if !FEATURE_PAL
2116         [System.Security.SuppressUnmanagedCodeSecurityAttribute()]
2117         internal static unsafe class HttpApi {
2118             
2119             [DllImport(HTTPAPI, ExactSpelling=true, CallingConvention=CallingConvention.StdCall, SetLastError=true)]
2120             internal static extern uint HttpInitialize(HTTPAPI_VERSION version, uint flags, void* pReserved);
2121
2122             [DllImport(HTTPAPI, ExactSpelling=true, CallingConvention=CallingConvention.StdCall, SetLastError=true)]
2123             internal static extern uint HttpReceiveRequestEntityBody(CriticalHandle requestQueueHandle, ulong requestId, uint flags, void* pEntityBuffer, uint entityBufferLength, out uint bytesReturned, NativeOverlapped* pOverlapped);
2124             [DllImport(HTTPAPI, EntryPoint = "HttpReceiveRequestEntityBody", ExactSpelling = true, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
2125             internal static extern uint HttpReceiveRequestEntityBody2(CriticalHandle requestQueueHandle, ulong requestId, uint flags, void* pEntityBuffer, uint entityBufferLength, out uint bytesReturned, [In] SafeHandle pOverlapped);
2126
2127             [SuppressMessage("Microsoft.Security", "CA2118:ReviewSuppressUnmanagedCodeSecurityUsage", Justification = "Implementation requires unmanaged code usage")]
2128             [DllImport(HTTPAPI, ExactSpelling=true, CallingConvention=CallingConvention.StdCall, SetLastError=true)]
2129             internal static extern uint HttpReceiveClientCertificate(CriticalHandle requestQueueHandle, ulong connectionId, uint flags, HTTP_SSL_CLIENT_CERT_INFO* pSslClientCertInfo, uint sslClientCertInfoSize, uint* pBytesReceived, NativeOverlapped* pOverlapped);
2130
2131             [SuppressMessage("Microsoft.Security", "CA2118:ReviewSuppressUnmanagedCodeSecurityUsage", Justification = "Implementation requires unmanaged code usage")]
2132             [DllImport(HTTPAPI, ExactSpelling=true, CallingConvention=CallingConvention.StdCall, SetLastError=true)]
2133             internal static extern uint HttpReceiveClientCertificate(CriticalHandle requestQueueHandle, ulong connectionId, uint flags, byte* pSslClientCertInfo, uint sslClientCertInfoSize, uint* pBytesReceived, NativeOverlapped* pOverlapped);
2134
2135             [SuppressMessage("Microsoft.Security", "CA2118:ReviewSuppressUnmanagedCodeSecurityUsage", Justification = "Implementation requires unmanaged code usage")]
2136             [DllImport(HTTPAPI, ExactSpelling=true, CallingConvention=CallingConvention.StdCall, SetLastError=true)]
2137             internal static extern uint HttpReceiveHttpRequest(CriticalHandle requestQueueHandle, ulong requestId, uint flags, HTTP_REQUEST* pRequestBuffer, uint requestBufferLength, uint* pBytesReturned, NativeOverlapped* pOverlapped);
2138
2139             [SuppressMessage("Microsoft.Security", "CA2118:ReviewSuppressUnmanagedCodeSecurityUsage", Justification = "Implementation requires unmanaged code usage")]
2140             [DllImport(HTTPAPI, ExactSpelling=true, CallingConvention=CallingConvention.StdCall, SetLastError=true)]
2141             internal static extern uint HttpSendHttpResponse(CriticalHandle requestQueueHandle, ulong requestId, uint flags, HTTP_RESPONSE* pHttpResponse, void* pCachePolicy, uint* pBytesSent, SafeLocalFree pRequestBuffer, uint requestBufferLength, NativeOverlapped* pOverlapped, void* pLogData);
2142
2143             [SuppressMessage("Microsoft.Security", "CA2118:ReviewSuppressUnmanagedCodeSecurityUsage", Justification = "Implementation requires unmanaged code usage")]
2144             [DllImport(HTTPAPI, ExactSpelling=true, CallingConvention=CallingConvention.StdCall, SetLastError=true)]
2145             internal static extern uint HttpSendResponseEntityBody(CriticalHandle requestQueueHandle, ulong requestId, uint flags, ushort entityChunkCount, HTTP_DATA_CHUNK* pEntityChunks, uint* pBytesSent, SafeLocalFree pRequestBuffer, uint requestBufferLength, NativeOverlapped* pOverlapped, void* pLogData);
2146
2147             [SuppressMessage("Microsoft.Security", "CA2118:ReviewSuppressUnmanagedCodeSecurityUsage", Justification = "Implementation requires unmanaged code usage")]
2148             [DllImport(HTTPAPI, ExactSpelling = true, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
2149             internal static extern uint HttpCancelHttpRequest(CriticalHandle requestQueueHandle, ulong requestId, IntPtr pOverlapped);
2150
2151             [SuppressMessage("Microsoft.Security", "CA2118:ReviewSuppressUnmanagedCodeSecurityUsage", Justification = "Implementation requires unmanaged code usage")]
2152             [DllImport(HTTPAPI, EntryPoint = "HttpSendResponseEntityBody", ExactSpelling = true, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
2153             internal static extern uint HttpSendResponseEntityBody2(CriticalHandle requestQueueHandle, ulong requestId, uint flags, ushort entityChunkCount, IntPtr pEntityChunks, out uint pBytesSent, SafeLocalFree pRequestBuffer, uint requestBufferLength, SafeHandle pOverlapped, IntPtr pLogData);
2154
2155             [SuppressMessage("Microsoft.Security", "CA2118:ReviewSuppressUnmanagedCodeSecurityUsage", Justification = "Implementation requires unmanaged code usage")]
2156             [DllImport(HTTPAPI, ExactSpelling=true, CallingConvention=CallingConvention.StdCall, SetLastError=true)]
2157             internal static extern uint HttpWaitForDisconnect(CriticalHandle requestQueueHandle, ulong connectionId, NativeOverlapped* pOverlapped);
2158
2159             [SuppressMessage("Microsoft.Security", "CA2118:ReviewSuppressUnmanagedCodeSecurityUsage", Justification = "Implementation requires unmanaged code usage")]
2160             [DllImport(HTTPAPI, ExactSpelling = true, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
2161             internal static extern uint HttpCreateServerSession(HTTPAPI_VERSION version, ulong* serverSessionId, uint reserved);
2162
2163             [SuppressMessage("Microsoft.Security", "CA2118:ReviewSuppressUnmanagedCodeSecurityUsage", Justification = "Implementation requires unmanaged code usage")]
2164             [DllImport(HTTPAPI, ExactSpelling = true, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
2165             internal static extern uint HttpCreateUrlGroup(ulong serverSessionId, ulong* urlGroupId, uint reserved);
2166
2167             [SuppressMessage("Microsoft.Security", "CA2118:ReviewSuppressUnmanagedCodeSecurityUsage", Justification = "Implementation requires unmanaged code usage")]
2168             [DllImport(HTTPAPI, ExactSpelling = true, CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode, SetLastError = true)]
2169             internal static extern uint HttpAddUrlToUrlGroup(ulong urlGroupId, string pFullyQualifiedUrl, ulong context, uint pReserved);
2170
2171             [SuppressMessage("Microsoft.Security", "CA2118:ReviewSuppressUnmanagedCodeSecurityUsage", Justification = "Implementation requires unmanaged code usage")]
2172             [DllImport(HTTPAPI, ExactSpelling = true, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
2173             internal static extern uint HttpSetUrlGroupProperty(ulong urlGroupId, HTTP_SERVER_PROPERTY serverProperty, IntPtr pPropertyInfo, uint propertyInfoLength);
2174
2175             [SuppressMessage("Microsoft.Security", "CA2118:ReviewSuppressUnmanagedCodeSecurityUsage", Justification = "Implementation requires unmanaged code usage")]
2176             [DllImport(HTTPAPI, ExactSpelling = true, CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode, SetLastError = true)]
2177             internal static extern uint HttpRemoveUrlFromUrlGroup(ulong urlGroupId, string pFullyQualifiedUrl, uint flags);
2178
2179             [DllImport(HTTPAPI, ExactSpelling = true, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
2180             internal static extern uint HttpCloseServerSession(ulong serverSessionId);
2181
2182             [SuppressMessage("Microsoft.Security", "CA2118:ReviewSuppressUnmanagedCodeSecurityUsage", Justification = "Implementation requires unmanaged code usage")]
2183             [DllImport(HTTPAPI, ExactSpelling = true, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
2184             internal static extern uint HttpCloseUrlGroup(ulong urlGroupId);
2185
2186             [SuppressMessage("Microsoft.Security", "CA2118:ReviewSuppressUnmanagedCodeSecurityUsage", Justification = "Implementation requires unmanaged code usage")]
2187             [DllImport(TOKENBINDING, CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)]
2188             public static extern int TokenBindingVerifyMessage(
2189                 [In] byte* tokenBindingMessage,
2190                 [In] uint tokenBindingMessageSize,
2191                 [In] IntPtr keyType,
2192                 [In] byte* tlsUnique,
2193                 [In] uint tlsUniqueSize,
2194                 [Out] out HeapAllocHandle resultList);
2195
2196             internal sealed class HeapAllocHandle : SafeHandleZeroOrMinusOneIsInvalid
2197             {
2198                 private static readonly IntPtr ProcessHeap = GetProcessHeap();
2199
2200                 // Called by P/Invoke when returning SafeHandles.
2201                 private HeapAllocHandle()
2202                     : base(ownsHandle: true)
2203                 {
2204                 }
2205
2206                 // Do not provide a finalizer - SafeHandle's critical finalizer will call ReleaseHandle for you.
2207                 protected override bool ReleaseHandle()
2208                 {
2209                     return HeapFree(ProcessHeap, 0, handle);
2210                 }
2211             }
2212
2213             internal enum HTTP_API_VERSION {
2214                 Invalid,
2215                 Version10,
2216                 Version20,
2217             }
2218
2219             // see http.w for definitions
2220             internal enum HTTP_SERVER_PROPERTY {
2221                 HttpServerAuthenticationProperty,
2222                 HttpServerLoggingProperty,
2223                 HttpServerQosProperty,
2224                 HttpServerTimeoutsProperty,
2225                 HttpServerQueueLengthProperty,
2226                 HttpServerStateProperty,
2227                 HttpServer503VerbosityProperty,
2228                 HttpServerBindingProperty,
2229                 HttpServerExtendedAuthenticationProperty,
2230                 HttpServerListenEndpointProperty,
2231                 HttpServerChannelBindProperty,
2232                 HttpServerProtectionLevelProperty,
2233             }
2234                        
2235             internal enum HTTP_REQUEST_INFO_TYPE {
2236                 HttpRequestInfoTypeAuth,
2237                 HttpRequestInfoTypeChannelBind,
2238                 HttpRequestInfoTypeSslProtocol,
2239                 HttpRequestInfoTypeSslTokenBinding
2240             }
2241
2242             internal enum HTTP_RESPONSE_INFO_TYPE {
2243                 HttpResponseInfoTypeMultipleKnownHeaders,
2244                 HttpResponseInfoTypeAuthenticationProperty,
2245                 HttpResponseInfoTypeQosProperty ,
2246             }
2247
2248             internal enum HTTP_TIMEOUT_TYPE {
2249                 EntityBody,
2250                 DrainEntityBody,
2251                 RequestQueue,
2252                 IdleConnection,
2253                 HeaderWait,
2254                 MinSendRate,
2255             }
2256
2257             internal const int MaxTimeout = 6;
2258
2259             [StructLayout(LayoutKind.Sequential)]
2260             internal struct HTTP_VERSION {
2261                 internal ushort MajorVersion;
2262                 internal ushort MinorVersion;
2263             }
2264
2265             [StructLayout(LayoutKind.Sequential)]
2266             internal struct HTTP_KNOWN_HEADER {
2267                 internal ushort RawValueLength;
2268                 internal sbyte* pRawValue;
2269             }
2270
2271             [StructLayout(LayoutKind.Sequential, Size=32)]
2272             internal struct HTTP_DATA_CHUNK {
2273                 internal HTTP_DATA_CHUNK_TYPE DataChunkType;
2274                 internal uint p0;
2275                 internal byte* pBuffer;
2276                 internal uint BufferLength;
2277             }
2278
2279             [StructLayout(LayoutKind.Sequential)]
2280             internal struct HTTPAPI_VERSION {
2281                 internal ushort HttpApiMajorVersion;
2282                 internal ushort HttpApiMinorVersion;
2283             }
2284
2285             [StructLayout(LayoutKind.Sequential)]
2286             internal struct HTTP_COOKED_URL {
2287                 internal ushort FullUrlLength;
2288                 internal ushort HostLength;
2289                 internal ushort AbsPathLength;
2290                 internal ushort QueryStringLength;
2291                 internal ushort* pFullUrl;
2292                 internal ushort* pHost;
2293                 internal ushort* pAbsPath;
2294                 internal ushort* pQueryString;
2295             }
2296
2297             [StructLayout(LayoutKind.Sequential)]
2298             internal struct SOCKADDR {
2299                 internal ushort sa_family;
2300                 internal byte sa_data;
2301                 internal byte sa_data_02;
2302                 internal byte sa_data_03;
2303                 internal byte sa_data_04;
2304                 internal byte sa_data_05;
2305                 internal byte sa_data_06;
2306                 internal byte sa_data_07;
2307                 internal byte sa_data_08;
2308                 internal byte sa_data_09;
2309                 internal byte sa_data_10;
2310                 internal byte sa_data_11;
2311                 internal byte sa_data_12;
2312                 internal byte sa_data_13;
2313                 internal byte sa_data_14;
2314             }
2315
2316             [StructLayout(LayoutKind.Sequential)]
2317             internal struct HTTP_TRANSPORT_ADDRESS {
2318                 internal SOCKADDR* pRemoteAddress;
2319                 internal SOCKADDR* pLocalAddress;
2320             }
2321
2322             [StructLayout(LayoutKind.Sequential)]
2323             internal struct HTTP_SSL_CLIENT_CERT_INFO {
2324                 internal uint CertFlags;
2325                 internal uint CertEncodedSize;
2326                 internal byte* pCertEncoded;
2327                 internal void* Token;
2328                 internal byte CertDeniedByMapper;
2329             }
2330
2331             internal enum HTTP_SERVICE_BINDING_TYPE : uint { 
2332                 HttpServiceBindingTypeNone = 0,
2333                 HttpServiceBindingTypeW,
2334                 HttpServiceBindingTypeA
2335             }
2336
2337             [StructLayout(LayoutKind.Sequential)]
2338             internal struct HTTP_SERVICE_BINDING_BASE
2339             {
2340                 internal HTTP_SERVICE_BINDING_TYPE Type;
2341             }
2342
2343             [StructLayout(LayoutKind.Sequential)]
2344             internal struct HTTP_REQUEST_CHANNEL_BIND_STATUS
2345             {
2346                 internal IntPtr ServiceName;
2347                 internal IntPtr ChannelToken;
2348                 internal uint ChannelTokenSize;
2349                 internal uint Flags;
2350             }
2351
2352             [StructLayout(LayoutKind.Sequential)]
2353             internal struct HTTP_UNKNOWN_HEADER {
2354                 internal ushort NameLength;
2355                 internal ushort RawValueLength;
2356                 internal sbyte* pName;
2357                 internal sbyte* pRawValue;
2358             }
2359
2360             [StructLayout(LayoutKind.Sequential)]
2361             internal struct HTTP_SSL_INFO {
2362                 internal ushort ServerCertKeySize;
2363                 internal ushort ConnectionKeySize;
2364                 internal uint ServerCertIssuerSize;
2365                 internal uint ServerCertSubjectSize;
2366                 internal sbyte* pServerCertIssuer;
2367                 internal sbyte* pServerCertSubject;
2368                 internal HTTP_SSL_CLIENT_CERT_INFO* pClientCertInfo;
2369                 internal uint SslClientCertNegotiated;
2370             }
2371
2372             [StructLayout(LayoutKind.Sequential)]
2373             internal struct HTTP_RESPONSE_HEADERS {
2374                 internal ushort UnknownHeaderCount;
2375                 internal HTTP_UNKNOWN_HEADER* pUnknownHeaders;
2376                 internal ushort TrailerCount;
2377                 internal HTTP_UNKNOWN_HEADER* pTrailers;
2378                 internal HTTP_KNOWN_HEADER KnownHeaders;
2379                 internal HTTP_KNOWN_HEADER KnownHeaders_02;
2380                 internal HTTP_KNOWN_HEADER KnownHeaders_03;
2381                 internal HTTP_KNOWN_HEADER KnownHeaders_04;
2382                 internal HTTP_KNOWN_HEADER KnownHeaders_05;
2383                 internal HTTP_KNOWN_HEADER KnownHeaders_06;
2384                 internal HTTP_KNOWN_HEADER KnownHeaders_07;
2385                 internal HTTP_KNOWN_HEADER KnownHeaders_08;
2386                 internal HTTP_KNOWN_HEADER KnownHeaders_09;
2387                 internal HTTP_KNOWN_HEADER KnownHeaders_10;
2388                 internal HTTP_KNOWN_HEADER KnownHeaders_11;
2389                 internal HTTP_KNOWN_HEADER KnownHeaders_12;
2390                 internal HTTP_KNOWN_HEADER KnownHeaders_13;
2391                 internal HTTP_KNOWN_HEADER KnownHeaders_14;
2392                 internal HTTP_KNOWN_HEADER KnownHeaders_15;
2393                 internal HTTP_KNOWN_HEADER KnownHeaders_16;
2394                 internal HTTP_KNOWN_HEADER KnownHeaders_17;
2395                 internal HTTP_KNOWN_HEADER KnownHeaders_18;
2396                 internal HTTP_KNOWN_HEADER KnownHeaders_19;
2397                 internal HTTP_KNOWN_HEADER KnownHeaders_20;
2398                 internal HTTP_KNOWN_HEADER KnownHeaders_21;
2399                 internal HTTP_KNOWN_HEADER KnownHeaders_22;
2400                 internal HTTP_KNOWN_HEADER KnownHeaders_23;
2401                 internal HTTP_KNOWN_HEADER KnownHeaders_24;
2402                 internal HTTP_KNOWN_HEADER KnownHeaders_25;
2403                 internal HTTP_KNOWN_HEADER KnownHeaders_26;
2404                 internal HTTP_KNOWN_HEADER KnownHeaders_27;
2405                 internal HTTP_KNOWN_HEADER KnownHeaders_28;
2406                 internal HTTP_KNOWN_HEADER KnownHeaders_29;
2407                 internal HTTP_KNOWN_HEADER KnownHeaders_30;
2408             }
2409
2410             [StructLayout(LayoutKind.Sequential)]
2411             internal struct HTTP_REQUEST_HEADERS {
2412                 internal ushort UnknownHeaderCount;
2413                 internal HTTP_UNKNOWN_HEADER* pUnknownHeaders;
2414                 internal ushort TrailerCount;
2415                 internal HTTP_UNKNOWN_HEADER* pTrailers;
2416                 internal HTTP_KNOWN_HEADER KnownHeaders;
2417                 internal HTTP_KNOWN_HEADER KnownHeaders_02;
2418                 internal HTTP_KNOWN_HEADER KnownHeaders_03;
2419                 internal HTTP_KNOWN_HEADER KnownHeaders_04;
2420                 internal HTTP_KNOWN_HEADER KnownHeaders_05;
2421                 internal HTTP_KNOWN_HEADER KnownHeaders_06;
2422                 internal HTTP_KNOWN_HEADER KnownHeaders_07;
2423                 internal HTTP_KNOWN_HEADER KnownHeaders_08;
2424                 internal HTTP_KNOWN_HEADER KnownHeaders_09;
2425                 internal HTTP_KNOWN_HEADER KnownHeaders_10;
2426                 internal HTTP_KNOWN_HEADER KnownHeaders_11;
2427                 internal HTTP_KNOWN_HEADER KnownHeaders_12;
2428                 internal HTTP_KNOWN_HEADER KnownHeaders_13;
2429                 internal HTTP_KNOWN_HEADER KnownHeaders_14;
2430                 internal HTTP_KNOWN_HEADER KnownHeaders_15;
2431                 internal HTTP_KNOWN_HEADER KnownHeaders_16;
2432                 internal HTTP_KNOWN_HEADER KnownHeaders_17;
2433                 internal HTTP_KNOWN_HEADER KnownHeaders_18;
2434                 internal HTTP_KNOWN_HEADER KnownHeaders_19;
2435                 internal HTTP_KNOWN_HEADER KnownHeaders_20;
2436                 internal HTTP_KNOWN_HEADER KnownHeaders_21;
2437                 internal HTTP_KNOWN_HEADER KnownHeaders_22;
2438                 internal HTTP_KNOWN_HEADER KnownHeaders_23;
2439                 internal HTTP_KNOWN_HEADER KnownHeaders_24;
2440                 internal HTTP_KNOWN_HEADER KnownHeaders_25;
2441                 internal HTTP_KNOWN_HEADER KnownHeaders_26;
2442                 internal HTTP_KNOWN_HEADER KnownHeaders_27;
2443                 internal HTTP_KNOWN_HEADER KnownHeaders_28;
2444                 internal HTTP_KNOWN_HEADER KnownHeaders_29;
2445                 internal HTTP_KNOWN_HEADER KnownHeaders_30;
2446                 internal HTTP_KNOWN_HEADER KnownHeaders_31;
2447                 internal HTTP_KNOWN_HEADER KnownHeaders_32;
2448                 internal HTTP_KNOWN_HEADER KnownHeaders_33;
2449                 internal HTTP_KNOWN_HEADER KnownHeaders_34;
2450                 internal HTTP_KNOWN_HEADER KnownHeaders_35;
2451                 internal HTTP_KNOWN_HEADER KnownHeaders_36;
2452                 internal HTTP_KNOWN_HEADER KnownHeaders_37;
2453                 internal HTTP_KNOWN_HEADER KnownHeaders_38;
2454                 internal HTTP_KNOWN_HEADER KnownHeaders_39;
2455                 internal HTTP_KNOWN_HEADER KnownHeaders_40;
2456                 internal HTTP_KNOWN_HEADER KnownHeaders_41;
2457             }
2458
2459             internal enum HTTP_VERB : int {
2460                 HttpVerbUnparsed = 0,
2461                 HttpVerbUnknown = 1,
2462                 HttpVerbInvalid = 2,
2463                 HttpVerbOPTIONS = 3,
2464                 HttpVerbGET = 4,
2465                 HttpVerbHEAD = 5,
2466                 HttpVerbPOST = 6,
2467                 HttpVerbPUT = 7,
2468                 HttpVerbDELETE = 8,
2469                 HttpVerbTRACE = 9,
2470                 HttpVerbCONNECT = 10,
2471                 HttpVerbTRACK = 11,
2472                 HttpVerbMOVE = 12,
2473                 HttpVerbCOPY = 13,
2474                 HttpVerbPROPFIND = 14,
2475                 HttpVerbPROPPATCH = 15,
2476                 HttpVerbMKCOL = 16,
2477                 HttpVerbLOCK = 17,
2478                 HttpVerbUNLOCK = 18,
2479                 HttpVerbSEARCH = 19,
2480                 HttpVerbMaximum = 20,
2481             }
2482
2483             internal static readonly string[] HttpVerbs = new string[] {
2484                 null,
2485                 "Unknown",
2486                 "Invalid",
2487                 "OPTIONS",
2488                 "GET",
2489                 "HEAD",
2490                 "POST",
2491                 "PUT",
2492                 "DELETE",
2493                 "TRACE",
2494                 "CONNECT",
2495                 "TRACK",
2496                 "MOVE",
2497                 "COPY",
2498                 "PROPFIND",
2499                 "PROPPATCH",
2500                 "MKCOL",
2501                 "LOCK",
2502                 "UNLOCK",
2503                 "SEARCH",
2504             };
2505
2506             internal enum HTTP_DATA_CHUNK_TYPE : int {
2507                 HttpDataChunkFromMemory = 0,
2508                 HttpDataChunkFromFileHandle = 1,
2509                 HttpDataChunkFromFragmentCache = 2,
2510                 HttpDataChunkMaximum = 3,
2511             }
2512
2513             [StructLayout(LayoutKind.Sequential)]
2514             internal struct HTTP_RESPONSE_INFO {
2515                 internal HTTP_RESPONSE_INFO_TYPE Type;
2516                 internal uint Length;
2517                 internal void* pInfo;
2518             }
2519
2520             [StructLayout(LayoutKind.Sequential)]
2521             internal struct HTTP_RESPONSE {
2522                 internal uint Flags;
2523                 internal HTTP_VERSION Version;
2524                 internal ushort StatusCode;
2525                 internal ushort ReasonLength;
2526                 internal sbyte* pReason;
2527                 internal HTTP_RESPONSE_HEADERS Headers;
2528                 internal ushort EntityChunkCount;
2529                 internal HTTP_DATA_CHUNK* pEntityChunks;
2530                 internal ushort ResponseInfoCount;
2531                 internal HTTP_RESPONSE_INFO* pResponseInfo;
2532             }
2533
2534             [StructLayout(LayoutKind.Sequential)]
2535             internal struct HTTP_REQUEST_INFO {
2536                 internal HTTP_REQUEST_INFO_TYPE InfoType;
2537                 internal uint InfoLength;
2538                 internal void* pInfo;
2539             }
2540
2541             [StructLayout(LayoutKind.Sequential)]
2542             internal struct HTTP_REQUEST {
2543                 internal uint Flags;
2544                 internal ulong ConnectionId;
2545                 internal ulong RequestId;
2546                 internal ulong UrlContext;
2547                 internal HTTP_VERSION Version;
2548                 internal HTTP_VERB Verb;
2549                 internal ushort UnknownVerbLength;
2550                 internal ushort RawUrlLength;
2551                 internal sbyte* pUnknownVerb;
2552                 internal sbyte* pRawUrl;
2553                 internal HTTP_COOKED_URL CookedUrl;
2554                 internal HTTP_TRANSPORT_ADDRESS Address;
2555                 internal HTTP_REQUEST_HEADERS Headers;
2556                 internal ulong BytesReceived;
2557                 internal ushort EntityChunkCount;
2558                 internal HTTP_DATA_CHUNK* pEntityChunks;
2559                 internal ulong RawConnectionId;
2560                 internal HTTP_SSL_INFO* pSslInfo;
2561             }
2562
2563             [StructLayout(LayoutKind.Sequential)]
2564             internal struct HTTP_REQUEST_V2
2565             {
2566                 internal HTTP_REQUEST RequestV1;
2567                 internal ushort RequestInfoCount;
2568                 internal HTTP_REQUEST_INFO* pRequestInfo;
2569             }
2570
2571             [StructLayout(LayoutKind.Sequential)]
2572             internal struct HTTP_TIMEOUT_LIMIT_INFO {
2573                 internal HTTP_FLAGS Flags;
2574                 internal ushort EntityBody;
2575                 internal ushort DrainEntityBody;
2576                 internal ushort RequestQueue;
2577                 internal ushort IdleConnection;
2578                 internal ushort HeaderWait;
2579                 internal uint MinSendRate;
2580             }
2581
2582             [StructLayout(LayoutKind.Sequential)]
2583             internal struct HTTP_BINDING_INFO {
2584                 internal HTTP_FLAGS Flags;
2585                 internal IntPtr RequestQueueHandle;                
2586             }
2587
2588             [StructLayout(LayoutKind.Sequential)]
2589             internal unsafe struct HTTP_REQUEST_TOKEN_BINDING_INFO
2590             {
2591                 public byte* TokenBinding;
2592                 public uint TokenBindingSize;
2593                 public byte* TlsUnique;
2594                 public uint TlsUniqueSize;
2595                 public IntPtr KeyType;
2596             }
2597
2598             internal enum TOKENBINDING_HASH_ALGORITHM : byte
2599             {
2600                 TOKENBINDING_HASH_ALGORITHM_SHA256 = 4,
2601             }
2602
2603             internal enum TOKENBINDING_SIGNATURE_ALGORITHM : byte
2604             {
2605                 TOKENBINDING_SIGNATURE_ALGORITHM_RSA = 1,
2606                 TOKENBINDING_SIGNATURE_ALGORITHM_ECDSAP256 = 3,
2607             }
2608
2609             internal enum TOKENBINDING_TYPE : byte
2610             {
2611                 TOKENBINDING_TYPE_PROVIDED = 0,
2612                 TOKENBINDING_TYPE_REFERRED = 1,
2613             }
2614
2615             internal enum TOKENBINDING_EXTENSION_FORMAT
2616             {
2617                 TOKENBINDING_EXTENSION_FORMAT_UNDEFINED = 0,
2618             }
2619
2620             [StructLayout(LayoutKind.Sequential)]
2621             internal struct TOKENBINDING_IDENTIFIER
2622             {
2623                 public TOKENBINDING_TYPE bindingType;
2624                 public TOKENBINDING_HASH_ALGORITHM hashAlgorithm;
2625                 public TOKENBINDING_SIGNATURE_ALGORITHM signatureAlgorithm;
2626             }
2627
2628             [StructLayout(LayoutKind.Sequential)]
2629             internal unsafe struct TOKENBINDING_RESULT_DATA
2630             {
2631                 public uint identifierSize;
2632                 public TOKENBINDING_IDENTIFIER* identifierData;
2633                 public TOKENBINDING_EXTENSION_FORMAT extensionFormat;
2634                 public uint extensionSize;
2635                 public IntPtr extensionData;
2636             }
2637
2638             [StructLayout(LayoutKind.Sequential)]
2639             internal unsafe struct TOKENBINDING_RESULT_LIST
2640             {
2641                 public uint resultCount;
2642                 public TOKENBINDING_RESULT_DATA* resultData;
2643             }
2644             
2645             // see http.w for definitions
2646             [Flags]
2647             internal enum HTTP_FLAGS : uint {
2648                 NONE                                = 0x00000000,
2649                 HTTP_RECEIVE_REQUEST_FLAG_COPY_BODY = 0x00000001,
2650                 HTTP_RECEIVE_SECURE_CHANNEL_TOKEN   = 0x00000001,
2651                 HTTP_SEND_RESPONSE_FLAG_DISCONNECT  = 0x00000001,
2652                 HTTP_SEND_RESPONSE_FLAG_MORE_DATA   = 0x00000002,
2653                 HTTP_SEND_RESPONSE_FLAG_BUFFER_DATA = 0x00000004,
2654                 HTTP_SEND_RESPONSE_FLAG_RAW_HEADER  = 0x00000004,
2655                 HTTP_SEND_REQUEST_FLAG_MORE_DATA    = 0x00000001,
2656                 HTTP_PROPERTY_FLAG_PRESENT          = 0x00000001,
2657                 HTTP_INITIALIZE_SERVER              = 0x00000001,
2658                 HTTP_INITIALIZE_CBT                 = 0x00000004,
2659                 HTTP_SEND_RESPONSE_FLAG_OPAQUE      = 0x00000040,
2660             }
2661
2662             const int HttpHeaderRequestMaximum  = (int)HttpRequestHeader.UserAgent + 1;
2663             const int HttpHeaderResponseMaximum = (int)HttpResponseHeader.WwwAuthenticate + 1;
2664
2665             internal static class HTTP_REQUEST_HEADER_ID {
2666                 internal static string ToString(int position) {
2667                     return m_Strings[position];
2668                 }
2669
2670                 private static string[] m_Strings = {
2671                     "Cache-Control",
2672                     "Connection",
2673                     "Date",
2674                     "Keep-Alive",
2675                     "Pragma",
2676                     "Trailer",
2677                     "Transfer-Encoding",
2678                     "Upgrade",
2679                     "Via",
2680                     "Warning",
2681
2682                     "Allow",
2683                     "Content-Length",
2684                     "Content-Type",
2685                     "Content-Encoding",
2686                     "Content-Language",
2687                     "Content-Location",
2688                     "Content-MD5",
2689                     "Content-Range",
2690                     "Expires",
2691                     "Last-Modified",
2692
2693                     "Accept",
2694                     "Accept-Charset",
2695                     "Accept-Encoding",
2696                     "Accept-Language",
2697                     "Authorization",
2698                     "Cookie",
2699                     "Expect",
2700                     "From",
2701                     "Host",
2702                     "If-Match",
2703
2704                     "If-Modified-Since",
2705                     "If-None-Match",
2706                     "If-Range",
2707                     "If-Unmodified-Since",
2708                     "Max-Forwards",
2709                     "Proxy-Authorization",
2710                     "Referer",
2711                     "Range",
2712                     "Te",
2713                     "Translate",
2714                     "User-Agent",
2715                 };
2716             }
2717
2718             internal static class HTTP_RESPONSE_HEADER_ID {
2719                 private static Hashtable m_Hashtable;
2720
2721                 static HTTP_RESPONSE_HEADER_ID() {
2722                     m_Hashtable = new Hashtable((int)Enum.HttpHeaderResponseMaximum);
2723                     for (int i = 0; i < (int)Enum.HttpHeaderResponseMaximum; i++) {
2724                         m_Hashtable.Add(m_Strings[i], i);
2725                     }
2726                 }
2727
2728                 internal static int IndexOfKnownHeader(string HeaderName) {
2729                     object index = m_Hashtable[HeaderName];
2730                     return index==null ? -1 : (int)index;
2731     }
2732
2733                 internal static string ToString(int position) {
2734                     return m_Strings[position];
2735 }
2736
2737                 internal enum Enum {
2738                     HttpHeaderCacheControl          = 0,    // general-header [section 4.5]
2739                     HttpHeaderConnection            = 1,    // general-header [section 4.5]
2740                     HttpHeaderDate                  = 2,    // general-header [section 4.5]
2741                     HttpHeaderKeepAlive             = 3,    // general-header [not in rfc]
2742                     HttpHeaderPragma                = 4,    // general-header [section 4.5]
2743                     HttpHeaderTrailer               = 5,    // general-header [section 4.5]
2744                     HttpHeaderTransferEncoding      = 6,    // general-header [section 4.5]
2745                     HttpHeaderUpgrade               = 7,    // general-header [section 4.5]
2746                     HttpHeaderVia                   = 8,    // general-header [section 4.5]
2747                     HttpHeaderWarning               = 9,    // general-header [section 4.5]
2748
2749                     HttpHeaderAllow                 = 10,   // entity-header  [section 7.1]
2750                     HttpHeaderContentLength         = 11,   // entity-header  [section 7.1]
2751                     HttpHeaderContentType           = 12,   // entity-header  [section 7.1]
2752                     HttpHeaderContentEncoding       = 13,   // entity-header  [section 7.1]
2753                     HttpHeaderContentLanguage       = 14,   // entity-header  [section 7.1]
2754                     HttpHeaderContentLocation       = 15,   // entity-header  [section 7.1]
2755                     HttpHeaderContentMd5            = 16,   // entity-header  [section 7.1]
2756                     HttpHeaderContentRange          = 17,   // entity-header  [section 7.1]
2757                     HttpHeaderExpires               = 18,   // entity-header  [section 7.1]
2758                     HttpHeaderLastModified          = 19,   // entity-header  [section 7.1]
2759
2760
2761                     // Response Headers
2762
2763                     HttpHeaderAcceptRanges          = 20,   // response-header [section 6.2]
2764                     HttpHeaderAge                   = 21,   // response-header [section 6.2]
2765                     HttpHeaderEtag                  = 22,   // response-header [section 6.2]
2766                     HttpHeaderLocation              = 23,   // response-header [section 6.2]
2767                     HttpHeaderProxyAuthenticate     = 24,   // response-header [section 6.2]
2768                     HttpHeaderRetryAfter            = 25,   // response-header [section 6.2]
2769                     HttpHeaderServer                = 26,   // response-header [section 6.2]
2770                     HttpHeaderSetCookie             = 27,   // response-header [not in rfc]
2771                     HttpHeaderVary                  = 28,   // response-header [section 6.2]
2772                     HttpHeaderWwwAuthenticate       = 29,   // response-header [section 6.2]
2773
2774                     HttpHeaderResponseMaximum       = 30,
2775
2776
2777                     HttpHeaderMaximum               = 41
2778                 }
2779
2780                 private static string[] m_Strings = {
2781                     "Cache-Control",
2782                     "Connection",
2783                     "Date",
2784                     "Keep-Alive",
2785                     "Pragma",
2786                     "Trailer",
2787                     "Transfer-Encoding",
2788                     "Upgrade",
2789                     "Via",
2790                     "Warning",
2791
2792                     "Allow",
2793                     "Content-Length",
2794                     "Content-Type",
2795                     "Content-Encoding",
2796                     "Content-Language",
2797                     "Content-Location",
2798                     "Content-MD5",
2799                     "Content-Range",
2800                     "Expires",
2801                     "Last-Modified",
2802
2803                     "Accept-Ranges",
2804                     "Age",
2805                     "ETag",
2806                     "Location",
2807                     "Proxy-Authenticate",
2808                     "Retry-After",
2809                     "Server",
2810                     "Set-Cookie",
2811                     "Vary",
2812                     "WWW-Authenticate",
2813                 };
2814             }
2815
2816             private static HTTPAPI_VERSION version;
2817             private static volatile bool extendedProtectionSupported;
2818
2819             //
2820             // This property is used by HttpListener to pass the version structure to the native layer in API
2821             // calls. 
2822             //
2823             internal static HTTPAPI_VERSION Version {
2824                 get {
2825                     return version;
2826                 }
2827             }
2828
2829             //
2830             // This property is used by HttpListener to get the Api version in use so that it uses appropriate 
2831             // Http APIs.
2832             //
2833             internal static HTTP_API_VERSION ApiVersion {
2834                 get {
2835                     if (version.HttpApiMajorVersion == 2 && version.HttpApiMinorVersion == 0) {
2836                         return HTTP_API_VERSION.Version20;
2837                     } 
2838                     else if (version.HttpApiMajorVersion == 1 && version.HttpApiMinorVersion == 0) {
2839                         return HTTP_API_VERSION.Version10;
2840                     } 
2841                     else {
2842                         return HTTP_API_VERSION.Invalid;
2843                     }
2844                 }
2845             }
2846
2847             //
2848             // returns 'true' if http.sys supports CBT: either the system is Win7+, or http.sys was patched.
2849             //
2850             internal static bool ExtendedProtectionSupported {
2851                 get {
2852                     return extendedProtectionSupported;
2853                 }
2854             }
2855
2856             static HttpApi() {
2857                 InitHttpApi(2, 0);
2858             }
2859
2860             private static void InitHttpApi(ushort majorVersion, ushort minorVersion) {
2861                 version.HttpApiMajorVersion = majorVersion;
2862                 version.HttpApiMinorVersion = minorVersion;
2863
2864                 GlobalLog.Print("HttpApi::.ctor() calling HttpApi.HttpInitialize() for Version " + majorVersion + "." + minorVersion);
2865
2866                 // For pre-Win7 OS versions, we need to check whether http.sys contains the CBT patch.
2867                 // We do so by passing HTTP_INITIALIZE_CBT flag to HttpInitialize. If the flag is not 
2868                 // supported, http.sys is not patched. Note that http.sys will return invalid parameter
2869                 // also on Win7, even though it shipped with CBT support. Therefore we must not pass
2870                 // the flag on Win7 and later.
2871                 uint statusCode = ErrorCodes.ERROR_SUCCESS;
2872                 extendedProtectionSupported = true;
2873
2874                 if (ComNetOS.IsWin7orLater) {
2875                     // on Win7 and later, we don't pass the CBT flag. CBT is always supported.
2876                     statusCode = HttpApi.HttpInitialize(version, (uint)HTTP_FLAGS.HTTP_INITIALIZE_SERVER, null);
2877                 }
2878                 else {
2879                     statusCode = HttpApi.HttpInitialize(version,
2880                         (uint)(HTTP_FLAGS.HTTP_INITIALIZE_SERVER | HTTP_FLAGS.HTTP_INITIALIZE_CBT), null);
2881
2882                     // if the status code is INVALID_PARAMETER, http.sys does not support CBT.
2883                     if (statusCode == ErrorCodes.ERROR_INVALID_PARAMETER) {
2884                         if (Logging.On) Logging.PrintWarning(Logging.HttpListener, SR.GetString(SR.net_listener_cbt_not_supported));
2885                        
2886                         // try again without CBT flag: HttpListener can still be used, but doesn't support EP
2887                         extendedProtectionSupported = false;
2888                         statusCode = HttpApi.HttpInitialize(version, (uint)HTTP_FLAGS.HTTP_INITIALIZE_SERVER, null);
2889                     }
2890                 }
2891
2892                 supported = statusCode == ErrorCodes.ERROR_SUCCESS;
2893
2894                 GlobalLog.Print("HttpApi::.ctor() call to HttpApi.HttpInitialize() returned:" + statusCode + " supported:" + supported);
2895             }
2896
2897             static volatile bool supported;
2898             internal static bool Supported {
2899                 get {
2900                     return supported;
2901                 }
2902             }
2903
2904             // Server API
2905
2906             internal static WebHeaderCollection GetHeaders(byte[] memoryBlob, IntPtr originalAddress)
2907             {
2908                 GlobalLog.Enter("HttpApi::GetHeaders()");
2909
2910                 // Return value.
2911                 WebHeaderCollection headerCollection = new WebHeaderCollection(WebHeaderCollectionType.HttpListenerRequest);
2912                 fixed (byte* pMemoryBlob = memoryBlob)
2913                 {
2914                     HTTP_REQUEST* request = (HTTP_REQUEST*) pMemoryBlob;
2915                     long fixup = pMemoryBlob - (byte*) originalAddress;
2916                     int index;
2917
2918                     // unknown headers
2919                     if (request->Headers.UnknownHeaderCount != 0)
2920                     {
2921                         HTTP_UNKNOWN_HEADER* pUnknownHeader = (HTTP_UNKNOWN_HEADER*) (fixup + (byte*) request->Headers.pUnknownHeaders);
2922                         for (index = 0; index < request->Headers.UnknownHeaderCount; index++)
2923                         {
2924                             // For unknown headers, when header value is empty, RawValueLength will be 0 and 
2925                             // pRawValue will be null.
2926                             if (pUnknownHeader->pName != null && pUnknownHeader->NameLength > 0)
2927                             {
2928                                 string headerName = new string(pUnknownHeader->pName + fixup, 0, pUnknownHeader->NameLength);
2929                                 string headerValue;
2930                                 if (pUnknownHeader->pRawValue != null && pUnknownHeader->RawValueLength > 0) {
2931                                     headerValue = new string(pUnknownHeader->pRawValue + fixup, 0, pUnknownHeader->RawValueLength);
2932                                 }
2933                                 else {
2934                                     headerValue = string.Empty;
2935                                 }
2936                                 headerCollection.AddInternal(headerName, headerValue);
2937                             }
2938                             pUnknownHeader++;
2939                         }
2940                     }
2941
2942                     // known headers
2943                     HTTP_KNOWN_HEADER* pKnownHeader = &request->Headers.KnownHeaders;
2944                     for (index = 0; index < HttpHeaderRequestMaximum; index++)
2945                     {
2946                         // For known headers, when header value is empty, RawValueLength will be 0 and 
2947                         // pRawValue will point to empty string ("\0")
2948                         if (pKnownHeader->pRawValue != null)
2949                         {
2950                             string headerValue = new string(pKnownHeader->pRawValue + fixup, 0, pKnownHeader->RawValueLength);
2951                             headerCollection.AddInternal(HTTP_REQUEST_HEADER_ID.ToString(index), headerValue);
2952                         }
2953                         pKnownHeader++;
2954                     }
2955                 }
2956
2957                 GlobalLog.Leave("HttpApi::GetHeaders()");
2958                 return headerCollection;
2959             }
2960
2961             private static string GetKnownHeader(HTTP_REQUEST* request, long fixup, int headerIndex)
2962             {
2963                 GlobalLog.Enter("HttpApi::GetKnownHeader()");
2964                 string header = null;
2965
2966                 HTTP_KNOWN_HEADER* pKnownHeader = (&request->Headers.KnownHeaders) + headerIndex;
2967                 GlobalLog.Print("HttpApi::GetKnownHeader() pKnownHeader:0x" + ((IntPtr) pKnownHeader).ToString("x"));
2968                 GlobalLog.Print("HttpApi::GetKnownHeader() pRawValue:0x" + ((IntPtr) pKnownHeader->pRawValue).ToString("x") + " RawValueLength:" + pKnownHeader->RawValueLength.ToString());
2969                 // For known headers, when header value is empty, RawValueLength will be 0 and 
2970                 // pRawValue will point to empty string ("\0")
2971                 if (pKnownHeader->pRawValue != null)
2972                 {
2973                     header = new string(pKnownHeader->pRawValue + fixup, 0, pKnownHeader->RawValueLength);
2974                 }
2975
2976                 GlobalLog.Leave("HttpApi::GetKnownHeader() return:" + ValidationHelper.ToString(header));
2977                 return header;
2978             }
2979
2980             internal static string GetKnownHeader(HTTP_REQUEST* request, int headerIndex)
2981             {
2982                 return GetKnownHeader(request, 0, headerIndex);
2983             }
2984
2985             internal static string GetKnownHeader(byte[] memoryBlob, IntPtr originalAddress, int headerIndex)
2986             {
2987                 fixed (byte* pMemoryBlob = memoryBlob)
2988                 {
2989                     return GetKnownHeader((HTTP_REQUEST*) pMemoryBlob, pMemoryBlob - (byte*) originalAddress, headerIndex);
2990                 }
2991             }
2992
2993             private unsafe static string GetVerb(HTTP_REQUEST* request, long fixup)
2994             {
2995                 GlobalLog.Enter("HttpApi::GetVerb()");
2996                 string verb = null;
2997
2998                 if ((int) request->Verb > (int) HTTP_VERB.HttpVerbUnknown && (int) request->Verb < (int) HTTP_VERB.HttpVerbMaximum)
2999                 {
3000                     verb = HttpVerbs[(int) request->Verb];
3001                 }
3002                 else if (request->Verb == HTTP_VERB.HttpVerbUnknown && request->pUnknownVerb != null)
3003                 {
3004                     verb = new string(request->pUnknownVerb + fixup, 0, request->UnknownVerbLength);
3005                 }
3006
3007                 GlobalLog.Leave("HttpApi::GetVerb() return:" + ValidationHelper.ToString(verb));
3008                 return verb;
3009             }
3010
3011             internal unsafe static string GetVerb(HTTP_REQUEST* request)
3012             {
3013                 return GetVerb(request, 0);
3014             }
3015
3016             internal unsafe static string GetVerb(byte[] memoryBlob, IntPtr originalAddress)
3017             {
3018                 fixed (byte* pMemoryBlob = memoryBlob)
3019                 {
3020                     return GetVerb((HTTP_REQUEST*) pMemoryBlob, pMemoryBlob - (byte*) originalAddress);
3021                 }
3022             }
3023
3024             internal static HTTP_VERB GetKnownVerb(byte[] memoryBlob, IntPtr originalAddress)
3025             {
3026                 GlobalLog.Enter("HttpApi::GetKnownVerb()");
3027
3028                 // Return value.
3029                 HTTP_VERB verb = HTTP_VERB.HttpVerbUnknown;
3030                 fixed (byte* pMemoryBlob = memoryBlob)
3031                 {
3032                     HTTP_REQUEST* request = (HTTP_REQUEST*) pMemoryBlob;
3033                     if ((int)request->Verb > (int)HTTP_VERB.HttpVerbUnparsed && (int)request->Verb < (int)HTTP_VERB.HttpVerbMaximum)
3034                     {
3035                         verb = request->Verb;
3036                     }
3037                 }
3038
3039                 GlobalLog.Leave("HttpApi::GetKnownVerb()");
3040                 return verb;
3041             }
3042
3043             internal static uint GetChunks(byte[] memoryBlob, IntPtr originalAddress, ref int dataChunkIndex, ref uint dataChunkOffset, byte[] buffer, int offset, int size)
3044             {
3045                 GlobalLog.Enter("HttpApi::GetChunks() memoryBlob:" + ValidationHelper.ToString(memoryBlob));
3046
3047                 // Return value.
3048                 uint dataRead = 0;
3049                 fixed(byte* pMemoryBlob = memoryBlob)
3050                 {
3051                     HTTP_REQUEST* request = (HTTP_REQUEST*) pMemoryBlob;
3052                     long fixup = pMemoryBlob - (byte*) originalAddress;
3053
3054                     if (request->EntityChunkCount > 0 && dataChunkIndex < request->EntityChunkCount && dataChunkIndex != -1)
3055                     {
3056                         HTTP_DATA_CHUNK* pDataChunk = (HTTP_DATA_CHUNK*) (fixup + (byte*) &request->pEntityChunks[dataChunkIndex]);
3057
3058                         fixed(byte* pReadBuffer = buffer)
3059                         {
3060                             byte* pTo = &pReadBuffer[offset];
3061
3062                             while (dataChunkIndex < request->EntityChunkCount && dataRead < size){
3063                                 if(dataChunkOffset >= pDataChunk->BufferLength){
3064                                     dataChunkOffset = 0;
3065                                     dataChunkIndex ++;
3066                                     pDataChunk++;
3067                                 }
3068                                 else{
3069                                     byte* pFrom = pDataChunk->pBuffer + dataChunkOffset + fixup;
3070
3071                                     uint bytesToRead =  pDataChunk->BufferLength - (uint)dataChunkOffset;
3072                                     if (bytesToRead  > (uint)size){
3073                                         bytesToRead = (uint)size;
3074                                     }
3075                                     for (uint i=0;i<bytesToRead;i++)
3076                                     {
3077                                         *(pTo++) = *(pFrom++);
3078                                     }
3079                                     dataRead+=bytesToRead;
3080                                     dataChunkOffset += bytesToRead;
3081                                 }
3082                             }
3083                         }
3084                     }
3085                     //we're finished.
3086                     if(dataChunkIndex ==  request->EntityChunkCount){
3087                         dataChunkIndex = -1;
3088                     }
3089                 }
3090
3091                 GlobalLog.Leave("HttpApi::GetChunks()");
3092                 return dataRead;
3093             }
3094
3095             internal static IPEndPoint GetRemoteEndPoint(byte[] memoryBlob, IntPtr originalAddress)
3096             {
3097                 GlobalLog.Enter("HttpApi::GetRemoteEndPoint()");
3098
3099                 SocketAddress v4address = new SocketAddress(AddressFamily.InterNetwork, SocketAddress.IPv4AddressSize);
3100                 SocketAddress v6address = new SocketAddress(AddressFamily.InterNetworkV6, SocketAddress.IPv6AddressSize);
3101
3102                 fixed (byte* pMemoryBlob = memoryBlob)
3103                 {
3104                     HTTP_REQUEST* request = (HTTP_REQUEST*) pMemoryBlob;
3105                     IntPtr address = request->Address.pRemoteAddress != null ? (IntPtr) (pMemoryBlob - (byte*) originalAddress + (byte*) request->Address.pRemoteAddress) : IntPtr.Zero;
3106                     CopyOutAddress(address, ref v4address, ref v6address);
3107                 }
3108
3109                 IPEndPoint endpoint = null;
3110                 if (v4address != null)
3111                 {
3112                     endpoint = IPEndPoint.Any.Create(v4address) as IPEndPoint;
3113                 }
3114                 else if (v6address != null)
3115                 {
3116                     endpoint = IPEndPoint.IPv6Any.Create(v6address) as IPEndPoint;
3117                 }
3118
3119                 GlobalLog.Leave("HttpApi::GetRemoteEndPoint()");
3120                 return endpoint;
3121             }
3122
3123             internal static IPEndPoint GetLocalEndPoint(byte[] memoryBlob, IntPtr originalAddress)
3124             {
3125                 GlobalLog.Enter("HttpApi::GetLocalEndPoint()");
3126
3127                 SocketAddress v4address = new SocketAddress(AddressFamily.InterNetwork, SocketAddress.IPv4AddressSize);
3128                 SocketAddress v6address = new SocketAddress(AddressFamily.InterNetworkV6, SocketAddress.IPv6AddressSize);
3129
3130                 fixed (byte* pMemoryBlob = memoryBlob)
3131                 {
3132                     HTTP_REQUEST* request = (HTTP_REQUEST*) pMemoryBlob;
3133                     IntPtr address = request->Address.pLocalAddress != null ? (IntPtr) (pMemoryBlob - (byte*) originalAddress + (byte*) request->Address.pLocalAddress) : IntPtr.Zero;
3134                     CopyOutAddress(address, ref v4address, ref v6address);
3135                 }
3136
3137                 IPEndPoint endpoint = null;
3138                 if (v4address != null)
3139                 {
3140                     endpoint = IPEndPoint.Any.Create(v4address) as IPEndPoint;
3141                 }
3142                 else if (v6address != null)
3143                 {
3144                     endpoint = IPEndPoint.IPv6Any.Create(v6address) as IPEndPoint;
3145                 }
3146
3147                 GlobalLog.Leave("HttpApi::GetLocalEndPoint()");
3148                 return endpoint;
3149             }
3150             
3151             internal static HTTP_REQUEST_TOKEN_BINDING_INFO* GetTlsTokenBindingRequestInfo(byte[] memoryBlob, IntPtr originalAddress){
3152                 
3153                 fixed (byte* pMemoryBlob = memoryBlob)
3154                 {
3155                     HTTP_REQUEST_V2* request = (HTTP_REQUEST_V2*)pMemoryBlob;                    
3156                     long fixup = pMemoryBlob - (byte*) originalAddress;
3157
3158                     for (int i = 0; i < request->RequestInfoCount; i++)
3159                     {
3160                         HTTP_REQUEST_INFO* pThisInfo = (HTTP_REQUEST_INFO*)(fixup + (byte*)&request->pRequestInfo[i]);
3161                         if (pThisInfo != null && pThisInfo->InfoType == HTTP_REQUEST_INFO_TYPE.HttpRequestInfoTypeSslTokenBinding)
3162                         {
3163                             return (HTTP_REQUEST_TOKEN_BINDING_INFO*)pThisInfo->pInfo;
3164                         }
3165                     }
3166                 }
3167                 return null;
3168             }
3169
3170             [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
3171             private static void CopyOutAddress(IntPtr address, ref SocketAddress v4address, ref SocketAddress v6address)
3172             {
3173                 if (address != IntPtr.Zero)
3174                 {
3175                     ushort addressFamily = *((ushort*) address);
3176                     if (addressFamily == (ushort) AddressFamily.InterNetwork)
3177                     {
3178                         v6address = null;
3179                         fixed (byte* pBuffer = v4address.m_Buffer)
3180                         {
3181                             for (int index = 2; index < SocketAddress.IPv4AddressSize; index++)
3182                             {
3183                                 pBuffer[index] = ((byte*) address)[index];
3184                             }
3185                         }
3186                         return;
3187                     }
3188                     if (addressFamily == (ushort) AddressFamily.InterNetworkV6)
3189                     {
3190                         v4address = null;
3191                         fixed (byte* pBuffer = v6address.m_Buffer)
3192                         {
3193                             for (int index = 2; index < SocketAddress.IPv6AddressSize; index++)
3194                             {
3195                                 pBuffer[index] = ((byte*) address)[index];
3196                             }
3197                         }
3198                         return;
3199                     }
3200                 }
3201
3202                 v4address = null;
3203                 v6address = null;
3204             }
3205         }
3206
3207         [SuppressUnmanagedCodeSecurity]
3208         internal unsafe static class SecureStringHelper
3209         {
3210 #if DEBUG
3211             // this method is only called as part of an assert
3212             internal static bool AreEqualValues(SecureString secureString1, SecureString secureString2)
3213             {
3214                 IntPtr bstr1 = IntPtr.Zero;
3215                 IntPtr bstr2 = IntPtr.Zero;
3216                 bool result = false;
3217
3218                 if (secureString1 == null)
3219                 {
3220                     if (secureString2 == null)
3221                         return true;
3222                     else
3223                         return false;
3224                 }
3225                 else if (secureString2 == null)
3226                 {
3227                     return false;
3228                 }
3229
3230                 // strings are non-null at this point
3231
3232                 if ((object)secureString1 == (object)secureString2)
3233                     return true;  // same objects
3234
3235                 if (secureString1.Length != secureString2.Length)
3236                     return false;
3237
3238                 // strings are same length.  decrypt to unmanaged memory and compare them.
3239
3240                 try
3241                 {
3242                     bstr1 = Marshal.SecureStringToBSTR(secureString1);
3243                     bstr2 = Marshal.SecureStringToBSTR(secureString2);
3244                     result = true;
3245                     for (int i = 0; i < secureString1.Length; i++)
3246                     {
3247                         if (*((char*)bstr1 + i) != *((char*)bstr2 + i))
3248                         {
3249                             result = false;
3250                             break;
3251                         }
3252                     }
3253                 }
3254                 finally
3255                 {
3256                     if (bstr1 != IntPtr.Zero)
3257                         Marshal.ZeroFreeBSTR(bstr1);
3258                     if (bstr2 != IntPtr.Zero)
3259                         Marshal.ZeroFreeBSTR(bstr2);
3260                 }
3261                 return result;
3262             }
3263 #endif
3264
3265             internal static string CreateString(SecureString secureString)
3266             {
3267                 string plainString;
3268                 IntPtr bstr = IntPtr.Zero;
3269
3270                 if (secureString == null || secureString.Length == 0)
3271                     return String.Empty;
3272
3273                 try
3274                 {
3275                     bstr = Marshal.SecureStringToBSTR(secureString);
3276                     plainString = Marshal.PtrToStringBSTR(bstr);
3277                 }
3278                 finally
3279                 {
3280                     if (bstr != IntPtr.Zero)
3281                         Marshal.ZeroFreeBSTR(bstr);
3282                 }
3283                 return plainString;
3284             }
3285
3286             internal static SecureString CreateSecureString(string plainString)
3287             {
3288                 SecureString secureString;
3289
3290                 if (plainString == null || plainString.Length == 0)
3291                     return new SecureString();
3292
3293                 fixed (char* pch = plainString)
3294                 {
3295                     secureString = new SecureString(pch, plainString.Length);
3296                 }
3297
3298                 return secureString;
3299             }
3300         }
3301 #endif // !FEATURE_PAL
3302
3303 #if !FEATURE_PAL
3304         internal const int CLSCTX_SERVER = 0x15;
3305         [DllImport(OLE32, PreserveSig=false)] 
3306         public static extern void CoCreateInstance(
3307             [In] ref Guid clsid,
3308             IntPtr pUnkOuter,
3309             int context,
3310             [In] ref Guid iid,
3311             [MarshalAs(UnmanagedType.IUnknown)] out Object o );
3312 #endif // !FEATURE_PAL
3313     
3314         // Used to support Windows Store apps.  
3315         // This code was provided by Immo Landwerth from the CLR team.
3316         [FriendAccessAllowed]
3317         internal class AppXHelper
3318         {
3319             [SecuritySafeCritical]
3320             internal static Lazy<IntPtr> PrimaryWindowHandle = new Lazy<IntPtr>(() => GetPrimaryWindowHandle());
3321
3322             [SecuritySafeCritical]
3323             [SuppressMessage("Microsoft.Usage", "CA1806:DoNotIgnoreMethodResults", 
3324                 MessageId = "System.Net.UnsafeNclNativeMethods+AppXHelper.GetWindowThreadProcessId(System.IntPtr,System.Int32@)",
3325                 Justification = "The return value of is the thread ID that created the window, not an error code.")]
3326             private static IntPtr GetPrimaryWindowHandle()
3327             {
3328                 IntPtr primaryWindow = IntPtr.Zero;
3329                 GuiThreadInfo info = new GuiThreadInfo();
3330                 info.cbSize = Marshal.SizeOf(info);
3331                 // Find the current active window.
3332                 if (GetGUIThreadInfo(0, ref info) != 0 && info.hwndActive != IntPtr.Zero)
3333                 {
3334                     int processId;
3335                     // Find the process for that window.
3336                     GetWindowThreadProcessId(info.hwndActive, out processId);
3337                     // Make sure the current active window belongs to our process.
3338                     if (processId == Process.GetCurrentProcess().Id)
3339                     {
3340                         primaryWindow = info.hwndActive;
3341                     }
3342                 }
3343                 return primaryWindow;
3344             }
3345             
3346             [DllImport(USER32, SetLastError=true, ExactSpelling=true)]
3347             private static extern uint GetGUIThreadInfo(int threadId, ref GuiThreadInfo info);
3348
3349             [DllImport(USER32, ExactSpelling=true)]
3350             private static extern uint GetWindowThreadProcessId(IntPtr hwnd, out int processId);
3351
3352             private struct GuiThreadInfo
3353             {
3354                 public int cbSize; // Must be set to Marshal.SizeOf(GuiThreadInfo) before using.
3355                 public int flags;
3356                 public IntPtr hwndActive;
3357                 public IntPtr hwndFocus;
3358                 public IntPtr hwndCapture;
3359                 public IntPtr hwndMenuOwner;
3360                 public IntPtr hwndMoveSize;
3361                 public IntPtr hwndCaret;
3362                 // RECT
3363                 public int left;
3364                 public int top;
3365                 public int right;
3366                 public int bottom;
3367             }
3368         }
3369
3370         /// <remarks>
3371         /// Determines whether Token binding is supported on the machine or not
3372         /// This class is thread safe.
3373         /// The static method EnsureTokenBindingOSHelperInitialized is used to get that information.
3374         /// It calls the load library and caches the result under proper locks to make sure it is thread safe and only one call is made to load library.
3375         /// </remarks>
3376         internal static class TokenBindingOSHelper
3377         {
3378             private static bool s_supportsTokenBinding = false;
3379             private static object s_Lock = new object();
3380             private static volatile bool s_Initialized = false;
3381
3382             // <SecurityKernel Critical="True" Ring="0">
3383             // <CallsSuppressUnmanagedCode Name="UnsafeNclNativeMethods.GetProcAddress(System.Net.SafeLoadLibrary,System.String):System.IntPtr" />
3384             // <SatisfiesLinkDemand Name="SafeHandle.get_IsInvalid():System.Boolean" />
3385             // <ReferencesCritical Name="Method: SafeLoadLibrary.LoadLibraryEx(System.String):System.Net.SafeLoadLibrary" Ring="1" />
3386             // </SecurityKernel>
3387             [System.Security.SecurityCritical]
3388             private static void EnsureTokenBindingOSHelperInitialized()
3389             {
3390                 if (s_Initialized)
3391                 {
3392                     return;
3393                 }
3394                 lock (s_Lock)
3395                 {
3396                     if (s_Initialized)
3397                     {
3398                         return;
3399                     }
3400                     try
3401                     {
3402                         // if tokenbinding.dll is not available, TOKENBINDING is not supported
3403                         string dllFileName = Path.Combine(Environment.SystemDirectory, TOKENBINDING);
3404                         SafeLoadLibrary s_TokenBindingLibrary = SafeLoadLibrary.LoadLibraryEx(dllFileName);
3405                         if (!s_TokenBindingLibrary.IsInvalid)
3406                         {
3407                             s_supportsTokenBinding = s_TokenBindingLibrary.HasFunction("TokenBindingVerifyMessage");
3408                         }
3409                         s_Initialized = true;
3410                     }
3411                     catch (Exception e)
3412                     {
3413                         if (NclUtilities.IsFatal(e))
3414                         { 
3415                             throw;
3416                         }
3417                     }
3418                 }
3419             }
3420
3421             internal static bool SupportsTokenBinding
3422             {
3423                 get
3424                 {
3425                     EnsureTokenBindingOSHelperInitialized();
3426                     return s_supportsTokenBinding;
3427                 }
3428             }
3429         }
3430     }
3431 }