private void TestSet()
        {
            int hr;
            StreamBufferAttrDataType adt;
            short  Len = 4;
            IntPtr pba = Marshal.AllocCoTaskMem(Len);

            try
            {
                Marshal.WriteInt32(pba, 501);

                hr = m_sbra.SetAttribute(0, "DVR Index Granularity", StreamBufferAttrDataType.DWord, pba, Len);
                DsError.ThrowExceptionForHR(hr);

                Marshal.WriteInt32(pba, 0);

                hr = m_sbra.GetAttributeByName("DVR Index Granularity", 0, out adt, pba, ref Len);
                DsError.ThrowExceptionForHR(hr);

                int v = Marshal.ReadInt32(pba);
                Debug.Assert(v == 501, "pba");
            }
            finally
            {
                Marshal.FreeCoTaskMem(pba);
            }
        }
        /// <summary>Gets all of the attributes on a file.</summary>
        /// <returns>A collection of the attributes from the file.</returns>
        public override System.Collections.IDictionary GetAttributes(bool forCopy)
        {
            if (_editor == null)
            {
                throw new ObjectDisposedException(GetType().Name);
            }

            Hashtable     propsRetrieved = new Hashtable();
            List <string> tagsForCopy    = new List <string>();

            if (forCopy)
            {
                string overrideFile = System.IO.Path.Combine(System.IO.Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "MetatagOverride.txt");

                if (File.Exists(overrideFile))
                {
                    using (StreamReader sr = File.OpenText(overrideFile))
                    {
                        string tag;
                        tag = sr.ReadLine();
                        while (!String.IsNullOrEmpty(tag))
                        {
                            tagsForCopy.Add(tag);
                            tag = sr.ReadLine();
                        }
                    }
                }
                else
                {
                    tagsForCopy.AddRange(new string[] { "Description", "WM/ParentalRating", "WM/Provider", "WM/MediaCredits", "WM/MediaIsDelay", "WM/WMRVServiceID", "WM/WMRVInBandRatingLevel", "WM/MediaOriginalRunTime", "WM/MediaIsSAP", "WM/MediaIsFinale", "WM/MediaNetworkAffiliation", "WM/WMRVOriginalSoftPrePadding", "WM/WMRVOriginalSoftPostPadding", "Title", "WM/WMRVDTVContent", "WM/Mood", "WM/MediaIsSubtitled", "WM/WMRVActualSoftPrePadding", "WM/MediaStationName", "WM/ContentGroupDescription", "WM/Language", "WM/ParentalRatingReason", "WM/WMRVEndTime", "WM/WMRVHardPostPadding", "WM/VideoClosedCaptioning", "WM/WMRVInBandRatingAttributes", "WM/WMRVContentProtectedPercent", "WM/MediaIsTape", "WM/WMRVEncodeTime", "WM/MediaIsRepeat", "WM/WMRVHDContent", "WM/SubTitle", "WM/MediaIsLive", "WM/MediaOriginalBroadcastDateTime", "WM/SubTitleDescription", "Author", "WM/WMRVATSCContent", "WM/MediaStationCallSign", "WM/WMRVWatched", "WM/WMRVInBandRatingSystem", "WM/MediaOriginalChannel", "WM/AlbumTitle", "WM/ProviderRating", "WM/ProviderCopyright", "WM/MediaIsPremiere", "WM/WMRVContentProtected", "WM/Genre", "WM/Composer", "WM/OriginalReleaseTime", "WM/WMRVHardPrePadding", "WM/WMRVActualSoftPostPadding", "WM/ToolName", "WM/ToolVersion", "WM/WMRVScheduleItemID", "WM/WMRVRequestID", "WM/WMRVServiceID", "WM/WMRVProgramID", "WM/WMRVContentProtected" });
                }

                foreach (string tag in tagsForCopy)
                {
                    StreamBufferAttrDataType attributeType;
                    byte[] attributeValue = null;
                    IntPtr attPtr         = IntPtr.Zero;
                    //ushort attributeNameLength = 0;
                    short attributeValueLength = 0;

                    try
                    {
                        // Get the lengths of the name and the value, then use them to create buffers to receive them
                        _editor.GetAttributeByName(tag, 0, out attributeType, attPtr, ref attributeValueLength);

                        //attributeValue = new byte[attributeValueLength];
                        attPtr = Marshal.AllocHGlobal(attributeValueLength);

                        // Get the name and value
                        _editor.GetAttributeByName(tag, 0, out attributeType, attPtr, ref attributeValueLength);

                        attributeValue = new byte[attributeValueLength];
                        Marshal.Copy(attPtr, attributeValue, 0, attributeValueLength);

                        // If we got a name, parse the value and add the metadata item
                        if (attributeValue != null && attributeValue.Length > 0)
                        {
                            object val = ParseAttributeValue(attributeType, attributeValue);
                            string key = tag;
                            propsRetrieved[key] = new MetadataItem(key, val, attributeType);
                        }
                    }
                    finally
                    {
                        if (attPtr != IntPtr.Zero)
                        {
                            Marshal.FreeHGlobal(attPtr);
                        }
                    }
                }
            }
            else
            {
                // Get the number of attributes
                short attributeCount = 0;
                _editor.GetAttributeCount(0, out attributeCount);

                propsRetrieved.Add("FileName", new MetadataItem("FileName", _path, StreamBufferAttrDataType.String));

                // Get each attribute by index
                for (short i = 0; i < attributeCount; i++)
                {
                    IntPtr attPtr = IntPtr.Zero;
                    StreamBufferAttrDataType attributeType;
                    StringBuilder            attributeName = null;
                    byte[] attributeValue       = null;
                    short  attributeNameLength  = 0;
                    short  attributeValueLength = 0;

                    try
                    {
                        // Get the lengths of the name and the value, then use them to create buffers to receive them
                        //uint reserved = 0;
                        _editor.GetAttributeByIndex(i, 0, attributeName, ref attributeNameLength,
                                                    out attributeType, attPtr, ref attributeValueLength);

                        attPtr = Marshal.AllocHGlobal(attributeValueLength);

                        attributeName  = new StringBuilder(attributeNameLength);
                        attributeValue = new byte[attributeValueLength];

                        // Get the name and value
                        _editor.GetAttributeByIndex(i, 0, attributeName, ref attributeNameLength,
                                                    out attributeType, attPtr, ref attributeValueLength);

                        Marshal.Copy(attPtr, attributeValue, 0, attributeValueLength);

                        // If we got a name, parse the value and add the metadata item
                        if (attributeName != null && attributeName.Length > 0)
                        {
                            object val = ParseAttributeValue(attributeType, attributeValue);
                            string key = attributeName.ToString().TrimEnd('\0');
                            //if (!tagsForCopy.Contains(key))
                            propsRetrieved[key] = new MetadataItem(key, val, attributeType);
                        }
                    }
                    catch
                    {
                        //swallow error
                    }
                    finally
                    {
                        if (attPtr != IntPtr.Zero)
                        {
                            Marshal.FreeHGlobal(attPtr);
                        }
                    }
                }
            }
            // Return the parsed items
            return(propsRetrieved);
        }