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.
498 lines
12 KiB
498 lines
12 KiB
#include "precomp.h"
|
|
#pragma hdrstop
|
|
#include "msg.h"
|
|
|
|
|
|
ULONGLONG DriveFreeSpace[24];
|
|
DWORD DriveClusterSize[24];
|
|
DWORD DriveSectorSize[24];
|
|
PTSTR DriveFileSystem[24];
|
|
|
|
|
|
TCHAR
|
|
GetFirstDriveWithSpace(
|
|
IN DWORD RequiredSpace
|
|
)
|
|
{
|
|
TCHAR Drive;
|
|
|
|
for(Drive=TEXT('C'); Drive<=TEXT('Z'); Drive++) {
|
|
|
|
if(DriveFreeSpace[Drive-TEXT('C')] >= (ULONGLONG)RequiredSpace) {
|
|
return(Drive);
|
|
}
|
|
}
|
|
|
|
return(0);
|
|
}
|
|
|
|
|
|
VOID
|
|
GetDriveSectorInfo(
|
|
IN TCHAR Drive,
|
|
OUT PDWORD SectorSize,
|
|
OUT PDWORD ClusterSize
|
|
)
|
|
{
|
|
*SectorSize = DriveSectorSize[Drive-TEXT('C')];
|
|
*ClusterSize = DriveClusterSize[Drive-TEXT('C')];
|
|
}
|
|
|
|
|
|
VOID
|
|
GetFilesystemName(
|
|
IN TCHAR Drive,
|
|
OUT PTSTR FilesystemName,
|
|
IN UINT BufferSizeChars
|
|
)
|
|
{
|
|
_lstrcpyn(
|
|
FilesystemName,
|
|
DriveFileSystem[Drive-TEXT('C')] ? DriveFileSystem[Drive-TEXT('C')] : TEXT(""),
|
|
BufferSizeChars
|
|
);
|
|
}
|
|
|
|
|
|
BOOL
|
|
GetPartitionInfo(
|
|
IN TCHAR Drive,
|
|
OUT PPARTITION_INFORMATION PartitionInfo
|
|
)
|
|
{
|
|
TCHAR DriveName[] = TEXT("\\\\.\\?:");
|
|
HANDLE hDisk;
|
|
BOOL b;
|
|
DWORD DataSize;
|
|
|
|
DriveName[4] = Drive;
|
|
|
|
hDisk = CreateFile(
|
|
DriveName,
|
|
GENERIC_READ,
|
|
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
|
NULL,
|
|
OPEN_EXISTING,
|
|
0,
|
|
NULL
|
|
);
|
|
|
|
if(hDisk == INVALID_HANDLE_VALUE) {
|
|
return(FALSE);
|
|
}
|
|
|
|
b = DeviceIoControl(
|
|
hDisk,
|
|
IOCTL_DISK_GET_PARTITION_INFO,
|
|
NULL,
|
|
0,
|
|
PartitionInfo,
|
|
sizeof(PARTITION_INFORMATION),
|
|
&DataSize,
|
|
NULL
|
|
);
|
|
|
|
CloseHandle(hDisk);
|
|
|
|
return(b);
|
|
}
|
|
|
|
|
|
BOOL
|
|
IsDriveNotNTFT(
|
|
IN TCHAR Drive
|
|
)
|
|
{
|
|
PARTITION_INFORMATION PartitionInfo;
|
|
|
|
//
|
|
// If we can't open the drive, we can't determine whether it's
|
|
// FT or not. So return a value that says the drive is not not FT!
|
|
//
|
|
if(!GetPartitionInfo(Drive,&PartitionInfo)) {
|
|
return(FALSE);
|
|
}
|
|
|
|
//
|
|
// It's FT if the partition type is marked NTFT (ie, high bit set).
|
|
//
|
|
return ((PartitionInfo.PartitionType & 0x80) == 0);
|
|
}
|
|
|
|
|
|
UINT
|
|
MyGetDriveType(
|
|
IN TCHAR Drive
|
|
)
|
|
{
|
|
TCHAR DriveNameNt[] = TEXT("\\\\.\\?:");
|
|
TCHAR DriveName[] = TEXT("?:\\");
|
|
HANDLE hDisk;
|
|
BOOL b;
|
|
UINT rc;
|
|
DWORD DataSize;
|
|
DISK_GEOMETRY MediaInfo;
|
|
|
|
//
|
|
// First, get the win32 drive type. If it tells us DRIVE_REMOVABLE,
|
|
// then we need to see whether it's a floppy or hard disk. Otherwise
|
|
// just believe the api.
|
|
//
|
|
//
|
|
DriveName[0] = Drive;
|
|
if((rc = GetDriveType(DriveName)) == DRIVE_REMOVABLE) {
|
|
|
|
DriveNameNt[4] = Drive;
|
|
|
|
hDisk = CreateFile(
|
|
DriveNameNt,
|
|
GENERIC_READ,
|
|
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
|
NULL,
|
|
OPEN_EXISTING,
|
|
0,
|
|
NULL
|
|
);
|
|
|
|
if(hDisk != INVALID_HANDLE_VALUE) {
|
|
|
|
b = DeviceIoControl(
|
|
hDisk,
|
|
IOCTL_DISK_GET_DRIVE_GEOMETRY,
|
|
NULL,
|
|
0,
|
|
&MediaInfo,
|
|
sizeof(MediaInfo),
|
|
&DataSize,
|
|
NULL
|
|
);
|
|
|
|
//
|
|
// It's really a hard disk if the media type is removable.
|
|
//
|
|
if(b && (MediaInfo.MediaType == RemovableMedia)) {
|
|
rc = DRIVE_FIXED;
|
|
}
|
|
|
|
CloseHandle(hDisk);
|
|
}
|
|
}
|
|
|
|
return(rc);
|
|
}
|
|
|
|
|
|
|
|
VOID
|
|
GetInfoAboutDrives(
|
|
IN HWND hdlg
|
|
)
|
|
{
|
|
TCHAR DriveName[4] = TEXT("x:\\");
|
|
TCHAR Drive;
|
|
DWORD SectorsPerCluster,BytesPerSector,FreeClusters,TotalClusters;
|
|
BOOL b;
|
|
TCHAR Buffer[512];
|
|
DWORD DontCare;
|
|
|
|
//
|
|
// Iterate drives c-z.
|
|
//
|
|
for(Drive=TEXT('C'); Drive<=TEXT('Z'); Drive++) {
|
|
|
|
DriveName[0] = Drive;
|
|
|
|
//
|
|
// Assume drive not valid.
|
|
//
|
|
DriveFreeSpace[Drive-TEXT('C')] = 0;
|
|
DriveClusterSize[Drive-TEXT('C')] = 0;
|
|
DriveSectorSize[Drive-TEXT('C')] = 0;
|
|
DriveFileSystem[Drive-TEXT('C')] = NULL;
|
|
|
|
#ifndef _X86_
|
|
//
|
|
// Try to convert the drive letter to an arc path.
|
|
// If this fails, assume the drive is not accessible
|
|
// from the firmware and is thus not valid.
|
|
//
|
|
{
|
|
PWSTR ArcPath;
|
|
|
|
if(ArcPath = DriveLetterToArcPath(Drive)) {
|
|
FREE(ArcPath);
|
|
} else {
|
|
continue;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
//
|
|
// Attempt to determine drive type.
|
|
// Only local, fixed, non-FT drives are valid.
|
|
//
|
|
if(MyGetDriveType(Drive) == DRIVE_FIXED) {
|
|
|
|
//
|
|
// Delete any local source that may already be present
|
|
// in the disk.
|
|
//
|
|
DelnodeTemporaryFiles(hdlg,Drive,LocalSourceDirectory);
|
|
#ifdef _X86_
|
|
DelnodeTemporaryFiles(hdlg,Drive,FloppylessBootDirectory);
|
|
#endif
|
|
|
|
if(IsDriveNotNTFT(Drive)) {
|
|
|
|
RetreiveAndFormatMessageIntoBuffer(
|
|
MSG_CHECKING_DRIVE,
|
|
Buffer,
|
|
SIZECHARS(Buffer),
|
|
Drive
|
|
);
|
|
|
|
SendMessage(hdlg,WMX_BILLBOARD_STATUS,0,(LPARAM)Buffer);
|
|
|
|
//
|
|
// Determine filesystem on the drive.
|
|
//
|
|
b = GetVolumeInformation(
|
|
DriveName,
|
|
NULL,0, // don't care about volume label...
|
|
NULL, // ...or serial number
|
|
&DontCare,&DontCare, // .. or max component length or flags
|
|
Buffer, // want filesystem name
|
|
SIZECHARS(Buffer)
|
|
);
|
|
|
|
if(b) {
|
|
|
|
b = GetDiskFreeSpace(
|
|
DriveName,
|
|
&SectorsPerCluster,
|
|
&BytesPerSector,
|
|
&FreeClusters,
|
|
&TotalClusters
|
|
);
|
|
|
|
if(b) {
|
|
|
|
DriveFileSystem[Drive-TEXT('C')] = DupString(Buffer);
|
|
|
|
DriveClusterSize[Drive-TEXT('C')] = SectorsPerCluster * BytesPerSector;
|
|
DriveSectorSize[Drive-TEXT('C')] = BytesPerSector;
|
|
|
|
//
|
|
// Disallow hpfs drives.
|
|
//
|
|
if(lstrcmpi(Buffer,TEXT("HPFS"))) {
|
|
DriveFreeSpace[Drive-TEXT('C')] = UInt32x32To64(
|
|
DriveClusterSize[Drive-TEXT('C')],
|
|
FreeClusters
|
|
);
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
Sleep(200);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
DWORD
|
|
ThreadInspectComputer(
|
|
PVOID ThreadParameter
|
|
)
|
|
{
|
|
HWND hdlg;
|
|
BOOL b;
|
|
TCHAR Buffer[512];
|
|
TCHAR Drive;
|
|
int i;
|
|
|
|
hdlg = (HWND)ThreadParameter;
|
|
|
|
try {
|
|
//
|
|
// Give the dialog box a chance to come up.
|
|
//
|
|
Sleep(50);
|
|
|
|
//
|
|
// Assume success.
|
|
//
|
|
b = TRUE;
|
|
|
|
#ifdef _X86_
|
|
SystemPartitionDrive = x86DetermineSystemPartition(hdlg);
|
|
#else
|
|
//
|
|
// Initialize nv-ram stuff and read boot variables.
|
|
// Do this first because the disk check needs to know
|
|
// whether disks are accessible from the firmware;
|
|
// we will check this by trying to convert the drive letter
|
|
// to an arc path.
|
|
//
|
|
|
|
RetreiveAndFormatMessageIntoBuffer(
|
|
MSG_READING_NVRAM,
|
|
Buffer,
|
|
SIZECHARS(Buffer)
|
|
);
|
|
|
|
SendMessage(hdlg,WMX_BILLBOARD_STATUS,0,(LPARAM)Buffer);
|
|
|
|
b = InitializeArcStuff(hdlg);
|
|
|
|
//
|
|
// Let the user see the message.
|
|
//
|
|
Sleep(200);
|
|
#endif
|
|
|
|
//
|
|
// Determine free space, filesystem, etc on all drives.
|
|
//
|
|
GetInfoAboutDrives(hdlg);
|
|
|
|
#ifdef _X86_
|
|
//
|
|
// If the system partition is HPFS, give an error.
|
|
//
|
|
if(b) {
|
|
GetFilesystemName(SystemPartitionDrive,Buffer,SIZECHARS(Buffer));
|
|
if(!lstrcmpi(Buffer,TEXT("HPFS"))) {
|
|
|
|
MessageBoxFromMessage(
|
|
hdlg,
|
|
MSG_SYSPART_IS_HPFS,
|
|
AppTitleStringId,
|
|
MB_OK | MB_ICONSTOP,
|
|
SystemPartitionDrive
|
|
);
|
|
|
|
b = FALSE;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
//
|
|
// If any drive is hpfs, give a warning. The user can continue.
|
|
//
|
|
if(b) {
|
|
|
|
b = FALSE;
|
|
|
|
for(Drive=TEXT('C'); Drive<=TEXT('Z'); Drive++) {
|
|
|
|
GetFilesystemName(Drive,Buffer,SIZECHARS(Buffer));
|
|
if(!lstrcmpi(Buffer,TEXT("HPFS"))) {
|
|
b = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if(b) {
|
|
i = MessageBoxFromMessage(
|
|
hdlg,
|
|
MSG_HPFS_DRIVES_EXIST,
|
|
AppTitleStringId,
|
|
MB_YESNO | MB_ICONSTOP | MB_DEFBUTTON2
|
|
);
|
|
|
|
b = (i == IDYES);
|
|
} else {
|
|
b = TRUE;
|
|
}
|
|
}
|
|
|
|
//
|
|
// If the system is on hpfs, give a warning. The user can choose to continue,
|
|
// such as if someone wants to install a fresh build on another partition.
|
|
//
|
|
if(b) {
|
|
GetWindowsDirectory(Buffer,SIZECHARS(Buffer));
|
|
Drive = Buffer[0];
|
|
GetFilesystemName(Drive,Buffer,SIZECHARS(Buffer));
|
|
if(!lstrcmpi(Buffer,TEXT("HPFS"))) {
|
|
|
|
i = MessageBoxFromMessage(
|
|
hdlg,
|
|
MSG_SYSTEM_ON_HPFS,
|
|
AppTitleStringId,
|
|
MB_YESNO | MB_ICONSTOP | MB_DEFBUTTON2,
|
|
Drive
|
|
);
|
|
|
|
if(i != IDYES) {
|
|
b = FALSE;
|
|
}
|
|
}
|
|
}
|
|
|
|
#ifdef _X86_
|
|
CheckAColon();
|
|
|
|
//
|
|
// Check space for floppyless operation up front.
|
|
//
|
|
if(b && FloppylessOperation
|
|
&&(DriveFreeSpace[SystemPartitionDrive-TEXT('C')] < (3*FLOPPY_CAPACITY))) {
|
|
|
|
//
|
|
// We must check to see whether the not-enough-space error is because
|
|
// the system partition is mirrored.
|
|
//
|
|
if(IsDriveNotNTFT(SystemPartitionDrive)) {
|
|
MessageBoxFromMessage(
|
|
hdlg,
|
|
MSG_NO_SPACE_FOR_FLOPPYLESS,
|
|
AppTitleStringId,
|
|
MB_OK | MB_ICONSTOP,
|
|
SystemPartitionDrive,
|
|
3*FLOPPY_CAPACITY
|
|
);
|
|
} else {
|
|
MessageBoxFromMessage(
|
|
hdlg,
|
|
MSG_SYSPART_NTFT_SINGLE,
|
|
IDS_ERROR,
|
|
MB_OK | MB_ICONSTOP
|
|
);
|
|
}
|
|
|
|
b = FALSE;
|
|
}
|
|
#endif
|
|
|
|
PostMessage(hdlg,WMX_BILLBOARD_DONE,0,b);
|
|
|
|
} except(EXCEPTION_EXECUTE_HANDLER) {
|
|
|
|
MessageBoxFromMessage(
|
|
hdlg,
|
|
MSG_GENERIC_EXCEPTION,
|
|
AppTitleStringId,
|
|
MB_ICONSTOP | MB_OK | MB_TASKMODAL,
|
|
GetExceptionCode()
|
|
);
|
|
|
|
PostMessage(hdlg, WMX_BILLBOARD_DONE, 0, FALSE);
|
|
|
|
b = FALSE;
|
|
}
|
|
|
|
ExitThread(b);
|
|
return(b); // avoid compiler warning
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|