1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351
|
//------------------------------------------------------------------------------
// <copyright file="Logging.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
//------------------------------------------------------------------------------
using System.Security.Permissions;
namespace System.Net.PeerToPeer
{
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Win32.SafeHandles;
using System.Security;
using System.Runtime.InteropServices;
using System.Runtime.ConstrainedExecution;
using System.Threading;
using System.Net.Sockets;
using Microsoft.Win32;
using System.Diagnostics;
using System.IO;
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
internal struct PEER_PNRP_CLOUD_INFO
{
internal IntPtr pwzCloudName;
internal UInt32 dwScope;
internal UInt32 dwScopeId;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
internal struct PEER_PNRP_REGISTRATION_INFO
{
internal string pwszCloudName;
internal string pwszPublishingIdentity;
internal UInt32 cAddresses;
internal IntPtr ArrayOfSOCKADDRIN6Pointers;
internal ushort wport;
internal string pwszComment;
internal PEER_DATA payLoad;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
internal struct PEER_PNRP_ENDPOINT_INFO
{
internal IntPtr pwszPeerName;
internal UInt32 cAddresses;
internal IntPtr ArrayOfSOCKADDRIN6Pointers;
internal IntPtr pwszComment;
internal PEER_DATA payLoad;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
internal struct PEER_DATA
{
internal UInt32 cbPayload;
internal IntPtr pbPayload;
}
[System.Security.SuppressUnmanagedCodeSecurityAttribute()]
internal static class UnsafeP2PNativeMethods
{
internal const string P2P = "p2p.dll";
[DllImport(P2P, CharSet = CharSet.Unicode)]
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
internal extern static void PeerFreeData(IntPtr dataToFree);
[SecurityCritical]
[DllImport(P2P, CharSet = CharSet.Unicode)]
internal extern static Int32 PeerPnrpGetCloudInfo(out UInt32 pNumClouds, out SafePeerData pArrayOfClouds);
[DllImport(P2P, CharSet = CharSet.Unicode)]
internal extern static Int32 PeerPnrpStartup(ushort versionRequired);
[SecurityCritical]
[DllImport(P2P, CharSet = CharSet.Unicode)]
internal extern static Int32
PeerCreatePeerName(string identity, string classfier, out SafePeerData peerName);
//[DllImport(P2P, CharSet = CharSet.Unicode)]
//internal extern static Int32 PeerCreatePeerName(string identity, string classfier, out SafePeerData peerName);
[SecurityCritical]
[DllImport(P2P, CharSet = CharSet.Unicode)]
internal extern static Int32 PeerIdentityGetDefault(out SafePeerData defaultIdentity);
/*
[DllImport(P2P, CharSet = CharSet.Unicode)]
internal extern static Int32 PeerIdentityCreate(string classifier, string friendlyName, IntPtr hCryptoProv, out SafePeerData defaultIdentity);
*/
[SecurityCritical]
[DllImport(P2P, CharSet = CharSet.Unicode)]
internal extern static Int32 PeerNameToPeerHostName(string peerName, out SafePeerData peerHostName);
[SecurityCritical]
[DllImport(P2P, CharSet = CharSet.Unicode)]
internal extern static Int32 PeerHostNameToPeerName(string peerHostName, out SafePeerData peerName);
[SecurityCritical]
[DllImport(P2P, CharSet = CharSet.Unicode)]
public extern static Int32 PeerPnrpRegister(string pcwzPeerName,
ref PEER_PNRP_REGISTRATION_INFO registrationInfo,
out SafePeerNameUnregister handle);
[DllImport(P2P, CharSet = CharSet.Unicode)]
public extern static Int32 PeerPnrpUnregister(IntPtr handle);
[SecurityCritical]
[DllImport(P2P, CharSet = CharSet.Unicode)]
public extern static Int32 PeerPnrpUpdateRegistration(SafePeerNameUnregister hRegistration,
ref PEER_PNRP_REGISTRATION_INFO registrationInfo);
[SecurityCritical]
[DllImport(P2P, CharSet = CharSet.Unicode)]
public extern static Int32 PeerPnrpResolve(string pcwzPeerNAme,
string pcwzCloudName,
ref UInt32 pcEndPoints,
out SafePeerData pEndPoints);
[SecurityCritical]
[DllImport(P2P, CharSet = CharSet.Unicode)]
public extern static Int32 PeerPnrpStartResolve(string pcwzPeerNAme,
string pcwzCloudName,
UInt32 cEndPoints,
SafeWaitHandle hEvent,
out SafePeerNameEndResolve safePeerNameEndResolve);
[SecurityCritical]
[DllImport(P2P, CharSet = CharSet.Unicode)]
public extern static Int32 PeerPnrpGetEndpoint(IntPtr Handle,
out SafePeerData pEndPoint);
[DllImport(P2P, CharSet = CharSet.Unicode)]
public extern static Int32 PeerPnrpEndResolve(IntPtr Handle);
private static object s_InternalSyncObject;
private static volatile bool s_Initialized;
private const int PNRP_VERSION = 2;
private static object InternalSyncObject {
get {
if (s_InternalSyncObject == null) {
object o = new object();
Interlocked.CompareExchange(ref s_InternalSyncObject, o, null);
}
return s_InternalSyncObject;
}
}
// <SecurityKernel Critical="True" Ring="0">
// <CallsSuppressUnmanagedCode Name="PeerPnrpStartup(UInt16):Int32" />
// <SatisfiesLinkDemand Name="Marshal.GetExceptionForHR(System.Int32):System.Exception" />
// </SecurityKernel>
[System.Security.SecurityCritical]
internal static void PnrpStartup()
{
if (!s_Initialized) {
lock (InternalSyncObject) {
if (!s_Initialized) {
Int32 result = PeerPnrpStartup(PNRP_VERSION);
if (result != 0) {
throw new PeerToPeerException(SR.GetString(SR.Pnrp_StartupFailed), Marshal.GetExceptionForHR(result));
}
s_Initialized = true;
}
}
}
} //end of method PnrpStartup
}
// <SecurityKernel Critical="True" Ring="0">
// <SatisfiesLinkDemand Name="SafeHandleZeroOrMinusOneIsInvalid" />
// </SecurityKernel>
#pragma warning disable 618 // Have not migrated to v4 transparency yet
[System.Security.SecurityCritical(System.Security.SecurityCriticalScope.Everything)]
#pragma warning restore 618
[System.Security.SuppressUnmanagedCodeSecurityAttribute()]
internal sealed class SafePeerData : SafeHandleZeroOrMinusOneIsInvalid
{
private SafePeerData() : base(true) { }
//private SafePeerData(bool ownsHandle) : base(ownsHandle) { }
internal string UnicodeString
{
get
{
return Marshal.PtrToStringUni(handle);
}
}
protected override bool ReleaseHandle()
{
UnsafeP2PNativeMethods.PeerFreeData(handle);
SetHandleAsInvalid(); //Mark it closed - This does not change the value of the handle it self
SetHandle(IntPtr.Zero); //Mark it invalid - Change the value to Zero
return true;
}
}
// <SecurityKernel Critical="True" Ring="0">
// <SatisfiesLinkDemand Name="SafeHandleZeroOrMinusOneIsInvalid" />
// </SecurityKernel>
#pragma warning disable 618 // Have not migrated to v4 transparency yet
[System.Security.SecurityCritical(System.Security.SecurityCriticalScope.Everything)]
#pragma warning restore 618
[System.Security.SuppressUnmanagedCodeSecurityAttribute()]
internal sealed class SafePeerNameUnregister : SafeHandleZeroOrMinusOneIsInvalid
{
internal SafePeerNameUnregister() : base(true) { }
//internal SafePeerNameUnregister(bool ownsHandle) : base(ownsHandle) { }
protected override bool ReleaseHandle()
{
UnsafeP2PNativeMethods.PeerPnrpUnregister(handle);
SetHandleAsInvalid(); //Mark it closed - This does not change the value of the handle it self
SetHandle(IntPtr.Zero); //Mark it invalid - Change the value to Zero
return true;
}
}
// <SecurityKernel Critical="True" Ring="0">
// <SatisfiesLinkDemand Name="SafeHandleZeroOrMinusOneIsInvalid" />
// </SecurityKernel>
#pragma warning disable 618 // Have not migrated to v4 transparency yet
[System.Security.SecurityCritical(System.Security.SecurityCriticalScope.Everything)]
#pragma warning restore 618
[System.Security.SuppressUnmanagedCodeSecurityAttribute()]
internal sealed class SafePeerNameEndResolve : SafeHandleZeroOrMinusOneIsInvalid
{
internal SafePeerNameEndResolve() : base(true) { }
//internal SafePeerNameEndResolve(bool ownsHandle) : base(ownsHandle) { }
protected override bool ReleaseHandle()
{
UnsafeP2PNativeMethods.PeerPnrpEndResolve(handle);
SetHandleAsInvalid(); //Mark it closed - This does not change the value of the handle it self
SetHandle(IntPtr.Zero); //Mark it invalid - Change the value to Zero
return true;
}
}
/// <remarks>
/// Determines whether P2P is installed
/// Note static constructors are guaranteed to be
/// run in a thread safe manner. so no locks are necessary
/// </remarks>
internal static class PeerToPeerOSHelper
{
private const string OSInstallTypeRegKey = @"Software\Microsoft\Windows NT\CurrentVersion";
private const string OSInstallTypeRegKeyPath = @"HKEY_LOCAL_MACHINE\" + OSInstallTypeRegKey;
private const string OSInstallTypeRegName = "InstallationType";
private const string InstallTypeStringServerCore = "Server Core";
private static bool s_supportsP2P = false;
private static SafeLoadLibrary s_P2PLibrary = null;
// <SecurityKernel Critical="True" Ring="0">
// <CallsSuppressUnmanagedCode Name="UnsafeSystemNativeMethods.GetProcAddress(System.Net.SafeLoadLibrary,System.String):System.IntPtr" />
// <SatisfiesLinkDemand Name="SafeHandle.get_IsInvalid():System.Boolean" />
// <ReferencesCritical Name="Field: s_P2PLibrary" Ring="1" />
// <ReferencesCritical Name="Method: SafeLoadLibrary.LoadLibraryEx(System.String):System.Net.SafeLoadLibrary" Ring="1" />
// </SecurityKernel>
[System.Security.SecurityCritical]
static PeerToPeerOSHelper() {
if (IsSupportedOS()) {
// if OS is supported, but p2p.dll is not available, P2P is not supported (original behavior)
string dllFileName = Path.Combine(Environment.SystemDirectory, UnsafeP2PNativeMethods.P2P);
s_P2PLibrary = SafeLoadLibrary.LoadLibraryEx(dllFileName);
if (!s_P2PLibrary.IsInvalid) {
IntPtr Address = UnsafeSystemNativeMethods.GetProcAddress(s_P2PLibrary, "PeerCreatePeerName");
if (Address != IntPtr.Zero) {
s_supportsP2P = true;
}
}
}
//else --> the SafeLoadLibrary would have already been marked
// closed by the LoadLibraryEx call above.
}
[SecurityCritical]
private static bool IsSupportedOS()
{
// extend this method when adding further OS/install type restrictions
// P2P is not supported on Server Core installation type
if (IsServerCore()) {
return false;
}
return true;
}
[SecurityCritical]
[RegistryPermission(SecurityAction.Assert, Read = OSInstallTypeRegKeyPath)]
private static bool IsServerCore()
{
// This code does the same as System.Net.ComNetOS.GetWindowsInstallType(). Since ComNetOS is internal and
// we don't want to add InternalsVisibleToAttribute to System.dll, we have to duplicate the code.
try {
using (RegistryKey installTypeKey = Registry.LocalMachine.OpenSubKey(OSInstallTypeRegKey)) {
string installType = installTypeKey.GetValue(OSInstallTypeRegName) as string;
if (string.IsNullOrEmpty(installType)) {
Logging.P2PTraceSource.TraceEvent(TraceEventType.Warning, 0,
SR.GetString(SR.P2P_empty_osinstalltype, OSInstallTypeRegKey + "\\" + OSInstallTypeRegName));
}
else {
if (String.Compare(installType, InstallTypeStringServerCore, StringComparison.OrdinalIgnoreCase) == 0) {
return true;
}
}
}
}
catch (UnauthorizedAccessException e) {
Logging.P2PTraceSource.TraceEvent(TraceEventType.Warning, 0,
SR.GetString(SR.P2P_cant_determine_osinstalltype, OSInstallTypeRegKey, e.Message));
}
catch (SecurityException e) {
Logging.P2PTraceSource.TraceEvent(TraceEventType.Warning, 0,
SR.GetString(SR.P2P_cant_determine_osinstalltype, OSInstallTypeRegKey, e.Message));
}
return false;
}
internal static bool SupportsP2P {
get {
return s_supportsP2P;
}
}
internal static IntPtr P2PModuleHandle
{
// <SecurityKernel Critical="True" Ring="0">
// <SatisfiesLinkDemand Name="SafeHandle.get_IsClosed():System.Boolean" />
// <SatisfiesLinkDemand Name="SafeHandle.get_IsInvalid():System.Boolean" />
// <SatisfiesLinkDemand Name="SafeHandle.DangerousGetHandle():System.IntPtr" />
// <ReferencesCritical Name="Field: s_P2PLibrary" Ring="1" />
// </SecurityKernel>
[System.Security.SecurityCritical]
[SecurityPermissionAttribute(SecurityAction.LinkDemand, UnmanagedCode=true)]
get
{
if (!s_P2PLibrary.IsClosed && !s_P2PLibrary.IsInvalid)
return s_P2PLibrary.DangerousGetHandle();
return IntPtr.Zero;
}
}
}
}
|