mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
955 lines
22 KiB
955 lines
22 KiB
//+---------------------------------------------------------------------------
|
|
//
|
|
// Microsoft Windows
|
|
// Copyright (C) Microsoft Corporation, 1992 - 1994.
|
|
//
|
|
// File: cdrom.cxx
|
|
//
|
|
// Contents: This module contains the set of routines that display and
|
|
// control the drive letters for CdRom devices.
|
|
//
|
|
// History: 9-Dec-93 Bob Rinne Created
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
#include "headers.hxx"
|
|
#pragma hdrstop
|
|
|
|
#include "cdrom.hxx"
|
|
#include "dialogs.h"
|
|
#include "drives.hxx"
|
|
#include "help.hxx"
|
|
#include "nt.hxx"
|
|
#include "ntlow.hxx"
|
|
|
|
|
|
WCHAR g_SourcePathLetter = L'\0';
|
|
WCHAR g_SourcePathKeyName[80];
|
|
WCHAR g_SourcePathValueName[30];
|
|
|
|
|
|
PCDROM_DESCRIPTOR
|
|
CdRomFindSelectedDevice(
|
|
VOID
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Find the selected CD-ROM. There should only be one.
|
|
|
|
Arguments:
|
|
|
|
none
|
|
|
|
Return Value:
|
|
|
|
Pointer to the correct structure, or NULL if it doesn't exist
|
|
|
|
--*/
|
|
|
|
{
|
|
FDASSERT(1 == CdRomSelectionCount);
|
|
|
|
ULONG i;
|
|
|
|
for (i = 0; i < CdRomCount; i++)
|
|
{
|
|
if (CdRomArray[i].Selected)
|
|
{
|
|
return &CdRomArray[i];
|
|
}
|
|
}
|
|
|
|
FDASSERT(FALSE);
|
|
return NULL;
|
|
}
|
|
|
|
|
|
|
|
|
|
PCDROM_DESCRIPTOR
|
|
CdRomFindDevice(
|
|
IN ULONG CdRomNumber
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Find the correct CD-ROM
|
|
|
|
Arguments:
|
|
|
|
CdRomNumber - the device number
|
|
|
|
Return Value:
|
|
|
|
Pointer to the correct structure, or NULL if it doesn't exist
|
|
|
|
--*/
|
|
|
|
{
|
|
FDASSERT(0 <= CdRomNumber && CdRomNumber < CdRomCount);
|
|
return &CdRomArray[CdRomNumber];
|
|
}
|
|
|
|
|
|
|
|
ULONG
|
|
CdRomFindDeviceNumber(
|
|
IN WCHAR DriveLetter
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Find the correct CD-ROM
|
|
|
|
Arguments:
|
|
|
|
CdRomNumber - the device number
|
|
|
|
Return Value:
|
|
|
|
Pointer to the correct structure, or NULL if it doesn't exist
|
|
|
|
--*/
|
|
|
|
{
|
|
FDASSERT(DriveLetter >= L'C' && DriveLetter <= L'Z');
|
|
ULONG i;
|
|
|
|
for (i = 0; i < CdRomCount; i++)
|
|
{
|
|
if (CdRomArray[i].DriveLetter == DriveLetter)
|
|
{
|
|
return i;
|
|
}
|
|
}
|
|
|
|
FDASSERT(FALSE);
|
|
return 0xffffffff;
|
|
}
|
|
|
|
|
|
PCDROM_DESCRIPTOR
|
|
CdRomFindDriveLetter(
|
|
IN WCHAR DriveLetter
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Find the CD-ROM with the drive letter
|
|
|
|
Arguments:
|
|
|
|
DriveLetter - the drive letter to find
|
|
|
|
Return Value:
|
|
|
|
Pointer to the correct structure, or NULL if it doesn't exist
|
|
|
|
--*/
|
|
|
|
{
|
|
FDASSERT(DriveLetter >= L'C' && DriveLetter <= L'Z');
|
|
ULONG i;
|
|
|
|
for (i = 0; i < CdRomCount; i++)
|
|
{
|
|
if (CdRomArray[i].DriveLetter == DriveLetter)
|
|
{
|
|
return &CdRomArray[i];
|
|
}
|
|
}
|
|
|
|
FDASSERT(FALSE);
|
|
return NULL;
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOL
|
|
CdRomUsingDriveLetter(
|
|
IN WCHAR DriveLetter
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Determine if a CD-ROM device is using the drive letter
|
|
|
|
Arguments:
|
|
|
|
DriveLetter - the drive letter to find
|
|
|
|
Return Value:
|
|
|
|
TRUE if one is using the letter
|
|
|
|
--*/
|
|
|
|
{
|
|
FDASSERT(DriveLetter >= L'C' && DriveLetter <= L'Z');
|
|
ULONG i;
|
|
|
|
for (i = 0; i < CdRomCount; i++)
|
|
{
|
|
if (CdRomArray[i].DriveLetter == DriveLetter)
|
|
{
|
|
return TRUE;
|
|
}
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
|
|
VOID
|
|
CdRomChangeDriveLetter(
|
|
IN PCDROM_DESCRIPTOR Cdrom,
|
|
IN WCHAR NewDriveLetter
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Change a CD-ROM drive letter
|
|
|
|
Arguments:
|
|
|
|
None
|
|
|
|
Return Value:
|
|
|
|
None
|
|
|
|
--*/
|
|
|
|
{
|
|
DWORD action;
|
|
WCHAR deviceName[40];
|
|
WCHAR driveName[10];
|
|
OBJECT_ATTRIBUTES oa;
|
|
HANDLE handle;
|
|
NTSTATUS status;
|
|
IO_STATUS_BLOCK statusBlock;
|
|
UNICODE_STRING unicodeName;
|
|
UINT errorMode;
|
|
|
|
action = ConfirmationDialog(
|
|
MSG_DRIVE_RENAME_WARNING,
|
|
MB_ICONQUESTION | MB_YESNO | MB_DEFBUTTON2);
|
|
|
|
if (action == IDNO)
|
|
{
|
|
return;
|
|
}
|
|
|
|
// Attempt to open and lock the cdrom.
|
|
|
|
wsprintf(deviceName, TEXT("\\Device\\CdRom%d"), Cdrom->DeviceNumber);
|
|
|
|
RtlInitUnicodeString(&unicodeName, deviceName);
|
|
|
|
memset(&oa, 0, sizeof(OBJECT_ATTRIBUTES));
|
|
oa.Length = sizeof(OBJECT_ATTRIBUTES);
|
|
oa.ObjectName = &unicodeName;
|
|
oa.Attributes = OBJ_CASE_INSENSITIVE;
|
|
|
|
errorMode = SetErrorMode(SEM_FAILCRITICALERRORS);
|
|
status = NtOpenFile(&handle,
|
|
SYNCHRONIZE | FILE_READ_DATA,
|
|
&oa,
|
|
&statusBlock,
|
|
FILE_SHARE_READ,
|
|
FILE_SYNCHRONOUS_IO_ALERT);
|
|
SetErrorMode(errorMode);
|
|
|
|
if (!NT_SUCCESS(status))
|
|
{
|
|
ErrorDialog(MSG_CANNOT_LOCK_CDROM);
|
|
return;
|
|
}
|
|
|
|
// Lock the drive to insure that no other access is occurring
|
|
// to the volume. This is done via the "Low" routine for
|
|
// convenience
|
|
|
|
status = LowLockDrive(handle);
|
|
|
|
if (!NT_SUCCESS(status))
|
|
{
|
|
LowCloseDisk(handle);
|
|
ErrorDialog(MSG_CANNOT_LOCK_CDROM);
|
|
return;
|
|
}
|
|
|
|
// Before attempting to move the name, see if the letter
|
|
// is currently in use - could be a new network connection
|
|
// or a partition that is scheduled for deletion.
|
|
|
|
DWORD ec;
|
|
WCHAR dosName[MAX_PATH];
|
|
PWSTR linkTarget;
|
|
|
|
//
|
|
// No need to look if anyone is using the no-drive letter.
|
|
//
|
|
|
|
if (NewDriveLetter != NO_DRIVE_LETTER_EVER) {
|
|
|
|
wsprintfW(dosName, L"\\DosDevices\\%wc:", NewDriveLetter);
|
|
ec = GetDriveLetterLinkTarget(dosName, &linkTarget);
|
|
if (ec == NO_ERROR)
|
|
{
|
|
// Something is using this letter.
|
|
|
|
LowCloseDisk(handle);
|
|
ErrorDialog(MSG_CANNOT_MOVE_CDROM);
|
|
return;
|
|
}
|
|
|
|
}
|
|
|
|
//
|
|
// If it didn't used to have a letter, no point in trying
|
|
// to remove it.
|
|
//
|
|
|
|
if (Cdrom->DriveLetter != NO_DRIVE_LETTER_EVER) {
|
|
|
|
wsprintf(driveName, TEXT("%c:"), Cdrom->DriveLetter);
|
|
if (!DefineDosDevice(DDD_REMOVE_DEFINITION, driveName, NULL))
|
|
{
|
|
LowCloseDisk(handle);
|
|
ErrorDialog(MSG_CDROM_LETTER_ERROR);
|
|
return;
|
|
}
|
|
|
|
}
|
|
|
|
status = DiskRegistryAssignCdRomLetter(
|
|
Cdrom->DeviceName,
|
|
NewDriveLetter);
|
|
|
|
if (Cdrom->DriveLetter != NO_DRIVE_LETTER_EVER) {
|
|
|
|
MarkDriveLetterFree(Cdrom->DriveLetter);
|
|
|
|
// See if this was the device used to install NT
|
|
|
|
if (L'\0' != g_SourcePathLetter)
|
|
{
|
|
if (g_SourcePathLetter == Cdrom->DriveLetter)
|
|
{
|
|
LONG error;
|
|
HKEY keyHandle;
|
|
DWORD valueType;
|
|
ULONG size;
|
|
PWSTR string;
|
|
|
|
// Update the source path
|
|
|
|
error = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
|
|
g_SourcePathKeyName,
|
|
0,
|
|
KEY_ALL_ACCESS,
|
|
&keyHandle);
|
|
if (error == NO_ERROR)
|
|
{
|
|
error = RegQueryValueEx(keyHandle,
|
|
g_SourcePathValueName,
|
|
NULL,
|
|
&valueType,
|
|
NULL,
|
|
&size);
|
|
if (error == NO_ERROR)
|
|
{
|
|
string = (PWSTR) LocalAlloc(LMEM_FIXED, size);
|
|
if (NULL != string)
|
|
{
|
|
error = RegQueryValueEx(keyHandle,
|
|
g_SourcePathValueName,
|
|
NULL,
|
|
&valueType,
|
|
(LPBYTE)string,
|
|
&size);
|
|
if (error == NO_ERROR)
|
|
{
|
|
*string = g_SourcePathLetter = NewDriveLetter;
|
|
RegSetValueEx(keyHandle,
|
|
g_SourcePathValueName,
|
|
0,
|
|
REG_SZ,
|
|
(LPBYTE)string,
|
|
size);
|
|
}
|
|
}
|
|
LocalFree(string);
|
|
}
|
|
RegCloseKey(keyHandle);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// set up new device letter - name is already set up, take care not to
|
|
// assign the no drive letter.
|
|
|
|
if (NewDriveLetter != NO_DRIVE_LETTER_EVER) {
|
|
|
|
wsprintf(driveName, TEXT("%c:"), NewDriveLetter);
|
|
if (DefineDosDevice(DDD_RAW_TARGET_PATH, driveName, deviceName))
|
|
{
|
|
Cdrom->DriveLetter = NewDriveLetter;
|
|
MarkDriveLetterUsed(Cdrom->DriveLetter);
|
|
}
|
|
else
|
|
{
|
|
RegistryChanged = TRUE;
|
|
}
|
|
} else {
|
|
|
|
Cdrom->DriveLetter = NO_DRIVE_LETTER_EVER;
|
|
|
|
}
|
|
LowCloseDisk(handle);
|
|
}
|
|
|
|
|
|
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: InitializeCdRomInfo
|
|
//
|
|
// Synopsis: Initialize all information about CD-ROMs
|
|
//
|
|
// Arguments: (none)
|
|
//
|
|
// Returns: TRUE on success, FALSE on failure
|
|
//
|
|
// History: 2-Mar-94 BruceFo Created
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
BOOL
|
|
InitializeCdRomInfo(
|
|
VOID
|
|
)
|
|
{
|
|
WCHAR driveLetter;
|
|
PWSTR linkTarget;
|
|
WCHAR dosDevicesName[sizeof(L"\\DosDevices\\A:")];
|
|
DWORD ec;
|
|
ULONG count;
|
|
PCDROM_DESCRIPTOR cdrom;
|
|
LONG error;
|
|
DWORD valueType;
|
|
HKEY keyHandle;
|
|
ULONG size;
|
|
PWSTR string;
|
|
|
|
//
|
|
// Get the CD-ROM source path
|
|
//
|
|
|
|
LoadString(g_hInstance,
|
|
IDS_SOURCE_PATH,
|
|
g_SourcePathKeyName,
|
|
ARRAYLEN(g_SourcePathKeyName));
|
|
LoadString(g_hInstance,
|
|
IDS_SOURCE_PATH_NAME,
|
|
g_SourcePathValueName,
|
|
ARRAYLEN(g_SourcePathValueName));
|
|
|
|
error = RegOpenKey(HKEY_LOCAL_MACHINE, g_SourcePathKeyName, &keyHandle);
|
|
if (error == NO_ERROR)
|
|
{
|
|
error = RegQueryValueEx(keyHandle,
|
|
g_SourcePathValueName,
|
|
NULL,
|
|
&valueType,
|
|
NULL,
|
|
&size);
|
|
if (error == NO_ERROR)
|
|
{
|
|
string = (PWSTR) LocalAlloc(LMEM_FIXED, size);
|
|
if (NULL != string)
|
|
{
|
|
error = RegQueryValueEx(keyHandle,
|
|
g_SourcePathValueName,
|
|
NULL,
|
|
&valueType,
|
|
(LPBYTE)string,
|
|
&size);
|
|
if (error == NO_ERROR)
|
|
{
|
|
g_SourcePathLetter = *string;
|
|
}
|
|
}
|
|
LocalFree(string);
|
|
}
|
|
RegCloseKey(keyHandle);
|
|
}
|
|
|
|
//
|
|
// First, count how many CD-ROM devices there are
|
|
//
|
|
|
|
wsprintf(dosDevicesName, L"\\DosDevices\\A:");
|
|
|
|
CdRomCount = 0;
|
|
|
|
{
|
|
|
|
NTSTATUS ntStatus;
|
|
SYSTEM_DEVICE_INFORMATION deviceInformationData;
|
|
|
|
ntStatus = NtQuerySystemInformation(
|
|
SystemDeviceInformation,
|
|
&deviceInformationData,
|
|
sizeof(SYSTEM_DEVICE_INFORMATION),
|
|
NULL
|
|
);
|
|
|
|
if (NT_SUCCESS(ntStatus)) {
|
|
|
|
CdRomCount = deviceInformationData.NumberOfCdRoms;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (0 == CdRomCount)
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
g_AllowCdRom = TRUE;
|
|
|
|
//
|
|
// First we find all the cd rom devices that have an actual drive
|
|
// letter. Afterwards, we will look for those that have have
|
|
// no letter.
|
|
//
|
|
|
|
CdRomArray = (PCDROM_DESCRIPTOR)Malloc(CdRomCount * sizeof(CDROM_DESCRIPTOR));
|
|
|
|
count = 0;
|
|
for (driveLetter = L'C'; driveLetter <= L'Z'; driveLetter++)
|
|
{
|
|
dosDevicesName[12] = driveLetter;
|
|
|
|
if ((ec = GetDriveLetterLinkTarget(dosDevicesName, &linkTarget)) == NO_ERROR)
|
|
{
|
|
if (_wcsnicmp(linkTarget, L"\\Device\\CdRom", 13) == 0)
|
|
{
|
|
cdrom = &CdRomArray[count];
|
|
|
|
cdrom->DeviceName = (PWSTR)Malloc((lstrlen(linkTarget)+1) * sizeof(WCHAR));
|
|
lstrcpy(cdrom->DeviceName, linkTarget);
|
|
|
|
//
|
|
// Get the device number
|
|
//
|
|
|
|
PWCHAR cp;
|
|
|
|
cp = cdrom->DeviceName;
|
|
while (*cp)
|
|
{
|
|
if (iswdigit(*cp))
|
|
{
|
|
break;
|
|
}
|
|
cp++;
|
|
}
|
|
|
|
if (*cp)
|
|
{
|
|
cdrom->DeviceNumber = wcstoul(cp, NULL, 10);
|
|
}
|
|
else
|
|
{
|
|
// error: no device number! Don't add this one
|
|
Free(cdrom->DeviceName);
|
|
--CdRomCount;
|
|
continue;
|
|
}
|
|
|
|
cdrom->hDCMem = NULL;
|
|
cdrom->hbmMem = NULL;
|
|
cdrom->Selected = FALSE;
|
|
cdrom->LeftRight.Left = 0;
|
|
cdrom->LeftRight.Right = 0;
|
|
cdrom->DriveLetter = driveLetter;
|
|
|
|
cdrom->VolumeLabel = NULL;
|
|
cdrom->TypeName = NULL;
|
|
|
|
RefreshCdRomData(cdrom);
|
|
|
|
++count;
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// if the count is equal to the number of cdroms in the system
|
|
// then the're aren't any without a drive letter.
|
|
//
|
|
// Keep going until we found all of the Cdroms.
|
|
//
|
|
|
|
DWORD potentialDeviceNumber;
|
|
WCHAR ntDeviceName[MAX_PATH];
|
|
UNICODE_STRING ntDeviceNameString;
|
|
|
|
|
|
potentialDeviceNumber = 0;
|
|
for (
|
|
potentialDeviceNumber = 0;
|
|
count != CdRomCount;
|
|
potentialDeviceNumber++
|
|
) {
|
|
|
|
DWORD i;
|
|
HANDLE ntDeviceHandle;
|
|
OBJECT_ATTRIBUTES deviceObjectAttributes;
|
|
NTSTATUS openStatus;
|
|
IO_STATUS_BLOCK ioStatusBlock;
|
|
|
|
//
|
|
// BUG BUG This is very piggish. Look to see if the potential
|
|
// cdrom device "number" is already in the list of devices we
|
|
// know about. If it is, go on to the next one.
|
|
//
|
|
//
|
|
|
|
for (
|
|
i = 0;
|
|
i < count;
|
|
i++
|
|
) {
|
|
|
|
if (potentialDeviceNumber == CdRomArray[i].DeviceNumber) {
|
|
|
|
goto bottomOfPotential;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
//
|
|
// Form a name based on the number
|
|
//
|
|
|
|
wsprintf(ntDeviceName,L"\\Device\\CdRom%d",potentialDeviceNumber);
|
|
RtlInitUnicodeString(
|
|
&ntDeviceNameString,
|
|
&ntDeviceName[0]
|
|
);
|
|
|
|
InitializeObjectAttributes(
|
|
&deviceObjectAttributes,
|
|
&ntDeviceNameString,
|
|
OBJ_CASE_INSENSITIVE,
|
|
NULL,
|
|
NULL
|
|
);
|
|
|
|
//
|
|
// See if it's there.
|
|
//
|
|
|
|
openStatus = NtOpenFile(
|
|
&ntDeviceHandle,
|
|
(ACCESS_MASK)SYNCHRONIZE,
|
|
&deviceObjectAttributes,
|
|
&ioStatusBlock,
|
|
FILE_SHARE_READ,
|
|
0UL
|
|
);
|
|
if ( !NT_SUCCESS(openStatus) ) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
//
|
|
// We have the device open. Close it right away. Fill
|
|
// in the cd rom structure. The refresh cdrom code will
|
|
// know how do deal with a cdrom with no drive letter.
|
|
// size
|
|
//
|
|
|
|
NtClose(ntDeviceHandle);
|
|
|
|
cdrom = &CdRomArray[count];
|
|
|
|
cdrom->DeviceName = (PWSTR)Malloc((ntDeviceNameString.Length+1) * sizeof(WCHAR));
|
|
lstrcpy(cdrom->DeviceName, ntDeviceNameString.Buffer);
|
|
|
|
cdrom->DeviceNumber = potentialDeviceNumber;
|
|
cdrom->hDCMem = NULL;
|
|
cdrom->hbmMem = NULL;
|
|
cdrom->Selected = FALSE;
|
|
cdrom->LeftRight.Left = 0;
|
|
cdrom->LeftRight.Right = 0;
|
|
cdrom->DriveLetter = NO_DRIVE_LETTER_EVER;
|
|
|
|
cdrom->VolumeLabel = NULL;
|
|
cdrom->TypeName = NULL;
|
|
|
|
RefreshCdRomData(cdrom);
|
|
|
|
++count;
|
|
|
|
bottomOfPotential:;
|
|
|
|
}
|
|
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
VOID
|
|
RefreshCdRomData(
|
|
PCDROM_DESCRIPTOR Cdrom
|
|
)
|
|
{
|
|
WCHAR rootPath[4];
|
|
rootPath[0] = Cdrom->DriveLetter;
|
|
rootPath[1] = L':';
|
|
rootPath[2] = L'\\';
|
|
rootPath[3] = L'\0';
|
|
|
|
WCHAR volumeLabel[100];
|
|
WCHAR typeName[100];
|
|
|
|
// Free old stuff first
|
|
|
|
if (NULL != Cdrom->VolumeLabel)
|
|
{
|
|
Free(Cdrom->VolumeLabel);
|
|
}
|
|
|
|
if (NULL != Cdrom->TypeName)
|
|
{
|
|
Free(Cdrom->TypeName);
|
|
}
|
|
|
|
Cdrom->TotalSpaceInMB = 0;
|
|
Cdrom->TypeName = NULL;
|
|
Cdrom->VolumeLabel = NULL;
|
|
|
|
UINT errorMode = SetErrorMode(SEM_FAILCRITICALERRORS);
|
|
|
|
HANDLE ntDeviceHandle;
|
|
OBJECT_ATTRIBUTES deviceObjectAttributes;
|
|
UNICODE_STRING ntDeviceNameString;
|
|
NTSTATUS ioStatus;
|
|
IO_STATUS_BLOCK ioStatusBlock;
|
|
FILE_FS_SIZE_INFORMATION sizeInformation;
|
|
PFILE_FS_ATTRIBUTE_INFORMATION attributeInformation;
|
|
PFILE_FS_VOLUME_INFORMATION volumeInformation;
|
|
DWORD volumeInformationLength;
|
|
DWORD attributeInformationLength;
|
|
|
|
|
|
//
|
|
// Allocate two strings. The first to hold the file system name. The
|
|
// second to hold the volume name. After we get them both back we will
|
|
// allocate new memory just big enough to hold them.
|
|
//
|
|
|
|
attributeInformationLength = sizeof(FILE_FS_ATTRIBUTE_INFORMATION) +
|
|
((MAX_PATH+1)*sizeof(WCHAR));
|
|
volumeInformationLength = sizeof(FILE_FS_VOLUME_INFORMATION) +
|
|
((MAX_PATH+1)*sizeof(WCHAR));
|
|
|
|
attributeInformation = (PFILE_FS_ATTRIBUTE_INFORMATION)Malloc(attributeInformationLength);
|
|
|
|
if (!attributeInformation) {
|
|
|
|
SetErrorMode(errorMode);
|
|
return;
|
|
|
|
}
|
|
|
|
volumeInformation = (PFILE_FS_VOLUME_INFORMATION)Malloc(volumeInformationLength);
|
|
|
|
if (!volumeInformation) {
|
|
|
|
Free(attributeInformation);
|
|
SetErrorMode(errorMode);
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
RtlInitUnicodeString(
|
|
&ntDeviceNameString,
|
|
Cdrom->DeviceName
|
|
);
|
|
|
|
InitializeObjectAttributes(
|
|
&deviceObjectAttributes,
|
|
&ntDeviceNameString,
|
|
OBJ_CASE_INSENSITIVE,
|
|
NULL,
|
|
NULL
|
|
);
|
|
|
|
//
|
|
// Open the file
|
|
//
|
|
|
|
ioStatus = NtOpenFile(
|
|
&ntDeviceHandle,
|
|
(ACCESS_MASK)FILE_LIST_DIRECTORY | SYNCHRONIZE,
|
|
&deviceObjectAttributes,
|
|
&ioStatusBlock,
|
|
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
|
FILE_SYNCHRONOUS_IO_NONALERT | FILE_DIRECTORY_FILE
|
|
);
|
|
|
|
if ( !NT_SUCCESS(ioStatus) ) {
|
|
|
|
Free(attributeInformation);
|
|
Free(volumeInformation);
|
|
SetErrorMode(errorMode);
|
|
return;
|
|
|
|
}
|
|
|
|
//
|
|
// Try to get the volume label
|
|
//
|
|
|
|
ioStatus = NtQueryVolumeInformationFile(
|
|
ntDeviceHandle,
|
|
&ioStatusBlock,
|
|
volumeInformation,
|
|
volumeInformationLength,
|
|
FileFsVolumeInformation
|
|
);
|
|
|
|
if (NT_SUCCESS(ioStatus)) {
|
|
|
|
|
|
Cdrom->VolumeLabel = (PWCHAR)Malloc(volumeInformation->VolumeLabelLength
|
|
+ sizeof(WCHAR));
|
|
if (Cdrom->VolumeLabel) {
|
|
|
|
RtlZeroMemory(
|
|
Cdrom->VolumeLabel,
|
|
volumeInformation->VolumeLabelLength+sizeof(WCHAR)
|
|
);
|
|
RtlMoveMemory(
|
|
Cdrom->VolumeLabel,
|
|
volumeInformation->VolumeLabel,
|
|
volumeInformation->VolumeLabelLength
|
|
);
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Free(volumeInformation);
|
|
|
|
ioStatus = NtQueryVolumeInformationFile(
|
|
ntDeviceHandle,
|
|
&ioStatusBlock,
|
|
attributeInformation,
|
|
attributeInformationLength,
|
|
FileFsAttributeInformation
|
|
);
|
|
|
|
if (NT_SUCCESS(ioStatus)) {
|
|
|
|
Cdrom->TypeName = (PWCHAR)Malloc(attributeInformation->FileSystemNameLength
|
|
+ sizeof(WCHAR));
|
|
|
|
if (Cdrom->TypeName) {
|
|
|
|
RtlZeroMemory(
|
|
Cdrom->TypeName,
|
|
attributeInformation->FileSystemNameLength+
|
|
sizeof(WCHAR)
|
|
);
|
|
RtlMoveMemory(
|
|
Cdrom->TypeName,
|
|
attributeInformation->FileSystemName,
|
|
attributeInformation->FileSystemNameLength
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Free(attributeInformation);
|
|
|
|
//
|
|
// Determine the size parameters of the volume.
|
|
//
|
|
|
|
ioStatus = NtQueryVolumeInformationFile(
|
|
ntDeviceHandle,
|
|
&ioStatusBlock,
|
|
&sizeInformation,
|
|
sizeof(sizeInformation),
|
|
FileFsSizeInformation
|
|
);
|
|
NtClose(ntDeviceHandle);
|
|
SetErrorMode(errorMode);
|
|
if ( !NT_SUCCESS(ioStatus) ) {
|
|
|
|
Cdrom->TotalSpaceInMB = 0;
|
|
|
|
} else {
|
|
|
|
LONGLONG temp;
|
|
|
|
if (sizeInformation.TotalAllocationUnits.HighPart) {
|
|
sizeInformation.TotalAllocationUnits.LowPart = (ULONG)-1;
|
|
}
|
|
temp = UInt32x32To64(
|
|
sizeInformation.TotalAllocationUnits.LowPart,
|
|
sizeInformation.SectorsPerAllocationUnit
|
|
);
|
|
|
|
temp *= sizeInformation.BytesPerSector;
|
|
temp /= (1024*1024);
|
|
Cdrom->TotalSpaceInMB = (ULONG)temp;
|
|
|
|
}
|
|
}
|
|
|
|
|
|
VOID
|
|
RefreshAllCdRomData(
|
|
VOID
|
|
)
|
|
{
|
|
PCDROM_DESCRIPTOR cdrom;
|
|
ULONG i;
|
|
for (i=0; i<CdRomCount; i++)
|
|
{
|
|
cdrom = CdRomFindDevice(i);
|
|
RefreshCdRomData(cdrom);
|
|
}
|
|
}
|