Code:
/ Net / Net / 3.5.50727.3053 / DEVDIV / depot / DevDiv / releases / whidbey / netfxsp / ndp / fx / src / Net / System / Net / NetworkInformation / NetworkAddressChange.cs / 1 / NetworkAddressChange.cs
namespace System.Net.NetworkInformation {
using System.Net;
using System.Net.NetworkInformation;
using System.Net.Sockets;
using System.Collections;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Threading;
using System.Runtime.InteropServices;
[Flags]
internal enum StartIPOptions {Both = 3, None = 0, StartIPv4 = 1, StartIPv6 = 2}
public class NetworkAvailabilityEventArgs:EventArgs{
bool isAvailable;
internal NetworkAvailabilityEventArgs(bool isAvailable){
this.isAvailable = isAvailable;
}
public bool IsAvailable{
get{
return isAvailable;
}
}
}
public sealed class NetworkChange{
private NetworkChange(){}
static public event NetworkAvailabilityChangedEventHandler NetworkAvailabilityChanged{
add{
if (! ComNetOS.IsWin2K)
throw new PlatformNotSupportedException(SR.GetString(SR.Win2000Required));
AvailabilityChangeListener.Start(value);
}
remove{
AvailabilityChangeListener.Stop(value);
}
}
static public event NetworkAddressChangedEventHandler NetworkAddressChanged{
add{
if (! ComNetOS.IsWin2K)
throw new PlatformNotSupportedException(SR.GetString(SR.Win2000Required));
AddressChangeListener.Start(value);
}
remove{
AddressChangeListener.Stop(value);
}
}
static internal bool CanListenForNetworkChanges {
get{
if (! ComNetOS.IsWin2K )
return false;
return true;
}
}
/* Consider removing
static internal void UnsafeListenForNetworkChanges(NetworkAddressChangedEventHandler handler)
{
if (!CanListenForNetworkChanges)
{
throw new PlatformNotSupportedException(SR.GetString(SR.Win2000Required));
}
AddressChangeListener.UnsafeStart(handler);
}
*/
internal static class AvailabilityChangeListener{
static object syncObject = new object();
static private ListDictionary s_availabilityCallerArray = null;
static NetworkAddressChangedEventHandler addressChange = null;
static bool isAvailable = false;
private static ContextCallback s_RunHandlerCallback = new ContextCallback(RunHandlerCallback);
private static void RunHandlerCallback(object state)
{
((NetworkAvailabilityChangedEventHandler) state)(null, new NetworkAvailabilityEventArgs(isAvailable));
}
private static void ChangedAddress(object sender, EventArgs eventArgs) {
lock(syncObject){
bool isAvailableNow = SystemNetworkInterface.InternalGetIsNetworkAvailable();
if (isAvailableNow != isAvailable) {
isAvailable = isAvailableNow;
DictionaryEntry[] callerArray = new DictionaryEntry[s_availabilityCallerArray.Count];
s_availabilityCallerArray.CopyTo(callerArray, 0);
for (int i = 0; i < callerArray.Length; i++)
{
NetworkAvailabilityChangedEventHandler handler = (NetworkAvailabilityChangedEventHandler) callerArray[i].Key;
ExecutionContext context = (ExecutionContext) callerArray[i].Value;
if (context == null)
{
handler(null, new NetworkAvailabilityEventArgs(isAvailable));
}
else
{
ExecutionContext.Run(context.CreateCopy(), s_RunHandlerCallback, handler);
}
}
}
}
}
internal static void Start(NetworkAvailabilityChangedEventHandler caller){
lock(syncObject){
if (s_availabilityCallerArray == null) {
s_availabilityCallerArray = new ListDictionary();
addressChange = new NetworkAddressChangedEventHandler(ChangedAddress);
}
if (s_availabilityCallerArray.Count == 0) {
isAvailable = NetworkInterface.GetIsNetworkAvailable();
AddressChangeListener.UnsafeStart(addressChange);
}
if ((caller != null) && (!s_availabilityCallerArray.Contains(caller))) {
s_availabilityCallerArray.Add(caller, ExecutionContext.Capture());
}
}
}
internal static void Stop(NetworkAvailabilityChangedEventHandler caller)
{
lock(syncObject){
s_availabilityCallerArray.Remove(caller);
if(s_availabilityCallerArray.Count == 0){
AddressChangeListener.Stop(addressChange);
}
}
}
}
//helper class for detecting address change events.
internal unsafe static class AddressChangeListener{
static private ListDictionary s_callerArray = new ListDictionary();
static private ContextCallback s_runHandlerCallback = new ContextCallback(RunHandlerCallback);
static private RegisteredWaitHandle s_registeredWait;
//need to keep the reference so it isn't GC'd before the native call executes
static private bool s_isListening = false;
static private bool s_isPending = false;
static private SafeCloseSocketAndEvent s_ipv4Socket = null;
static private SafeCloseSocketAndEvent s_ipv6Socket = null;
static private WaitHandle s_ipv4WaitHandle = null;
static private WaitHandle s_ipv6WaitHandle = null;
//callback fired when an address change occurs
private static void AddressChangedCallback(object stateObject, bool signaled) {
lock (s_callerArray) {
//the listener was cancelled, which would only happen if we aren't listening
//for more events.
s_isPending = false;
if (!s_isListening) {
return;
}
s_isListening = false;
// Need to copy the array so the callback can call start and stop
DictionaryEntry[] callerArray = new DictionaryEntry[s_callerArray.Count];
s_callerArray.CopyTo(callerArray, 0);
//wait for the next address change
StartHelper(null,false,(StartIPOptions)stateObject);
for (int i = 0; i < callerArray.Length; i++)
{
NetworkAddressChangedEventHandler handler = (NetworkAddressChangedEventHandler) callerArray[i].Key;
ExecutionContext context = (ExecutionContext) callerArray[i].Value;
if (context == null)
{
handler(null, EventArgs.Empty);
}
else
{
ExecutionContext.Run(context.CreateCopy(), s_runHandlerCallback, handler);
}
}
}
}
private static void RunHandlerCallback(object state)
{
((NetworkAddressChangedEventHandler) state)(null, EventArgs.Empty);
}
//start listening
internal static void Start(NetworkAddressChangedEventHandler caller)
{
StartHelper(caller, true, StartIPOptions.Both);
}
internal static void UnsafeStart(NetworkAddressChangedEventHandler caller)
{
StartHelper(caller, false, StartIPOptions.Both);
}
private static void StartHelper(NetworkAddressChangedEventHandler caller, bool captureContext, StartIPOptions startIPOptions)
{
lock (s_callerArray) {
// setup changedEvent and native overlapped struct.
if(s_ipv4Socket == null){
Socket.InitializeSockets();
int blocking;
if(Socket.SupportsIPv4){
blocking = -1;
s_ipv4Socket = SafeCloseSocketAndEvent.CreateWSASocketWithEvent(AddressFamily.InterNetwork, SocketType.Dgram, (ProtocolType)0, true, false);
UnsafeNclNativeMethods.OSSOCK.ioctlsocket(s_ipv4Socket, IoctlSocketConstants.FIONBIO,ref blocking);
s_ipv4WaitHandle = s_ipv4Socket.GetEventHandle();
}
if(Socket.OSSupportsIPv6){
blocking = -1;
s_ipv6Socket = SafeCloseSocketAndEvent.CreateWSASocketWithEvent(AddressFamily.InterNetworkV6, SocketType.Dgram, (ProtocolType)0, true, false);
UnsafeNclNativeMethods.OSSOCK.ioctlsocket(s_ipv6Socket,IoctlSocketConstants.FIONBIO,ref blocking);
s_ipv6WaitHandle = s_ipv6Socket.GetEventHandle();
}
}
if ((caller != null) && (!s_callerArray.Contains(caller))) {
s_callerArray.Add(caller, captureContext ? ExecutionContext.Capture() : null);
}
//if s_listener is not null, it means we are already actively listening
if (s_isListening || s_callerArray.Count == 0) {
return;
}
if(!s_isPending){
int length;
SocketError errorCode;
if(Socket.SupportsIPv4 && (startIPOptions & StartIPOptions.StartIPv4) !=0){
s_registeredWait = ThreadPool.UnsafeRegisterWaitForSingleObject(
s_ipv4WaitHandle,
new WaitOrTimerCallback(AddressChangedCallback),
StartIPOptions.StartIPv4,
-1,
true );
errorCode = (SocketError) UnsafeNclNativeMethods.OSSOCK.WSAIoctl_Blocking(
s_ipv4Socket.DangerousGetHandle(),
(int) IOControlCode.AddressListChange,
null, 0, null, 0,
out length,
IntPtr.Zero, IntPtr.Zero);
if (errorCode != SocketError.Success) {
NetworkInformationException exception = new NetworkInformationException();
if (exception.ErrorCode != (uint)SocketError.WouldBlock) {
throw exception;
}
}
errorCode = (SocketError)UnsafeNclNativeMethods.OSSOCK.WSAEventSelect(s_ipv4Socket, s_ipv4Socket.GetEventHandle().SafeWaitHandle, AsyncEventBits.FdAddressListChange);
if (errorCode != SocketError.Success) {
throw new NetworkInformationException();
}
}
if(Socket.OSSupportsIPv6 && (startIPOptions & StartIPOptions.StartIPv6) !=0){
s_registeredWait = ThreadPool.UnsafeRegisterWaitForSingleObject(
s_ipv6WaitHandle,
new WaitOrTimerCallback(AddressChangedCallback),
StartIPOptions.StartIPv6,
-1,
true );
errorCode = (SocketError) UnsafeNclNativeMethods.OSSOCK.WSAIoctl_Blocking(
s_ipv6Socket.DangerousGetHandle(),
(int) IOControlCode.AddressListChange,
null, 0, null, 0,
out length,
IntPtr.Zero, IntPtr.Zero);
if (errorCode != SocketError.Success) {
NetworkInformationException exception = new NetworkInformationException();
if (exception.ErrorCode != (uint)SocketError.WouldBlock) {
throw exception;
}
}
errorCode = (SocketError)UnsafeNclNativeMethods.OSSOCK.WSAEventSelect(s_ipv6Socket, s_ipv6Socket.GetEventHandle().SafeWaitHandle, AsyncEventBits.FdAddressListChange);
if (errorCode != SocketError.Success) {
throw new NetworkInformationException();
}
}
}
s_isListening = true;
s_isPending = true;
}
}
//stop listening
internal static void Stop(object caller)
{
lock(s_callerArray){
s_callerArray.Remove(caller);
if (s_callerArray.Count == 0 && s_isListening) {
s_isListening = false;
}
}
} //ends ignoreaddresschanges
}
}
public delegate void NetworkAddressChangedEventHandler(object sender, EventArgs e);
public delegate void NetworkAvailabilityChangedEventHandler(object sender, NetworkAvailabilityEventArgs e);
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
namespace System.Net.NetworkInformation {
using System.Net;
using System.Net.NetworkInformation;
using System.Net.Sockets;
using System.Collections;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Threading;
using System.Runtime.InteropServices;
[Flags]
internal enum StartIPOptions {Both = 3, None = 0, StartIPv4 = 1, StartIPv6 = 2}
public class NetworkAvailabilityEventArgs:EventArgs{
bool isAvailable;
internal NetworkAvailabilityEventArgs(bool isAvailable){
this.isAvailable = isAvailable;
}
public bool IsAvailable{
get{
return isAvailable;
}
}
}
public sealed class NetworkChange{
private NetworkChange(){}
static public event NetworkAvailabilityChangedEventHandler NetworkAvailabilityChanged{
add{
if (! ComNetOS.IsWin2K)
throw new PlatformNotSupportedException(SR.GetString(SR.Win2000Required));
AvailabilityChangeListener.Start(value);
}
remove{
AvailabilityChangeListener.Stop(value);
}
}
static public event NetworkAddressChangedEventHandler NetworkAddressChanged{
add{
if (! ComNetOS.IsWin2K)
throw new PlatformNotSupportedException(SR.GetString(SR.Win2000Required));
AddressChangeListener.Start(value);
}
remove{
AddressChangeListener.Stop(value);
}
}
static internal bool CanListenForNetworkChanges {
get{
if (! ComNetOS.IsWin2K )
return false;
return true;
}
}
/* Consider removing
static internal void UnsafeListenForNetworkChanges(NetworkAddressChangedEventHandler handler)
{
if (!CanListenForNetworkChanges)
{
throw new PlatformNotSupportedException(SR.GetString(SR.Win2000Required));
}
AddressChangeListener.UnsafeStart(handler);
}
*/
internal static class AvailabilityChangeListener{
static object syncObject = new object();
static private ListDictionary s_availabilityCallerArray = null;
static NetworkAddressChangedEventHandler addressChange = null;
static bool isAvailable = false;
private static ContextCallback s_RunHandlerCallback = new ContextCallback(RunHandlerCallback);
private static void RunHandlerCallback(object state)
{
((NetworkAvailabilityChangedEventHandler) state)(null, new NetworkAvailabilityEventArgs(isAvailable));
}
private static void ChangedAddress(object sender, EventArgs eventArgs) {
lock(syncObject){
bool isAvailableNow = SystemNetworkInterface.InternalGetIsNetworkAvailable();
if (isAvailableNow != isAvailable) {
isAvailable = isAvailableNow;
DictionaryEntry[] callerArray = new DictionaryEntry[s_availabilityCallerArray.Count];
s_availabilityCallerArray.CopyTo(callerArray, 0);
for (int i = 0; i < callerArray.Length; i++)
{
NetworkAvailabilityChangedEventHandler handler = (NetworkAvailabilityChangedEventHandler) callerArray[i].Key;
ExecutionContext context = (ExecutionContext) callerArray[i].Value;
if (context == null)
{
handler(null, new NetworkAvailabilityEventArgs(isAvailable));
}
else
{
ExecutionContext.Run(context.CreateCopy(), s_RunHandlerCallback, handler);
}
}
}
}
}
internal static void Start(NetworkAvailabilityChangedEventHandler caller){
lock(syncObject){
if (s_availabilityCallerArray == null) {
s_availabilityCallerArray = new ListDictionary();
addressChange = new NetworkAddressChangedEventHandler(ChangedAddress);
}
if (s_availabilityCallerArray.Count == 0) {
isAvailable = NetworkInterface.GetIsNetworkAvailable();
AddressChangeListener.UnsafeStart(addressChange);
}
if ((caller != null) && (!s_availabilityCallerArray.Contains(caller))) {
s_availabilityCallerArray.Add(caller, ExecutionContext.Capture());
}
}
}
internal static void Stop(NetworkAvailabilityChangedEventHandler caller)
{
lock(syncObject){
s_availabilityCallerArray.Remove(caller);
if(s_availabilityCallerArray.Count == 0){
AddressChangeListener.Stop(addressChange);
}
}
}
}
//helper class for detecting address change events.
internal unsafe static class AddressChangeListener{
static private ListDictionary s_callerArray = new ListDictionary();
static private ContextCallback s_runHandlerCallback = new ContextCallback(RunHandlerCallback);
static private RegisteredWaitHandle s_registeredWait;
//need to keep the reference so it isn't GC'd before the native call executes
static private bool s_isListening = false;
static private bool s_isPending = false;
static private SafeCloseSocketAndEvent s_ipv4Socket = null;
static private SafeCloseSocketAndEvent s_ipv6Socket = null;
static private WaitHandle s_ipv4WaitHandle = null;
static private WaitHandle s_ipv6WaitHandle = null;
//callback fired when an address change occurs
private static void AddressChangedCallback(object stateObject, bool signaled) {
lock (s_callerArray) {
//the listener was cancelled, which would only happen if we aren't listening
//for more events.
s_isPending = false;
if (!s_isListening) {
return;
}
s_isListening = false;
// Need to copy the array so the callback can call start and stop
DictionaryEntry[] callerArray = new DictionaryEntry[s_callerArray.Count];
s_callerArray.CopyTo(callerArray, 0);
//wait for the next address change
StartHelper(null,false,(StartIPOptions)stateObject);
for (int i = 0; i < callerArray.Length; i++)
{
NetworkAddressChangedEventHandler handler = (NetworkAddressChangedEventHandler) callerArray[i].Key;
ExecutionContext context = (ExecutionContext) callerArray[i].Value;
if (context == null)
{
handler(null, EventArgs.Empty);
}
else
{
ExecutionContext.Run(context.CreateCopy(), s_runHandlerCallback, handler);
}
}
}
}
private static void RunHandlerCallback(object state)
{
((NetworkAddressChangedEventHandler) state)(null, EventArgs.Empty);
}
//start listening
internal static void Start(NetworkAddressChangedEventHandler caller)
{
StartHelper(caller, true, StartIPOptions.Both);
}
internal static void UnsafeStart(NetworkAddressChangedEventHandler caller)
{
StartHelper(caller, false, StartIPOptions.Both);
}
private static void StartHelper(NetworkAddressChangedEventHandler caller, bool captureContext, StartIPOptions startIPOptions)
{
lock (s_callerArray) {
// setup changedEvent and native overlapped struct.
if(s_ipv4Socket == null){
Socket.InitializeSockets();
int blocking;
if(Socket.SupportsIPv4){
blocking = -1;
s_ipv4Socket = SafeCloseSocketAndEvent.CreateWSASocketWithEvent(AddressFamily.InterNetwork, SocketType.Dgram, (ProtocolType)0, true, false);
UnsafeNclNativeMethods.OSSOCK.ioctlsocket(s_ipv4Socket, IoctlSocketConstants.FIONBIO,ref blocking);
s_ipv4WaitHandle = s_ipv4Socket.GetEventHandle();
}
if(Socket.OSSupportsIPv6){
blocking = -1;
s_ipv6Socket = SafeCloseSocketAndEvent.CreateWSASocketWithEvent(AddressFamily.InterNetworkV6, SocketType.Dgram, (ProtocolType)0, true, false);
UnsafeNclNativeMethods.OSSOCK.ioctlsocket(s_ipv6Socket,IoctlSocketConstants.FIONBIO,ref blocking);
s_ipv6WaitHandle = s_ipv6Socket.GetEventHandle();
}
}
if ((caller != null) && (!s_callerArray.Contains(caller))) {
s_callerArray.Add(caller, captureContext ? ExecutionContext.Capture() : null);
}
//if s_listener is not null, it means we are already actively listening
if (s_isListening || s_callerArray.Count == 0) {
return;
}
if(!s_isPending){
int length;
SocketError errorCode;
if(Socket.SupportsIPv4 && (startIPOptions & StartIPOptions.StartIPv4) !=0){
s_registeredWait = ThreadPool.UnsafeRegisterWaitForSingleObject(
s_ipv4WaitHandle,
new WaitOrTimerCallback(AddressChangedCallback),
StartIPOptions.StartIPv4,
-1,
true );
errorCode = (SocketError) UnsafeNclNativeMethods.OSSOCK.WSAIoctl_Blocking(
s_ipv4Socket.DangerousGetHandle(),
(int) IOControlCode.AddressListChange,
null, 0, null, 0,
out length,
IntPtr.Zero, IntPtr.Zero);
if (errorCode != SocketError.Success) {
NetworkInformationException exception = new NetworkInformationException();
if (exception.ErrorCode != (uint)SocketError.WouldBlock) {
throw exception;
}
}
errorCode = (SocketError)UnsafeNclNativeMethods.OSSOCK.WSAEventSelect(s_ipv4Socket, s_ipv4Socket.GetEventHandle().SafeWaitHandle, AsyncEventBits.FdAddressListChange);
if (errorCode != SocketError.Success) {
throw new NetworkInformationException();
}
}
if(Socket.OSSupportsIPv6 && (startIPOptions & StartIPOptions.StartIPv6) !=0){
s_registeredWait = ThreadPool.UnsafeRegisterWaitForSingleObject(
s_ipv6WaitHandle,
new WaitOrTimerCallback(AddressChangedCallback),
StartIPOptions.StartIPv6,
-1,
true );
errorCode = (SocketError) UnsafeNclNativeMethods.OSSOCK.WSAIoctl_Blocking(
s_ipv6Socket.DangerousGetHandle(),
(int) IOControlCode.AddressListChange,
null, 0, null, 0,
out length,
IntPtr.Zero, IntPtr.Zero);
if (errorCode != SocketError.Success) {
NetworkInformationException exception = new NetworkInformationException();
if (exception.ErrorCode != (uint)SocketError.WouldBlock) {
throw exception;
}
}
errorCode = (SocketError)UnsafeNclNativeMethods.OSSOCK.WSAEventSelect(s_ipv6Socket, s_ipv6Socket.GetEventHandle().SafeWaitHandle, AsyncEventBits.FdAddressListChange);
if (errorCode != SocketError.Success) {
throw new NetworkInformationException();
}
}
}
s_isListening = true;
s_isPending = true;
}
}
//stop listening
internal static void Stop(object caller)
{
lock(s_callerArray){
s_callerArray.Remove(caller);
if (s_callerArray.Count == 0 && s_isListening) {
s_isListening = false;
}
}
} //ends ignoreaddresschanges
}
}
public delegate void NetworkAddressChangedEventHandler(object sender, EventArgs e);
public delegate void NetworkAvailabilityChangedEventHandler(object sender, NetworkAvailabilityEventArgs e);
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- ConfigXmlText.cs
- QuotedPrintableStream.cs
- EdmPropertyAttribute.cs
- _Rfc2616CacheValidators.cs
- OleDbParameterCollection.cs
- ObjectDataSourceEventArgs.cs
- DataGridParentRows.cs
- Stack.cs
- CqlErrorHelper.cs
- Label.cs
- TypeConverterHelper.cs
- SiteIdentityPermission.cs
- _CommandStream.cs
- EventSourceCreationData.cs
- WebPartTracker.cs
- SHA384Managed.cs
- AnimationClock.cs
- ChildChangedEventArgs.cs
- FixedBufferAttribute.cs
- COM2PropertyDescriptor.cs
- TagMapInfo.cs
- ImageDrawing.cs
- Run.cs
- XamlUtilities.cs
- Visual3D.cs
- SqlDataReader.cs
- WebPartDisplayModeEventArgs.cs
- DelegateSerializationHolder.cs
- DataGridItemCollection.cs
- BooleanExpr.cs
- AutoResetEvent.cs
- X509CertificateChain.cs
- ParameterCollection.cs
- FunctionImportMapping.cs
- GeometryConverter.cs
- EntityModelSchemaGenerator.cs
- XmlSchemaSimpleTypeUnion.cs
- CacheEntry.cs
- UIElementParaClient.cs
- UnSafeCharBuffer.cs
- ProfileBuildProvider.cs
- CubicEase.cs
- SapiRecoInterop.cs
- DBCommandBuilder.cs
- SystemException.cs
- ThreadSafeMessageFilterTable.cs
- CodeMemberMethod.cs
- SecurityHelper.cs
- ListControl.cs
- CharAnimationBase.cs
- MachineKeyValidationConverter.cs
- StructuredTypeInfo.cs
- SafeNativeMethods.cs
- SymbolType.cs
- DependencyObjectProvider.cs
- ISCIIEncoding.cs
- ControlCollection.cs
- MissingFieldException.cs
- DependencyObjectValidator.cs
- WebPartHeaderCloseVerb.cs
- DataServiceRequestException.cs
- AudioFormatConverter.cs
- BitmapEffectDrawing.cs
- MarkupObject.cs
- RayHitTestParameters.cs
- MSAAEventDispatcher.cs
- QilGenerator.cs
- TableItemPattern.cs
- CodeExpressionCollection.cs
- RtType.cs
- AuthenticationManager.cs
- GuidTagList.cs
- VisualStyleInformation.cs
- ListMarkerLine.cs
- EntityModelSchemaGenerator.cs
- OutOfProcStateClientManager.cs
- HighlightVisual.cs
- MetadataPropertyCollection.cs
- fixedPageContentExtractor.cs
- UIHelper.cs
- VisualStyleRenderer.cs
- ListViewItem.cs
- SoapHeaders.cs
- HostExecutionContextManager.cs
- WebHeaderCollection.cs
- DiscoveryExceptionDictionary.cs
- WebServiceErrorEvent.cs
- StrongNameMembershipCondition.cs
- WindowsIPAddress.cs
- FormatterServicesNoSerializableCheck.cs
- VectorValueSerializer.cs
- MissingManifestResourceException.cs
- JulianCalendar.cs
- HwndHostAutomationPeer.cs
- ObfuscateAssemblyAttribute.cs
- WebAdminConfigurationHelper.cs
- TypeSystem.cs
- Parser.cs
- InstanceKeyCompleteException.cs
- PrePrepareMethodAttribute.cs