Windows NT 4.0 source code leak
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.
 
 
 
 
 
 

576 lines
14 KiB

/** FILE: syspart.c ******** Module Header ********************************
*
* Control panel applet for System configuration. This file holds
* everything to do with finding the system partition where the
* boot.ini file for x86 systems resides.
*
* History:
* 08 Sept 1994 -by- Steve Cathcart [stevecat]
* Took base routines from TedM's SETUP code
*
* Copyright (C) 1994 Microsoft Corporation
*
*************************************************************************/
//==========================================================================
// Include files
//==========================================================================
// C Runtime
#include "stdio.h"
#include "stdlib.h"
// For NT apis
#include "nt.h"
#include "ntrtl.h"
#include "nturtl.h"
// For Windows apis
#include "windows.h"
#include "winioctl.h"
//==========================================================================
// Local Definitions
//==========================================================================
#define MALLOC(size) Malloc(size)
#define REALLOC(block,size) Realloc((block),(size))
#define FREE(block) Free(&(block))
//==========================================================================
// Typedefs and Structs
//==========================================================================
//==========================================================================
// External Declarations
//==========================================================================
/* Functions */
extern void ErrMemDlg (HWND hParent);
//==========================================================================
// Local Data Declarations
//==========================================================================
//==========================================================================
// Local Function Prototypes
//==========================================================================
#ifdef _X86_
PVOID Malloc (IN DWORD Size)
/*++
Routine Description:
Allocates memory and fatal errors if none is available.
Arguments:
Size - number of bytes to allocate
Return Value:
Pointer to memory.
--*/
{
PVOID p;
if ((p = (PVOID)LocalAlloc(LPTR,Size)) == NULL)
{
ErrMemDlg (NULL);
}
return(p);
}
VOID Free (IN OUT PVOID *Block)
/*++
Routine Description:
Free a block of memory previously allocated with Malloc().
Arguments:
Block - supplies pointer to block to free.
Return Value:
None.
--*/
{
LocalFree((HLOCAL)*Block);
*Block = NULL;
}
PVOID Realloc (IN PVOID Block, IN DWORD Size)
/*++
Routine Description:
Reallocates a block of memory previously allocated with Malloc();
fatal errors if none is available.
Arguments:
Block - supplies pointer to block to resize
Size - number of bytes to allocate
Return Value:
Pointer to memory.
--*/
{
PVOID p;
if ((p = LocalReAlloc((HLOCAL)Block,Size,0)) == NULL)
{
ErrMemDlg (NULL);
}
return (p);
}
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);
}
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);
}
PWSTR ArcPathToNtPath (IN PWSTR ArcPath)
{
NTSTATUS Status;
HANDLE ObjectHandle;
OBJECT_ATTRIBUTES Obja;
UNICODE_STRING UnicodeString;
UCHAR Buffer[1024];
PWSTR arcPath;
PWSTR ntPath;
//
// Assume failure
//
ntPath = NULL;
arcPath = MALLOC(((wcslen(ArcPath)+1)*sizeof(WCHAR)) + sizeof(L"\\ArcName"));
wcscpy (arcPath, L"\\ArcName\\");
wcscat (arcPath, ArcPath);
RtlInitUnicodeString (&UnicodeString, arcPath);
InitializeObjectAttributes (
&Obja,
&UnicodeString,
OBJ_CASE_INSENSITIVE,
NULL,
NULL
);
Status = NtOpenSymbolicLinkObject (
&ObjectHandle,
READ_CONTROL | SYMBOLIC_LINK_QUERY,
&Obja
);
if (NT_SUCCESS(Status))
{
//
// Query the object to get the link target.
//
UnicodeString.Buffer = (PWSTR)Buffer;
UnicodeString.Length = 0;
UnicodeString.MaximumLength = sizeof(Buffer);
Status = NtQuerySymbolicLinkObject (
ObjectHandle,
&UnicodeString,
NULL
);
if (NT_SUCCESS(Status))
{
ntPath = MALLOC(UnicodeString.Length+sizeof(WCHAR));
CopyMemory(ntPath,UnicodeString.Buffer,UnicodeString.Length);
ntPath[UnicodeString.Length/sizeof(WCHAR)] = 0;
}
NtClose (ObjectHandle);
}
FREE (arcPath);
return (ntPath);
}
BOOL AppearsToBeSysPart(
IN PDRIVE_LAYOUT_INFORMATION DriveLayout,
IN WCHAR Drive
)
{
PARTITION_INFORMATION PartitionInfo,*p;
BOOL IsPrimary;
unsigned i;
HANDLE FindHandle;
WIN32_FIND_DATA FindData;
PTSTR BootFiles[] = { TEXT("BOOT.INI"),
TEXT("NTLDR"),
TEXT("NTDETECT.COM"),
NULL
};
TCHAR FileName[64];
//
// Get partition information for this partition.
//
if (!GetPartitionInfo((TCHAR)Drive,&PartitionInfo))
{
return(FALSE);
}
//
// See if the drive is a primary partition.
//
IsPrimary = FALSE;
for (i=0; i<min(DriveLayout->PartitionCount,4); i++)
{
p = &DriveLayout->PartitionEntry[i];
if((p->PartitionType != PARTITION_ENTRY_UNUSED)
&& (p->StartingOffset.QuadPart == PartitionInfo.StartingOffset.QuadPart)
&& (p->PartitionLength.QuadPart == PartitionInfo.PartitionLength.QuadPart))
{
IsPrimary = TRUE;
break;
}
}
if (!IsPrimary)
{
return(FALSE);
}
//
// Don't rely on the active partition flag. This could easily not be
// accurate (like user is using os/2 boot manager, for example).
//
//
// See whether an nt boot files are present on this drive.
//
for (i=0; BootFiles[i]; i++)
{
wsprintf (FileName, TEXT("%wc:\\%s"), Drive, BootFiles[i]);
FindHandle = FindFirstFile (FileName, &FindData);
if (FindHandle == INVALID_HANDLE_VALUE)
{
return (FALSE);
}
else
{
FindClose (FindHandle);
}
}
return (TRUE);
}
TCHAR x86DetermineSystemPartition (IN HWND hdlg)
/*++
Routine Description:
Determine the system partition on x86 machines.
The system partition is the primary partition on the boot disk.
Usually this is the active partition on disk 0 and usually it's C:.
However the user could have remapped drive letters and generally
determining the system partition with 100% accuracy is not possible.
The one thing we can be sure of is that the system partition is on
the physical hard disk with the arc path multi(0)disk(0)rdisk(0).
We can be sure of this because by definition this is the arc path
for bios drive 0x80.
This routine determines which drive letters represent drives on
that physical hard drive, and checks each for the nt boot files.
The first drive found with those files is assumed to be the system
partition.
If for some reason we cannot determine the system partition by the above
method, we simply assume it's C:.
Arguments:
hdlg - Handle of topmost window currently being displayed. (unused)
Return Value:
Drive letter of system partition.
--*/
{
BOOL GotIt;
PWSTR NtDevicePath;
WCHAR Drive;
WCHAR DriveName[3];
WCHAR Buffer[512];
DWORD NtDevicePathLen;
PWSTR p;
DWORD PhysicalDriveNumber;
HANDLE hDisk;
BOOL b;
DWORD DataSize;
PVOID DriveLayout;
DWORD DriveLayoutSize;
DriveName[1] = L':';
DriveName[2] = 0;
GotIt = FALSE;
//
// The system partition must be on multi(0)disk(0)rdisk(0)
//
if (NtDevicePath = ArcPathToNtPath (L"multi(0)disk(0)rdisk(0)"))
{
//
// The arc path for a disk device is usually linked
// to partition0. Get rid of the partition part of the name.
//
CharLowerW (NtDevicePath);
if (p = wcsstr (NtDevicePath, L"\\partition"))
{
*p = 0;
}
NtDevicePathLen = lstrlenW (NtDevicePath);
//
// Determine the physical drive number of this drive.
// If the name is not of the form \device\harddiskx then
// something is very wrong.
//
if (!wcsncmp (NtDevicePath, L"\\device\\harddisk", 16))
{
PhysicalDriveNumber = wcstoul (NtDevicePath+16, NULL, 10);
wsprintfW (Buffer, L"\\\\.\\PhysicalDrive%u", PhysicalDriveNumber);
//
// Get drive layout info for this physical disk.
//
hDisk = CreateFileW (
Buffer,
GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
0,
NULL
);
if (hDisk != INVALID_HANDLE_VALUE)
{
//
// Get partition information.
//
DriveLayout = MALLOC(1024);
DriveLayoutSize = 1024;
retry:
b = DeviceIoControl (
hDisk,
IOCTL_DISK_GET_DRIVE_LAYOUT,
NULL,
0,
DriveLayout,
DriveLayoutSize,
&DataSize,
NULL
);
if (!b && (GetLastError() == ERROR_INSUFFICIENT_BUFFER))
{
DriveLayoutSize += 1024;
DriveLayout = REALLOC(DriveLayout,DriveLayoutSize);
goto retry;
}
CloseHandle (hDisk);
if (b)
{
//
// The system partition can only be a drive that is on
// this disk. We make this determination by looking at NT drive names
// for each drive letter and seeing if the nt equivalent of
// multi(0)disk(0)rdisk(0) is a prefix.
//
for (Drive=L'C'; Drive<=L'Z'; Drive++)
{
if (MyGetDriveType ((TCHAR)Drive) == DRIVE_FIXED)
{
DriveName[0] = Drive;
if (QueryDosDeviceW (DriveName, Buffer, sizeof(Buffer)/sizeof(WCHAR)))
{
if (!_wcsnicmp (NtDevicePath, Buffer, NtDevicePathLen))
{
//
// Now look to see whether there's an nt boot sector and
// boot files on this drive.
//
if (AppearsToBeSysPart(DriveLayout,Drive))
{
GotIt = TRUE;
break;
}
}
}
}
}
}
FREE(DriveLayout);
}
}
FREE(NtDevicePath);
}
return (GotIt ? (TCHAR)Drive : TEXT('C'));
}
#endif // _x86_