Here is the snipit of code in error from the DDK for the cdrom.sys driver.
The module name is cdrom.c.
The cdrom.sys driver does not assign the suffix number correctly to the
device name/symbolic link name when there is another cdrom driver installed
in the system. The ‘CdRomCounter’ variable below is used to generate the
device name and symbolic link suffix name below.
Example
//device/cdrom%d where %d is equal to CdRomCounter.
//Snipit of Code Begin
NTSTATUS
CdRomAddDevice(
IN PDRIVER_OBJECT DriverObject,
IN PDEVICE_OBJECT PhysicalDeviceObject
)
/*++
Routine Description:
This routine creates and initializes a new FDO for the corresponding
PDO. It may perform property queries on the FDO but cannot do any
media access operations.
Arguments:
DriverObject - CDROM class driver object.
Pdo - the physical device object we are being added to
Return Value:
status
–*/
{
NTSTATUS status;
PAGED_CODE();
//
// Get the address of the count of the number of cdroms already
initialized.
//
status = CreateCdRomDeviceObject(
DriverObject,
PhysicalDeviceObject,
CdRomCounter);
//
// Note: this always increments CdRomCounter
// it will eventually wrap, and fail additions
// if an existing cdrom has the given number.
// so unlikely that we won’t even bother considering
// this case, since the cure is quite likely worse
// than the symptoms.
//
if(NT_SUCCESS(status)) {
DebugPrint((2, “CDROM.SYS Add #%x succeeded\n”,CdRomCounter));
IoGetConfigurationInformation()->CdRomCount++;
CdRomCounter++;
} else {
DebugPrint((1, “CDROM.SYS Add #%x failed! %x\n”,CdRomCounter,
status));
}
return status;
}
//Snipit of Code End
The CdRomCounter variable is a global counter which is assigned to zero to
begin with. If the CdRom.sys driver was the only driver in the system that
controlled CdRoms for that system, then there is no
problem. But, if there are multiple drivers on a system that control CdRoms
then there is a problem. The code above is using it’s own internal counter
to generate the device names. It does not
call IoGetConfigurationInformation to get the number of CdRomCounts already
seen by the system. An even better solution would be to do what the disk
driver did. This code is taken from a snipit of code from the DDK for the
disk.sys driver. Module Name disk.c, Function Name DiskCreateFdo().
//Snipit of Code Begin
*DeviceCount = 0;
//
// Set up an object directory to contain the objects for this
// device and all its partitions.
//
do {
WCHAR buffer[64];
UNICODE_STRING unicodeDirectoryName;
swprintf(buffer, L"\Device\Harddisk%d", *DeviceCount);
RtlInitUnicodeString(&unicodeDirectoryName, buffer);
InitializeObjectAttributes(&objectAttributes,
&unicodeDirectoryName,
OBJ_CASE_INSENSITIVE | OBJ_PERMANENT,
NULL,
NULL);
status = ZwCreateDirectoryObject(&handle,
DIRECTORY_ALL_ACCESS,
&objectAttributes);
(*DeviceCount)++;
} while((status == STATUS_OBJECT_NAME_COLLISION) ||
(status == STATUS_OBJECT_NAME_EXISTS));
if (!NT_SUCCESS(status)) {
DebugPrint((1, “DiskCreateFdo: Could not create directory - %lx\n”,
status));
return(status);
}
//
// When this loop exits the count is inflated by one - fix that.
//
(*DeviceCount)–;
//
// Claim the device.
//
lowerDevice = IoGetAttachedDeviceReference(PhysicalDeviceObject);
status = ClassClaimDevice(lowerDevice, FALSE);
if (!NT_SUCCESS(status)) {
ZwMakeTemporaryObject(handle);
ZwClose(handle);
ObDereferenceObject(lowerDevice);
return status;
}
//
// Create a device object for this device. Each physical disk will
// have at least one device object. The required device object
// describes the entire device. Its directory path is
// \Device\HarddiskN\Partition0, where N = device number.
//
status = DiskGenerateDeviceName(TRUE,
*DeviceCount,
0,
NULL,
NULL,
&deviceName);
if(!NT_SUCCESS(status)) {
DebugPrint((1, “DiskCreateFdo - couldn’t create name %lx\n”,
status));
goto DiskCreateFdoExit;
}
// End Snipit of Code
The disk driver above first searches the device name space looking for an
open suffix number to use. In this case:
swprintf(buffer, L"\Device\Harddisk%d", *DeviceCount);
It will not come out of this while loop until it has found an open device
name. This will ensure that
if there is another disk driver in the system assigning device names that
the two will not interfere with each other in assigning those names.
In conclusion, if you are writing your own cdrom device driver and you need
to use Microsoft’s cdrom driver as well. Then you will have a problem with
the two assigning identical device names because Microsoft’s driver only
assumes that it is the only driver assigning device names for cdroms. In my
case, my cdrom driver loaded first and grabbed \Device\CdRom0, then
Microsoft’s cdrom driver loaded and tried to assign \Device\CdRom0 for the
USB cdrom attached to our system. It failed it’s AddDevice entry because it
was already assigned to the other cdrom in the system controlled by my
driver. The user is unable to access the cdrom on the USB bus. Major
problem. If I could get around PnP driver order loading, then I could fix
this by loading my driver second. But my driver is loaded first even when
the tag ordering value I supply in the SCSI CDROM Group is after the
cdrom.sys drivers tag value.
I have tried Service Pack 1 and still get the same problem. I sure hope
this can get fixed for Service Pack 2.
Thanks,
Joe
You are currently subscribed to ntdev as: $subst(‘Recip.EmailAddr’)
To unsubscribe send a blank email to leave-ntdev-$subst(‘Recip.MemberIDChar’)@lists.osr.com