public bool ReadCDText(out List <Track> cdTracks)
        {
            cdTracks = null;

            int numTracks = GetNumTracks();

            if (numTracks == -1)
            {
                return(false);
            }

            Version version = Environment.OSVersion.Version;

            if (((Environment.OSVersion.Platform != PlatformID.Win32NT) || (version.Major < 5)) || ((version.Major == 5) && (version.Minor < 1)))
            {
                return(false);
            }

            Kernel32.CDROM_READ_TOC_EX structure = new Kernel32.CDROM_READ_TOC_EX
            {
                Format = Kernel32.CDROM_READ_TOC_EX_FORMAT.CDTEXT
            };
            int    cb  = Marshal.SizeOf(structure);
            IntPtr ptr = Marshal.AllocHGlobal(cb);

            Marshal.StructureToPtr(structure, ptr, true);

            Kernel32.CDROM_TOC_CD_TEXT_DATA cdrom_toc_cd_text_data = new Kernel32.CDROM_TOC_CD_TEXT_DATA
            {
                Length = (ushort)Marshal.SizeOf(typeof(Kernel32.CDROM_TOC_CD_TEXT_DATA))
            };

            IntPtr ptr2 = Marshal.AllocHGlobal(cdrom_toc_cd_text_data.Length);

            Marshal.StructureToPtr(cdrom_toc_cd_text_data, ptr2, true);
            uint bytesReturned = 0;
            bool flag          = Kernel32.DeviceIoControl(this.CDHandle, Kernel32.IOCTL_CDROM_READ_TOC_EX, ptr, (uint)cb, ptr2, cdrom_toc_cd_text_data.Length, ref bytesReturned, IntPtr.Zero) != 0;

            if (flag)
            {
                Marshal.PtrToStructure(ptr2, cdrom_toc_cd_text_data);
                cdTracks = this.BuildCDTracks(cdrom_toc_cd_text_data);
            }

            Marshal.FreeHGlobal(ptr2);
            Marshal.FreeHGlobal(ptr);

            return(flag && cdTracks != null && cdTracks.Count > 0);
        }
        private List <Track> BuildCDTracks(Kernel32.CDROM_TOC_CD_TEXT_DATA Data)
        {
            int numTracks = GetNumTracks();

            if (numTracks == -1)
            {
                return(null);
            }

            List <Track> tracks = new List <Track>();

            List <string> titles  = new List <string>();
            List <string> artists = new List <string>();
            List <string> genres  = new List <string>();

            try
            {
                Debug.WriteLine("CD_TEXT info dump BEGIN:");
                StringBuilder sb = new StringBuilder();

                for (int i = 0; i < Data.Descriptors.MaxIndex; i++)
                {
                    string line = "";
                    foreach (char c in Data.Descriptors[i].Text)
                    {
                        if (c != '\0')
                        {
                            line += c;
                        }
                        else
                        {
                            line += ".";
                        }
                    }

                    sb.Append(line);
                }
                Debug.WriteLine("CD_TEXT: " + sb.ToString());
                Debug.WriteLine("CD_TEXT info dump END");

                string item = string.Empty;

                for (int i = 0; i < Data.Descriptors.MaxIndex; i++)
                {
                    Kernel32.CDROM_TOC_CD_TEXT_DATA_BLOCK cdrom_toc_cd_text_data_block = Data.Descriptors[i];
                    foreach (char ch in cdrom_toc_cd_text_data_block.Text)
                    {
                        if (ch != '\0')
                        {
                            item = item + ch;
                            continue;
                        }

                        switch (cdrom_toc_cd_text_data_block.PackType)
                        {
                        case Kernel32.CDROM_CD_TEXT_PACK.ALBUM_NAME:
                            if (string.IsNullOrEmpty(item) == false || titles.Count == 0)
                            {
                                titles.Add(item);
                            }
                            item = string.Empty;
                            break;

                        case Kernel32.CDROM_CD_TEXT_PACK.GENRE:
                            if (string.IsNullOrEmpty(item) == false || genres.Count == 0)
                            {
                                genres.Add(item);
                            }
                            item = string.Empty;
                            break;

                        case Kernel32.CDROM_CD_TEXT_PACK.PERFORMER:
                            if (string.IsNullOrEmpty(item) == false || artists.Count == 0)
                            {
                                artists.Add(item);
                            }
                            item = string.Empty;
                            break;

                        default:
                            item = string.Empty;
                            break;
                        }
                    }
                }
            }
            catch (IndexOutOfRangeException)
            {
            }
            finally
            {
            }

            //int max = titles.Count;
            //if (artists.Count != 0 && max > artists.Count)
            //    max = artists.Count;
            //if (genres.Count != 0 && max > genres.Count)
            //    max = genres.Count;

            if (numTracks > 0)
            {
                string mainTitle  = (titles.Count > 0) ? titles[0] : null;
                string mainArtist = (artists.Count > 0) ? artists[0] : null;
                string mainGenre  = (genres.Count > 0) ? genres[0] : null;

                for (int i = 1; i <= numTracks; i++)
                {
                    Track track = new Track();
                    track.Index = i;

                    try
                    {
                        if (titles.Count > i ||
                            titles.Count > i ||
                            titles.Count > i)
                        {
                            if (titles.Count > i)
                            {
                                track.Title = titles[i];
                            }
                            if (artists.Count > i)
                            {
                                track.Artist = artists[i];
                            }
                            if (genres.Count > i)
                            {
                                track.Genre = genres[i];
                            }

                            if (!string.IsNullOrEmpty(mainTitle))
                            {
                                track.Album = mainTitle;
                            }
                            if (string.IsNullOrEmpty(track.Artist) &&
                                !string.IsNullOrEmpty(mainArtist))
                            {
                                track.Artist = mainArtist;
                            }
                        }
                    }
                    catch { }

                    tracks.Add(track);
                }
            }

            return(tracks);
        }