Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / cdf / src / WCF / System.ServiceModel.Activation / System / ServiceModel / Activation / MetabaseReader.cs / 1305376 / MetabaseReader.cs
//------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------
namespace System.ServiceModel.Activation
{
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Runtime;
using System.Runtime.InteropServices;
using System.Security;
using System.ServiceModel.Activation.Interop;
using System.Threading;
// These values are copied from %SDXROOT%\public\sdk\inc\iiscnfg.h.
enum MetabasePropertyType
{
ServerBindings = 1023,
SecureBindings = 2021,
AuthFlags = 6000,
Realm = 6001,
AnonymousUserName = 6020,
AnonymousPassword = 6021,
AccessSslFlags = 6030,
AuthPersistence = 6031,
AuthProviders = 6032,
}
[Fx.Tag.SecurityNote(Critical = "Does a bunch of unsafe and native access." +
"Caller should guard MetabaseReader instance as well as any results.")]
#pragma warning disable 618 // have not moved to the v4 security model yet
[SecurityCritical(SecurityCriticalScope.Everything)]
#pragma warning restore 618
class MetabaseReader : IDisposable
{
internal const string LMPath = "/LM";
const uint E_INSUFFICIENT_BUFFER = 0x8007007A;
const uint E_PATH_NOT_FOUND = 0x80070003;
const uint E_DATA_NOT_FOUND = 0x800CC801;
static IMSAdminBase adminBase;
static object syncRoot = new object();
int mdHandle = 0;
[Fx.Tag.SecurityNote(Critical = "Stores a handle.")]
[SecurityCritical]
METADATA_RECORD record;
[Fx.Tag.SecurityNote(Critical = "Handle to an unmanaged resource.")]
[SecurityCritical]
SafeHandle bufferHandle;
uint currentBufferSize = 1024;
bool disposed;
[Fx.Tag.SecurityNote(Safe = "Access Critical Private Members but does not expose critical private members to callers.")]
[SecuritySafeCritical]
public MetabaseReader()
{
lock (syncRoot)
{
if (adminBase == null)
{
adminBase = (IMSAdminBase)new MSAdminBase();
}
}
uint handle;
uint hResult = adminBase.OpenKey(MSAdminBase.METADATA_MASTER_ROOT_HANDLE, LMPath,
MSAdminBase.METADATA_PERMISSION_READ, MSAdminBase.DEFAULT_METABASE_TIMEOUT, out handle);
mdHandle = (int) handle;
if (hResult != 0)
{
throw FxTrace.Exception.AsError(new COMException(SR.Hosting_MetabaseAccessError, (int)hResult));
}
bufferHandle = SafeHGlobalHandleCritical.AllocHGlobal(currentBufferSize);
}
~MetabaseReader()
{
Dispose(false);
}
[Fx.Tag.SecurityNote(Safe = "Access Critical Private Members and returns a managed representation of the handle.")]
[SecurityCritical]
public object GetData(string path, MetabasePropertyType propertyType)
{
return GetData(path, (uint)propertyType);
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
[Fx.Tag.SecurityNote(Safe = "Access Critical Private Members but does not expose critical private members to callers.")]
[SecuritySafeCritical]
void EnsureRecordBuffer(uint bytes)
{
if (bytes <= currentBufferSize)
{
return;
}
bufferHandle.Close();
currentBufferSize = bytes;
bufferHandle = SafeHGlobalHandleCritical.AllocHGlobal(currentBufferSize);
record.pbMDData = bufferHandle.DangerousGetHandle();
record.dwMDDataLen = currentBufferSize;
}
[Fx.Tag.SecurityNote(Critical = "Accesses and Returns SecurityCritical private data.")]
[SecurityCritical]
object GetData(string path, uint type)
{
uint bytes = currentBufferSize;
record.dwMDAttributes = MSAdminBase.METADATA_INHERIT;
record.dwMDUserType = MSAdminBase.IIS_MD_UT_SERVER;
record.dwMDDataType = MSAdminBase.ALL_METADATA;
record.dwMDIdentifier = type;
record.pbMDData = bufferHandle.DangerousGetHandle();
record.dwMDDataLen = currentBufferSize;
uint hResult = adminBase.GetData((uint) mdHandle, path, ref record, ref bytes);
if (hResult == E_INSUFFICIENT_BUFFER)
{
EnsureRecordBuffer(bytes);
hResult = adminBase.GetData((uint) mdHandle, path, ref record, ref bytes);
}
if (hResult == E_PATH_NOT_FOUND || hResult == E_DATA_NOT_FOUND)
{
return null;
}
else if (hResult != 0)
{
throw FxTrace.Exception.AsError(new COMException(SR.Hosting_MetabaseAccessError, (int)hResult));
}
return ConvertData();
}
[Fx.Tag.SecurityNote(Critical = "Accesses and Returns SecurityCritical private data.")]
[SecurityCritical]
object ConvertData()
{
switch (record.dwMDDataType)
{
case MSAdminBase.DWORD_METADATA:
return (UInt32)Marshal.ReadInt32(record.pbMDData);
case MSAdminBase.EXPANDSZ_METADATA:
case MSAdminBase.STRING_METADATA:
return Marshal.PtrToStringUni(record.pbMDData);
case MSAdminBase.MULTISZ_METADATA:
return RecordToStringArray();
default:
throw FxTrace.Exception.AsError(new NotSupportedException(
SR.Hosting_MetabaseDataTypeUnsupported(
record.dwMDDataType.ToString(NumberFormatInfo.CurrentInfo),
record.dwMDIdentifier.ToString(NumberFormatInfo.CurrentInfo))));
}
}
[Fx.Tag.SecurityNote(Critical = "Accesses and Returns SecurityCritical private data.")]
[SecurityCritical]
string[] RecordToStringArray()
{
List list = new List();
if (record.dwMDDataType == MSAdminBase.MULTISZ_METADATA)
{
// Ensure that the data is an array of double-byte unicode chars.
if ((record.dwMDDataLen & 1) != 0)
{
throw FxTrace.Exception.AsError(new DataMisalignedException(
SR.Hosting_MetabaseDataStringsTerminate(record.dwMDIdentifier.ToString(NumberFormatInfo.CurrentInfo))));
}
int startPos = 0;
int endPos = 0;
while (record.dwMDDataLen > 0)
{
// Scan for a null terminator.
while (endPos < record.dwMDDataLen && Marshal.ReadInt16(record.pbMDData, endPos) != 0)
{
endPos += 2;
}
if (endPos == record.dwMDDataLen &&
Marshal.ReadInt16(record.pbMDData, endPos - 2) != 0)
{
throw FxTrace.Exception.AsError(new DataMisalignedException(
SR.Hosting_MetabaseDataStringsTerminate(record.dwMDIdentifier.ToString(NumberFormatInfo.CurrentInfo))));
}
// End of the string.
if (endPos == startPos)
{
break;
}
// Convert to string.
list.Add(Marshal.PtrToStringUni(new IntPtr(record.pbMDData.ToInt64() + startPos),
(endPos - startPos)/2));
// Go to next string
startPos = endPos += 2;
}
}
return list.ToArray();
}
[Fx.Tag.SecurityNote(Safe = "Access Critical Private Members but does not expose critical private members to callers.")]
[SecuritySafeCritical]
void Dispose(bool disposing)
{
if (!disposed)
{
if (disposing)
{
record.pbMDData = IntPtr.Zero;
currentBufferSize = 0;
if (bufferHandle != null)
{
bufferHandle.Close();
}
}
int handleToClose = Interlocked.Exchange(ref mdHandle, 0);
if (handleToClose != 0)
{
adminBase.CloseKey((uint) handleToClose);
}
//Notice we cannot assign adminBase to NULL in Dispose, because
//it could be shared by multiple instances of MetabaseReader.
disposed = true;
}
}
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
//------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------
namespace System.ServiceModel.Activation
{
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Runtime;
using System.Runtime.InteropServices;
using System.Security;
using System.ServiceModel.Activation.Interop;
using System.Threading;
// These values are copied from %SDXROOT%\public\sdk\inc\iiscnfg.h.
enum MetabasePropertyType
{
ServerBindings = 1023,
SecureBindings = 2021,
AuthFlags = 6000,
Realm = 6001,
AnonymousUserName = 6020,
AnonymousPassword = 6021,
AccessSslFlags = 6030,
AuthPersistence = 6031,
AuthProviders = 6032,
}
[Fx.Tag.SecurityNote(Critical = "Does a bunch of unsafe and native access." +
"Caller should guard MetabaseReader instance as well as any results.")]
#pragma warning disable 618 // have not moved to the v4 security model yet
[SecurityCritical(SecurityCriticalScope.Everything)]
#pragma warning restore 618
class MetabaseReader : IDisposable
{
internal const string LMPath = "/LM";
const uint E_INSUFFICIENT_BUFFER = 0x8007007A;
const uint E_PATH_NOT_FOUND = 0x80070003;
const uint E_DATA_NOT_FOUND = 0x800CC801;
static IMSAdminBase adminBase;
static object syncRoot = new object();
int mdHandle = 0;
[Fx.Tag.SecurityNote(Critical = "Stores a handle.")]
[SecurityCritical]
METADATA_RECORD record;
[Fx.Tag.SecurityNote(Critical = "Handle to an unmanaged resource.")]
[SecurityCritical]
SafeHandle bufferHandle;
uint currentBufferSize = 1024;
bool disposed;
[Fx.Tag.SecurityNote(Safe = "Access Critical Private Members but does not expose critical private members to callers.")]
[SecuritySafeCritical]
public MetabaseReader()
{
lock (syncRoot)
{
if (adminBase == null)
{
adminBase = (IMSAdminBase)new MSAdminBase();
}
}
uint handle;
uint hResult = adminBase.OpenKey(MSAdminBase.METADATA_MASTER_ROOT_HANDLE, LMPath,
MSAdminBase.METADATA_PERMISSION_READ, MSAdminBase.DEFAULT_METABASE_TIMEOUT, out handle);
mdHandle = (int) handle;
if (hResult != 0)
{
throw FxTrace.Exception.AsError(new COMException(SR.Hosting_MetabaseAccessError, (int)hResult));
}
bufferHandle = SafeHGlobalHandleCritical.AllocHGlobal(currentBufferSize);
}
~MetabaseReader()
{
Dispose(false);
}
[Fx.Tag.SecurityNote(Safe = "Access Critical Private Members and returns a managed representation of the handle.")]
[SecurityCritical]
public object GetData(string path, MetabasePropertyType propertyType)
{
return GetData(path, (uint)propertyType);
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
[Fx.Tag.SecurityNote(Safe = "Access Critical Private Members but does not expose critical private members to callers.")]
[SecuritySafeCritical]
void EnsureRecordBuffer(uint bytes)
{
if (bytes <= currentBufferSize)
{
return;
}
bufferHandle.Close();
currentBufferSize = bytes;
bufferHandle = SafeHGlobalHandleCritical.AllocHGlobal(currentBufferSize);
record.pbMDData = bufferHandle.DangerousGetHandle();
record.dwMDDataLen = currentBufferSize;
}
[Fx.Tag.SecurityNote(Critical = "Accesses and Returns SecurityCritical private data.")]
[SecurityCritical]
object GetData(string path, uint type)
{
uint bytes = currentBufferSize;
record.dwMDAttributes = MSAdminBase.METADATA_INHERIT;
record.dwMDUserType = MSAdminBase.IIS_MD_UT_SERVER;
record.dwMDDataType = MSAdminBase.ALL_METADATA;
record.dwMDIdentifier = type;
record.pbMDData = bufferHandle.DangerousGetHandle();
record.dwMDDataLen = currentBufferSize;
uint hResult = adminBase.GetData((uint) mdHandle, path, ref record, ref bytes);
if (hResult == E_INSUFFICIENT_BUFFER)
{
EnsureRecordBuffer(bytes);
hResult = adminBase.GetData((uint) mdHandle, path, ref record, ref bytes);
}
if (hResult == E_PATH_NOT_FOUND || hResult == E_DATA_NOT_FOUND)
{
return null;
}
else if (hResult != 0)
{
throw FxTrace.Exception.AsError(new COMException(SR.Hosting_MetabaseAccessError, (int)hResult));
}
return ConvertData();
}
[Fx.Tag.SecurityNote(Critical = "Accesses and Returns SecurityCritical private data.")]
[SecurityCritical]
object ConvertData()
{
switch (record.dwMDDataType)
{
case MSAdminBase.DWORD_METADATA:
return (UInt32)Marshal.ReadInt32(record.pbMDData);
case MSAdminBase.EXPANDSZ_METADATA:
case MSAdminBase.STRING_METADATA:
return Marshal.PtrToStringUni(record.pbMDData);
case MSAdminBase.MULTISZ_METADATA:
return RecordToStringArray();
default:
throw FxTrace.Exception.AsError(new NotSupportedException(
SR.Hosting_MetabaseDataTypeUnsupported(
record.dwMDDataType.ToString(NumberFormatInfo.CurrentInfo),
record.dwMDIdentifier.ToString(NumberFormatInfo.CurrentInfo))));
}
}
[Fx.Tag.SecurityNote(Critical = "Accesses and Returns SecurityCritical private data.")]
[SecurityCritical]
string[] RecordToStringArray()
{
List list = new List();
if (record.dwMDDataType == MSAdminBase.MULTISZ_METADATA)
{
// Ensure that the data is an array of double-byte unicode chars.
if ((record.dwMDDataLen & 1) != 0)
{
throw FxTrace.Exception.AsError(new DataMisalignedException(
SR.Hosting_MetabaseDataStringsTerminate(record.dwMDIdentifier.ToString(NumberFormatInfo.CurrentInfo))));
}
int startPos = 0;
int endPos = 0;
while (record.dwMDDataLen > 0)
{
// Scan for a null terminator.
while (endPos < record.dwMDDataLen && Marshal.ReadInt16(record.pbMDData, endPos) != 0)
{
endPos += 2;
}
if (endPos == record.dwMDDataLen &&
Marshal.ReadInt16(record.pbMDData, endPos - 2) != 0)
{
throw FxTrace.Exception.AsError(new DataMisalignedException(
SR.Hosting_MetabaseDataStringsTerminate(record.dwMDIdentifier.ToString(NumberFormatInfo.CurrentInfo))));
}
// End of the string.
if (endPos == startPos)
{
break;
}
// Convert to string.
list.Add(Marshal.PtrToStringUni(new IntPtr(record.pbMDData.ToInt64() + startPos),
(endPos - startPos)/2));
// Go to next string
startPos = endPos += 2;
}
}
return list.ToArray();
}
[Fx.Tag.SecurityNote(Safe = "Access Critical Private Members but does not expose critical private members to callers.")]
[SecuritySafeCritical]
void Dispose(bool disposing)
{
if (!disposed)
{
if (disposing)
{
record.pbMDData = IntPtr.Zero;
currentBufferSize = 0;
if (bufferHandle != null)
{
bufferHandle.Close();
}
}
int handleToClose = Interlocked.Exchange(ref mdHandle, 0);
if (handleToClose != 0)
{
adminBase.CloseKey((uint) handleToClose);
}
//Notice we cannot assign adminBase to NULL in Dispose, because
//it could be shared by multiple instances of MetabaseReader.
disposed = true;
}
}
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- TemplateControlParser.cs
- ComPlusTraceRecord.cs
- EntityStoreSchemaFilterEntry.cs
- HttpCookie.cs
- ArraySubsetEnumerator.cs
- CompileXomlTask.cs
- GPRECTF.cs
- CodeMemberMethod.cs
- _Win32.cs
- DataGridViewCellValueEventArgs.cs
- FilteredAttributeCollection.cs
- shaperfactoryquerycachekey.cs
- StrokeCollectionDefaultValueFactory.cs
- BooleanProjectedSlot.cs
- Point3D.cs
- InternalConfigConfigurationFactory.cs
- ElementHost.cs
- ListenerConfig.cs
- CollectionDataContractAttribute.cs
- UxThemeWrapper.cs
- FormsAuthenticationUserCollection.cs
- CodeTypeParameter.cs
- HttpStreamFormatter.cs
- MessageSecurityVersionConverter.cs
- SafeCryptoHandles.cs
- KeyConstraint.cs
- HMACSHA256.cs
- WebPartDisplayModeCancelEventArgs.cs
- DesignerAttribute.cs
- PublisherIdentityPermission.cs
- ForwardPositionQuery.cs
- ListViewSortEventArgs.cs
- AttachedAnnotation.cs
- XmlSchemaInferenceException.cs
- UnconditionalPolicy.cs
- ErrorHandlerModule.cs
- WorkflowExecutor.cs
- SQLByte.cs
- GACIdentityPermission.cs
- BuiltInExpr.cs
- DispatcherExceptionFilterEventArgs.cs
- XmlIgnoreAttribute.cs
- ObjectStateEntry.cs
- ValidationRuleCollection.cs
- ListBindingHelper.cs
- FirstMatchCodeGroup.cs
- SiteMapHierarchicalDataSourceView.cs
- ContainerSelectorBehavior.cs
- DataGridCell.cs
- DataGridViewLinkColumn.cs
- ConcurrentStack.cs
- Viewport2DVisual3D.cs
- SoapAttributeOverrides.cs
- FatalException.cs
- WeakReferenceList.cs
- Compress.cs
- TcpConnectionPoolSettings.cs
- DocobjHost.cs
- ViewBase.cs
- PrintPreviewGraphics.cs
- NumberSubstitution.cs
- CodeSubDirectory.cs
- NonParentingControl.cs
- QueryOpcode.cs
- returneventsaver.cs
- CollectionViewProxy.cs
- _AuthenticationState.cs
- DebugController.cs
- CaseExpr.cs
- Section.cs
- ArgumentNullException.cs
- GradientStop.cs
- AttachedPropertyBrowsableWhenAttributePresentAttribute.cs
- ColumnClickEvent.cs
- DesignerUtility.cs
- Recipient.cs
- UpdatePanelTrigger.cs
- SimpleWebHandlerParser.cs
- SqlDependencyUtils.cs
- ItemAutomationPeer.cs
- FileSystemEnumerable.cs
- CodeGenHelper.cs
- ObjectTag.cs
- InkSerializer.cs
- Accessors.cs
- CipherData.cs
- FileVersionInfo.cs
- SpanIndex.cs
- CellCreator.cs
- RealizationContext.cs
- coordinator.cs
- HttpDictionary.cs
- SqlAliasesReferenced.cs
- SweepDirectionValidation.cs
- EventLogPermissionAttribute.cs
- JsonServiceDocumentSerializer.cs
- QilSortKey.cs
- NavigationWindowAutomationPeer.cs
- AccessDataSource.cs
- ListViewCancelEventArgs.cs