Code:
/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / wpf / src / Framework / MS / Internal / IO / Packaging / indexingfiltermarshaler.cs / 1305600 / indexingfiltermarshaler.cs
//------------------------------------------------------------------------------
//
//
// Copyright (C) Microsoft Corporation. All rights reserved.
//
//
// Description:
// Class which acts as adaptor between IManagedFilter and IFilter.
// Used by PackageFilter for XamlFilter and CorePropertiesFilter.
// Used by EncryptedPackageFilter for CorePropertiesFilter.
//
// History:
// 02/25/2004: JohnLarc: Creation, using BruceMac's code from XamlFilter, ContainerFilter, and ManagedFilterMarshalingHelper.
// 08/26/2004: JohnLarc: Removed access to indexing filters from managed code.
// 07/18/2005: ArindamB: Removed IPersistStream and IPersistFile interfaces.
//
//-----------------------------------------------------------------------------
using System.Diagnostics;
using System;
using System.Runtime.InteropServices;
using System.Collections;
using System.Windows; // for ExceptionStringTable
using System.Security; // for SecurityCritical
using MS.Internal.Interop; // for STAT_CHUNK, etc.
using MS.Internal; // for Invariant
using MS.Win32;
namespace MS.Internal.IO.Packaging
{
#region IndexingFilterMarshaler
///
/// Adapter for IManagedFilter. Used to obtain an IFilter interface from an IManagedFilter.
///
///
/// IManagedFilter is supported by filters which have purely managed implementation and don't work
/// with interop entities. Callers like PackageFilter and EncryptedPackageFilter which support
/// IFilter interfaces interact with IManagedFilters like XamlFilter, PackageCorePropertiesFilter
/// and EncryptedPackageCorePropertiesFilter through IndexingFilterMarshaler.
///
internal class IndexingFilterMarshaler : IFilter
{
#region Static members.
///
/// pre-defined GUID for storage properties on file system files (as per MSDN)
///
internal static Guid PSGUID_STORAGE = new Guid(0xb725f130, 0x47ef, 0x101a, 0xa5, 0xf1, 0x02, 0x60, 0x8c, 0x9e, 0xeb, 0xac);
/// Cache frequently used size values to incur reflection cost just once.
internal const Int32 _int16Size = 2;
///
/// Constructor.
///
/// IManagedFilter implementation
internal IndexingFilterMarshaler(IManagedFilter managedFilter)
{
if (managedFilter == null)
{
throw new ArgumentNullException("managedFilter");
}
_implementation = managedFilter;
}
///
/// Init
///
/// length of aAttributes
/// array of FULLPROPSPEC structs
/// managed array
internal static ManagedFullPropSpec[] MarshalFullPropSpecArray(
uint cAttributes, // length of aAttributes
FULLPROPSPEC[] aAttributes)
{
// If there are attributes, these override the flags
if (cAttributes > 0)
{
// Attributes count and array should match.
// This has already been checked for by XpsFilter.
Invariant.Assert(aAttributes != null);
ManagedFullPropSpec[] initAttributes = new ManagedFullPropSpec[checked((int)cAttributes)];
// convert to managed equivalents to isolate the marshaling effort
for (int i = 0; i < cAttributes; i++)
{
// convert and add to local list
initAttributes[i] = new ManagedFullPropSpec(aAttributes[i]);
}
return initAttributes;
}
else
return null;
}
///
/// StringToPtr
///
/// Converts a managed string into the format useful for IFilter.GetText
/// string to convert
/// maximum number of characters to convert
/// pointer to write to
///
/// This method, if exposed to partially trusted callers, can lead to arbitrary memory writing.
/// Critical - This code could be used to attempt to build a string from arbitrary data.
/// This code is not intended to be used from PT code.
/// Not designed to be accessible from public surface at all. Invoked (indirectly) by unmanaged client code.
///
[SecurityCritical]
internal static void MarshalStringToPtr(string s, ref uint bufCharacterCount, IntPtr p)
{
// bufCharacterCount is never supposed to be zero at this level.
Invariant.Assert(bufCharacterCount != 0);
// ensure the interface rules are followed
// string must also be null terminated so we restrict the length to buf size - 1
if ((uint)(s.Length) > bufCharacterCount - 1)
throw new InvalidOperationException(SR.Get(SRID.FilterGetTextBufferOverflow));
// Return the number of characters written, including the terminating null.
bufCharacterCount = (UInt32)s.Length + 1;
// convert string to unmanaged string and write into provided buffer
Marshal.Copy(s.ToCharArray(), 0, p, s.Length);
// null terminate (16bit's of zero to replace one Unicode character)
Marshal.WriteInt16(p, s.Length * _int16Size, 0);
}
///
/// Marshal Managed to Native PROPSPEC
///
///
///
///
/// Critical: calls Marshal.StringToCoTaskMemUni which LinkDemands, and writes string into unmanaged memory.
///
[SecurityCritical]
internal static void MarshalPropSpec(ManagedPropSpec propSpec, ref PROPSPEC native)
{
native.propType = (uint)propSpec.PropType;
switch (propSpec.PropType)
{
case PropSpecType.Id:
native.union.propId = (uint)propSpec.PropId;
break;
case PropSpecType.Name:
native.union.name = Marshal.StringToCoTaskMemUni(propSpec.PropName);
break;
default:
Invariant.Assert(false); // propSpec.PropType is set by internal code in the filter logic.
break;
}
}
///
/// Marshal Managed to Native FULLPROPSPEC
///
///
///
///
/// Critical: calls MarshalPropSpec which is Critical. Returns a pointer to unmanaged memory.
///
[SecurityCritical]
internal static void MarshalFullPropSpec(ManagedFullPropSpec fullPropSpec, ref FULLPROPSPEC native)
{
native.guid = fullPropSpec.Guid;
MarshalPropSpec(fullPropSpec.Property, ref native.property);
}
///
/// GetChunk
///
/// An interop STAT_CHUNK from a ManagedChunk
///
/// Critical: calls MarshalFullPropSpec which is Critical. Returns a pointer to unmanaged memory.
///
[SecurityCritical]
internal static STAT_CHUNK MarshalChunk(ManagedChunk chunk)
{
STAT_CHUNK native = new STAT_CHUNK();
native.idChunk = chunk.ID;
Invariant.Assert(chunk.BreakType >= CHUNK_BREAKTYPE.CHUNK_NO_BREAK && chunk.BreakType <= CHUNK_BREAKTYPE.CHUNK_EOC);
native.breakType = chunk.BreakType;
Invariant.Assert(
chunk.Flags >= 0
&&
chunk.Flags <= (CHUNKSTATE.CHUNK_TEXT | CHUNKSTATE.CHUNK_VALUE | CHUNKSTATE.CHUNK_FILTER_OWNED_VALUE));
native.flags = chunk.Flags;
native.locale = chunk.Locale;
native.idChunkSource = chunk.ChunkSource;
native.cwcStartSource = chunk.StartSource;
native.cwcLenSource = chunk.LenSource;
MarshalFullPropSpec(chunk.Attribute, ref native.attribute);
return native;
}
///
/// MarshalPropVariant
///
/// Object to marshal, should be DateTime or String
/// newly allocated PROPVARIANT structure
///
/// Critical: calls Marshal.StringToCoTaskMemAnsi which LinkDemands, and writes string into unmanaged memory.
///
[SecurityCritical]
internal static IntPtr MarshalPropVariant(Object obj)
{
IntPtr pszVal = IntPtr.Zero;
IntPtr pNative = IntPtr.Zero;
try
{
PROPVARIANT v;
if (obj is string)
{
pszVal = Marshal.StringToCoTaskMemAnsi((string)obj);
v = new PROPVARIANT();
v.vt = VARTYPE.VT_LPSTR;
v.union.pszVal = pszVal;
}
else if (obj is DateTime)
{
v = new PROPVARIANT();
v.vt = VARTYPE.VT_FILETIME;
long longFileTime = ((DateTime)obj).ToFileTime();
v.union.filetime.dwLowDateTime = (Int32)longFileTime;
v.union.filetime.dwHighDateTime = (Int32)((longFileTime >> 32) & 0xFFFFFFFF);
}
else
{
throw new InvalidOperationException(
SR.Get(SRID.FilterGetValueMustBeStringOrDateTime));
}
// allocate an unmanaged PROPVARIANT to return
pNative = Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(PROPVARIANT)));
// Per MSDN, AllocCoTaskMem never returns null. One can't be too careful, though.
Invariant.Assert(pNative != null);
// marshal the managed PROPVARIANT into the unmanaged block and return it
Marshal.StructureToPtr(v, pNative, false);
}
catch
{
if (pszVal != IntPtr.Zero)
{
Marshal.FreeCoTaskMem(pszVal);
}
if (pNative != IntPtr.Zero)
{
Marshal.FreeCoTaskMem(pNative);
}
throw;
}
return pNative;
}
#endregion Static members.
#region IFilter implementation
///
/// Init
///
/// usage flags
/// length of aAttributes
/// array of FULLPROPSPEC structs
/// flags
public IFILTER_FLAGS Init(IFILTER_INIT grfFlags, // IFILTER_INIT value
uint cAttributes, // length of aAttributes
FULLPROPSPEC[] aAttributes) // restrict responses to the specified attributes
{
ManagedFullPropSpec[] managedArray = MarshalFullPropSpecArray(
cAttributes, aAttributes);
return _implementation.Init(grfFlags, managedArray);
}
///
/// GetChunk
///
/// the next chunk
///
/// Critical: calls MarshalChunk which is Critical. Returns a pointer to unmanaged memory.
///
[SecurityCritical]
public STAT_CHUNK GetChunk()
{
// Get the managed chunk
ManagedChunk managedChunk = _implementation.GetChunk();
if (managedChunk == null)
{
// End of chunks.
if (ThrowOnEndOfChunks)
{
// Throw exception.
throw new COMException(SR.Get(SRID.FilterEndOfChunks),
(int)FilterErrorCode.FILTER_E_END_OF_CHUNKS);
}
// Return STAT_CHUNK with idChunk as 0.
STAT_CHUNK chunk = new STAT_CHUNK();
chunk.idChunk = 0;
return chunk;
}
// Valid chunk. Return corresponding STAT_CHUNK.
return MarshalChunk(managedChunk);
}
///
/// GetText
///
/// Buffer size in Unicode characters (not bytes)
/// Pre-allocated buffer for us to write into. String must be null-terminated.
///
/// Critical - Invokes the critical method MarshalStringToPtr, which could be used to attempt to build a string from arbitrary data.
/// This code is not intended to be called from PT code.
/// Not designed to be accessible from public surface at all. Invoked (indirectly) by unmanaged client code.
///
[SecurityCritical]
public void GetText(ref uint bufCharacterCount, IntPtr pBuffer)
{
// NOTE: bufCharacterCount and pBuffer are already validated by XpsFilter.
// In future, if this class is exposed publicly or used in a way other than
// through XpsFilter, proper checks needs to be present either here or in the caller.
// get the managed string and marshal
MarshalStringToPtr(_implementation.GetText((int)bufCharacterCount - 1),
ref bufCharacterCount, pBuffer);
}
///
/// GetValue
///
/// newly allocated PROPVARIANT structure
///
/// Critical: calls MarshalPropVariant which is Critical. Returns a pointer to unmanaged memory.
///
[SecurityCritical]
public IntPtr GetValue()
{
return MarshalPropVariant(_implementation.GetValue());
}
///
/// BindRegion
///
///
///
///
/// The MSDN specification requires this function to return E_NOTIMPL for the time being.
///
public IntPtr BindRegion(FILTERREGION origPos, ref Guid riid)
{
// The following exception maps to E_NOTIMPL.
throw new NotImplementedException(SR.Get(SRID.FilterBindRegionNotImplemented));
}
#endregion IFilter implementation
#region Properties
///
/// If set to true, FILTER_E_END_OF_CHUNKS exception is thrown
/// by IFilter.GetChunk() on end of chunks.
/// If false, a STAT_CHUNK with idChunk as 0 is returned instead.
///
internal bool ThrowOnEndOfChunks
{
get
{
return _throwOnEndOfChunks;
}
set
{
_throwOnEndOfChunks = value;
}
}
#endregion Properties
#region Fields
private IManagedFilter _implementation;
private bool _throwOnEndOfChunks = true;
#endregion Fields
}
#endregion IndexingFilterMarshaler
}
// 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
- ScriptingJsonSerializationSection.cs
- CriticalExceptions.cs
- TileBrush.cs
- WebHttpBindingCollectionElement.cs
- XmlQuerySequence.cs
- AuthenticationSection.cs
- ResourceProperty.cs
- VideoDrawing.cs
- TextRange.cs
- SubpageParagraph.cs
- WebBrowserSiteBase.cs
- SQLMoneyStorage.cs
- SiteMapSection.cs
- SamlAuthorityBinding.cs
- ObjectFullSpanRewriter.cs
- ConcurrentQueue.cs
- WindowsToolbarAsMenu.cs
- FocusManager.cs
- WindowsMenu.cs
- SafeFileMapViewHandle.cs
- XmlSerializerSection.cs
- ResXResourceSet.cs
- Walker.cs
- ObjectManager.cs
- ComboBoxAutomationPeer.cs
- GeneralTransform2DTo3D.cs
- Transaction.cs
- ServiceOperationParameter.cs
- DataBinding.cs
- SimpleTypeResolver.cs
- PolyLineSegmentFigureLogic.cs
- MeasureItemEvent.cs
- EntityClassGenerator.cs
- SmiEventSink_DeferedProcessing.cs
- WebMessageFormatHelper.cs
- NegotiationTokenProvider.cs
- AddToCollection.cs
- SystemColors.cs
- KeyedCollection.cs
- ParseHttpDate.cs
- DeclaredTypeValidatorAttribute.cs
- LicFileLicenseProvider.cs
- TimeSpanStorage.cs
- TextAnchor.cs
- GridItemPattern.cs
- NameTable.cs
- TypeExtension.cs
- FrameworkContentElement.cs
- SqlMultiplexer.cs
- BitSet.cs
- MarkerProperties.cs
- CompoundFileStreamReference.cs
- PersonalizationState.cs
- SelectionPattern.cs
- ColorKeyFrameCollection.cs
- CompressStream.cs
- HeaderCollection.cs
- HttpCachePolicy.cs
- Mapping.cs
- OdbcEnvironmentHandle.cs
- TypefaceCollection.cs
- UnsignedPublishLicense.cs
- QueryableDataSourceHelper.cs
- Partitioner.cs
- FontFamilyIdentifier.cs
- XmlDataLoader.cs
- InvalidPrinterException.cs
- PolygonHotSpot.cs
- FileDialog_Vista.cs
- XmlAggregates.cs
- MessageSecurityProtocol.cs
- CurrentChangingEventManager.cs
- PropertyReferenceSerializer.cs
- Pool.cs
- RuntimeCompatibilityAttribute.cs
- DesignerWidgets.cs
- CanExecuteRoutedEventArgs.cs
- DataBoundControl.cs
- ProfileProvider.cs
- CalendarKeyboardHelper.cs
- HitTestWithGeometryDrawingContextWalker.cs
- XamlStream.cs
- TitleStyle.cs
- WinEventQueueItem.cs
- SqlNotificationEventArgs.cs
- FixedSOMLineCollection.cs
- ToolStripOverflowButton.cs
- UInt64Storage.cs
- WorkflowView.cs
- FormsAuthenticationModule.cs
- QilValidationVisitor.cs
- NgenServicingAttributes.cs
- PermissionSetTriple.cs
- XmlSerializerVersionAttribute.cs
- LayoutExceptionEventArgs.cs
- ConditionCollection.cs
- PropertyGrid.cs
- Viewport2DVisual3D.cs
- HttpModuleCollection.cs
- EditorResources.cs