Justin
2004-02-05 00:26:06 UTC
Anyone have an example of how to read cd text data? I am trying to use the IOCTL_CDROM_READ_TOC_EX command to return CDROM_TOC_CD_TEXT_DATA, but all I have been able to get is various errors: "The device is not ready" and "Incorrect Function" (each error with the same compiled exe but on different machines). Using the same drive handle and same audio CDs I have successfully read Track ISRCs and basic TOC info using IOCTL_CDROM_READ_Q_CHANNEL and IOCTL_CDROM_READ_TOC.
What I do is I get a handle to my cd-rom, then I lock the cd-rom drive using IOCTL_CDROM_MEDIA_REMOVAL then I read the TOC from the cd using IOCTL_CDROM_READ_TOC then I loop through each of the songs from FirstTrack to LastTrack in the TOC and I get the ISRC using IOCTL_CDROM_READ_Q_CHANNEL and print it out and get the text data using IOCTL_CDROM_READ_TOC_EX and would print it out if it worked through each iteration. Then I unlock the cd drive.
Below is the code I have in C++ that I am trying to use but getting the errors (DeviceIOControl returns FALSE and I get the text of the error with GetLastError()):
hDevice is a a HANDLE to my cd rom drive retrieved with the CreateFile function. I know it is a valid handle because I can successfully open and close the cd drive and read the TOC (first & last track numbers and TRACK_DATA items) and read the track ISRCs.
I am also curious if anyone knows how I can figure out the size I should specify of the output buffer for this command. Currently I am just setting it to 255 bytes, but don't know if that is enough or too much or what.
BOOL getTrackTextData(HANDLE& hDevice, UCHAR trackNum, CDROM_TOC_CD_TEXT_DATA& output)
{
CDROM_READ_TOC_EX inBuf;
inBuf.Format = CDROM_READ_TOC_EX_FORMAT_CDTEXT;
inBuf.Reserved1 = 0;
inBuf.Msf = 1;
inBuf.SessionTrack = trackNum;
inBuf.Reserved2 = 0;
inBuf.Reserved3 = 0;
BOOL bResult;
DWORD bytesRet;
bResult = DeviceIoControl(hDevice, IOCTL_CDROM_READ_TOC_EX, &inBuf, sizeof(inBuf), &output, 255, &bytesRet, (LPOVERLAPPED) NULL);
if (bResult)
{
printf("Success with %i bytes returned.\n", bytesRet);
}
return (bResult);
}
the above function is then called with the following (where i is a loop counter and cdDevice is the cd-rom handle):
....
CDROM_TOC_CD_TEXT_DATA trackCDText;
bReturn = getTrackTextData(cdDevice, i, trackCDText);
....
ps. sorry if this is not the best looking code, I am pretty new to c++
Thank You for any help you can provide.
What I do is I get a handle to my cd-rom, then I lock the cd-rom drive using IOCTL_CDROM_MEDIA_REMOVAL then I read the TOC from the cd using IOCTL_CDROM_READ_TOC then I loop through each of the songs from FirstTrack to LastTrack in the TOC and I get the ISRC using IOCTL_CDROM_READ_Q_CHANNEL and print it out and get the text data using IOCTL_CDROM_READ_TOC_EX and would print it out if it worked through each iteration. Then I unlock the cd drive.
Below is the code I have in C++ that I am trying to use but getting the errors (DeviceIOControl returns FALSE and I get the text of the error with GetLastError()):
hDevice is a a HANDLE to my cd rom drive retrieved with the CreateFile function. I know it is a valid handle because I can successfully open and close the cd drive and read the TOC (first & last track numbers and TRACK_DATA items) and read the track ISRCs.
I am also curious if anyone knows how I can figure out the size I should specify of the output buffer for this command. Currently I am just setting it to 255 bytes, but don't know if that is enough or too much or what.
BOOL getTrackTextData(HANDLE& hDevice, UCHAR trackNum, CDROM_TOC_CD_TEXT_DATA& output)
{
CDROM_READ_TOC_EX inBuf;
inBuf.Format = CDROM_READ_TOC_EX_FORMAT_CDTEXT;
inBuf.Reserved1 = 0;
inBuf.Msf = 1;
inBuf.SessionTrack = trackNum;
inBuf.Reserved2 = 0;
inBuf.Reserved3 = 0;
BOOL bResult;
DWORD bytesRet;
bResult = DeviceIoControl(hDevice, IOCTL_CDROM_READ_TOC_EX, &inBuf, sizeof(inBuf), &output, 255, &bytesRet, (LPOVERLAPPED) NULL);
if (bResult)
{
printf("Success with %i bytes returned.\n", bytesRet);
}
return (bResult);
}
the above function is then called with the following (where i is a loop counter and cdDevice is the cd-rom handle):
....
CDROM_TOC_CD_TEXT_DATA trackCDText;
bReturn = getTrackTextData(cdDevice, i, trackCDText);
....
ps. sorry if this is not the best looking code, I am pretty new to c++
Thank You for any help you can provide.