Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

dev2dos.c File Reference

#include <ntrtlp.h>
#include <mountdev.h>

Go to the source code of this file.

Classes

struct  _DEVICE_NAME_ENTRY

Typedefs

typedef _DEVICE_NAME_ENTRY DEVICE_NAME_ENTRY
typedef _DEVICE_NAME_ENTRYPDEVICE_NAME_ENTRY

Functions

NTSTATUS QuerySymbolicLink (IN PUNICODE_STRING SymbolicLinkName, OUT PUNICODE_STRING LinkTarget)
NTSTATUS QueryDeviceNameForPath (IN PUNICODE_STRING Path, OUT PUNICODE_STRING DeviceName)
NTSTATUS OpenDeviceReparseIndex (IN PUNICODE_STRING DeviceName, OUT PHANDLE Handle)
BOOLEAN IsVolumeName (IN PUNICODE_STRING Name)
NTSTATUS GetNextReparseVolumePath (IN HANDLE Handle, OUT PUNICODE_STRING Path)
NTSTATUS FindPathForDevice (IN PUNICODE_STRING StartingPath, IN PUNICODE_STRING DeviceName, IN OUT PLIST_ENTRY DevicesInPath, OUT PUNICODE_STRING FinalPath)
NTSTATUS RtlVolumeDeviceToDosName (IN PVOID VolumeDeviceObject, OUT PUNICODE_STRING DosName)


Typedef Documentation

typedef struct _DEVICE_NAME_ENTRY DEVICE_NAME_ENTRY
 

typedef struct _DEVICE_NAME_ENTRY * PDEVICE_NAME_ENTRY
 

Referenced by FindPathForDevice().


Function Documentation

NTSTATUS FindPathForDevice IN PUNICODE_STRING  StartingPath,
IN PUNICODE_STRING  DeviceName,
IN OUT PLIST_ENTRY  DevicesInPath,
OUT PUNICODE_STRING  FinalPath
 

Definition at line 454 of file dev2dos.c.

References _DEVICE_NAME_ENTRY::DeviceName, ExAllocatePool, ExFreePool(), GetNextReparseVolumePath(), _DEVICE_NAME_ENTRY::ListEntry, NT_SUCCESS, NTSTATUS(), OpenDeviceReparseIndex(), PagedPool, path, PDEVICE_NAME_ENTRY, QueryDeviceNameForPath(), RtlEqualUnicodeString(), and TRUE.

Referenced by RtlVolumeDeviceToDosName().

00463 : 00464 00465 This routine finds a path (if any) to the given device that begins 00466 with the given starting path. The final path returned includes the 00467 starting path. 00468 00469 Arguments: 00470 00471 StartingPath - Supplies the path to begin the search on. 00472 00473 DeviceName - Supplies the device name whose path we are searching for. 00474 00475 DevicesInPath - Supplies a list of the devices in all proper prefixes 00476 of the path. 00477 00478 FinalPath - Returns the final path to the given device. 00479 00480 Return Value: 00481 00482 NTSTATUS 00483 00484 --*/ 00485 00486 { 00487 NTSTATUS status; 00488 UNICODE_STRING startingDeviceName; 00489 PLIST_ENTRY l; 00490 PDEVICE_NAME_ENTRY entry; 00491 HANDLE h; 00492 UNICODE_STRING path, newStart; 00493 00494 status = QueryDeviceNameForPath(StartingPath, &startingDeviceName); 00495 if (!NT_SUCCESS(status)) { 00496 return status; 00497 } 00498 00499 if (RtlEqualUnicodeString(DeviceName, &startingDeviceName, TRUE)) { 00500 ExFreePool(startingDeviceName.Buffer); 00501 FinalPath->Length = StartingPath->Length; 00502 FinalPath->MaximumLength = FinalPath->Length + sizeof(WCHAR); 00503 FinalPath->Buffer = ExAllocatePool(PagedPool, 00504 FinalPath->MaximumLength); 00505 if (!FinalPath->Buffer) { 00506 return STATUS_INSUFFICIENT_RESOURCES; 00507 } 00508 00509 RtlCopyMemory(FinalPath->Buffer, StartingPath->Buffer, 00510 FinalPath->Length); 00511 FinalPath->Buffer[FinalPath->Length/sizeof(WCHAR)] = 0; 00512 00513 return STATUS_SUCCESS; 00514 } 00515 00516 for (l = DevicesInPath->Flink; l != DevicesInPath; l = l->Flink) { 00517 entry = CONTAINING_RECORD(l, DEVICE_NAME_ENTRY, ListEntry); 00518 if (RtlEqualUnicodeString(&entry->DeviceName, &startingDeviceName, 00519 TRUE)) { 00520 00521 ExFreePool(startingDeviceName.Buffer); 00522 return STATUS_UNSUCCESSFUL; 00523 } 00524 } 00525 00526 status = OpenDeviceReparseIndex(&startingDeviceName, &h); 00527 if (!NT_SUCCESS(status)) { 00528 ExFreePool(startingDeviceName.Buffer); 00529 return status; 00530 } 00531 00532 entry = ExAllocatePool(PagedPool, sizeof(DEVICE_NAME_ENTRY)); 00533 if (!entry) { 00534 ZwClose(h); 00535 ExFreePool(startingDeviceName.Buffer); 00536 return STATUS_INSUFFICIENT_RESOURCES; 00537 } 00538 entry->DeviceName = startingDeviceName; 00539 InsertTailList(DevicesInPath, &entry->ListEntry); 00540 00541 for (;;) { 00542 00543 status = GetNextReparseVolumePath(h, &path); 00544 if (!NT_SUCCESS(status)) { 00545 break; 00546 } 00547 newStart.Length = StartingPath->Length + path.Length; 00548 newStart.MaximumLength = newStart.Length + sizeof(WCHAR); 00549 newStart.Buffer = ExAllocatePool(PagedPool, newStart.MaximumLength); 00550 if (!newStart.Buffer) { 00551 ExFreePool(path.Buffer); 00552 status = STATUS_INSUFFICIENT_RESOURCES; 00553 break; 00554 } 00555 00556 RtlCopyMemory(newStart.Buffer, StartingPath->Buffer, 00557 StartingPath->Length); 00558 RtlCopyMemory((PCHAR) newStart.Buffer + StartingPath->Length, 00559 path.Buffer, path.Length); 00560 newStart.Buffer[newStart.Length/sizeof(WCHAR)] = 0; 00561 ExFreePool(path.Buffer); 00562 00563 status = FindPathForDevice(&newStart, DeviceName, DevicesInPath, 00564 FinalPath); 00565 ExFreePool(newStart.Buffer); 00566 if (NT_SUCCESS(status)) { 00567 break; 00568 } 00569 } 00570 00571 RemoveEntryList(&entry->ListEntry); 00572 ExFreePool(entry); 00573 ZwClose(h); 00574 ExFreePool(startingDeviceName.Buffer); 00575 00576 return status; 00577 }

NTSTATUS GetNextReparseVolumePath IN HANDLE  Handle,
OUT PUNICODE_STRING  Path
 

Definition at line 326 of file dev2dos.c.

References ExAllocatePool, ExFreePool(), FALSE, Handle, IsVolumeName(), NT_SUCCESS, NTSTATUS(), NULL, PagedPool, TRUE, USHORT, and ZwOpenFile().

Referenced by FindPathForDevice().

00333 : 00334 00335 This routine queries the reparse index for the next volume mount point. 00336 00337 Arguments: 00338 00339 Handle - Supplies the handle. 00340 00341 Path - Returns the path. 00342 00343 00344 Return Value: 00345 00346 NTSTATUS 00347 00348 --*/ 00349 00350 { 00351 NTSTATUS status; 00352 IO_STATUS_BLOCK ioStatus; 00353 FILE_REPARSE_POINT_INFORMATION reparseInfo; 00354 UNICODE_STRING fileId; 00355 OBJECT_ATTRIBUTES oa; 00356 HANDLE h; 00357 PREPARSE_DATA_BUFFER reparse; 00358 UNICODE_STRING volumeName; 00359 ULONG nameInfoSize; 00360 PFILE_NAME_INFORMATION nameInfo; 00361 00362 for (;;) { 00363 00364 status = ZwQueryDirectoryFile(Handle, NULL, NULL, NULL, &ioStatus, 00365 &reparseInfo, sizeof(reparseInfo), 00366 FileReparsePointInformation, TRUE, NULL, 00367 FALSE); 00368 if (!NT_SUCCESS(status)) { 00369 return status; 00370 } 00371 00372 if (reparseInfo.Tag != IO_REPARSE_TAG_MOUNT_POINT) { 00373 continue; 00374 } 00375 00376 fileId.Length = sizeof(reparseInfo.FileReference); 00377 fileId.MaximumLength = fileId.Length; 00378 fileId.Buffer = (PWSTR) &reparseInfo.FileReference; 00379 00380 InitializeObjectAttributes(&oa, &fileId, 0, Handle, NULL); 00381 00382 status = ZwOpenFile(&h, SYNCHRONIZE | FILE_GENERIC_READ, &oa, 00383 &ioStatus, FILE_SHARE_READ | FILE_SHARE_WRITE, 00384 FILE_OPEN_BY_FILE_ID | FILE_OPEN_REPARSE_POINT | 00385 FILE_SYNCHRONOUS_IO_ALERT); 00386 if (!NT_SUCCESS(status)) { 00387 continue; 00388 } 00389 00390 reparse = ExAllocatePool(PagedPool, MAXIMUM_REPARSE_DATA_BUFFER_SIZE); 00391 if (!reparse) { 00392 ZwClose(h); 00393 return STATUS_INSUFFICIENT_RESOURCES; 00394 } 00395 00396 status = ZwFsControlFile(h, NULL, NULL, NULL, &ioStatus, 00397 FSCTL_GET_REPARSE_POINT, NULL, 0, reparse, 00398 MAXIMUM_REPARSE_DATA_BUFFER_SIZE); 00399 if (!NT_SUCCESS(status)) { 00400 ExFreePool(reparse); 00401 ZwClose(h); 00402 continue; 00403 } 00404 00405 volumeName.Length = reparse->MountPointReparseBuffer.SubstituteNameLength - 00406 sizeof(WCHAR); 00407 volumeName.MaximumLength = volumeName.Length + sizeof(WCHAR); 00408 volumeName.Buffer = (PWCHAR) 00409 ((PCHAR) reparse->MountPointReparseBuffer.PathBuffer + 00410 reparse->MountPointReparseBuffer.SubstituteNameOffset); 00411 volumeName.Buffer[volumeName.Length/sizeof(WCHAR)] = 0; 00412 00413 if (!IsVolumeName(&volumeName)) { 00414 ExFreePool(reparse); 00415 ZwClose(h); 00416 continue; 00417 } 00418 00419 ExFreePool(reparse); 00420 00421 nameInfoSize = 1024; 00422 nameInfo = ExAllocatePool(PagedPool, nameInfoSize); 00423 if (!nameInfo) { 00424 ZwClose(h); 00425 continue; 00426 } 00427 00428 status = ZwQueryInformationFile(h, &ioStatus, nameInfo, nameInfoSize, 00429 FileNameInformation); 00430 ZwClose(h); 00431 if (!NT_SUCCESS(status)) { 00432 continue; 00433 } 00434 00435 Path->Length = (USHORT) nameInfo->FileNameLength; 00436 Path->MaximumLength = Path->Length + sizeof(WCHAR); 00437 Path->Buffer = ExAllocatePool(PagedPool, Path->MaximumLength); 00438 if (!Path->Buffer) { 00439 ExFreePool(nameInfo); 00440 continue; 00441 } 00442 00443 RtlCopyMemory(Path->Buffer, nameInfo->FileName, Path->Length); 00444 Path->Buffer[Path->Length/sizeof(WCHAR)] = 0; 00445 00446 ExFreePool(nameInfo); 00447 break; 00448 } 00449 00450 return status; 00451 }

BOOLEAN IsVolumeName IN PUNICODE_STRING  Name  ) 
 

Definition at line 296 of file dev2dos.c.

References FALSE, Name, and TRUE.

Referenced by GetNextReparseVolumePath().

00300 { 00301 if (Name->Length == 96 && 00302 Name->Buffer[0] == '\\' && 00303 Name->Buffer[1] == '?' && 00304 Name->Buffer[2] == '?' && 00305 Name->Buffer[3] == '\\' && 00306 Name->Buffer[4] == 'V' && 00307 Name->Buffer[5] == 'o' && 00308 Name->Buffer[6] == 'l' && 00309 Name->Buffer[7] == 'u' && 00310 Name->Buffer[8] == 'm' && 00311 Name->Buffer[9] == 'e' && 00312 Name->Buffer[10] == '{' && 00313 Name->Buffer[19] == '-' && 00314 Name->Buffer[24] == '-' && 00315 Name->Buffer[29] == '-' && 00316 Name->Buffer[34] == '-' && 00317 Name->Buffer[47] == '}') { 00318 00319 return TRUE; 00320 } 00321 00322 return FALSE; 00323 }

NTSTATUS OpenDeviceReparseIndex IN PUNICODE_STRING  DeviceName,
OUT PHANDLE  Handle
 

Definition at line 225 of file dev2dos.c.

References _FILE_OBJECT::DeviceObject, ExAllocatePool, ExFreePool(), _VPB::Flags, Handle, IoGetDeviceObjectPointer(), L, NT_SUCCESS, NTSTATUS(), ObDereferenceObject, PagedPool, RtlInitUnicodeString(), _DEVICE_OBJECT::Vpb, VPB_MOUNTED, and ZwOpenFile().

Referenced by FindPathForDevice().

00232 : 00233 00234 This routine opens the reparse index on the given device. 00235 00236 Arguments: 00237 00238 DeviceName - Supplies the device name. 00239 00240 Handle - Returns the handle. 00241 00242 Return Value: 00243 00244 NTSTATUS 00245 00246 --*/ 00247 00248 { 00249 NTSTATUS status; 00250 PFILE_OBJECT fileObject; 00251 PDEVICE_OBJECT deviceObject; 00252 UNICODE_STRING reparseSuffix, reparseName; 00253 OBJECT_ATTRIBUTES oa; 00254 IO_STATUS_BLOCK ioStatus; 00255 00256 status = IoGetDeviceObjectPointer(DeviceName, FILE_READ_ATTRIBUTES, 00257 &fileObject, &deviceObject); 00258 if (!NT_SUCCESS(status)) { 00259 return status; 00260 } 00261 deviceObject = fileObject->DeviceObject; 00262 00263 if (!deviceObject->Vpb || !(deviceObject->Vpb->Flags&VPB_MOUNTED)) { 00264 ObDereferenceObject(fileObject); 00265 return STATUS_UNSUCCESSFUL; 00266 } 00267 00268 ObDereferenceObject(fileObject); 00269 00270 RtlInitUnicodeString(&reparseSuffix, 00271 L"\\$Extend\\$Reparse:$R:$INDEX_ALLOCATION"); 00272 reparseName.Length = DeviceName->Length + reparseSuffix.Length; 00273 reparseName.MaximumLength = reparseName.Length + sizeof(WCHAR); 00274 reparseName.Buffer = ExAllocatePool(PagedPool, reparseName.MaximumLength); 00275 if (!reparseName.Buffer) { 00276 return STATUS_INSUFFICIENT_RESOURCES; 00277 } 00278 00279 RtlCopyMemory(reparseName.Buffer, DeviceName->Buffer, DeviceName->Length); 00280 RtlCopyMemory((PCHAR) reparseName.Buffer + DeviceName->Length, 00281 reparseSuffix.Buffer, reparseSuffix.Length); 00282 reparseName.Buffer[reparseName.Length/sizeof(WCHAR)] = 0; 00283 00284 InitializeObjectAttributes(&oa, &reparseName, OBJ_CASE_INSENSITIVE, 0, 0); 00285 status = ZwOpenFile(Handle, SYNCHRONIZE | FILE_LIST_DIRECTORY, &oa, 00286 &ioStatus, FILE_SHARE_READ | FILE_SHARE_WRITE, 00287 FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_ALERT | 00288 FILE_OPEN_FOR_BACKUP_INTENT); 00289 00290 ExFreePool(reparseName.Buffer); 00291 00292 return status; 00293 }

NTSTATUS QueryDeviceNameForPath IN PUNICODE_STRING  Path,
OUT PUNICODE_STRING  DeviceName
 

Definition at line 149 of file dev2dos.c.

References ExAllocatePool, ExFreePool(), NT_SUCCESS, NTSTATUS(), NULL, PagedPool, QuerySymbolicLink(), and ZwOpenFile().

Referenced by FindPathForDevice().

00156 : 00157 00158 This routine returns the device name for the given path. It first checks 00159 to see if the path is a symbolic link and then checks to see if it is a 00160 volume reparse point. 00161 00162 Arguments: 00163 00164 Path - Supplies the path. 00165 00166 DeviceName - Returns the device name. 00167 00168 Return Value: 00169 00170 NTSTATUS 00171 00172 --*/ 00173 00174 { 00175 NTSTATUS status; 00176 OBJECT_ATTRIBUTES oa; 00177 HANDLE h; 00178 IO_STATUS_BLOCK ioStatus; 00179 PREPARSE_DATA_BUFFER reparse; 00180 UNICODE_STRING volumeName; 00181 00182 status = QuerySymbolicLink(Path, DeviceName); 00183 if (NT_SUCCESS(status)) { 00184 return status; 00185 } 00186 00187 InitializeObjectAttributes(&oa, Path, OBJ_CASE_INSENSITIVE, 0, 0); 00188 status = ZwOpenFile(&h, SYNCHRONIZE | FILE_GENERIC_READ, &oa, &ioStatus, 00189 FILE_SHARE_READ | FILE_SHARE_WRITE, 00190 FILE_OPEN_REPARSE_POINT | FILE_SYNCHRONOUS_IO_ALERT); 00191 if (!NT_SUCCESS(status)) { 00192 return status; 00193 } 00194 00195 reparse = ExAllocatePool(PagedPool, MAXIMUM_REPARSE_DATA_BUFFER_SIZE); 00196 if (!reparse) { 00197 ZwClose(h); 00198 return STATUS_INSUFFICIENT_RESOURCES; 00199 } 00200 00201 status = ZwFsControlFile(h, NULL, NULL, NULL, &ioStatus, 00202 FSCTL_GET_REPARSE_POINT, NULL, 0, reparse, 00203 MAXIMUM_REPARSE_DATA_BUFFER_SIZE); 00204 ZwClose(h); 00205 if (!NT_SUCCESS(status)) { 00206 ExFreePool(reparse); 00207 return status; 00208 } 00209 00210 volumeName.Length = reparse->MountPointReparseBuffer.SubstituteNameLength - 00211 sizeof(WCHAR); 00212 volumeName.MaximumLength = volumeName.Length + sizeof(WCHAR); 00213 volumeName.Buffer = (PWCHAR) 00214 ((PCHAR) reparse->MountPointReparseBuffer.PathBuffer + 00215 reparse->MountPointReparseBuffer.SubstituteNameOffset); 00216 volumeName.Buffer[volumeName.Length/sizeof(WCHAR)] = 0; 00217 00218 status = QuerySymbolicLink(&volumeName, DeviceName); 00219 ExFreePool(reparse); 00220 00221 return status; 00222 }

NTSTATUS QuerySymbolicLink IN PUNICODE_STRING  SymbolicLinkName,
OUT PUNICODE_STRING  LinkTarget
 

Definition at line 94 of file dev2dos.c.

References ExAllocatePool, ExFreePool(), NT_SUCCESS, NTSTATUS(), NULL, and PagedPool.

Referenced by QueryDeviceNameForPath(), and RtlVolumeDeviceToDosName().

00101 : 00102 00103 This routine returns the target of the symbolic link name. 00104 00105 Arguments: 00106 00107 SymbolicLinkName - Supplies the symbolic link name. 00108 00109 LinkTarget - Returns the link target. 00110 00111 Return Value: 00112 00113 NTSTATUS 00114 00115 --*/ 00116 00117 { 00118 OBJECT_ATTRIBUTES oa; 00119 NTSTATUS status; 00120 HANDLE h; 00121 00122 InitializeObjectAttributes(&oa, SymbolicLinkName, OBJ_CASE_INSENSITIVE, 00123 0, 0); 00124 00125 status = ZwOpenSymbolicLinkObject(&h, GENERIC_READ, &oa); 00126 if (!NT_SUCCESS(status)) { 00127 return status; 00128 } 00129 00130 LinkTarget->MaximumLength = 200*sizeof(WCHAR); 00131 LinkTarget->Length = 0; 00132 LinkTarget->Buffer = ExAllocatePool(PagedPool, LinkTarget->MaximumLength); 00133 if (!LinkTarget->Buffer) { 00134 ZwClose(h); 00135 return STATUS_INSUFFICIENT_RESOURCES; 00136 } 00137 00138 status = ZwQuerySymbolicLinkObject(h, LinkTarget, NULL); 00139 ZwClose(h); 00140 00141 if (!NT_SUCCESS(status)) { 00142 ExFreePool(LinkTarget->Buffer); 00143 } 00144 00145 return status; 00146 }

NTSTATUS RtlVolumeDeviceToDosName IN PVOID  VolumeDeviceObject,
OUT PUNICODE_STRING  DosName
 

Definition at line 580 of file dev2dos.c.

References c, CHAR, ExAllocatePool, Executive, ExFreePool(), FALSE, FindPathForDevice(), IoBuildDeviceIoControlRequest(), IoCallDriver, KeInitializeEvent, KernelMode, KeWaitForSingleObject(), L, NT_SUCCESS, NTSTATUS(), NULL, PagedPool, QuerySymbolicLink(), RtlEqualUnicodeString(), RtlInitUnicodeString(), and TRUE.

00587 : 00588 00589 This routine returns a valid DOS path for the given device object. 00590 This caller of this routine must call ExFreePool on DosName->Buffer 00591 when it is no longer needed. 00592 00593 Arguments: 00594 00595 VolumeDeviceObject - Supplies the volume device object. 00596 00597 DosName - Returns the DOS name for the volume 00598 00599 Return Value: 00600 00601 NTSTATUS 00602 00603 --*/ 00604 00605 { 00606 PDEVICE_OBJECT volumeDeviceObject = VolumeDeviceObject; 00607 PMOUNTDEV_NAME name; 00608 CHAR output[512]; 00609 KEVENT event; 00610 PIRP irp; 00611 IO_STATUS_BLOCK ioStatus; 00612 NTSTATUS status; 00613 UNICODE_STRING deviceName; 00614 WCHAR buffer[30]; 00615 UNICODE_STRING driveLetterName; 00616 WCHAR c; 00617 UNICODE_STRING linkTarget; 00618 LIST_ENTRY devicesInPath; 00619 00620 name = (PMOUNTDEV_NAME) output; 00621 KeInitializeEvent(&event, NotificationEvent, FALSE); 00622 irp = IoBuildDeviceIoControlRequest(IOCTL_MOUNTDEV_QUERY_DEVICE_NAME, 00623 volumeDeviceObject, NULL, 0, name, 512, 00624 FALSE, &event, &ioStatus); 00625 if (!irp) { 00626 return STATUS_INSUFFICIENT_RESOURCES; 00627 } 00628 00629 status = IoCallDriver(volumeDeviceObject, irp); 00630 if (status == STATUS_PENDING) { 00631 KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL); 00632 status = ioStatus.Status; 00633 } 00634 00635 if (!NT_SUCCESS(status)) { 00636 return status; 00637 } 00638 00639 deviceName.MaximumLength = deviceName.Length = name->NameLength; 00640 deviceName.Buffer = name->Name; 00641 00642 swprintf(buffer, L"\\??\\C:"); 00643 RtlInitUnicodeString(&driveLetterName, buffer); 00644 00645 for (c = 'A'; c <= 'Z'; c++) { 00646 driveLetterName.Buffer[4] = c; 00647 00648 status = QuerySymbolicLink(&driveLetterName, &linkTarget); 00649 if (!NT_SUCCESS(status)) { 00650 continue; 00651 } 00652 00653 if (RtlEqualUnicodeString(&linkTarget, &deviceName, TRUE)) { 00654 ExFreePool(linkTarget.Buffer); 00655 break; 00656 } 00657 00658 ExFreePool(linkTarget.Buffer); 00659 } 00660 00661 if (c <= 'Z') { 00662 DosName->Buffer = ExAllocatePool(PagedPool, 3*sizeof(WCHAR)); 00663 if (!DosName->Buffer) { 00664 return STATUS_INSUFFICIENT_RESOURCES; 00665 } 00666 DosName->MaximumLength = 6; 00667 DosName->Length = 4; 00668 DosName->Buffer[0] = c; 00669 DosName->Buffer[1] = ':'; 00670 DosName->Buffer[2] = 0; 00671 return STATUS_SUCCESS; 00672 } 00673 00674 for (c = 'A'; c <= 'Z'; c++) { 00675 driveLetterName.Buffer[4] = c; 00676 InitializeListHead(&devicesInPath); 00677 status = FindPathForDevice(&driveLetterName, &deviceName, 00678 &devicesInPath, DosName); 00679 00680 if (NT_SUCCESS(status)) { 00681 DosName->Length -= 4*sizeof(WCHAR); 00682 RtlMoveMemory(DosName->Buffer, &DosName->Buffer[4], 00683 DosName->Length); 00684 DosName->Buffer[DosName->Length/sizeof(WCHAR)] = 0; 00685 return status; 00686 } 00687 } 00688 00689 return status; 00690 } }


Generated on Sat May 15 19:43:26 2004 for test by doxygen 1.3.7