From: Joe Moriarty [joe.moriarty@east.sun.com] Sent: Tuesday, May 08, 2001 4:06 PM To: NT Developers Interest List Cc: SunPCI Team; NT Development List Subject: [ntdev] Bug in the cdrom.sys driver for Win2K. 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: GlennEverhart@FirstUSA.com To unsubscribe send a blank email to leave-ntdev-247T@lists.osr.com