Microsoft KB Archive/235128

{|
 * width="100%"|

INFO: Understanding Device Names and Symbolic Links

 * }

Q235128

-

The information in this article applies to:


 * Microsoft Windows 2000 Advanced Server
 * Microsoft Windows 2000 Server
 * Microsoft Windows 2000 Professional
 * Microsoft Windows NT Server version 4.0
 * Microsoft Windows NT Workstation version 4.0

-

SUMMARY
Devices like hard disks, serial ports, and parallel ports have an internal Windows NT device name and may optionally have an MS-DOS device name. These names are located in the Windows NT Object Manager's namespace. While Windows NT itself and kernel-mode drivers use NT device names, Win32 programs must use the MS-DOS device names. The MS-DOS device name is a symbolic link to the underlying NT device name. This article explains device names, symbolic links, and how Win32 programs can create and remove symbolic links.

Internal NT Device Names
When a kernel-mode device driver is loaded, its initialization routine registers a device name with Windows NT's Object Manager. This name is referred to as the Windows NT device name. The kernel-mode components of Windows NT and kernel-mode drivers reference devices by their Windows NT device names. These names have a format, such as \Device\CDRom0 and \Device\Serial0 and also exist in the \device directory of the Object Manager's namespace.

Win32 programs cannot use internal Windows NT device names to access devices because the Win32 subsystem and Win32 API require the more familiar drive letters and MS-DOS device names, such as A:, C:, COM1:, and LPT1:. Although Win32 programs may not use Windows NT device names, they can however, define and remove MS-DOS device names to access devices. They can also retrieve the internal Windows NT device name associated with an MS-DOS device name. The example code in the "Symbolic Links" section of this article demonstrates how to do this.

To gain a better understanding of how the Object Manager tracks names to devices and other system objects, you can view the Object Manager's namespace with the WinObj.exe tool in the Platform SDK.

MS-DOS Device Names
Win32 programs use devices like drives, serial ports, and parallel ports through their MS-DOS device names. For disk drives, these are drive letters like A: and C:. For serial and parallel ports these are names like COM1:, COM2:, and LPT1:. Like Windows NT device names, these names reside in the Object Manager's namespace, but in the \?? directory, which is visible to user-mode Win32 programs.

What makes MS-DOS device names different from Windows NT device names is that they are not used by the Windows NT kernel or kernel-mode drivers. Their purpose is simply to refer to Windows NT device names so that Win32 programs can use the familiar drive letters and device names; for example, COM1:, to access the Windows NT devices. Thus, MS-DOS device names are called "symbolic links" to Windows NT device names. That is, an MS-DOS device name exists in the Object Manager's \?? directory and points to a Windows NT device name in the Object Manager's \device directory.

Each MS-DOS device name can point to at most one internal Windows NT device. However, multiple MS-DOS device names can point to a single device. For example, while C: can only point to a single partition, it is possible to have two or more drive letters, like D:, E:, and Z:, point to the same partition.

Symbolic Links
Symbolic links created by the system persist across computer restarts because they are stored in the registry. Applications may also create symbolic links with the DefineDosDevice API. These links are valid only until the computer is restarted or turned off unless the registry keys containing information about the links are updated.

There can be multiple symbolic links to a Windows NT device name. However, only the MS-DOS device name that the system initially assigned to the internal Windows NT device remains across reboots. Therefore, it is possible to create additional symbolic links that assign multiple drive letters to a single CD-ROM drive, but the additional drive letters will only remain until the machine is turned off or restarted.

Win32 programs can retrieve the Windows NT device name that is associated with a given MS-DOS device name by calling QueryDosDevice with the MS-DOS device name. Following is example code that shows how to do this:

char szNtDeviceName[MAX_PATH];

if (QueryDosDevice ("C:", szNtDeviceName, MAX_PATH)) {  printf ("C: is linked to %s\n", szNtDeviceName); } Win32 programs can create and delete symbolic links by calling DefineDosDevice. To create a symbolic link, call DefineDosDevice with the DDD_RAW_TARGET_PATH flag. To remove a symbolic link, call it with the DDD_REMOVE_DEFINITION and DDD_RAW_TARGET_PATH flags. The following sample program demonstrates both of these operations:

/* DDD

This sample shows how to associate an MS-DOS device name with a      Windows NT device name. The association is a symbolic link between device names stored in the Object Manager's namespace. Applications use the MS-DOS device name, but Windows NT and kernel-mode drivers use the Windows NT device name.

Usage: ddd   ddd -r 

NOTE: If the MS-DOS device name is a driver letter, the trailing backlash is not accepted by DefineDosDevice or QueryDosDevice.

NOTE: The MS-DOS device name is defined only until the computer is   restarted.

To make the drive letter associations permanent on Window NT 4.0, you have to update HKEY_LOCAL_MACHINE\SYSTEM\DISK\Information. However, the contents of the value are undocumented.

On Windows 2000, you have to use the Volume Mount Point APIs.

/* during build. */
 * 1) define WIN32_LEAN_AND_MEAN /* Reduce number of system headers parsed */


 * 1) include 
 * 2) include 

void main (int argc, char **argv) {  char * pszDosDeviceName, * pszNtDeviceName;

bool fRemoveDeviceName = false; bool fResult;

/*     Command-line parsing. 1) Make sure correct number of arguments are supplied.       2) See if you should add or remove the MS-DOS Device Name. */   if (argc != 3) {     printf("\nusage: %s      to add\n",             argv[0]); printf("usage: %s [-r]                to remove\n",             argv[0]); printf("\n\texample: %s d: \\device\\cdrom0\n", argv[0]); return; }

fRemoveDeviceName = !lstrcmpi (argv[1], "-r");

/* Now, add/remove the DOS device name. */   if (fRemoveDeviceName) {     /*         Remove the MS-DOS device name. First, get the name of the Windows NT device from the symbolic link, then delete the symbolic link. */      pszDosDeviceName = argv[2];

pszNtDeviceName = (char *)LocalAlloc (LPTR, MAX_PATH);

fResult = QueryDosDevice (pszDosDeviceName, pszNtDeviceName,                               MAX_PATH); if (fResult) {        fResult = DefineDosDevice (DDD_RAW_TARGET_PATH|                                    DDD_REMOVE_DEFINITION|                                    DDD_EXACT_MATCH_ON_REMOVE,                                    pszDosDeviceName, pszNtDeviceName); }     if (!fResult) printf("error %lu: could not remove %s\n",               GetLastError, pszDosDeviceName);

LocalFree (pszNtDeviceName); }  else {     /* Add the DOS device name */

pszDosDeviceName = argv[1]; pszNtDeviceName = argv[2];

fResult = DefineDosDevice (DDD_RAW_TARGET_PATH, pszDosDeviceName,                                pszNtDeviceName); if (!fResult) printf("error %lu: could not link %s to %s\n",               GetLastError, pszDosDeviceName, pszNtDeviceName); }

} Additional query words: DOS DEVICE

Keywords : kbKernBase kbOSWinNT400 kbOSWin2000 kbSDKPlatform kbSDKWin32 _IK kbGrpDSKernBase

Issue type : kbinfo

Technology : kbWinNTsearch kbWinNTWsearch kbWinNTW400 kbWinNTW400search kbWinNT400xsearch kbwin2000AdvServ kbwin2000AdvServSearch kbwin2000Serv kbWinNTSsearch kbWinNTS400xsearch kbWinNTS400 kbwin2000ServSearch kbwin2000Search kbwin2000ProSearch kbwin2000Pro kbWinAdvServSearch