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.
 
 
 
 
 
 

1089 lines
27 KiB

/*++
Copyright (c) 1993 Microsoft Corporation
Module Name:
dnflop.c
Abstract:
Floppy-disk creation routines for 32-bit winnt setup.
Author:
Ted Miller (tedm) 19-December-1993
Revision History:
--*/
#include "precomp.h"
#pragma hdrstop
#ifdef _X86_
#include "msg.h"
//
// This header file contains an array of 512 bytes
// representing the NT FAT boot code, in a variable
// of type unsigned char[] called FatBootCode.
//
#include <bootfat.h>
#pragma pack(1)
//
// Define bpb structure.
//
typedef struct _MY_BPB {
USHORT BytesPerSector;
UCHAR SectorsPerCluster;
USHORT ReservedSectors;
UCHAR FatCount;
USHORT RootDirectoryEntries;
USHORT SectorCountSmall;
UCHAR MediaDescriptor;
USHORT SectorsPerFat;
USHORT SectorsPerTrack;
USHORT HeadCount;
} MY_BPB, *PMY_BPB;
#pragma pack()
//
// Marco for accessing unaligned ushorts in the above structure.
// Not strictly needed on x86 but if this code is ever portable
// then this is necessary.
//
#define U_USHORT(x) (*(USHORT UNALIGNED *)&(x))
// Macro to align a buffer.
//
#define ALIGN(p,val) \
\
(PVOID)((((ULONG)(p) + (val) - 1)) & (~((val) - 1)))
BOOL
DnCopyOemBootFiles(
HWND hdlg,
PTSTR TargetPath
)
{
ULONG Count;
DWORD d;
DWORD ec;
DWORD BytesWritten;
UINT SrcNo = 0;
UINT SourceIndex[MAX_SOURCES];
PTSTR SourceDirectory = WINNT_OEM_TEXTMODE_DIR;
TCHAR SourceFilename[MAX_PATH];
TCHAR TargetFilename[MAX_PATH];
for( Count = 0; Count < OemBootFilesCount; Count++ ) {
//
// Form full paths. For secondary files (ie, files getting copied
// to boot floppies/local boot dir) we want to pick one of the
// sources and not just use the same source over and over.
//
for(d=0; d<SourceCount; d++) {
SourceIndex[d] = (SrcNo+d)%SourceCount;
}
SrcNo = (SrcNo + 1) % SourceCount;
do {
for(d=0; d<SourceCount; d++) {
if(bCancelled) {
return((DWORD)(-1));
}
_lstrcpyn(SourceFilename,Sources[SourceIndex[d]],MAX_PATH);
DnConcatenatePaths(SourceFilename,SourceDirectory,MAX_PATH);
DnConcatenatePaths(SourceFilename,OemBootFiles[Count],MAX_PATH);
_lstrcpyn(TargetFilename,TargetPath,MAX_PATH);
DnConcatenatePaths(TargetFilename,OemBootFiles[Count],MAX_PATH);
BytesWritten = DnCopyOneFile(hdlg,SourceFilename,TargetFilename,&ec);
if(BytesWritten != (DWORD)(-1)) {
ec = NO_ERROR; // causes break out of while loop
break; // break out of for loop
}
//
// Got an error copying. If this is that last source we can try
// then tell the user about the error. Otherwise let the loop
// continue and we'll try the next source.
//
if(d == (SourceCount-1)) {
switch(DnFileCopyError(hdlg,SourceFilename,TargetFilename,ec)) {
case COPYERR_EXIT:
PostMessage(hdlg,WM_COMMAND,IDCANCEL,0);
return((DWORD)(-1));
case COPYERR_SKIP:
ec = NO_ERROR; // causes break out of while loop
d = SourceCount; // causes break out of for loop
BytesWritten = 0;
break;
case COPYERR_RETRY:
//
// Set vars to force starting over at source 0.
//
ec = NO_ERROR+1; // forces us to stay within while loop
d = (DWORD)(-1); // forces for loop to start over
break;
}
}
}
} while(ec != NO_ERROR);
}
return( TRUE );
}
BOOL
MyGetBpb(
OUT PMY_BPB Bpb,
OUT PBOOL DriveBusy
)
/*++
Routine Description:
Return the BPB for the disk in drive A:. The BPB is read directly
from the disk.
Arguments:
Bpb - receives the BPB.
Return Value:
Boolean value indicating whether the bpb was successfully retreived
and copied into the caller-supplied buffer.
--*/
{
PVOID UnalignedBuffer;
PUCHAR Buffer;
HANDLE Handle;
BOOL b;
DWORD BytesRead;
//
// This value is only used to allocate a buffer
// to read sector 0 of the floppy in a:.
//
DWORD BytesPerSector = 512;
//
// Open A:
//
Handle = CreateFile(
TEXT("\\\\.\\A:"),
GENERIC_READ,
0,
NULL,
OPEN_EXISTING,
0,
NULL
);
if(Handle == INVALID_HANDLE_VALUE) {
DWORD err = GetLastError();
*DriveBusy = ((err == ERROR_SHARING_VIOLATION) || (err == ERROR_ACCESS_DENIED));
return(FALSE);
}
//
// Allocate an aligned buffer.
//
UnalignedBuffer = MALLOC(2*BytesPerSector);
Buffer = ALIGN(UnalignedBuffer,BytesPerSector);
if(b = ReadFile(Handle,Buffer,BytesPerSector,&BytesRead,NULL)) {
if((Buffer[0] == 0xeb)
&& (Buffer[2] == 0x90)
&& (Buffer[510] == 0x55)
&& (Buffer[511] == 0xaa))
{
//
// Transfer the bpb into the caller's buffer.
//
CopyMemory(Bpb,Buffer+11,sizeof(MY_BPB));
} else {
//
// Bogus signature, probably not DOS disk.
//
b = FALSE;
}
}
//
// Clean up.
//
FREE(UnalignedBuffer);
CloseHandle(Handle);
return(b);
}
BOOL
MyWriteBootSector(
IN PUCHAR Buffer
)
/*++
Routine Description:
Write a bufferful of data to the bootsector of the disk in drive a.
Arguments:
Buffer - supplies the boot sector to be written. This buffer should
be 512 bytes long.
Return Value:
Boolean value indicating whether the boot sector was successfully
written.
--*/
{
PVOID UBuffer,ABuffer;
HANDLE Handle;
BOOL rc;
DWORD BytesWritten;
//
// This value is only used to allocate a buffer
// to read sector 0 of the floppy in a:.
//
DWORD BytesPerSector = 512;
//
// Open A:
//
Handle = CreateFile(
TEXT("\\\\.\\A:"),
GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
FILE_FLAG_WRITE_THROUGH,
NULL
);
if(Handle == INVALID_HANDLE_VALUE) {
return(FALSE);
}
UBuffer = MALLOC(2*BytesPerSector);
ABuffer = ALIGN(UBuffer,BytesPerSector);
CopyMemory(ABuffer,Buffer,BytesPerSector);
rc = WriteFile(Handle,ABuffer,BytesPerSector,&BytesWritten,NULL);
FREE(UBuffer);
CloseHandle(Handle);
return(rc);
}
BOOL
DnPromptAndInspectFloppy(
IN DWORD FirstPromptId,
IN DWORD SubsequentPromptId,
OUT PMY_BPB Bpb,
IN HWND hdlg,
IN PTSTR FloppyName,
IN PTSTR Floppy0Name,
IN PTSTR Floppy1Name,
IN PTSTR Floppy2Name
)
/*++
Routine Description:
Prompt the user to insert a floppy disk in drive a:, and inspect
the disk to make sure it appears to be a formatted MS-DOS compatible
floppy disk.
Arguments:
FirstPromptId - supplies the message to be used in prompting the
user to insert the disk.
SubsequentPromptId - supplies the message to be used to prompt the
user for a disk if the first disk he inserts is not acceptable.
Return Value:
FALSE if the user elects to exit setup. TRUE if setup should continue.
--*/
{
DWORD PromptId,ErrorId;
DWORD FreeSpace;
DWORD spc,bps,freeclus,totclus;
DWORD ec;
BOOL DriveBusy;
int rc;
PromptId = FirstPromptId;
do {
do {
rc = UiMessageBox(
hdlg,
PromptId,
AppTitleStringId,
MB_OKCANCEL | MB_ICONASTERISK,
FloppyName,
Floppy0Name,
Floppy1Name,
Floppy2Name
);
if(rc == IDCANCEL) {
ec = UiMessageBox(
hdlg,
MSG_SURE_EXIT,
AppTitleStringId,
MB_YESNO | MB_DEFBUTTON2 | MB_ICONQUESTION
);
if(ec == IDYES) {
return(FALSE);
}
}
} while(rc == IDCANCEL);
PromptId = SubsequentPromptId;
ErrorId = 0;
//
// Get the BPB for the disk in the drive.
//
if(!MyGetBpb(Bpb,&DriveBusy)) {
// Unable to get the current BPB for the disk. Assume
// Assume not formatted or not formatted correctly.
//
ErrorId = DriveBusy ? MSG_FLOPPY_BUSY : MSG_FLOPPY_NOT_FORMATTED;
} else {
//
// Sanity check on the BPB
//
if((U_USHORT(Bpb->BytesPerSector) != 512)
|| ( (Bpb->SectorsPerCluster != 1)
&& (Bpb->SectorsPerCluster != 2)) // for 2.88M disks
|| (U_USHORT(Bpb->ReservedSectors) != 1)
|| (Bpb->FatCount != 2)
|| !U_USHORT(Bpb->SectorCountSmall) // should be < 32M
|| (Bpb->MediaDescriptor == 0xf8) // hard disk
|| (U_USHORT(Bpb->HeadCount) != 2)
|| !U_USHORT(Bpb->RootDirectoryEntries)) {
ErrorId = MSG_FLOPPY_BAD_FORMAT;
} else {
if(GetDiskFreeSpace(TEXT("A:\\"),&spc,&bps,&freeclus,&totclus)) {
FreeSpace = freeclus * spc * bps;
if(FreeSpace < FLOPPY_CAPACITY) {
ErrorId = MSG_FLOPPY_NOT_BLANK;
}
} else {
ErrorId = MSG_FLOPPY_CANT_GET_SPACE;
}
}
}
//
// If there is a problem with the disk, inform the user.
//
if(ErrorId) {
UiMessageBox(
hdlg,
ErrorId,
IDS_ERROR,
MB_OK | MB_ICONEXCLAMATION
);
}
} while(ErrorId);
return(TRUE);
}
BOOL
DoCreateBootFloppies(
IN HWND hdlg,
IN PTSTR Floppy0Name,
IN PTSTR Floppy1Name,
IN PTSTR Floppy2Name
)
/*++
Routine Description:
Create the winnt boot floppies by copying files listed in three
sections of dosnet.inf to 3 separate floppies, and preparing one
of the floppies to boot the setup boot loader.
If we are in floppyless operation, we will instead copy the files
into a special directory on the system partition (usually C:).
This routine is expecting to be the entry point of a separate
thread to perform this action.
Arguments:
hdlg - supplies handle to dialog currently displayed.
Return Value:
FALSE if the program should end (critical error).
TRUE otherwise.
--*/
{
int i;
DWORD ErrorId;
UCHAR SectorBuffer[512];
TCHAR TextBuffer[1024];
MY_BPB Bpb;
BOOL b;
BOOL rc = TRUE;
DWORD ec;
TCHAR BootRoot[64];
PTSTR System32Dir;
if(FloppylessOperation) {
BootRoot[0] = SystemPartitionDrive;
BootRoot[1] = ':';
lstrcpy(BootRoot+2,FloppylessBootDirectory);
//
// Create the boot dir. First get rid of any file by that name.
//
SetFileAttributes(BootRoot,FILE_ATTRIBUTE_NORMAL);
DeleteFile(BootRoot);
CreateDirectory(BootRoot,NULL);
RetreiveAndFormatMessageIntoBuffer(
MSG_PREPARING_FLOPPYLESS,
TextBuffer,
SIZECHARS(TextBuffer)
);
} else {
RetreiveAndFormatMessageIntoBuffer(
CreateLocalSource ? MSG_PREPARING_FLOPPY_ALSO : MSG_PREPARING_FLOPPY,
TextBuffer,
SIZECHARS(TextBuffer),
Floppy2Name
);
lstrcpy(BootRoot,TEXT("A:"));
}
System32Dir = MALLOC((lstrlen(BootRoot)*sizeof(TCHAR))+sizeof(TEXT("\\SYSTEM32")));
lstrcpy(System32Dir,BootRoot);
lstrcat(System32Dir,TEXT("\\SYSTEM32"));
//
// Get a floppy in the drive -- this will be "Windows NT Setup Disk #3"
//
if(FloppylessOperation) {
b = TRUE;
} else {
b = DnPromptAndInspectFloppy(
MSG_FIRST_FLOPPY_PROMPT,
MSG_GENERIC_FLOPPY_PROMPT,
&Bpb,
hdlg,
Floppy2Name,
Floppy0Name,
Floppy1Name,
Floppy2Name
);
}
if(!b || bCancelled) {
rc = FALSE;
goto flop1;
}
AuxillaryStatus(hdlg,TextBuffer);
//
// Copy files to the disk.
//
ec = CopySectionOfFilesToCopy(
hdlg,
INF_FLOPPYFILES2,
BootRoot,
0,
FALSE
);
if(ec == (DWORD)(-1) || bCancelled) {
AuxillaryStatus(hdlg,NULL);
rc = FALSE;
goto flop1;
}
if(!FloppylessOperation) {
RetreiveAndFormatMessageIntoBuffer(
CreateLocalSource ? MSG_PREPARING_FLOPPY_ALSO : MSG_PREPARING_FLOPPY,
TextBuffer,
SIZECHARS(TextBuffer),
Floppy1Name
);
}
do {
//
// Get a floppy in the drive -- this will be "Windows NT Setup Disk #2"
//
if(FloppylessOperation) {
b = TRUE;
} else {
b = DnPromptAndInspectFloppy(
MSG_GENERIC_FLOPPY_PROMPT,
MSG_GENERIC_FLOPPY_PROMPT,
&Bpb,
hdlg,
Floppy1Name,
Floppy0Name,
Floppy1Name,
Floppy2Name
);
}
if(!b || bCancelled) {
rc = FALSE;
goto flop1;
}
AuxillaryStatus(hdlg,TextBuffer);
//
// Hack: create system32 directory on the floppy.
//
SetFileAttributes(System32Dir,FILE_ATTRIBUTE_NORMAL);
DeleteFile(System32Dir);
CreateDirectory(System32Dir,NULL);
//
// Copy files to the disk.
//
ec = CopySectionOfFilesToCopy(
hdlg,
INF_FLOPPYFILES1,
BootRoot,
0,
FALSE
);
if(ec == (DWORD)(-1) || bCancelled) {
AuxillaryStatus(hdlg,NULL);
rc = FALSE;
goto flop1;
}
//
// Unless we're creating retail boot disks, put a small file
// on the disk indicating that it's a winnt setup.
//
if(FloppyOption != OnlyRetailFloppies) {
b = DnIndicateWinnt(hdlg,BootRoot,NULL,NULL);
AuxillaryStatus(hdlg,NULL);
if(!b) {
UiMessageBox(
hdlg,
MSG_CANT_WRITE_FLOPPY,
IDS_ERROR,
MB_OK | MB_ICONEXCLAMATION
);
}
}
} while(!b);
if(!FloppylessOperation) {
RetreiveAndFormatMessageIntoBuffer(
CreateLocalSource ? MSG_PREPARING_FLOPPY_ALSO : MSG_PREPARING_FLOPPY,
TextBuffer,
SIZECHARS(TextBuffer),
Floppy0Name
);
}
do {
ErrorId = 0;
//
// Get a floppy in the drive -- this will be "Windows NT Setup Boot Disk"
//
if(FloppylessOperation) {
b = TRUE;
} else {
b = DnPromptAndInspectFloppy(
MSG_GENERIC_FLOPPY_PROMPT,
MSG_GENERIC_FLOPPY_PROMPT,
&Bpb,
hdlg,
Floppy0Name,
Floppy0Name,
Floppy1Name,
Floppy2Name
);
}
if(!b || bCancelled) {
rc = FALSE;
goto flop1;
}
AuxillaryStatus(hdlg,TextBuffer);
if(!FloppylessOperation) {
CopyMemory(SectorBuffer,FatBootCode,512);
//
// Copy the BPB we retreived for the disk into the bootcode template.
// We only care about the original BPB fields, through the head count
// field. We will fill in the other fields ourselves.
//
strncpy(SectorBuffer+3,"MSDOS5.0",8);
CopyMemory(SectorBuffer+11,&Bpb,sizeof(MY_BPB));
//
// Set up other fields in the bootsector/BPB/xBPB.
//
// Large sector count (4 bytes)
// Hidden sector count (4 bytes)
// current head (1 byte, not necessary to set this, but what the heck)
// physical disk# (1 byte)
//
ZeroMemory(SectorBuffer+28,10);
//
// Extended BPB signature
//
SectorBuffer[38] = 41;
//
// Serial number
//
*(DWORD UNALIGNED *)(SectorBuffer+39) = ((GetTickCount() << 12)
| ((GetTickCount() >> 4) & 0xfff));
//
// volume label/system id
//
strncpy(SectorBuffer+43,"NO NAME ",11);
strncpy(SectorBuffer+54,"FAT12 ",8);
//
// Overwrite the 'ntldr' string with 'setupldr.bin' so the right file gets
// loaded when the floppy is booted.
//
for(i=499; i>0; --i) {
if(!memcmp("NTLDR ",SectorBuffer+i,11)) {
strncpy(SectorBuffer+i,"SETUPLDRBIN",11);
break;
}
}
}
//
// Write the boot sector.
//
if(FloppylessOperation || MyWriteBootSector(SectorBuffer)) {
//
// Copy files into the disk.
//
ec = CopySectionOfFilesToCopy(
hdlg,
INF_FLOPPYFILES0,
BootRoot,
0,
FALSE
);
AuxillaryStatus(hdlg,NULL);
if(ec == (DWORD)(-1) || bCancelled) {
rc = FALSE;
goto flop1;
}
} else {
AuxillaryStatus(hdlg,NULL);
ErrorId = MSG_FLOPPY_WRITE_BS;
}
if(ErrorId) {
UiMessageBox(
hdlg,
ErrorId,
IDS_ERROR,
MB_OK | MB_ICONEXCLAMATION
);
}
} while(ErrorId);
//
// Additionally in the floppyless case, we need to copy some files
// from the boot directory to the root of the system partition drive.
//
if(FloppylessOperation && rc) {
TCHAR DriveRootPath[] = TEXT("?:\\");
BOOL b, ForceNoComp = FALSE;
DWORD DontCare;
DWORD FsFlags;
AuxillaryStatus(hdlg,TextBuffer);
DriveRootPath[0] = SystemPartitionDrive;
b = GetVolumeInformation(
DriveRootPath,
NULL,0, // don't care about volume label...
NULL, // ...or serial number
&DontCare, // .. or max component length
&FsFlags, // want fs flags
NULL,0 // don't care about fs name
);
if(b && (FsFlags & FS_FILE_COMPRESSION)) {
ForceNoComp = TRUE;
}
ec = CopySectionOfFilesToCopy(
hdlg,
INF_FLOPPYFILESX,
BootRoot,
0,
FALSE
);
AuxillaryStatus(hdlg,NULL);
if(ec == (DWORD)(-1) || bCancelled) {
rc = FALSE;
goto flop1;
}
AuxillaryStatus(hdlg,TextBuffer);
System32Dir[0] = BootRoot[0];
System32Dir[1] = TEXT(':');
System32Dir[2] = 0;
rc = DnCopyFilesInSection(hdlg,
INF_ROOTBOOTFILES,
BootRoot,
System32Dir,
ForceNoComp
);
AuxillaryStatus(hdlg,NULL);
if(rc && !bCancelled) {
AuxillaryStatus(hdlg,TextBuffer);
if(rc = DnMungeBootIni(hdlg)) {
rc = DnLayAuxBootSector(hdlg);
}
AuxillaryStatus(hdlg,NULL);
if(rc && !bCancelled && OemPreInstall) {
TCHAR OemBootDir[MAX_PATH];
AuxillaryStatus(hdlg,TextBuffer);
lstrcpy( OemBootDir, BootRoot );
DnConcatenatePaths(OemBootDir,WINNT_OEM_DIR,MAX_PATH);
if( DnpCreateOneDirectory( OemBootDir, hdlg ) ) {
rc = DnCopyOemBootFiles( hdlg, OemBootDir );
}
AuxillaryStatus(hdlg,NULL);
}
}
}
flop1:
FREE(System32Dir);
return(rc);
}
DWORD
ThreadAuxilliaryAction(
IN PVOID ThreadParameter
)
{
HWND hdlg;
BOOL b;
PTSTR Floppy0Name,Floppy1Name;
PTSTR Floppy2Name;
hdlg = (HWND)ThreadParameter;
try {
if(CreateFloppies || FloppylessOperation) {
Floppy0Name = MyLoadString(ServerProduct ? IDS_SFLOPPY0_NAME : IDS_WFLOPPY0_NAME);
Floppy1Name = MyLoadString(ServerProduct ? IDS_SFLOPPY1_NAME : IDS_WFLOPPY1_NAME);
Floppy2Name = MyLoadString(ServerProduct ? IDS_SFLOPPY2_NAME : IDS_WFLOPPY2_NAME);
b = DoCreateBootFloppies(
hdlg,
Floppy0Name,
Floppy1Name,
Floppy2Name
);
FREE(Floppy0Name);
FREE(Floppy1Name);
FREE(Floppy2Name);
if(!b) {
//
// If the user has cancelled winnt32, do not post IDCANCEL massage.
// Otherwise, winnt32 will start a second instance of ThreadRestoreComputer,
// and due to a race condition between the two instances of the thread,
// the temporary directory $win_nt$.~ls will not be deleted.
//
if( !bCancelled ) {
PostMessage(hdlg, WM_COMMAND, IDCANCEL, 0);
}
}
} else {
b = TRUE;
}
PostMessage(hdlg,WMX_AUXILLIARY_ACTION_DONE,b,0);
} except(EXCEPTION_EXECUTE_HANDLER) {
MessageBoxFromMessage(
hdlg,
MSG_GENERIC_EXCEPTION,
AppTitleStringId,
MB_ICONSTOP | MB_OK | MB_SETFOREGROUND,
GetExceptionCode()
);
b = FALSE;
PostMessage(hdlg,WMX_AUXILLIARY_ACTION_DONE,b,0);
}
ExitThread(b);
return(b);
}
UINT
DlgProcSysPartSpaceWarn(
IN HWND hdlg,
IN UINT msg,
IN WPARAM wParam,
IN LPARAM lParam
)
{
switch(msg) {
case WM_INITDIALOG:
{
TCHAR Buffer[4096];
PTSTR p;
p = MyLoadString(AppTitleStringId);
SetWindowText(hdlg,p);
FREE(p);
//
//
// Center the dialog on the screen and bring it to the top.
//
CenterDialog(hdlg);
SetForegroundWindow(hdlg);
MessageBeep(MB_ICONQUESTION);
//
// Set the icon to be the warning exclamation
//
SendDlgItemMessage(
hdlg,
IDC_EXCLAIM,
STM_SETICON,
(WPARAM)LoadIcon(NULL, IDI_EXCLAMATION),
0
);
RetreiveAndFormatMessageIntoBuffer(
MSG_SYSPART_LOW_X86,
Buffer,
SIZECHARS(Buffer),
SystemPartitionDrive
);
SetDlgItemText(hdlg,IDC_TEXT1,Buffer);
return(FALSE);
}
case WM_COMMAND:
switch(LOWORD(wParam)) {
case IDOK:
case IDCANCEL:
EndDialog(hdlg, (UINT)LOWORD(wParam));
break;
case ID_HELP:
MyWinHelp(hdlg, IDD_SYSPART_LOW_X86);
break;
default:
return(FALSE);
}
break;
default:
return(FALSE);
}
return(TRUE);
}
VOID
CheckAColon(
VOID
)
{
#ifndef ALLOW_525
HANDLE h;
BOOL b;
UCHAR Buffer[2048];
DWORD Size;
PDISK_GEOMETRY Geometry;
unsigned i,Count;
AColonIsAcceptable = FALSE;
//
// Open A: device
//
h = CreateFile(
TEXT("\\\\.\\A:"),
FILE_READ_ATTRIBUTES,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
0,
NULL
);
if(h != INVALID_HANDLE_VALUE) {
b = DeviceIoControl(
h,
IOCTL_DISK_GET_MEDIA_TYPES,
NULL,
0,
Buffer,
sizeof(Buffer),
&Size,
NULL
);
if(b) {
Geometry = (PDISK_GEOMETRY)Buffer;
Count = Size/sizeof(DISK_GEOMETRY);
for(i=0; !AColonIsAcceptable && (i<Count); i++) {
switch(Geometry[i].MediaType) {
case Unknown: // unknown media type
case F5_1Pt2_512: // 5.25", 1.2MB, 512 bytes/sector
case F3_720_512: // 3.5", 720KB, 512 bytes/sector
case F5_360_512: // 5.25", 360KB, 512 bytes/sector
case F5_320_512: // 5.25", 320KB, 512 bytes/sector
case F5_320_1024: // 5.25", 320KB, 1024 bytes/sector
case F5_180_512: // 5.25", 180KB, 512 bytes/sector
case F5_160_512: // 5.25", 160KB, 512 bytes/sector
case FixedMedia: // Fixed hard disk media
case RemovableMedia: // Removable media other than floppy
//
// All of these are unacceptable
//
break;
case F3_1Pt44_512: // 3.5", 1.44MB, 512 bytes/sector
case F3_2Pt88_512: // 3.5", 2.88MB, 512 bytes/sector
case F3_20Pt8_512: // 3.5", 20.8MB, 512 bytes/sector
default:
//
// All of these are acceptable. Assume that any
// types added in the future will also be acceptable.
//
AColonIsAcceptable = TRUE;
break;
}
}
}
CloseHandle(h);
}
#endif
}
#endif //def _X86_