As Maxim properly stated, the use of DeviceInterfaces is highly
encouraged. This allows you to have as many of these attached as you
need, and removes the need to try to figure out how to uniquely name the
device. The DDK contains sample code for CDROM.SYS, which both creates
a legacy name (\.\CdromN) and a device interface (using GUID
CdRomClassGuid from ntddstor.h).
One simple reason to not use the legacy names is that there is no
guarantee that they will stay the same for a given device. The
interface names (at least how CDROM uses them) *do* stay the same across
system reboots. In addition, user mode and kernel mode apps can
register for device interface arrivals and removals, and you can delay
the creation/deletion of the device interfaces until the device is
actually ready to accept IO, too! So, the use of device interfaces has
many advantages.
The disadvantage is that it is difficult to start enumerating these
devices. Once you know the key routines, however, the code is easy to
write. To enumerate the devices using the device interface, look at the
following three routines in MSDN:
SetupDiGetClassDevs()
SetupDiEnumDeviceInterfaces()
SetupDiGetDeviceInterfaceDetail()
Here’s some untested, no-warranty psuedo-code for how to find all given
devices. Closing any opened handles and freeing allocated memory is
specifically left as an exercise for the reader.
========================================================================
How to enumerate all devices of a class (such as CDROM):
// SetupDiGetClassDevs – gets the set of all devices of a specified
class,
// such as CdRomClassGuid (ntddstor.h).
GUID cdromGuid = CdRomClassGuid;
deviceInfoHandle =
SetupDiGetClassDevs(&cdromGuid, NULL, NULL,
(DIGCF_PRESENT | DIGCF_INTERFACEDEVICE));
for (int i = 0; i < 0x40000; i++)
{
SP_DEVICE_INTERFACE_DATA diData;
ULONG requiredSize = 0;
DWORD error;
RtlZeroMemory(&diData, sizeof(SP_DEVICE_INTERFACE_DATA));
diData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
// SetupDiEnumDeviceInterfaces() – enumerates devices with a
specific
// interface GUID, such as CdRomClassGuid (ntddstor.h).
// request the Nth device – nonzero return on success
if (!SetupDiEnumDeviceInterfaces(deviceInfoHandle, 0,
&cdromGuid,
currentDeviceIndex, &diData))
{
DWORD error = GetLastError();
if (error == ERROR_NO_MORE_ITEMS)
{
break;
}
}
// SetupDiGetDeviceInterfaceDetail() – using the
DeviceInterfaceDetail
// returned above, call this twice (first to determine size
required,
// then to get info) to get the PNP path to the device.
// should never succeed with NULL buffer…
if (SetupDiGetDeviceInterfaceDetails(deviceInfoHandle, &diData,
NULL,
0, &requiredSize, NULL))
{
// throw Exception
}
if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
{
// throw Exception – the error must always be
INSUFFICIENT_BUFFER
}
if (requiredSize == 0)
{
// throw Exception – size should never, ever be zero!
}
// allocate diDetails. Add sizeof(TCHAR) to ensure NULL
termination.
diDetails = Alloc(requiredSize+sizeof(WCHAR));
if (!SetupDiGetDeviceInterfaceDetails(deviceInfoHandle, &diData,
diDetails, requiredSize,
&updatedSize, NULL))
{
// thow Exception - should succeed this time around
}
// diDetails->DevicePath is a NULL-terminated unicode string
// save (or use) that string for opening the device directly
}
========
There really should be a FAQ, and this one of the questions in that FAQ.

.
-----Original Message-----
From: Maxim S. Shatskih [mailto:xxxxx@storagecraft.com]
Sent: Monday, December 29, 2003 2:26 AM
Subject: Re: Device Name
XXX1 and so on until XXX4. My question is related to driver that how
can i
ensure that for first device i give the name as XXX0 and for next
device
as XXX1 and so on in my driver for any number of devices that are
present.
If symbolic name XXX0 already exists than i want the next name to be
XXX1
Use the device interfaces, it is better 
If you really need the legacy symlinks - then try to create XXX0, then
XXX1,
then so on - till STATUS_OBJECT_NAME_COLLISION is returned.
Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
xxxxx@storagecraft.com
http://www.storagecraft.com