Hi Everybody,
I try to develop some application in order to mount a vitual CDDA from BIN and CUE files. According to what I read here, I commited some mistakes by using IOCTLs instead of SCSI miniport, but the driver is almost finished except a few things I would like to know.
After adding the new device, my driver responds appropriate to IOCTL_CDROM_GET_DRIVE_GEOMETRY and IOCTL_CDROM_READ_TOC and all tracks are perfectly shown in Explorer as CDA files, but when I perform double-click on anyone of these, the following happens:
Winamp: Try to play but there is no sound because IOCTL_CDROM_RAW_READ is never send to my driver.
WMPlayer: IOCTL_CDROM_RAW_READ is sent to my driver but if longToRead = pRawInfo->SectorCount * CDROM_RAW_SECTOR_SIZE; Windows crashes when VikingCDReadOffset function is executed. Indeed, Windows crashes after returing to WMPlayer code, not into my reading function.
This is the case for IOCTL_CDROM_RAW_READ:
case IOCTL_CDROM_RAW_READ:
VikingCDLogS(“IOCTL_CDROM_RAW_READ”);
{
ULONG lengthIB = irpSp->Parameters.DeviceIoControl.InputBufferLength;
ULONG lengthOB = irpSp->Parameters.DeviceIoControl.OutputBufferLength;
ULONG lengthToRead = 0;
PRAW_READ_INFO pRawInfo = (PRAW_READ_INFO) Irp->AssociatedIrp.SystemBuffer;
VikingCDLogSL("SectorCount = ", pRawInfo->SectorCount);
VikingCDLogSL("lengthOB = ", lengthOB);
VikingCDLogSL("DiskOffset LowPart = ", pRawInfo->DiskOffset.LowPart);
VikingCDLogSL("DiskOffset HighPart = ", pRawInfo->DiskOffset.HighPart);
//VikingCDLogSL("DiskOffset QuadPart = ", pRawInfo->DiskOffset.QuadPart);
if ( lengthIB >= sizeof( RAW_READ_INFO ) && lengthOB >= ( pRawInfo->SectorCount * CDROM_RAW_SECTOR_SIZE ))
{
lengthIB = sizeof( RAW_READ_INFO );
lengthToRead = pRawInfo->SectorCount * CDROM_RAW_SECTOR_SIZE;
if (NT_SUCCESS(VikingCDReadOffset(&pRawInfo->DiskOffset, Irp->AssociatedIrp.SystemBuffer, lengthToRead, &diskExtension->DataFileName)))
{
VikingCDLogS(“RAW READ WORKSFINE”);
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = lengthOB;
break;
}else
{
VikingCDLogS(“RAW READ WORKSPOOR”);
Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = STATUS_DEVICE_NOT_READY;
break;
}
}
}
Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
break;
I use 2352 for CDROM_RAW_SECTOR_SIZE. My VikingCDReadOffset function is the following:
NTSTATUS VikingCDReadOffset(PLARGE_INTEGER offset, PVOID dest, ULONG length,
PUNICODE_STRING pFileName)
{
IO_STATUS_BLOCK IoStatusBlock;
OBJECT_ATTRIBUTES ObjectAttributes;
NTSTATUS status;
HANDLE FileHandle;
VikingCDLogS(“begin VikingCDReadOffset”);
if (pFileName == NULL)
return STATUS_DEVICE_NOT_READY;
InitializeObjectAttributes(
&ObjectAttributes,
pFileName,//&fileName,
OBJ_CASE_INSENSITIVE, // attributes
NULL,
NULL
);
status = ZwCreateFile(
&FileHandle,
GENERIC_READ,
&ObjectAttributes,
&IoStatusBlock,
NULL,
FILE_ATTRIBUTE_NORMAL,
FILE_SHARE_READ, // share read so we can open the same file more than once
FILE_OPEN,
FILE_SYNCHRONOUS_IO_NONALERT,
NULL, /* optional */
0
);
if (NT_SUCCESS(status))
{
VikingCDLogS(“open success”);
// good!!!
// write something out and then close the file
status = ZwReadFile(
FileHandle,NULL,NULL,NULL,
&IoStatusBlock,dest,length,offset,NULL);
if (NT_SUCCESS(status))
VikingCDLogS(“read success”);
else
VikingCDLogS(“read fail”);
ZwClose(FileHandle);
}
return status;
}
I have no idea what happens. It is very strange, because if I assign a low value to lengthToRead such as 4, Windows doesn’t crashes, but obviously there is no sound, just noise.
I have some LOGs of the IOCTL requested to my driver. Some of them are not implemented yet. I don’t know if it is the cause, but if CDROM_RAW_SECTOR_SIZE is sent to my driver, why cannot I read? Do I need to add some special offset? As you can see in VikingCDReadOffset, If offset 0x8000 is requested, for example, I find that position from the begining of the BIN file. I don’t know if it is correct.
This is the LOG when I use a low value for lengthToRead (as I above said, when I use the right value system crashes, so I don’t get any LOG, that is why I used lengthToRead = 4: just for showing the IOCTL sent):
-----Loading Driver-----
??\VirtualVikingCD00
\Device\VirtualVikingCD00
-----Adding Device in responce to IOCTL-----
??\A:
\Device\VirtualVikingCD000
Setting Image Format to VikingCD
ERROR: unrecognized IOCTL 4D0008
IOCTL_CDROM_GET_DRIVE_GEOMETRY
IOCTL_CDROM_GET_LAST_SESSION (NO IMPLEMENTED YET; IT RETURNS NOTHING)
IOCTL_CDROM_GET_DRIVE_GEOMETRY
IOCTL_CDROM_READ_TOC
ERROR: unrecognized IOCTL 41010
ERROR: unrecognized IOCTL 4D0008
IOCTL_CDROM_READ_Q_CHANNEL (NO IMPLEMENTED YET; IT RETURNS NOTHING)
IOCTL_CDROM_READ_Q_CHANNEL (NO IMPLEMENTED YET; IT RETURNS NOTHING)
IOCTL_CDROM_GET_VOLUME (NO IMPLEMENTED YET; IT RETURNS NOTHING)
IOCTL_CDROM_GET_VOLUME (NO IMPLEMENTED YET; IT RETURNS NOTHING)
IOCTL_CDROM_READ_Q_CHANNEL (NO IMPLEMENTED YET; IT RETURNS NOTHING)
IOCTL_CDROM_READ_Q_CHANNEL (NO IMPLEMENTED YET; IT RETURNS NOTHING)
IOCTL_CDROM_GET_VOLUME (NO IMPLEMENTED YET; IT RETURNS NOTHING)
IOCTL_CDROM_GET_VOLUME (NO IMPLEMENTED YET; IT RETURNS NOTHING)
IOCTL_CDROM_GET_DRIVE_GEOMETRY
ERROR: unrecognized IOCTL 2D1400
ERROR: unrecognized IOCTL 4D0008
ERROR: unrecognized IOCTL 2D1400
ERROR: unrecognized IOCTL 4D0008
IOCTL_CDROM_RAW_READ
SectorCount = 10
lengthOB = 9300
DiskOffset LowPart = 0
DiskOffset HighPart = 0
begin VikingCDReadOffset
open success
read success
RAW READ WORKSFINE
IOCTL_CDROM_RAW_READ
SectorCount = F
lengthOB = 9300
DiskOffset LowPart = 8000
DiskOffset HighPart = 0
begin VikingCDReadOffset
open success
read success
RAW READ WORKSFINE
IOCTL_CDROM_RAW_READ
SectorCount = E
lengthOB = 9300
DiskOffset LowPart = F800
DiskOffset HighPart = 0
begin VikingCDReadOffset
open success
read success
RAW READ WORKSFINE
IOCTL_CDROM_RAW_READ
SectorCount = D
lengthOB = 9300
DiskOffset LowPart = 16800
DiskOffset HighPart = 0
begin VikingCDReadOffset
open success
read success
RAW READ WORKSFINE
IOCTL_CDROM_RAW_READ
SectorCount = C
lengthOB = 9300
DiskOffset LowPart = 1D000
DiskOffset HighPart = 0
begin VikingCDReadOffset
open success
read success
RAW READ WORKSFINE
IOCTL_CDROM_RAW_READ
SectorCount = B
lengthOB = 9300
DiskOffset LowPart = 23000
DiskOffset HighPart = 0
begin VikingCDReadOffset
open success
read success
RAW READ WORKSFINE
IOCTL_CDROM_RAW_READ
SectorCount = A
lengthOB = 9300
DiskOffset LowPart = 28800
DiskOffset HighPart = 0
begin VikingCDReadOffset
open success
read success
RAW READ WORKSFINE
IOCTL_CDROM_RAW_READ
SectorCount = 9
lengthOB = 9300
DiskOffset LowPart = 2D800
DiskOffset HighPart = 0
begin VikingCDReadOffset
open success
read success
RAW READ WORKSFINE
IOCTL_CDROM_RAW_READ
SectorCount = 8
lengthOB = 9300
DiskOffset LowPart = 32000
DiskOffset HighPart = 0
begin VikingCDReadOffset
open success
read success
RAW READ WORKSFINE
IOCTL_CDROM_RAW_READ
SectorCount = 7
lengthOB = 9300
DiskOffset LowPart = 36000
DiskOffset HighPart = 0
begin VikingCDReadOffset
open success
read success
RAW READ WORKSFINE
IOCTL_CDROM_RAW_READ
SectorCount = 6
lengthOB = 9300
DiskOffset LowPart = 39800
DiskOffset HighPart = 0
begin VikingCDReadOffset
open success
read success
RAW READ WORKSFINE
IOCTL_CDROM_RAW_READ
SectorCount = 5
lengthOB = 9300
DiskOffset LowPart = 3C800
DiskOffset HighPart = 0
begin VikingCDReadOffset
open success
read success
RAW READ WORKSFINE
IOCTL_CDROM_RAW_READ
SectorCount = 4
lengthOB = 9300
DiskOffset LowPart = 3F000
DiskOffset HighPart = 0
begin VikingCDReadOffset
open success
read success
RAW READ WORKSFINE
IOCTL_CDROM_RAW_READ
SectorCount = 3
lengthOB = 9300
DiskOffset LowPart = 41000
DiskOffset HighPart = 0
begin VikingCDReadOffset
open success
read success
RAW READ WORKSFINE
IOCTL_CDROM_RAW_READ
SectorCount = 2
lengthOB = 9300
DiskOffset LowPart = 42800
DiskOffset HighPart = 0
begin VikingCDReadOffset
open success
read success
RAW READ WORKSFINE
IOCTL_CDROM_RAW_READ
SectorCount = 1
lengthOB = 9300
DiskOffset LowPart = 43800
DiskOffset HighPart = 0
begin VikingCDReadOffset
open success
read success
Up to here, Sector count are always 10:
begin VikingCDReadOffset
open success
read success
RAW READ WORKSFINE
IOCTL_CDROM_RAW_READ
SectorCount = 10
lengthOB = 9300
DiskOffset LowPart = 8F000
DiskOffset HighPart = 0
begin VikingCDReadOffset
open success
read success
RAW READ WORKSFINE
IOCTL_CDROM_RAW_READ
SectorCount = 10
lengthOB = 9300
DiskOffset LowPart = 96800
DiskOffset HighPart = 0
begin VikingCDReadOffset
open success
read success
RAW READ WORKSFINE
IOCTL_CDROM_RAW_READ
SectorCount = 10
lengthOB = 9300
DiskOffset LowPart = 9E000
DiskOffset HighPart = 0
begin VikingCDReadOffset
open success
read success
RAW READ WORKSFINE
IOCTL_CDROM_RAW_READ
SectorCount = 10
lengthOB = 9300
DiskOffset LowPart = A5800
DiskOffset HighPart = 0
begin VikingCDReadOffset
open success
read success
RAW READ WORKSFINE
IOCTL_CDROM_RAW_READ
SectorCount = 10
lengthOB = 9300
DiskOffset LowPart = AD000
DiskOffset HighPart = 0
begin VikingCDReadOffset
open success
read success
RAW READ WORKSFINE
IOCTL_CDROM_RAW_READ
SectorCount = 10
lengthOB = 9300
DiskOffset LowPart = B4800
DiskOffset HighPart = 0
If you compare the LOG with source above, you will see that it is easy to understand what was executed. Remember, it works only if I only read just 4 bytes…
If it is possible mount & read from BIN file using IOCTLs, I would like to do it. I don’t intend to continue with this project in order to do something more complicated. Only mounting a virtual drive and reading from the BIN file in order to play a standard CD AUDIO ripped.
If someone can help me, I will be glad. Thanks in advance.
Christian D’Orazio