windows-nt/Source/XPSP1/NT/base/ntsetup/legacy/dll/det_vol.c
2020-09-26 16:20:57 +08:00

750 lines
15 KiB
C

#include "precomp.h"
#pragma hdrstop
/*++
Copyright (c) 1990 Microsoft Corporation
Module Name:
det_vol.c
Abstract:
Disk/volume related detect operations for Win32 PDK Setup.
This module has no external dependencies and is not statically linked
to any part of Setup.
Author:
Ted Miller (tedm) June-August 1991
--*/
#define SPACE_FREE 1
#define SPACE_TOTAL 2
#define DRIVE_TYPE_REMOVABLE "RMV"
#define DRIVE_TYPE_FIXED "FIX"
#define DRIVE_TYPE_REMOTE "REM"
#define DRIVE_TYPE_CDROM "CDR"
#define DRIVE_TYPE_RAMDISK "RAM"
#define DRIVE_TYPE_UNKNOWN "?"
#define GET_TIME_CREATION 1
#define GET_TIME_LASTACCESS 2
#define GET_TIME_LASTWRITE 3
CB GetTimeOfFile(RGSZ,USHORT,SZ,CB,DWORD);
CB GetDrivesWorker(RGSZ,USHORT,SZ,CB,DWORD);
DWORD AreDrivesACertainType(DWORD,BOOL *);
VOID ConstructDiskList(BOOL *,LPSTR);
CB GetSpaceWorker(SZ,CB,DWORD);
//
// Routine to get a drive type. Like GetDriveType() win32 api except
// it attempts to differentiate between removable hard drives and floppies.
// Removeable hard drives will returned as DRIVE_FIXED so we can use
// DRIVE_REMOVABLE as a symonym for "floppy."
//
UINT
MyGetDriveType(
IN PSTR DriveName
)
{
CHAR DriveNameNt[MAX_PATH];
UINT rc;
//
// 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.
//
if((rc = GetDriveType(DriveName)) == DRIVE_REMOVABLE) {
if(DosPathToNtPathWorker(DriveName,DriveNameNt)) {
CharLower(DriveNameNt);
if(!strstr(DriveNameNt,"floppy")) {
rc = DRIVE_FIXED;
}
}
}
return(rc);
}
//
// Gets unused drives
//
CB
GetUnusedDrives(
IN RGSZ Args,
IN USHORT cArgs,
OUT SZ ReturnBuffer,
IN CB cbReturnBuffer
)
{
SZ sz;
RGSZ rgsz;
DWORD Disk;
CHAR szRoot[4] = "?:\\";
CHAR szDrive[3] = "?:";
CB cbRet;
Unused( Args );
Unused( cArgs );
Unused( cbReturnBuffer );
rgsz = RgszAlloc(1);
for( Disk = 26; Disk > 0; Disk-- ) {
szRoot[0] = (CHAR)(Disk - 1) + (CHAR)'A';
if ( MyGetDriveType( szRoot ) == 1 ) {
szDrive[0] = szRoot[0];
RgszAdd( &rgsz, SzDup( szDrive ) );
}
}
sz = SzListValueFromRgsz( rgsz );
lstrcpy( ReturnBuffer, sz );
cbRet = lstrlen( sz );
SFree( sz );
RgszFree( rgsz );
return( cbRet + 1 );
}
//
// Gets the type of a drive
//
CB
GetTypeOfDrive(
IN RGSZ Args,
IN USHORT cArgs,
OUT SZ ReturnBuffer,
IN CB cbReturnBuffer
)
{
SZ szType;
CHAR szRoot[ MAX_PATH];
SZ sz;
Unused( cbReturnBuffer );
if ( (cArgs >= 1) && (*(Args[0]) != '\0') ) {
lstrcpy( szRoot, Args[0] );
sz = szRoot + strlen(szRoot) -1;
if ( *sz != '\\' ) {
strcat( szRoot, "\\" );
}
switch (MyGetDriveType( szRoot )) {
case 0:
case 1:
return 0;
case DRIVE_REMOVABLE:
szType = DRIVE_TYPE_REMOVABLE;
break;
case DRIVE_FIXED:
szType = DRIVE_TYPE_FIXED;
break;
case DRIVE_REMOTE:
szType = DRIVE_TYPE_REMOTE;
break;
case DRIVE_CDROM:
szType = DRIVE_TYPE_CDROM;
break;
case DRIVE_RAMDISK:
szType = DRIVE_TYPE_RAMDISK;
break;
default:
szType = DRIVE_TYPE_UNKNOWN;
break;
}
} else {
szType= DRIVE_TYPE_UNKNOWN;
}
lstrcpy( ReturnBuffer, szType );
return lstrlen( ReturnBuffer )+1;
}
//
// Determines the existence of a directory
//
CB
DoesDirExist(
IN RGSZ Args,
IN USHORT cArgs,
OUT SZ ReturnBuffer,
IN CB cbReturnBuffer
)
{
DWORD Attr;
Unused( cbReturnBuffer );
if ( cArgs == 0 ) {
ReturnBuffer[0] = '\0';
return 0;
} else {
Attr = GetFileAttributes( Args[0] );
if ((Attr != -1) && ( Attr & FILE_ATTRIBUTE_DIRECTORY )) {
lstrcpy( ReturnBuffer, "YES" );
} else {
lstrcpy( ReturnBuffer, "NO" );
}
}
return lstrlen(ReturnBuffer)+1;
}
//
// Determines the existence of a file
//
CB
DoesFileExist(
IN RGSZ Args,
IN USHORT cArgs,
OUT SZ ReturnBuffer,
IN CB cbReturnBuffer
)
{
DWORD Attr;
Unused( cbReturnBuffer );
if ( cArgs == 0 ) {
ReturnBuffer[0] = '\0';
return 0;
} else {
Attr = GetFileAttributes( Args[0] );
if ((Attr != -1) && !( Attr & FILE_ATTRIBUTE_DIRECTORY )) {
lstrcpy( ReturnBuffer, "YES" );
} else {
lstrcpy( ReturnBuffer, "NO" );
}
}
return lstrlen(ReturnBuffer)+1;
}
//
// Get file size
//
CB
GetSizeOfFile(
IN RGSZ Args,
IN USHORT cArgs,
OUT SZ ReturnBuffer,
IN CB cbReturnBuffer
)
{
HANDLE hff;
WIN32_FIND_DATA ffd;
DWORD Size = 0;
#define ZERO_SIZE "0"
Unused( cbReturnBuffer );
ReturnBuffer[0] = '\0';
if (cArgs > 0) {
//
// get find file information and get the size information out of
// that
//
if ((hff = FindFirstFile(Args[0], &ffd)) != INVALID_HANDLE_VALUE) {
Size = ffd.nFileSizeLow;
_ltoa(Size, ReturnBuffer, 10);
FindClose(hff);
return lstrlen(ReturnBuffer)+1;
}
}
//
// If file not specified or file not found default return 0 size
//
lstrcpy( ReturnBuffer, ZERO_SIZE );
return lstrlen(ReturnBuffer)+1;
}
//
// Obtains creation time of a file
//
CB
GetFileCreationTime(
IN RGSZ Args,
IN USHORT cArgs,
OUT SZ ReturnBuffer,
IN CB cbReturnBuffer
)
{
return GetTimeOfFile( Args, cArgs, ReturnBuffer, cbReturnBuffer, GET_TIME_CREATION );
}
//
// Obtains last access time of a file
//
CB
GetFileLastAccessTime(
IN RGSZ Args,
IN USHORT cArgs,
OUT SZ ReturnBuffer,
IN CB cbReturnBuffer
)
{
return GetTimeOfFile( Args, cArgs, ReturnBuffer, cbReturnBuffer, GET_TIME_LASTACCESS );
}
//
// Obtains last write time of a file
//
CB
GetFileLastWriteTime(
IN RGSZ Args,
IN USHORT cArgs,
OUT SZ ReturnBuffer,
IN CB cbReturnBuffer
)
{
return GetTimeOfFile( Args, cArgs, ReturnBuffer, cbReturnBuffer, GET_TIME_LASTWRITE );
}
//
// Obtains any time of a file
//
CB
GetTimeOfFile(
IN RGSZ Args,
IN USHORT cArgs,
OUT SZ ReturnBuffer,
IN CB cbReturnBuffer,
IN DWORD WhatTime
)
{
HANDLE Handle;
FILETIME TimeCreation;
FILETIME TimeLastAccess;
FILETIME TimeLastWrite;
FILETIME WantedTime;
Unused( cbReturnBuffer );
ReturnBuffer[0] = '\0';
if ( ( cArgs > 0) &&
(WhatTime >= GET_TIME_CREATION) &&
(WhatTime <= GET_TIME_LASTWRITE) ) {
Handle = CreateFile( Args[0],
GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
0,
NULL );
if ( Handle != INVALID_HANDLE_VALUE ) {
if ( GetFileTime( Handle, &TimeCreation, &TimeLastAccess, &TimeLastWrite ) ) {
switch( WhatTime ) {
case GET_TIME_CREATION:
WantedTime = TimeCreation;
break;
case GET_TIME_LASTACCESS:
WantedTime = TimeLastAccess;
break;
case GET_TIME_LASTWRITE:
WantedTime = TimeLastWrite;
break;
default:
break;
}
}
CloseHandle( Handle );
wsprintf( ReturnBuffer, "{\"%lu\",\"%lu\"}", WantedTime.dwLowDateTime,
WantedTime.dwHighDateTime );
return lstrlen(ReturnBuffer)+1;
}
}
return 0;
}
/*
Return a list of floppy drive letters
*/
CB
GetFloppyDriveLetters(
IN RGSZ Args,
IN USHORT cArgs,
OUT SZ ReturnBuffer,
IN CB cbReturnBuffer
)
{
return(GetDrivesWorker(Args,
cArgs,
ReturnBuffer,
cbReturnBuffer,
DRIVE_REMOVABLE
)
);
}
/*
Return a list of hard drive letters
*/
CB
GetHardDriveLetters(
IN RGSZ Args,
IN USHORT cArgs,
OUT SZ ReturnBuffer,
IN CB cbReturnBuffer
)
{
return(GetDrivesWorker(Args,
cArgs,
ReturnBuffer,
cbReturnBuffer,
DRIVE_FIXED
)
);
}
/*
Return a list of filesystems on all hard drive volumes.
*/
CB
GetHardDriveFileSystems(
IN RGSZ Args,
IN USHORT cArgs,
OUT SZ ReturnBuffer,
IN CB cbReturnBuffer
)
{
BOOL HardDisk[26];
DWORD Disk;
LPSTR InsertPoint = ReturnBuffer;
char DiskName[4] = { 'x',':','\\','\0' };
char FileSys[MAX_PATH];
DWORD SizeSoFar;
UINT ErrorMode;
Unused(Args);
Unused(cArgs);
AreDrivesACertainType(DRIVE_FIXED,HardDisk);
*InsertPoint++ = '{';
SizeSoFar = 2;
ErrorMode = SetErrorMode( SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX );
for(Disk=0; Disk<26; Disk++) {
if(HardDisk[Disk]) {
DiskName[0] = (char)Disk + (char)'A';
if(!GetVolumeInformation(DiskName,NULL,0,NULL,NULL,NULL,FileSys,sizeof(FileSys))) {
*FileSys = '\0';
} else if(!lstrcmpi(FileSys,"raw")) {
*FileSys = '\0';
}
SizeSoFar += lstrlen(FileSys)+3; // 3 is for "",
if(SizeSoFar > cbReturnBuffer) {
SetErrorMode( ErrorMode );
return(SizeSoFar);
}
*InsertPoint++ = '"';
lstrcpy(InsertPoint,FileSys);
InsertPoint = strchr(InsertPoint,0);
*InsertPoint++ = '"';
*InsertPoint++ = ',';
}
}
if(*(InsertPoint-1) == ',') {
*(InsertPoint-1) = '}'; // overwrite final comma
} else {
if(++SizeSoFar > cbReturnBuffer) {
SetErrorMode( ErrorMode );
return(SizeSoFar);
}
*InsertPoint++ = '}';
}
*InsertPoint = '\0';
SetErrorMode( ErrorMode );
return(lstrlen(ReturnBuffer)+1);
}
/*
Return a list of ASCII representations of free space on all
hard disk volumes
*/
CB
GetHardDriveFreeSpace(
IN RGSZ Args,
IN USHORT cArgs,
OUT SZ ReturnBuffer,
IN CB cbReturnBuffer
)
{
CB Size;
UINT ErrorMode;
Unused(Args);
Unused(cArgs);
ErrorMode = SetErrorMode( SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX );
Size = GetSpaceWorker(ReturnBuffer,cbReturnBuffer,SPACE_FREE);
SetErrorMode( ErrorMode );
return(Size);
}
/*
Return a list of ASCII representations of total space on all
hard disk volumes
*/
CB
GetHardDriveTotalSpace(
IN RGSZ Args,
IN USHORT cArgs,
OUT SZ ReturnBuffer,
IN CB cbReturnBuffer
)
{
CB Size;
UINT ErrorMode;
Unused(Args);
Unused(cArgs);
ErrorMode = SetErrorMode( SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX );
Size = GetSpaceWorker(ReturnBuffer,cbReturnBuffer,SPACE_TOTAL);
SetErrorMode( ErrorMode );
return(Size);
}
/******************************************************************
Subroutines
*/
CB
GetDrivesWorker(
IN RGSZ Args,
IN USHORT cArgs,
OUT SZ ReturnBuffer,
IN CB cbReturnBuffer,
IN DWORD TypeOfDrive
)
{
char DriveName[4] = { 'x',':','\\','\0' };
BOOL IsValid[26];
DWORD NumMatches;
DWORD SpaceRequired;
Unused(Args);
Unused(cArgs);
NumMatches = AreDrivesACertainType(TypeOfDrive,IsValid);
SpaceRequired = (NumMatches * 5) + 3 - 1;
if(cbReturnBuffer < SpaceRequired) {
return(SpaceRequired);
} else {
ConstructDiskList(IsValid,ReturnBuffer);
return(lstrlen(ReturnBuffer)+1);
}
}
DWORD
AreDrivesACertainType(
IN DWORD TypeWereLookingFor,
IN BOOL *Results
)
{
char DriveLetter;
char DriveName[4] = { 'x',':','\\','\0' };
DWORD NumMatches = 0;
DWORD DriveNumber = 0;
for(DriveLetter='A'; DriveLetter <= 'Z'; DriveLetter++)
{
DriveName[0] = DriveLetter;
Results[DriveNumber] = (MyGetDriveType(DriveName) == TypeWereLookingFor);
if(Results[DriveNumber]) {
NumMatches++;
}
DriveNumber++;
}
return(NumMatches);
}
VOID
ConstructDiskList(
IN BOOL *ValidDisk,
IN LPSTR TextOut
)
{
DWORD DriveNumber;
LPSTR InsertPoint = TextOut;
*InsertPoint++ = '{';
for(DriveNumber=0; DriveNumber<26; DriveNumber++) {
if(ValidDisk[DriveNumber]) {
*InsertPoint++ = '"';
*InsertPoint++ = (char)DriveNumber + (char)'A';
*InsertPoint++ = ':';
*InsertPoint++ = '"';
*InsertPoint++ = ',';
}
}
if(*(InsertPoint-1) == ',') {
*(InsertPoint-1) = '}'; // overwrite final comma
} else {
*InsertPoint++ = '}';
}
*InsertPoint = '\0';
}
CB
GetSpaceWorker(
OUT SZ ReturnBuffer,
IN CB cbReturnBuffer,
IN DWORD TypeOfSpace
)
{
BOOL HardDisk[26];
DWORD Disk;
LPSTR InsertPoint = ReturnBuffer;
char DiskName[4] = { 'x',':','\\','\0' };
DWORD SizeSoFar;
DWORD SectorsPerCluster,BytesPerSector,FreeClusters,TotalClusters;
DWORD Space;
char SpaceSTR[15];
AreDrivesACertainType(DRIVE_FIXED,HardDisk);
*InsertPoint++ = '{';
SizeSoFar = 2;
for(Disk=0; Disk<26; Disk++) {
if(HardDisk[Disk]) {
DiskName[0] = (char)Disk + (char)'A';
if(GetDiskFreeSpace(DiskName,
&SectorsPerCluster,
&BytesPerSector,
&FreeClusters,
&TotalClusters))
{
Space = SectorsPerCluster * BytesPerSector
* (TypeOfSpace == SPACE_FREE ? FreeClusters : TotalClusters)
/ (1024*1024); // converts # to megabytes
} else {
// assume unformatted
Space = GetPartitionSize(DiskName);
}
wsprintf(SpaceSTR,"%lu",Space);
SizeSoFar += lstrlen(SpaceSTR)+3; // 3 is for "",
if(SizeSoFar > cbReturnBuffer) {
return(SizeSoFar);
}
*InsertPoint++ = '"';
lstrcpy(InsertPoint,SpaceSTR);
InsertPoint = strchr(InsertPoint,0);
*InsertPoint++ = '"';
*InsertPoint++ = ',';
}
}
if(*(InsertPoint-1) == ',') {
*(InsertPoint-1) = '}'; // overwrite final comma
} else {
if(++SizeSoFar > cbReturnBuffer) {
return(SizeSoFar);
}
*InsertPoint++ = '}';
}
*InsertPoint = '\0';
return(lstrlen(ReturnBuffer)+1);
}