1 //------------------------------------------------------------------------------
2 // <copyright file="UnsafeNativeMethods.cs" company="Microsoft">
3 // Copyright (c) Microsoft Corporation. All rights reserved.
5 //------------------------------------------------------------------------------
8 using System.Runtime.InteropServices;
9 using System.Runtime.CompilerServices;
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;
25 [System.Security.SuppressUnmanagedCodeSecurityAttribute()]
26 internal static class UnsafeNclNativeMethods {
30 internal const String DLLPREFIX = "";
31 internal const String DLLSUFFIX = ".dll";
32 #else // !PLATFORM_UNIX
34 internal const String DLLPREFIX = "lib";
35 internal const String DLLSUFFIX = ".dylib";
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";
43 internal const String DLLPREFIX = "lib";
44 internal const String DLLSUFFIX = ".so";
46 #endif // !PLATFORM_UNIX
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;
52 private const string KERNEL32 = "kernel32.dll";
53 #endif // !FEATURE_PAL
56 private const string WS2_32 = "ws2_32.dll";
58 private const string WS2_32 = ExternDll.Kernel32; // Resolves to rotor_pal
59 #endif // !FEATURE_PAL
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";
74 private const string OLE32 = "ole32.dll";
77 internal static extern IntPtr CreateSemaphore([In] IntPtr lpSemaphoreAttributes, [In] int lInitialCount, [In] int lMaximumCount, [In] IntPtr lpName);
81 internal static extern bool ReleaseSemaphore([In] IntPtr hSemaphore, [In] int lReleaseCount, [Out] out int lpPreviousCount);
85 internal static extern bool ReleaseSemaphore([In] IntPtr hSemaphore, [In] int lReleaseCount, [In] IntPtr lpPreviousCount);
89 internal static class ErrorCodes
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;
103 internal static class NTStatus
105 internal const uint STATUS_SUCCESS = 0x00000000;
106 internal const uint STATUS_OBJECT_NAME_NOT_FOUND = 0xC0000034;
109 [DllImport(KERNEL32, ExactSpelling=true, CallingConvention=CallingConvention.StdCall, SetLastError=true)]
110 internal static extern uint GetCurrentThreadId();
113 [DllImport(KERNEL32, ExactSpelling = true, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
114 internal static unsafe extern uint CancelIoEx(CriticalHandle handle, NativeOverlapped* overlapped);
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);
120 [DllImport(KERNEL32, CallingConvention = CallingConvention.Winapi, SetLastError = true)]
121 internal static extern IntPtr GetProcessHeap();
123 [DllImport(KERNEL32, CallingConvention = CallingConvention.Winapi, SetLastError = true)]
124 internal static extern bool HeapFree([In] IntPtr hHeap, [In] uint dwFlags, [In] IntPtr lpMem);
126 [System.Security.SecurityCritical]
127 [DllImport(KERNEL32, CallingConvention = CallingConvention.Winapi, SetLastError = true)]
128 internal extern static IntPtr GetProcAddress(SafeLoadLibrary hModule, string entryPoint);
131 internal enum FileCompletionNotificationModes : byte
134 SkipCompletionPortOnSuccess = 1,
135 SkipSetEventOnHandle = 2
139 [DllImport(KERNEL32, ExactSpelling = true)]
140 internal static extern void DebugBreak();
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
149 [SuppressUnmanagedCodeSecurity]
150 internal unsafe static class RegistryHelper
152 internal const uint REG_NOTIFY_CHANGE_LAST_SET = 4;
153 internal const uint REG_BINARY = 3;
154 internal const uint KEY_READ = 0x00020019;
156 internal static readonly IntPtr HKEY_CURRENT_USER = (IntPtr) unchecked((int) 0x80000001L);
157 internal static readonly IntPtr HKEY_LOCAL_MACHINE = (IntPtr) unchecked((int) 0x80000002L);
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);
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);
168 [DllImport(ADVAPI32, ExactSpelling=true, SetLastError=true)]
169 [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
170 internal static extern uint RegCloseKey(IntPtr key);
172 [DllImport(ADVAPI32, ExactSpelling=true, SetLastError=true)]
173 internal static extern uint RegNotifyChangeKeyValue(SafeRegistryHandle key, bool watchSubTree, uint notifyFilter, SafeWaitHandle regEvent, bool async);
175 [DllImport(ADVAPI32, ExactSpelling=true, SetLastError=true)]
176 internal static extern uint RegOpenCurrentUser(uint samDesired, out SafeRegistryHandle resultKey);
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);
182 [System.Security.SuppressUnmanagedCodeSecurityAttribute()]
183 internal unsafe class RasHelper
185 private static readonly bool s_RasSupported;
187 private ManualResetEvent m_RasEvent;
188 private bool m_Suppressed;
191 internal void Close()
193 ManualResetEvent rasEvent = m_RasEvent;
195 m_Suppressed = false;
196 if (rasEvent != null)
205 if (ComNetOS.InstallationType == WindowsInstallationType.ServerCore)
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;
213 s_RasSupported = true;
217 Logging.PrintInfo(Logging.Web, SR.GetString(SR.net_log_proxy_ras_supported, s_RasSupported));
224 throw new InvalidOperationException(SR.GetString(SR.net_log_proxy_ras_notsupported_exception));
227 m_RasEvent = new ManualResetEvent(false);
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);
232 GlobalLog.Print("RasHelper::RasHelper() RasConnectionNotification() statusCode:" + statusCode);
235 GlobalLog.Print("RasHelper::RasHelper() RasConnectionNotification() Marshal.GetLastWin32Error():" + Marshal.GetLastWin32Error());
242 internal static bool RasSupported
244 get { return s_RasSupported; }
247 internal bool HasChanged
256 ManualResetEvent rasEvent = m_RasEvent;
257 if (rasEvent == null)
259 throw new ObjectDisposedException(GetType().FullName);
261 return rasEvent.WaitOne(0, false);
265 internal void Reset()
269 ManualResetEvent rasEvent = m_RasEvent;
270 if (rasEvent == null)
272 throw new ObjectDisposedException(GetType().FullName);
278 internal static string GetCurrentConnectoid()
280 uint dwSize = (uint) Marshal.SizeOf(typeof(RASCONN));
281 GlobalLog.Print("RasHelper::GetCurrentConnectoid() using struct size dwSize:" + dwSize);
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)
292 RASCONN[] connections = null;
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)
304 count = checked(cb + dwSize - 1) / dwSize;
307 if (count == 0 || statusCode != 0)
312 for (uint i=0; i < count; i++)
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);
321 RASCONNSTATUS connectionStatus = new RASCONNSTATUS();
322 connectionStatus.dwSize = (uint)Marshal.SizeOf(connectionStatus);
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);
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;
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);
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);
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);
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;
360 const uint RASCN_Connection = 0x00000001;
361 const uint RASCN_Disconnection = 0x00000002;
363 const int UNLEN = 256;
364 const int PWLEN = 256;
365 const int DNLEN = 15;
367 const int MAX_PATH = 260;
369 const uint RASBASE = 600;
370 const uint ERROR_DIAL_ALREADY_IN_PROGRESS = (RASBASE+156);
371 const uint ERROR_BUFFER_TOO_SMALL = (RASBASE+3);
373 [StructLayout(LayoutKind.Sequential, Pack=4, CharSet=CharSet.Auto)]
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;
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;
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;
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;
431 const int RASCS_PAUSED = 0x1000;
432 const int RASCS_DONE = 0x2000;
438 RASCS_DeviceConnected,
439 RASCS_AllDevicesConnected,
444 RASCS_AuthChangePassword,
448 RASCS_ReAuthenticate,
450 RASCS_PrepareForCallback,
451 RASCS_WaitForModemReset,
452 RASCS_WaitForCallback,
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,
464 RASCS_Connected = RASCS_DONE,
469 [System.Security.SuppressUnmanagedCodeSecurityAttribute()]
470 internal static class SafeNetHandles_SECURITY {
472 [DllImport(SECUR32, ExactSpelling=true, SetLastError=true)]
473 [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
474 internal static extern int FreeContextBuffer(
475 [In] IntPtr contextBuffer);
478 [DllImport(SECUR32, ExactSpelling=true, SetLastError=true)]
479 [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
480 internal static extern int FreeCredentialsHandle(
481 ref SSPIHandle handlePtr
484 [DllImport(SECUR32, ExactSpelling=true, SetLastError=true)]
485 [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
486 internal static extern int DeleteSecurityContext(
487 ref SSPIHandle handlePtr
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,
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,
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,
517 [In] int bufferSize);
519 [DllImport(SECUR32, ExactSpelling=true, SetLastError=true)]
520 internal static extern int EnumerateSecurityPackagesW(
521 [Out] out int pkgnum,
522 [Out] out SafeFreeContextBuffer_SECURITY handle);
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,
530 [In] ref AuthIdentity authdata,
531 [In] void* keyCallback,
532 [In] void* keyArgument,
533 ref SSPIHandle handlePtr,
534 [Out] out long timeStamp
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,
544 [In] void* keyCallback,
545 [In] void* keyArgument,
546 ref SSPIHandle handlePtr,
547 [Out] out long timeStamp
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,
557 [In] SafeSspiAuthDataHandle authdata,
558 [In] void* keyCallback,
559 [In] void* keyArgument,
560 ref SSPIHandle handlePtr,
561 [Out] out long timeStamp
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,
570 [In] ref SecureCredential authData,
571 [In] void* keyCallback,
572 [In] void* keyArgument,
573 ref SSPIHandle handlePtr,
574 [Out] out long timeStamp
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,
585 [In] Endianness endianness,
586 [In] SecurityBufferDescriptor inputBuffer,
588 ref SSPIHandle outContextPtr,
589 [In, Out] SecurityBufferDescriptor outputBuffer,
590 [In, Out] ref ContextFlags attributes,
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
603 #endif // !FEATURE_PAL
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);
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
625 [DllImport(WS2_32, ExactSpelling = true, SetLastError = true)]
626 [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
627 internal static extern void freeaddrinfo([In] IntPtr info );
631 [System.Security.SuppressUnmanagedCodeSecurityAttribute()]
632 internal static class SafeNetHandles {
635 [DllImport(SECUR32, ExactSpelling=true, SetLastError=true)]
636 internal static extern int QuerySecurityContextToken(ref SSPIHandle phContext, [Out] out SafeCloseHandle handle);
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);
643 [DllImport(HTTPAPI, ExactSpelling = true, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
644 internal static extern unsafe uint HttpCloseRequestQueue(IntPtr pReqQueueHandle);
648 [DllImport(ExternDll.Kernel32, ExactSpelling=true, SetLastError=true)]
649 [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
650 internal static extern bool CloseHandle(IntPtr handle);
652 [DllImport(ExternDll.Kernel32, ExactSpelling=true, SetLastError=true)]
653 internal static extern SafeLocalFree LocalAlloc(int uFlags, UIntPtr sizetdwBytes);
655 [DllImport(ExternDll.Kernel32, EntryPoint = "LocalAlloc", SetLastError = true)]
656 internal static extern SafeLocalFreeChannelBinding LocalAllocChannelBinding(int uFlags, UIntPtr sizetdwBytes);
658 [DllImport(ExternDll.Kernel32, ExactSpelling=true, SetLastError=true)]
659 [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
660 internal static extern IntPtr LocalFree(IntPtr handle);
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
669 [DllImport(KERNEL32, ExactSpelling=true, SetLastError=true)]
670 [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
671 internal static extern unsafe bool FreeLibrary([In] IntPtr hModule);
676 // Consider removing.
677 [DllImport(CRYPT32, ExactSpelling=true, SetLastError=true)]
678 internal static extern bool CertGetCertificateChain(
679 [In] IntPtr chainEngine,
680 [In] SafeFreeCertContext certContext,
682 [In] SafeCloseStore additionalStore,
683 [In] ref ChainParameters certCP,
685 [In] IntPtr reserved,
686 [Out] out SafeFreeCertChain chainContext);
689 [DllImport(CRYPT32, ExactSpelling=true, SetLastError=true)]
690 [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
691 internal static extern void CertFreeCertificateChain(
692 [In] IntPtr pChainContext);
694 [DllImport(CRYPT32, ExactSpelling = true, SetLastError = true)]
695 [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
696 internal static extern void CertFreeCertificateChainList(
697 [In] IntPtr ppChainContext);
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);
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,
713 #endif // !FEATURE_PAL
715 [DllImport(ExternDll.Kernel32, ExactSpelling=true, SetLastError=true)]
716 [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
717 internal static extern IntPtr GlobalFree(IntPtr handle);
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
727 [DllImport(WS2_32, ExactSpelling=true, SetLastError=true)]
728 [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
729 internal static extern SocketError closesocket(
730 [In] IntPtr socketHandle
733 [DllImport(WS2_32, ExactSpelling=true, SetLastError=true)]
734 [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
735 internal static extern SocketError ioctlsocket(
738 [In, Out] ref int argp
741 [DllImport(WS2_32, ExactSpelling=true, SetLastError=true)]
742 [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
743 internal static extern SocketError WSAEventSelect(
746 [In] AsyncEventBits NetworkEvents
749 [DllImport(WS2_32, ExactSpelling=true, SetLastError=true)]
750 [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
751 internal static extern SocketError setsockopt(
753 [In] SocketOptionLevel optionLevel,
754 [In] SocketOptionName optionName,
755 [In] ref Linger linger,
756 [In] int optionLength
760 [DllImport(WS2_32, ExactSpelling=true, SetLastError=true)]
761 [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
762 internal static extern SocketError setsockopt(
764 [In] SocketOptionLevel optionLevel,
765 [In] SocketOptionName optionName,
766 [In] ref int optionValue,
767 [In] int optionLength
772 [DllImport(WININET, ExactSpelling=true, SetLastError = true)]
773 [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
774 unsafe internal static extern bool RetrieveUrlCacheEntryFileW(
776 [In] byte* entryPtr, //was [Out]
777 [In, Out] ref int entryBufSize,
778 [In] int dwReserved //must be 0
781 [DllImport(WININET, ExactSpelling=true, SetLastError = true)]
782 [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
783 unsafe internal static extern bool UnlockUrlCacheEntryFileW(
785 [In] int dwReserved //must be 0
787 #endif // !FEATURE_PAL
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:
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:
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
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
813 // objects are marshalled differently if they're:
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.
819 // a) for IN and OUT:
820 // [In, Out] ref Struct ([In, Out] is optional here)
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)
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)
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.
836 // a) for IN and OUT:
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)
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)
849 [System.Security.SuppressUnmanagedCodeSecurityAttribute()]
850 internal static class OSSOCK {
853 private const string WS2_32 = ROTOR_PAL;
855 private const string WS2_32 = "ws2_32.dll";
856 private const string mswsock = "mswsock.dll";
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 !
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 */
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;
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;
897 [StructLayout(LayoutKind.Sequential)]
898 internal struct ControlData {
899 internal UIntPtr length;
902 internal uint address;
906 [StructLayout(LayoutKind.Sequential)]
907 internal struct ControlDataIPv6 {
908 internal UIntPtr length;
911 [MarshalAs(UnmanagedType.ByValArray,SizeConst=16)]
912 internal byte[] address;
916 [StructLayout(LayoutKind.Sequential)]
917 internal struct WSAMsg {
918 internal IntPtr socketAddress;
919 internal uint addressLength;
920 internal IntPtr buffers;
922 internal WSABuffer controlBuffer;
923 internal SocketFlags flags;
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
933 internal enum TransmitPacketsElementFlags : uint {
940 // Structure equivalent to TRANSMIT_PACKETS_ELEMENT
942 // typedef struct _TRANSMIT_PACKETS_ELEMENT {
947 // LARGE_INTEGER nFileOffset;
953 // } TRANSMIT_PACKETS_ELEMENT;
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;
970 typedef struct _SOCKET_ADDRESS {
971 PSOCKADDR lpSockaddr;
973 } SOCKET_ADDRESS, *PSOCKET_ADDRESS;
975 [StructLayout(LayoutKind.Sequential)]
976 internal struct SOCKET_ADDRESS {
977 internal IntPtr lpSockAddr;
978 internal int iSockaddrLength;
982 typedef struct _SOCKET_ADDRESS_LIST {
984 SOCKET_ADDRESS Address[1];
985 } SOCKET_ADDRESS_LIST, *PSOCKET_ADDRESS_LIST, FAR *LPSOCKET_ADDRESS_LIST;
987 [StructLayout(LayoutKind.Sequential)]
988 internal struct SOCKET_ADDRESS_LIST {
989 internal int iAddressCount;
990 internal SOCKET_ADDRESS Addresses;
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
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
1009 [In] SocketConstructorFlags flags
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
1019 [In] SocketConstructorFlags flags
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
1029 [DllImport(WS2_32, SetLastError=true)]
1030 [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
1031 internal static extern SocketError ioctlsocket(
1032 [In] SafeCloseSocket socketHandle,
1034 [In, Out] ref int argp
1037 [DllImport(WS2_32, CharSet=CharSet.Ansi, BestFitMapping=false, ThrowOnUnmappableChar=true, SetLastError=true)]
1038 internal static extern IntPtr gethostbyname(
1042 [DllImport(WS2_32, SetLastError=true)]
1043 internal static extern IntPtr gethostbyaddr(
1046 [In] ProtocolFamily type
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
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
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
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
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
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
1099 // IPv6 Changes: need to receive and IPv6MulticastRequest from getsockopt
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
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
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
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
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
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
1157 // IPv6 Changes: need to pass an IPv6MulticastRequest to setsockopt
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
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
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
1193 [DllImport(mswsock, SetLastError = true, EntryPoint = "TransmitFile")]
1194 internal static extern bool TransmitFile_Blocking(
1196 [In] SafeHandle fileHandle,
1197 [In] int numberOfBytesToWrite,
1198 [In] int numberOfBytesPerSend,
1199 [In] SafeHandle overlapped,
1200 [In] TransmitFileBuffers buffers,
1201 [In] TransmitFileOptions flags
1204 [DllImport(mswsock, SetLastError = true, EntryPoint = "TransmitFile")]
1205 internal static extern bool TransmitFile_Blocking2(
1207 [In] IntPtr fileHandle,
1208 [In] int numberOfBytesToWrite,
1209 [In] int numberOfBytesPerSend,
1210 [In] SafeHandle overlapped,
1211 [In] TransmitFileBuffers buffers,
1212 [In] TransmitFileOptions flags
1215 #endif // !FEATURE_PAL
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,
1223 [In] SocketFlags socketFlags
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,
1232 [In] SocketFlags socketFlags
1235 [DllImport(WS2_32, SetLastError=true)]
1236 internal static extern SocketError listen(
1237 [In] SafeCloseSocket socketHandle,
1241 [DllImport(WS2_32, SetLastError=true)]
1242 internal static extern SocketError bind(
1243 [In] SafeCloseSocket socketHandle,
1244 [In] byte[] socketAddress,
1245 [In] int socketAddressSize
1248 [DllImport(WS2_32, SetLastError=true)]
1249 internal static extern SocketError shutdown(
1250 [In] SafeCloseSocket socketHandle,
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,
1260 [In] SocketFlags socketFlags,
1261 [In] byte[] socketAddress,
1262 [In] int socketAddressSize
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,
1271 [In] SocketFlags socketFlags,
1272 [Out] byte[] socketAddress,
1273 [In, Out] ref int socketAddressSize
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
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
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
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,
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
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
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
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
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
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
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
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
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
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
1432 [DllImport(WS2_32, SetLastError=true)]
1433 internal static extern SocketError WSAEventSelect(
1434 [In] SafeCloseSocket socketHandle,
1435 [In] SafeHandle Event,
1436 [In] AsyncEventBits NetworkEvents
1439 [DllImport(WS2_32, SetLastError=true)]
1440 internal static extern SocketError WSAEventSelect(
1441 [In] SafeCloseSocket socketHandle,
1443 [In] AsyncEventBits NetworkEvents
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,
1454 [Out] out IntPtr funcPtr,
1455 [In] int funcPtrSize,
1456 [Out] out int bytesTransferred,
1457 [In] IntPtr shouldBeNull,
1458 [In] IntPtr shouldBeNull2
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
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
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
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
1501 #endif // !FEATURE_PAL
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,
1509 [Out] out SocketFlags socketFlags
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 );
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);
1529 [DllImport(WS2_32, CharSet=CharSet.Unicode, BestFitMapping=false, ThrowOnUnmappableChar=true, SetLastError=true)]
1530 internal static extern SocketError GetNameInfoW(
1533 [In,Out] StringBuilder host,
1535 [In,Out] StringBuilder serv,
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
1548 #if SOCKETTHREADPOOL
1549 [DllImport("kernel32.dll", SetLastError = true)]
1550 public static extern bool BindIoCompletionCallback(
1551 SafeCloseSocket socketHandle,
1552 IOCompletionCallback function,
1556 [DllImport("kernel32.dll", SetLastError = true)]
1557 public static extern IntPtr CreateIoCompletionPort(
1558 SafeCloseSocket socketHandle,
1559 IntPtr ExistingCompletionPort,
1560 Int32 CompletionKey,
1561 Int32 NumberOfConcurrentThreads
1564 [DllImport("kernel32.dll", SetLastError = true)]
1565 public static extern IntPtr CreateIoCompletionPort(
1567 IntPtr ExistingCompletionPort,
1568 Int32 CompletionKey,
1569 Int32 NumberOfConcurrentThreads
1571 [DllImport("kernel32.dll", SetLastError = true)]
1572 public static extern IntPtr CreateIoCompletionPort(
1574 IntPtr ExistingCompletionPort,
1575 Int32 CompletionKey,
1576 Int32 NumberOfConcurrentThreads
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
1588 [DllImport("kernel32.dll", SetLastError = true)]
1589 public static extern bool PostQueuedCompletionStatus(
1590 IntPtr CompletionPort,
1591 Int32 dwNumberOfBytesTransferred,
1592 IntPtr dwCompletionKey,
1595 #endif // SOCKETTHREADPOOL
1596 #endif // !FEATURE_PAL
1598 }; // class UnsafeNclNativeMethods.OSSOCK
1602 // UnsafeNclNativeMethods.NativePKI class contains methods
1603 // imported from crypt32.dll.
1604 // They deal mainly with certificates handling when doing https://
1606 [System.Security.SuppressUnmanagedCodeSecurityAttribute()]
1607 internal static class NativePKI {
1609 [StructLayout(LayoutKind.Sequential)]
1610 internal struct CRYPT_OBJID_BLOB
1612 public UInt32 cbData;
1613 public IntPtr pbData;
1616 [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)]
1617 internal struct CERT_EXTENSION
1619 public IntPtr pszObjId;
1620 public UInt32 fCritical;
1621 public CRYPT_OBJID_BLOB Value;
1624 [StructLayout(LayoutKind.Sequential)]
1625 internal struct CERT_SELECT_CRITERIA
1627 public UInt32 dwType;
1628 public UInt32 cPara;
1629 public IntPtr ppPara;
1632 [DllImport(CRYPT32, ExactSpelling=true, SetLastError=true)]
1633 internal static extern int CertVerifyCertificateChainPolicy(
1635 [In] SafeFreeCertChain chainContext,
1636 [In] ref ChainPolicyParameter cpp,
1637 [In, Out] ref ChainPolicyStatus ps);
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);
1654 private enum CertificateSelect : int
1657 AllowExpired = 0x00000001,
1658 TrustedRoot = 0x00000002,
1659 DisallowSelfsigned = 0x00000004,
1660 HasPrivateKey = 0x00000008,
1661 HasKeyForSignature = 0x00000010,
1662 HasKeyForKeyExchange = 0x00000020,
1663 HardwareOnly = 0x00000040,
1664 AllowDuplicates = 0x00000080,
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()
1675 if (!ComNetOS.IsWin7orLater)
1677 throw new PlatformNotSupportedException();
1680 X509CertificateCollection certificates = new X509CertificateCollection();
1682 X509Store store = new X509Store(StoreName.My, StoreLocation.CurrentUser);
1683 store.Open(OpenFlags.MaxAllowed);
1686 SafeFreeCertChainList chainList = null;
1687 SafeCertSelectCritera criteria = new SafeCertSelectCritera();
1690 bool success = CertSelectCertificateChains(
1692 CertificateSelect.HasPrivateKey,
1694 criteria.Count, // DWORD
1695 criteria, // PCCERT_SELECT_CRITERIA
1702 throw new Win32Exception(); // Calls GetLastError.
1705 Debug.Assert(chainCount == 0 || !chainList.IsInvalid);
1707 for (int i = 0; i < chainCount; i++)
1709 // Resolve IntPtr in array.
1710 using (SafeFreeCertChain chainRef = new SafeFreeCertChain(
1711 Marshal.ReadIntPtr(chainList.DangerousGetHandle()
1712 + i * Marshal.SizeOf(typeof(IntPtr))), true))
1714 Debug.Assert(!chainRef.IsInvalid);
1716 // X509Chain will duplicate the chain by increasing its ref-count.
1717 X509Chain chain = new X509Chain(chainRef.DangerousGetHandle());
1719 // Copy base cert from chain.
1720 if (chain.ChainElements.Count > 0)
1722 X509Certificate2 cert = chain.ChainElements[0].Certificate;
1723 certificates.Add(cert);
1726 // Remove the X509Chain's reference prior to releasing the Chain List.
1735 chainList.Dispose();
1739 return certificates;
1741 }; // class UnsafeNclNativeMethods.NativePKI
1743 [System.Security.SuppressUnmanagedCodeSecurityAttribute()]
1744 internal static class NativeNTSSPI {
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
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
1764 }; // class UnsafeNclNativeMethods.NativeNTSSPI
1766 // The replacement for WinInet, WinHttp is preferred where it's available. We require version 5.1.
1767 [SuppressUnmanagedCodeSecurity]
1768 internal static class WinHttp
1770 [DllImport(WINHTTP, ExactSpelling=true, SetLastError=true)]
1771 internal static extern bool WinHttpDetectAutoProxyConfigUrl(AutoDetectType autoDetectFlags,
1772 out SafeGlobalFree autoConfigUrl);
1774 [DllImport(WINHTTP, SetLastError = true)]
1775 internal static extern bool WinHttpGetIEProxyConfigForCurrentUser(
1776 ref WINHTTP_CURRENT_USER_IE_PROXY_CONFIG proxyConfig);
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);
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);
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);
1792 [DllImport(WINHTTP, CharSet = CharSet.Unicode, SetLastError = true)]
1793 [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
1794 internal static extern bool WinHttpCloseHandle(IntPtr httpSession);
1796 [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
1797 internal struct WINHTTP_CURRENT_USER_IE_PROXY_CONFIG
1799 public bool AutoDetect;
1800 public IntPtr AutoConfigUrl;
1801 public IntPtr Proxy;
1802 public IntPtr ProxyBypass;
1806 internal enum AutoProxyFlags
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
1814 internal enum AccessType
1822 internal enum AutoDetectType
1825 Dhcp = 0x1, // WINHTTP_AUTO_DETECT_TYPE_DHCP
1826 DnsA = 0x2, // WINHTTP_AUTO_DETECT_TYPE_DNS_A
1829 [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
1830 internal struct WINHTTP_AUTOPROXY_OPTIONS
1832 public AutoProxyFlags Flags;
1834 public AutoDetectType AutoDetectFlags;
1836 [MarshalAs(UnmanagedType.LPWStr)]
1837 public string AutoConfigUrl;
1839 private IntPtr lpvReserved;
1841 private int dwReserved;
1843 public bool AutoLogonIfChallenged;
1846 [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
1847 internal struct WINHTTP_PROXY_INFO
1849 public AccessType AccessType;
1851 public IntPtr Proxy;
1853 public IntPtr ProxyBypass;
1856 internal enum ErrorCodes
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
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
1878 AuthCertNeeded = 12044, // ERROR_WINHTTP_CLIENT_AUTH_CERT_NEEDED
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
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
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
1896 NotInitialized = 12172, // ERROR_WINHTTP_NOT_INITIALIZED
1897 SecureFailure = 12175, // ERROR_WINHTTP_SECURE_FAILURE
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
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
1920 // Caching (must use WinInet to cache).
1922 [System.Security.SuppressUnmanagedCodeSecurityAttribute()]
1923 internal static class UnsafeWinInetCache {
1924 public const int MAX_PATH = 260;
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,
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
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
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
1962 [DllImport(WININET, CharSet = CharSet.Unicode, ExactSpelling=true, SetLastError = true)]
1963 internal static extern bool DeleteUrlCacheEntryW( [In] string urlName);
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
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,
1981 unsafe internal static extern bool ReadUrlCacheEntryStream(
1982 [In] SafeUnlockUrlCacheEntryStream urlCacheStream,
1984 [In] byte* bufferPtr,
1985 [In, Out] ref int bufferSz,
1986 [In] int dwReserved //must be 0
1989 internal static extern bool UnlockUrlCacheEntryStream(
1990 [In] IntPtr urlCacheStream,
1991 [In] int dwReserved //mustbe 0
1994 unsafe internal static extern bool GetUrlCacheEntryInfoEx(
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
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
2013 internal static extern bool FindNextUrlCacheGroup(
2015 [Out] out _WinInetCache.GroupId groupId,
2016 [In] IntPtr lpReserved //was [In,Out] must be IntPtr.Zero
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
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
2036 internal static extern WinInet.GroupId CreateUrlCacheGroup(
2037 [In] _WinInetCache.GroupFlag flags,
2038 [In] IntPtr lpReserved //must be IntPtr.Zero
2041 internal static extern bool DeleteUrlCacheGroup(
2042 [In] _WinInetCache.GroupId groupId,
2043 [In] _WinInetCache.GroupFlag flags,
2044 [In] IntPtr lpReserved //must be IntPtr.Zero
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
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
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
2078 unsafe internal static extern IntPtr FindFirstUrlCacheEntry(
2079 [In] string searchPattern,
2080 [In] byte* entryPtr, //was [Out]
2081 [In, Out]ref int entryBufSize
2085 unsafe internal static extern bool FindNextUrlCacheEntry(
2086 [In] IntPtr enumHandle,
2087 [In] byte* entryPtr, //was [Out]
2088 [In, Out]ref int entryBufSize
2091 internal static extern bool FindCloseUrlCache( [In] IntPtr enumHandle);
2096 [SuppressUnmanagedCodeSecurityAttribute]
2097 internal static class SspiHelper
2099 [DllImport(SECUR32, ExactSpelling = true, SetLastError = true)]
2100 [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
2101 internal unsafe static extern SecurityStatus SspiFreeAuthIdentity(
2102 [In] IntPtr authData);
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);
2113 #endif // !FEATURE_PAL
2116 [System.Security.SuppressUnmanagedCodeSecurityAttribute()]
2117 internal static unsafe class HttpApi {
2119 [DllImport(HTTPAPI, ExactSpelling=true, CallingConvention=CallingConvention.StdCall, SetLastError=true)]
2120 internal static extern uint HttpInitialize(HTTPAPI_VERSION version, uint flags, void* pReserved);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
2179 [DllImport(HTTPAPI, ExactSpelling = true, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
2180 internal static extern uint HttpCloseServerSession(ulong serverSessionId);
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);
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);
2196 internal sealed class HeapAllocHandle : SafeHandleZeroOrMinusOneIsInvalid
2198 private static readonly IntPtr ProcessHeap = GetProcessHeap();
2200 // Called by P/Invoke when returning SafeHandles.
2201 private HeapAllocHandle()
2202 : base(ownsHandle: true)
2206 // Do not provide a finalizer - SafeHandle's critical finalizer will call ReleaseHandle for you.
2207 protected override bool ReleaseHandle()
2209 return HeapFree(ProcessHeap, 0, handle);
2213 internal enum HTTP_API_VERSION {
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,
2235 internal enum HTTP_REQUEST_INFO_TYPE {
2236 HttpRequestInfoTypeAuth,
2237 HttpRequestInfoTypeChannelBind,
2238 HttpRequestInfoTypeSslProtocol,
2239 HttpRequestInfoTypeSslTokenBinding
2242 internal enum HTTP_RESPONSE_INFO_TYPE {
2243 HttpResponseInfoTypeMultipleKnownHeaders,
2244 HttpResponseInfoTypeAuthenticationProperty,
2245 HttpResponseInfoTypeQosProperty ,
2248 internal enum HTTP_TIMEOUT_TYPE {
2257 internal const int MaxTimeout = 6;
2259 [StructLayout(LayoutKind.Sequential)]
2260 internal struct HTTP_VERSION {
2261 internal ushort MajorVersion;
2262 internal ushort MinorVersion;
2265 [StructLayout(LayoutKind.Sequential)]
2266 internal struct HTTP_KNOWN_HEADER {
2267 internal ushort RawValueLength;
2268 internal sbyte* pRawValue;
2271 [StructLayout(LayoutKind.Sequential, Size=32)]
2272 internal struct HTTP_DATA_CHUNK {
2273 internal HTTP_DATA_CHUNK_TYPE DataChunkType;
2275 internal byte* pBuffer;
2276 internal uint BufferLength;
2279 [StructLayout(LayoutKind.Sequential)]
2280 internal struct HTTPAPI_VERSION {
2281 internal ushort HttpApiMajorVersion;
2282 internal ushort HttpApiMinorVersion;
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;
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;
2316 [StructLayout(LayoutKind.Sequential)]
2317 internal struct HTTP_TRANSPORT_ADDRESS {
2318 internal SOCKADDR* pRemoteAddress;
2319 internal SOCKADDR* pLocalAddress;
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;
2331 internal enum HTTP_SERVICE_BINDING_TYPE : uint {
2332 HttpServiceBindingTypeNone = 0,
2333 HttpServiceBindingTypeW,
2334 HttpServiceBindingTypeA
2337 [StructLayout(LayoutKind.Sequential)]
2338 internal struct HTTP_SERVICE_BINDING_BASE
2340 internal HTTP_SERVICE_BINDING_TYPE Type;
2343 [StructLayout(LayoutKind.Sequential)]
2344 internal struct HTTP_REQUEST_CHANNEL_BIND_STATUS
2346 internal IntPtr ServiceName;
2347 internal IntPtr ChannelToken;
2348 internal uint ChannelTokenSize;
2349 internal uint Flags;
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;
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;
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;
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;
2459 internal enum HTTP_VERB : int {
2460 HttpVerbUnparsed = 0,
2461 HttpVerbUnknown = 1,
2462 HttpVerbInvalid = 2,
2463 HttpVerbOPTIONS = 3,
2470 HttpVerbCONNECT = 10,
2474 HttpVerbPROPFIND = 14,
2475 HttpVerbPROPPATCH = 15,
2478 HttpVerbUNLOCK = 18,
2479 HttpVerbSEARCH = 19,
2480 HttpVerbMaximum = 20,
2483 internal static readonly string[] HttpVerbs = new string[] {
2506 internal enum HTTP_DATA_CHUNK_TYPE : int {
2507 HttpDataChunkFromMemory = 0,
2508 HttpDataChunkFromFileHandle = 1,
2509 HttpDataChunkFromFragmentCache = 2,
2510 HttpDataChunkMaximum = 3,
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;
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;
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;
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;
2563 [StructLayout(LayoutKind.Sequential)]
2564 internal struct HTTP_REQUEST_V2
2566 internal HTTP_REQUEST RequestV1;
2567 internal ushort RequestInfoCount;
2568 internal HTTP_REQUEST_INFO* pRequestInfo;
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;
2582 [StructLayout(LayoutKind.Sequential)]
2583 internal struct HTTP_BINDING_INFO {
2584 internal HTTP_FLAGS Flags;
2585 internal IntPtr RequestQueueHandle;
2588 [StructLayout(LayoutKind.Sequential)]
2589 internal unsafe struct HTTP_REQUEST_TOKEN_BINDING_INFO
2591 public byte* TokenBinding;
2592 public uint TokenBindingSize;
2593 public byte* TlsUnique;
2594 public uint TlsUniqueSize;
2595 public IntPtr KeyType;
2598 internal enum TOKENBINDING_HASH_ALGORITHM : byte
2600 TOKENBINDING_HASH_ALGORITHM_SHA256 = 4,
2603 internal enum TOKENBINDING_SIGNATURE_ALGORITHM : byte
2605 TOKENBINDING_SIGNATURE_ALGORITHM_RSA = 1,
2606 TOKENBINDING_SIGNATURE_ALGORITHM_ECDSAP256 = 3,
2609 internal enum TOKENBINDING_TYPE : byte
2611 TOKENBINDING_TYPE_PROVIDED = 0,
2612 TOKENBINDING_TYPE_REFERRED = 1,
2615 internal enum TOKENBINDING_EXTENSION_FORMAT
2617 TOKENBINDING_EXTENSION_FORMAT_UNDEFINED = 0,
2620 [StructLayout(LayoutKind.Sequential)]
2621 internal struct TOKENBINDING_IDENTIFIER
2623 public TOKENBINDING_TYPE bindingType;
2624 public TOKENBINDING_HASH_ALGORITHM hashAlgorithm;
2625 public TOKENBINDING_SIGNATURE_ALGORITHM signatureAlgorithm;
2628 [StructLayout(LayoutKind.Sequential)]
2629 internal unsafe struct TOKENBINDING_RESULT_DATA
2631 public uint identifierSize;
2632 public TOKENBINDING_IDENTIFIER* identifierData;
2633 public TOKENBINDING_EXTENSION_FORMAT extensionFormat;
2634 public uint extensionSize;
2635 public IntPtr extensionData;
2638 [StructLayout(LayoutKind.Sequential)]
2639 internal unsafe struct TOKENBINDING_RESULT_LIST
2641 public uint resultCount;
2642 public TOKENBINDING_RESULT_DATA* resultData;
2645 // see http.w for definitions
2647 internal enum HTTP_FLAGS : uint {
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,
2662 const int HttpHeaderRequestMaximum = (int)HttpRequestHeader.UserAgent + 1;
2663 const int HttpHeaderResponseMaximum = (int)HttpResponseHeader.WwwAuthenticate + 1;
2665 internal static class HTTP_REQUEST_HEADER_ID {
2666 internal static string ToString(int position) {
2667 return m_Strings[position];
2670 private static string[] m_Strings = {
2677 "Transfer-Encoding",
2704 "If-Modified-Since",
2707 "If-Unmodified-Since",
2709 "Proxy-Authorization",
2718 internal static class HTTP_RESPONSE_HEADER_ID {
2719 private static Hashtable m_Hashtable;
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);
2728 internal static int IndexOfKnownHeader(string HeaderName) {
2729 object index = m_Hashtable[HeaderName];
2730 return index==null ? -1 : (int)index;
2733 internal static string ToString(int position) {
2734 return m_Strings[position];
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]
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]
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]
2774 HttpHeaderResponseMaximum = 30,
2777 HttpHeaderMaximum = 41
2780 private static string[] m_Strings = {
2787 "Transfer-Encoding",
2807 "Proxy-Authenticate",
2816 private static HTTPAPI_VERSION version;
2817 private static volatile bool extendedProtectionSupported;
2820 // This property is used by HttpListener to pass the version structure to the native layer in API
2823 internal static HTTPAPI_VERSION Version {
2830 // This property is used by HttpListener to get the Api version in use so that it uses appropriate
2833 internal static HTTP_API_VERSION ApiVersion {
2835 if (version.HttpApiMajorVersion == 2 && version.HttpApiMinorVersion == 0) {
2836 return HTTP_API_VERSION.Version20;
2838 else if (version.HttpApiMajorVersion == 1 && version.HttpApiMinorVersion == 0) {
2839 return HTTP_API_VERSION.Version10;
2842 return HTTP_API_VERSION.Invalid;
2848 // returns 'true' if http.sys supports CBT: either the system is Win7+, or http.sys was patched.
2850 internal static bool ExtendedProtectionSupported {
2852 return extendedProtectionSupported;
2860 private static void InitHttpApi(ushort majorVersion, ushort minorVersion) {
2861 version.HttpApiMajorVersion = majorVersion;
2862 version.HttpApiMinorVersion = minorVersion;
2864 GlobalLog.Print("HttpApi::.ctor() calling HttpApi.HttpInitialize() for Version " + majorVersion + "." + minorVersion);
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;
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);
2879 statusCode = HttpApi.HttpInitialize(version,
2880 (uint)(HTTP_FLAGS.HTTP_INITIALIZE_SERVER | HTTP_FLAGS.HTTP_INITIALIZE_CBT), null);
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));
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);
2892 supported = statusCode == ErrorCodes.ERROR_SUCCESS;
2894 GlobalLog.Print("HttpApi::.ctor() call to HttpApi.HttpInitialize() returned:" + statusCode + " supported:" + supported);
2897 static volatile bool supported;
2898 internal static bool Supported {
2906 internal static WebHeaderCollection GetHeaders(byte[] memoryBlob, IntPtr originalAddress)
2908 GlobalLog.Enter("HttpApi::GetHeaders()");
2911 WebHeaderCollection headerCollection = new WebHeaderCollection(WebHeaderCollectionType.HttpListenerRequest);
2912 fixed (byte* pMemoryBlob = memoryBlob)
2914 HTTP_REQUEST* request = (HTTP_REQUEST*) pMemoryBlob;
2915 long fixup = pMemoryBlob - (byte*) originalAddress;
2919 if (request->Headers.UnknownHeaderCount != 0)
2921 HTTP_UNKNOWN_HEADER* pUnknownHeader = (HTTP_UNKNOWN_HEADER*) (fixup + (byte*) request->Headers.pUnknownHeaders);
2922 for (index = 0; index < request->Headers.UnknownHeaderCount; index++)
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)
2928 string headerName = new string(pUnknownHeader->pName + fixup, 0, pUnknownHeader->NameLength);
2930 if (pUnknownHeader->pRawValue != null && pUnknownHeader->RawValueLength > 0) {
2931 headerValue = new string(pUnknownHeader->pRawValue + fixup, 0, pUnknownHeader->RawValueLength);
2934 headerValue = string.Empty;
2936 headerCollection.AddInternal(headerName, headerValue);
2943 HTTP_KNOWN_HEADER* pKnownHeader = &request->Headers.KnownHeaders;
2944 for (index = 0; index < HttpHeaderRequestMaximum; index++)
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)
2950 string headerValue = new string(pKnownHeader->pRawValue + fixup, 0, pKnownHeader->RawValueLength);
2951 headerCollection.AddInternal(HTTP_REQUEST_HEADER_ID.ToString(index), headerValue);
2957 GlobalLog.Leave("HttpApi::GetHeaders()");
2958 return headerCollection;
2961 private static string GetKnownHeader(HTTP_REQUEST* request, long fixup, int headerIndex)
2963 GlobalLog.Enter("HttpApi::GetKnownHeader()");
2964 string header = null;
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)
2973 header = new string(pKnownHeader->pRawValue + fixup, 0, pKnownHeader->RawValueLength);
2976 GlobalLog.Leave("HttpApi::GetKnownHeader() return:" + ValidationHelper.ToString(header));
2980 internal static string GetKnownHeader(HTTP_REQUEST* request, int headerIndex)
2982 return GetKnownHeader(request, 0, headerIndex);
2985 internal static string GetKnownHeader(byte[] memoryBlob, IntPtr originalAddress, int headerIndex)
2987 fixed (byte* pMemoryBlob = memoryBlob)
2989 return GetKnownHeader((HTTP_REQUEST*) pMemoryBlob, pMemoryBlob - (byte*) originalAddress, headerIndex);
2993 private unsafe static string GetVerb(HTTP_REQUEST* request, long fixup)
2995 GlobalLog.Enter("HttpApi::GetVerb()");
2998 if ((int) request->Verb > (int) HTTP_VERB.HttpVerbUnknown && (int) request->Verb < (int) HTTP_VERB.HttpVerbMaximum)
3000 verb = HttpVerbs[(int) request->Verb];
3002 else if (request->Verb == HTTP_VERB.HttpVerbUnknown && request->pUnknownVerb != null)
3004 verb = new string(request->pUnknownVerb + fixup, 0, request->UnknownVerbLength);
3007 GlobalLog.Leave("HttpApi::GetVerb() return:" + ValidationHelper.ToString(verb));
3011 internal unsafe static string GetVerb(HTTP_REQUEST* request)
3013 return GetVerb(request, 0);
3016 internal unsafe static string GetVerb(byte[] memoryBlob, IntPtr originalAddress)
3018 fixed (byte* pMemoryBlob = memoryBlob)
3020 return GetVerb((HTTP_REQUEST*) pMemoryBlob, pMemoryBlob - (byte*) originalAddress);
3024 internal static HTTP_VERB GetKnownVerb(byte[] memoryBlob, IntPtr originalAddress)
3026 GlobalLog.Enter("HttpApi::GetKnownVerb()");
3029 HTTP_VERB verb = HTTP_VERB.HttpVerbUnknown;
3030 fixed (byte* pMemoryBlob = memoryBlob)
3032 HTTP_REQUEST* request = (HTTP_REQUEST*) pMemoryBlob;
3033 if ((int)request->Verb > (int)HTTP_VERB.HttpVerbUnparsed && (int)request->Verb < (int)HTTP_VERB.HttpVerbMaximum)
3035 verb = request->Verb;
3039 GlobalLog.Leave("HttpApi::GetKnownVerb()");
3043 internal static uint GetChunks(byte[] memoryBlob, IntPtr originalAddress, ref int dataChunkIndex, ref uint dataChunkOffset, byte[] buffer, int offset, int size)
3045 GlobalLog.Enter("HttpApi::GetChunks() memoryBlob:" + ValidationHelper.ToString(memoryBlob));
3049 fixed(byte* pMemoryBlob = memoryBlob)
3051 HTTP_REQUEST* request = (HTTP_REQUEST*) pMemoryBlob;
3052 long fixup = pMemoryBlob - (byte*) originalAddress;
3054 if (request->EntityChunkCount > 0 && dataChunkIndex < request->EntityChunkCount && dataChunkIndex != -1)
3056 HTTP_DATA_CHUNK* pDataChunk = (HTTP_DATA_CHUNK*) (fixup + (byte*) &request->pEntityChunks[dataChunkIndex]);
3058 fixed(byte* pReadBuffer = buffer)
3060 byte* pTo = &pReadBuffer[offset];
3062 while (dataChunkIndex < request->EntityChunkCount && dataRead < size){
3063 if(dataChunkOffset >= pDataChunk->BufferLength){
3064 dataChunkOffset = 0;
3069 byte* pFrom = pDataChunk->pBuffer + dataChunkOffset + fixup;
3071 uint bytesToRead = pDataChunk->BufferLength - (uint)dataChunkOffset;
3072 if (bytesToRead > (uint)size){
3073 bytesToRead = (uint)size;
3075 for (uint i=0;i<bytesToRead;i++)
3077 *(pTo++) = *(pFrom++);
3079 dataRead+=bytesToRead;
3080 dataChunkOffset += bytesToRead;
3086 if(dataChunkIndex == request->EntityChunkCount){
3087 dataChunkIndex = -1;
3091 GlobalLog.Leave("HttpApi::GetChunks()");
3095 internal static IPEndPoint GetRemoteEndPoint(byte[] memoryBlob, IntPtr originalAddress)
3097 GlobalLog.Enter("HttpApi::GetRemoteEndPoint()");
3099 SocketAddress v4address = new SocketAddress(AddressFamily.InterNetwork, SocketAddress.IPv4AddressSize);
3100 SocketAddress v6address = new SocketAddress(AddressFamily.InterNetworkV6, SocketAddress.IPv6AddressSize);
3102 fixed (byte* pMemoryBlob = memoryBlob)
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);
3109 IPEndPoint endpoint = null;
3110 if (v4address != null)
3112 endpoint = IPEndPoint.Any.Create(v4address) as IPEndPoint;
3114 else if (v6address != null)
3116 endpoint = IPEndPoint.IPv6Any.Create(v6address) as IPEndPoint;
3119 GlobalLog.Leave("HttpApi::GetRemoteEndPoint()");
3123 internal static IPEndPoint GetLocalEndPoint(byte[] memoryBlob, IntPtr originalAddress)
3125 GlobalLog.Enter("HttpApi::GetLocalEndPoint()");
3127 SocketAddress v4address = new SocketAddress(AddressFamily.InterNetwork, SocketAddress.IPv4AddressSize);
3128 SocketAddress v6address = new SocketAddress(AddressFamily.InterNetworkV6, SocketAddress.IPv6AddressSize);
3130 fixed (byte* pMemoryBlob = memoryBlob)
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);
3137 IPEndPoint endpoint = null;
3138 if (v4address != null)
3140 endpoint = IPEndPoint.Any.Create(v4address) as IPEndPoint;
3142 else if (v6address != null)
3144 endpoint = IPEndPoint.IPv6Any.Create(v6address) as IPEndPoint;
3147 GlobalLog.Leave("HttpApi::GetLocalEndPoint()");
3151 internal static HTTP_REQUEST_TOKEN_BINDING_INFO* GetTlsTokenBindingRequestInfo(byte[] memoryBlob, IntPtr originalAddress){
3153 fixed (byte* pMemoryBlob = memoryBlob)
3155 HTTP_REQUEST_V2* request = (HTTP_REQUEST_V2*)pMemoryBlob;
3156 long fixup = pMemoryBlob - (byte*) originalAddress;
3158 for (int i = 0; i < request->RequestInfoCount; i++)
3160 HTTP_REQUEST_INFO* pThisInfo = (HTTP_REQUEST_INFO*)(fixup + (byte*)&request->pRequestInfo[i]);
3161 if (pThisInfo != null && pThisInfo->InfoType == HTTP_REQUEST_INFO_TYPE.HttpRequestInfoTypeSslTokenBinding)
3163 return (HTTP_REQUEST_TOKEN_BINDING_INFO*)pThisInfo->pInfo;
3170 [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
3171 private static void CopyOutAddress(IntPtr address, ref SocketAddress v4address, ref SocketAddress v6address)
3173 if (address != IntPtr.Zero)
3175 ushort addressFamily = *((ushort*) address);
3176 if (addressFamily == (ushort) AddressFamily.InterNetwork)
3179 fixed (byte* pBuffer = v4address.m_Buffer)
3181 for (int index = 2; index < SocketAddress.IPv4AddressSize; index++)
3183 pBuffer[index] = ((byte*) address)[index];
3188 if (addressFamily == (ushort) AddressFamily.InterNetworkV6)
3191 fixed (byte* pBuffer = v6address.m_Buffer)
3193 for (int index = 2; index < SocketAddress.IPv6AddressSize; index++)
3195 pBuffer[index] = ((byte*) address)[index];
3207 [SuppressUnmanagedCodeSecurity]
3208 internal unsafe static class SecureStringHelper
3211 // this method is only called as part of an assert
3212 internal static bool AreEqualValues(SecureString secureString1, SecureString secureString2)
3214 IntPtr bstr1 = IntPtr.Zero;
3215 IntPtr bstr2 = IntPtr.Zero;
3216 bool result = false;
3218 if (secureString1 == null)
3220 if (secureString2 == null)
3225 else if (secureString2 == null)
3230 // strings are non-null at this point
3232 if ((object)secureString1 == (object)secureString2)
3233 return true; // same objects
3235 if (secureString1.Length != secureString2.Length)
3238 // strings are same length. decrypt to unmanaged memory and compare them.
3242 bstr1 = Marshal.SecureStringToBSTR(secureString1);
3243 bstr2 = Marshal.SecureStringToBSTR(secureString2);
3245 for (int i = 0; i < secureString1.Length; i++)
3247 if (*((char*)bstr1 + i) != *((char*)bstr2 + i))
3256 if (bstr1 != IntPtr.Zero)
3257 Marshal.ZeroFreeBSTR(bstr1);
3258 if (bstr2 != IntPtr.Zero)
3259 Marshal.ZeroFreeBSTR(bstr2);
3265 internal static string CreateString(SecureString secureString)
3268 IntPtr bstr = IntPtr.Zero;
3270 if (secureString == null || secureString.Length == 0)
3271 return String.Empty;
3275 bstr = Marshal.SecureStringToBSTR(secureString);
3276 plainString = Marshal.PtrToStringBSTR(bstr);
3280 if (bstr != IntPtr.Zero)
3281 Marshal.ZeroFreeBSTR(bstr);
3286 internal static SecureString CreateSecureString(string plainString)
3288 SecureString secureString;
3290 if (plainString == null || plainString.Length == 0)
3291 return new SecureString();
3293 fixed (char* pch = plainString)
3295 secureString = new SecureString(pch, plainString.Length);
3298 return secureString;
3301 #endif // !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,
3311 [MarshalAs(UnmanagedType.IUnknown)] out Object o );
3312 #endif // !FEATURE_PAL
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
3319 [SecuritySafeCritical]
3320 internal static Lazy<IntPtr> PrimaryWindowHandle = new Lazy<IntPtr>(() => GetPrimaryWindowHandle());
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()
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)
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)
3340 primaryWindow = info.hwndActive;
3343 return primaryWindow;
3346 [DllImport(USER32, SetLastError=true, ExactSpelling=true)]
3347 private static extern uint GetGUIThreadInfo(int threadId, ref GuiThreadInfo info);
3349 [DllImport(USER32, ExactSpelling=true)]
3350 private static extern uint GetWindowThreadProcessId(IntPtr hwnd, out int processId);
3352 private struct GuiThreadInfo
3354 public int cbSize; // Must be set to Marshal.SizeOf(GuiThreadInfo) before using.
3356 public IntPtr hwndActive;
3357 public IntPtr hwndFocus;
3358 public IntPtr hwndCapture;
3359 public IntPtr hwndMenuOwner;
3360 public IntPtr hwndMoveSize;
3361 public IntPtr hwndCaret;
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.
3376 internal static class TokenBindingOSHelper
3378 private static bool s_supportsTokenBinding = false;
3379 private static object s_Lock = new object();
3380 private static volatile bool s_Initialized = false;
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()
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)
3407 s_supportsTokenBinding = s_TokenBindingLibrary.HasFunction("TokenBindingVerifyMessage");
3409 s_Initialized = true;
3413 if (NclUtilities.IsFatal(e))
3421 internal static bool SupportsTokenBinding
3425 EnsureTokenBindingOSHelperInitialized();
3426 return s_supportsTokenBinding;