}// GetDataHere //------------------------------------------------- // Other IDataObject Methods // // We don't need to implement any of these other // methods, so if they are called, we'll just return // E_NOTIMPL //------------------------------------------------- public int GetData(ref FORMATETC pFormat, ref STGMEDIUM pMedium) { try { pMedium.hGlobal = (IntPtr)0; // We'll send this array if we don't know what to send byte[] Nothing = { 0x0, 0x0 }; ushort cf = (ushort)pFormat.cfFormat; if (cf != m_cfMultiSelect) { return(HRESULT.E_NOTIMPL); } CLSID cls = m_NodeData.Guid; SMMCObjectTypes ot = new SMMCObjectTypes(); ot.count = 1; ot.guid = new CLSID[] { cls }; pMedium.tymed = TYMED.HGLOBAL; pMedium.hGlobal = Marshal.AllocHGlobal(4 + 16); // We need to marshal this structure ourselves Marshal.WriteInt32(pMedium.hGlobal, 0, (int)ot.count); Marshal.WriteInt32(pMedium.hGlobal, 4, (int)ot.guid[0].x); Marshal.WriteInt16(pMedium.hGlobal, 8, (short)ot.guid[0].s1); Marshal.WriteInt16(pMedium.hGlobal, 10, (short)ot.guid[0].s2); for (int i = 0; i < 8; i++) { Marshal.WriteByte(pMedium.hGlobal, 12 + i, ot.guid[0].c[i]); } } catch (Exception e) { if ((int)pMedium.hGlobal != 0) { Marshal.FreeHGlobal(pMedium.hGlobal); } throw e; } return(HRESULT.S_OK); }// GetData
public void AddExtension(CLSID a, ref SCOPEDATAITEM b) { }
}// Object //------------------------------------------------- // GetDataHere // // This function will send certain data to the MMC. Note // this function uses the "unsafe" context... we need to // send a pointer to a byte array to IStream:Write, and this // is the easiest way to do it. //------------------------------------------------- public unsafe int GetDataHere(ref FORMATETC pFormat, ref STGMEDIUM pMedium) { IStream pStream = null; byte[] bDataToSend; int iLengthOfData; uint iDataSent = 0; try { // We'll send this array if we don't know what to send byte[] Nothing = { 0x0, 0x0 }; ushort cf = (ushort)pFormat.cfFormat; CreateStreamOnHGlobal(pMedium.hGlobal, 0, out pStream); // If we couldn't open a global handle.... if (pStream == null) { throw new Exception("Fail on CreateStreamOnHGlobal"); } // NOTE: the use of pointers is only possible because the function was marked // unsafe. Also, pData will only point to a valid address inside the "fixed" // block... outside of the "fixed" block the GC could move our memory around, resulting // in pData pointing to garbage. // See if we need to send a string.... if (cf == m_cfDisplayName || cf == m_cfSZNodeType) { if (cf == m_cfDisplayName) { bDataToSend = m_NodeData.bDisplayName; } else { bDataToSend = Nothing; } iLengthOfData = bDataToSend.Length; fixed(byte *pData = bDataToSend) { pStream.Write((IntPtr)pData, (uint)iLengthOfData, out iDataSent); } } // We need to send a GUID else if (cf == m_cfNodeType || cf == m_cfSnapinClsid) { CLSID cls = new CLSID(); if (cf == m_cfNodeType) { cls = m_NodeData.Guid; } else //if (cf == m_cfSnapinClsid) { // The GUID for this snapin cls.x = 0x18ba7139; cls.s1 = 0xd98b; cls.s2 = 0x43c2;; cls.c = new byte[8] { 0x94, 0xda, 0x26, 0x04, 0xe3, 0x4e, 0x17, 0x5d }; } IntPtr pData = Marshal.AllocCoTaskMem(16); // We need to marshal this structure ourselves Marshal.WriteInt32(pData, 0, (int)cls.x); Marshal.WriteInt16(pData, 4, (short)cls.s1); Marshal.WriteInt16(pData, 6, (short)cls.s2); for (int i = 0; i < 8; i++) { Marshal.WriteByte(pData, 8 + i, cls.c[i]); } pStream.Write(pData, 16, out iDataSent); Marshal.FreeCoTaskMem(pData); } // Close/Flush the stream Marshal.ReleaseComObject(pStream); } catch (Exception e) { if (pStream != null) { Marshal.ReleaseComObject(pStream); } throw e; } return(HRESULT.S_OK); }// GetDataHere