home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Chip 2002 November
/
Chip_2002-11_cd1.bin
/
zkuste
/
delphi
/
unity
/
d56
/
DW
/
DW10242.ZIP
/
DriveWorks.pas
< prev
next >
Wrap
Pascal/Delphi Source File
|
2002-07-08
|
21KB
|
735 lines
(*----------------------------- DriveWorks.pas -------------------------
V1.0.236 - 08.07.2002 current release
------------------------------------------------------------------------*)
unit DriveWorks;
interface
uses Classes, Windows, SysUtils, MMSystem, NumWorks, StringWorks, ShellApi;
type
TDWDriveShellInfo = packed record
Icon : hIcon;
Image : integer;
DisplayName,
TypeName : string
end;
TDWEjectRemovableResult = (dwejeUnsupported,
dwejeVolumeLocked,
dwejeUnremovable,
dwejeRequestFailed,
dwejeAllReady);
TDiocRegisters = record
EBX, EDX, ECX, EAX, EDI, ESI, Flags: DWORD;
end;
TVWin32CtlCode = (ccNone, ccVWin32IntIoctl, ccVWin32Int26,
ccVWin32Int25, ccVWin32Int13);
TBiosParamBlock = packed record
BytesPerSector: Word;
SectorsPerCluster: Byte;
ReservedSectors: Word;
NumFats: Byte;
NumRootEntries: Word;
NumSectors: Word;
MediaID: Byte;
SectorsPerFat: Word;
SectorsPerTrack: Word;
NumHeads: Word;
HiddenSectors: Word;
Dummy1: Word;
TotalSectors: LongInt;
Dummy2: array[0..5] of Byte;
end;
TDeviceParamBlock = packed record
Special: Byte;
DeviceType: Byte;
DeviceAttr: Word;
NumCylinders: Word;
MediaType: Byte;
BiosParamBlock: TBiosParamBlock;
end;
TFormatParamBlock = packed record
Reserved: Byte;
Head: Word;
Cylinder: Word;
end;
TDriveInformation = record
VolumeName : string;
VolumeSerialNumber,
MaximumComponentLength,
FileSystemFlags : DWord;
FileSystemName : string;
end;
TDiskGeometry = record
Cylinders: Integer;
MediaType: Integer;
TracksPerCylinder: DWord;
SectorsPerTrack: DWord;
BytesPerSector: DWord;
end;
(*V1.0.236*)
function GetDriveShellInfo(const Drive: Char): TDWDriveShellInfo;
function EjectRemovable(const Drive: Char): TDWEjectRemovableResult;
function ApplicationHostDrive: Char;
function AvailableDrives: TStringList;
function CloseCD(Drive: Char): Boolean;
function DrivesCount: Integer;
function DiskInDrive(Drive: Char): Boolean;
function DiskWriteProtected(Drive: Char): Boolean;
function DriveSectorsPerCluster(Drive: Char): Integer;
function DriveBytesPerSector(Drive: Char): Integer;
function DriveBytesPerCluster(Drive: Char): Integer;
function DriveFreeClusters(Drive: Char): Integer;
function DriveTotalClusters(Drive: Char): Integer;
function DriveFreeSpace(Drive: Char): Int64;
function DriveTotalSpace(Drive: Char): Int64;
function DriveSerialNumber(Drive: Char): String;
function DriveSerialNumberInt(Drive: Char): Integer;
function DriveVolumeName(Drive: Char): String;
function DriveMaxFilenameLength(Drive: Char): Integer;
function DriveCasePreserved(Drive: Char): Boolean;
function DriveSectorsPerTrack(Drive: Char): Integer;
function DriveReservedSectors(Drive: Char): Integer;
function DriveTracksCount(Drive: Char): Integer;
function DriveHeadCount(Drive: Char): Integer;
function DriveFATCount(Drive: Char): Integer;
function DriveRootEntries(Drive: Char): Integer;
function DriveHiddenSectors(Drive: Char): Integer;
function DriveCylinders(Drive: Char): Integer;
function DriveSectorsPerFAT(Drive: Char): Integer;
function DriveFilesystemName(Drive: Char): String;
function HardDrives: TStringList;
function HardDrivesLong: TStringList;
function OpenCD(Drive: Char): Boolean;
function SystemHostDrive: Char;
function ValidDriveLetter(Drive: Char): Boolean;
function ValidateDriveLetter(Drive: Char): Char;
function DriveLetterToIndex(Drive: Char): Byte;
function DriveIndexToLetter(Drive: Byte): Char;
function GetVolumeInformationX (Drive: Char; var V : TDriveInformation): Boolean;
function VWin32(CtlCode: TVWin32CtlCode; var Regs: TDiocRegisters): Boolean;
function GetDeviceParamBlock(Drive: Char; var ParamBlock: TDeviceParamBlock): Word;
function SetDeviceParamBlock(Drive: Char; var ParamBlock: TDeviceParamBlock): Word;
function FloppyReady(const Drive: char): Boolean;
function CompareDiskStruct(Drive: Char; var BPC, SPC, BPS, FC, TC: Integer; var FS, TS, DSN: Int64): Boolean;
var bbb:TDeviceParamBlock;
implementation
function GetDriveShellInfo(const Drive: Char): TDWDriveShellInfo;
var
SHFileInfo : TSHFileInfo;
begin
ShGetFileInfo (PChar(Drive + ':\'),
0,
SHFileInfo,
SizeOf (TSHFileInfo),
SHGFI_TYPENAME or
SHGFI_DISPLAYNAME or
SHGFI_SYSICONINDEX or
SHGFI_ICON);
with result do
begin
Icon := SHFileInfo.hIcon;
Image := SHFileInfo.iIcon;
DisplayName := SHFileInfo.szDisplayName;
TypeName := SHFileInfo.szTypeName
end
end;
function EjectRemovable(const Drive: Char): TDWEjectRemovableResult;
var
hDevice : THandle;
Nb : DWORD;
Reg : TDiocRegisters;
VersionInfo : TOSVersionInfo;
const
VWIN32_DIOC_DOS_IOCTL = 1;
IOCTL_STORAGE_EJECT_MEDIA = 2967560;
begin
result:= dwejeUnsupported;
VersionInfo.dwOSVersionInfoSize := SizeOf(TOSVersionInfo);
GetVersionEx(VersionInfo);
if VersionInfo.dwPlatformId = VER_PLATFORM_WIN32_NT then
hDevice := CreateFile(PChar('\\.\' + Drive + ':'), GENERIC_READ,
FILE_SHARE_READ, nil, OPEN_EXISTING, 0, 0)
else
hDevice := CreateFile('\\.\VWIN32', 0, 0, nil, 0,
FILE_FLAG_DELETE_ON_CLOSE, 0);
if hDevice = INVALID_HANDLE_VALUE then
RaiseLastWin32Error;
if VersionInfo.dwPlatformId = VER_PLATFORM_WIN32_NT then begin
if not DeviceIoControl(hDevice, IOCTL_STORAGE_EJECT_MEDIA,
nil, 0, nil, 0, Nb, nil) then
RaiseLastWin32Error;
end else begin
with Reg do begin
EAX := $440D;
EBX := Byte(Drive) - $40;
ECX := $0849;
end;
DeviceIoControl(hDevice, VWIN32_DIOC_DOS_IOCTL,
@Reg, SizeOf(Reg), @Reg, SizeOf(Reg), Nb, nil);
if Reg.Flags and 1 = 1 then case Reg.EAX of
$01: result:= dwejeUnsupported;
$B1: result:= dwejeVolumeLocked;
$B2: result:= dwejeUnremovable;
$B5: result:= dwejeRequestFailed;
end else result:= dwejeAllReady;
end;
CloseHandle(hDevice);
end;
function ApplicationHostDrive: Char;
begin
result:= ParamStr(0)[1];
end;
function AvailableDrives: TStringList;
var
i: Integer;
C: String;
DType: Integer;
DriveString: String;
begin
result:= TStringList.Create;
(* Zeichen 65 = A und 90 = Z -- Schleife durch alle m÷glichen Laufwerke *)
for i := 65 to 90 do
begin
(* Aktuellen Schleifenindex in entsprechenden Laufwerksbezeichner wandeln *)
C := chr(i)+':\';
(* Die Funktion GetDriveType() ermittelt den Medientyp des Laufwerks *)
DType := GetDriveType(PChar(C));
(* Ermittelten Medientyp auswerten und entsprechende Meldung generieren *)
case DType of
0: DriveString:= C+' Unbekannter Laufwerkstyp';
1: DriveString:= C+' Kein Stammverzeichnis gefunden';
DRIVE_REMOVABLE: DriveString:= C+' WechseldatentrΣger';
DRIVE_FIXED: DriveString:= C+' Festplatte';
DRIVE_REMOTE: DriveString:= C+' Netzwerklaufwerk';
DRIVE_CDROM: DriveString := C+' CD-ROM Laufwerk';
DRIVE_RAMDISK: DriveString := C+' RAM Disk';
end;
(* Gⁿltige Laufwerksbezeichner in Liste aufnehmen *)
if not ((DType = 0) or (DType = 1)) then result.Add(DriveString);
end;
end;
function CloseCD(Drive: Char): Boolean;
var
Res: MciError;
OpenParm: TMCI_Open_Parms;
Flags: DWORD;
S: string;
DeviceID: Word;
begin
Result := False;
S := Drive + ':';
Flags := mci_Open_Type or mci_Open_Element;
with OpenParm do
begin
dwCallback := 0;
lpstrDeviceType := 'CDAudio';
lpstrElementName := PChar(S);
end;
Res := mciSendCommand(0, mci_Open, Flags, Longint(@OpenParm));
if Res = 0 then Exit;
DeviceID := OpenParm.wDeviceID;
try
Res := mciSendCommand(DeviceID, MCI_SET, MCI_SET_DOOR_CLOSED, 0);
if Res = 0 then Exit;
Result := True;
finally
mciSendCommand(DeviceID, mci_Close, Flags, Longint(@OpenParm));
end;
end;
function DrivesCount: Integer;
var
TempList: TStringList;
begin
TempList:= AvailableDrives;
result:= TempList.Count;
TempList.Free;
end;
function DiskInDrive(Drive: Char): Boolean;
var
DriveNumber: Byte;
ErrorMode : Word;
begin
result := FALSE;
DriveNumber := ORD( UpCase(Drive) );
ErrorMode := SetErrorMode(SEM_FAILCRITICALERRORS);
try
if DiskSize(DriveNumber-ORD('A')+1) <> -1 then result:= TRUE;
finally
SetErrorMode(ErrorMode)
end;
end;
function DiskWriteProtected(Drive: Char): Boolean;
var
ErrorMode: Word;
PathName : String;
TempName : String;
begin
ErrorMode := SetErrorMode(SEM_FAILCRITICALERRORS);
try
Assert(Upcase(drive) in ['A'..'Z'], 'Invalid drive specification');
PathName := drive + ':\';
SetLength(TempName, MAX_PATH+1);
GetTempFileName(PChar(PathName), 'RWRO', 0, PChar(TempName));
result := (GetLastError = Windows.ERROR_WRITE_PROTECT);
if not result then result := not DeleteFile(TempName);
finally
SetErrorMode(ErrorMode)
end;
end;
function DriveSectorsPerCluster(Drive: Char): Integer;
var
RootPath: String;
SectorsPerCluster,
BytesPerSector,
NumFreeClusters,
TotalClusters: DWord;
begin
Drive:= ValidateDriveLetter(Drive);
RootPath:= Drive + ':\';
if GetDiskFreeSpace(PChar(RootPath), SectorsPerCluster,
BytesPerSector, NumFreeClusters, TotalClusters) then
result:= SectorsPerCluster else result:= -1;
end;
function DriveBytesPerSector(Drive: Char): Integer;
var
RootPath: String;
SectorsPerCluster,
BytesPerSector,
NumFreeClusters,
TotalClusters: DWord;
begin
Drive:= ValidateDriveLetter(Drive);
RootPath:= Drive + ':\';
if GetDiskFreeSpace(PChar(RootPath), SectorsPerCluster,
BytesPerSector, NumFreeClusters, TotalClusters) then
result:= BytesPerSector else result:= -1;
end;
function DriveBytesPerCluster(Drive: Char): Integer;
begin
result:= DriveBytesPerSector(Drive) * DriveSectorsPerCluster(Drive);
end;
function DriveFreeClusters(Drive: Char): Integer;
var
RootPath: String;
SectorsPerCluster,
BytesPerSector,
NumFreeClusters,
TotalClusters: DWord;
begin
Drive:= ValidateDriveLetter(Drive);
RootPath:= Drive + ':\';
if GetDiskFreeSpace(PChar(RootPath), SectorsPerCluster,
BytesPerSector, NumFreeClusters, TotalClusters) then
result:= NumFreeClusters else result:= -1;
end;
function DriveTotalClusters(Drive: Char): Integer;
var
RootPath: String;
SectorsPerCluster,
BytesPerSector,
NumFreeClusters,
TotalClusters: DWord;
begin
Drive:= ValidateDriveLetter(Drive);
RootPath:= Drive + ':\';
if GetDiskFreeSpace(PChar(RootPath), SectorsPerCluster,
BytesPerSector, NumFreeClusters, TotalClusters) then
result:= TotalClusters else result:= -1;
end;
function DriveFreeSpace(Drive: Char): Int64;
begin
result:= DiskFree(DriveLetterToIndex(Drive));
end;
function DriveTotalSpace(Drive: Char): Int64;
begin
result:= DiskSize(DriveLetterToIndex(Drive));
end;
function DriveSerialNumber(Drive: Char): String;
var
DI: TDriveInformation;
TempStr: String;
begin
Drive:= ValidateDriveLetter(Drive);
GetVolumeInformationX(Drive, DI);
TempStr:= IntToHex(DI.VolumeSerialNumber, 8);
result:= Copy(TempStr, 1, 4) + '-' + Copy(TempStr, 5, 4);
end;
function DriveSerialNumberInt(Drive: Char): Integer;
var
DI: TDriveInformation;
begin
Drive:= ValidateDriveLetter(Drive);
GetVolumeInformationX(Drive, DI);
result:= DI.VolumeSerialNumber;
end;
function DriveVolumeName(Drive: Char): String;
var
DI: TDriveInformation;
begin
Drive:= ValidateDriveLetter(Drive);
GetVolumeInformationX(Drive, DI);
result:= DI.VolumeName;
end;
function DriveMaxFilenameLength(Drive: Char): Integer;
var
DI: TDriveInformation;
begin
Drive:= ValidateDriveLetter(Drive);
GetVolumeInformationX(Drive, DI);
result:= DI.MaximumComponentLength;
end;
function DriveCasePreserved(Drive: Char): Boolean;
var
DI: TDriveInformation;
begin
Drive:= ValidateDriveLetter(Drive);
GetVolumeInformationX(Drive, DI);
result:= TRUE;//([FS_CASE_IS_PRESERVED] in DI.FileSystemFlags);
end;
function DriveSectorsPerTrack(Drive: Char): Integer;
var
DPB: TDeviceParamBlock;
begin
Drive:= ValidateDriveLetter(Drive);
GetDeviceParamBlock(Drive, DPB);
result:= DPB.BiosParamBlock.SectorsPerTrack;
end;
function DriveReservedSectors(Drive: Char): Integer;
var
DPB: TDeviceParamBlock;
begin
Drive:= ValidateDriveLetter(Drive);
GetDeviceParamBlock(Drive, DPB);
result:= DPB.BiosParamBlock.ReservedSectors;
end;
function DriveTracksCount(Drive: Char): Integer;
var
TotalSectors, TracksOn: Integer;
begin
Drive:= ValidateDriveLetter(Drive);
TotalSectors:= RoundUp(DriveTotalClusters(Drive) * DriveSectorsPerCluster(Drive));
TracksOn:= RoundUp(TotalSectors div DriveSectorsPerTrack(Drive))+1;
result:= RoundUp(TracksOn div DriveHeadCount(Drive));
end;
function DriveHeadCount(Drive: Char): Integer;
var
DPB: TDeviceParamBlock;
begin
Drive:= ValidateDriveLetter(Drive);
GetDeviceParamBlock(Drive, DPB);
result:= DPB.BiosParamBlock.NumHeads;
end;
function DriveFATCount(Drive: Char): Integer;
var
DPB: TDeviceParamBlock;
begin
Drive:= ValidateDriveLetter(Drive);
GetDeviceParamBlock(Drive, DPB);
result:= DPB.BiosParamBlock.NumFats;
end;
function DriveRootEntries(Drive: Char): Integer;
var
DPB: TDeviceParamBlock;
begin
Drive:= ValidateDriveLetter(Drive);
GetDeviceParamBlock(Drive, DPB);
result:= DPB.BiosParamBlock.NumRootEntries;
end;
function DriveHiddenSectors(Drive: Char): Integer;
var
DPB: TDeviceParamBlock;
begin
Drive:= ValidateDriveLetter(Drive);
GetDeviceParamBlock(Drive, DPB);
result:= DPB.BiosParamBlock.HiddenSectors;
end;
function DriveCylinders(Drive: Char): Integer;
var
DPB: TDeviceParamBlock;
begin
Drive:= ValidateDriveLetter(Drive);
GetDeviceParamBlock(Drive, DPB);
result:= DPB.NumCylinders;
end;
function DriveSectorsPerFAT(Drive: Char): Integer;
var
DPB: TDeviceParamBlock;
begin
Drive:= ValidateDriveLetter(Drive);
GetDeviceParamBlock(Drive, DPB);
result:= DPB.BiosParamBlock.SectorsPerFat;
end;
function DriveFilesystemName(Drive: Char): String;
var
DI: TDriveInformation;
begin
Drive:= ValidateDriveLetter(Drive);
GetVolumeInformationX(Drive, DI);
result:= DI.FileSystemName;
end;
function HardDrives: TStringList;
var
i: Integer;
C: String;
DType: Integer;
// DriveString: String;
begin
result:= TStringList.Create;
(* Zeichen 65 = A und 90 = Z -- Schleife durch alle m÷glichen Laufwerke *)
for i := 65 to 90 do
begin
(* Aktuellen Schleifenindex in entsprechenden Laufwerksbezeichner wandeln *)
C := chr(i)+':\';
(* Die Funktion GetDriveType() ermittelt den Medientyp des Laufwerks *)
DType := GetDriveType(PChar(C));
(* Gⁿltige Laufwerksbezeichner in Liste aufnehmen *)
if ( DType = DRIVE_FIXED ) then begin
result.Add(C);
end;
end;
end;
function HardDrivesLong: TStringList;
var
i: Integer;
C: String;
DType: Integer;
DriveString: String;
begin
result:= TStringList.Create;
(* Zeichen 65 = A und 90 = Z -- Schleife durch alle m÷glichen Laufwerke *)
for i := 65 to 90 do
begin
(* Aktuellen Schleifenindex in entsprechenden Laufwerksbezeichner wandeln *)
C := chr(i)+':\';
(* Die Funktion GetDriveType() ermittelt den Medientyp des Laufwerks *)
DType := GetDriveType(PChar(C));
(* Ermittelten Medientyp auswerten und entsprechende Meldung generieren *)
case DType of
DRIVE_FIXED: begin
DriveString:= DriveVolumeName(Chr(I));
DriveString:= PChar(Copy(DriveString, 1, StringLen(DriveString)) +
' (' + Chr(I) + ':)');
result.Add(DriveString);
end;
end;
end;
end;
function OpenCD(Drive: Char): Boolean;
var
Res: MciError;
OpenParm: TMCI_Open_Parms;
Flags: DWORD;
S: string;
DeviceID: Word;
begin
Result := False;
S := Drive + ':';
Flags := mci_Open_Type or mci_Open_Element;
with OpenParm do
begin
dwCallback := 0;
lpstrDeviceType := 'CDAudio';
lpstrElementName := PChar(S);
end;
Res := mciSendCommand(0, mci_Open, Flags, Longint(@OpenParm));
if Res = 0 then Exit;
DeviceID := OpenParm.wDeviceID;
try
Res := mciSendCommand(DeviceID, MCI_SET, MCI_SET_DOOR_OPEN, 0);
if Res = 0 then Exit;
Result := True;
finally
mciSendCommand(DeviceID, mci_Close, Flags, Longint(@OpenParm));
end;
end;
function SystemHostDrive: Char;
var
SysDir: Pchar;
begin
SysDir:= StrAlloc(MAX_PATH);
GetWindowsDirectory(SysDir, MAX_PATH+1);
result:= SysDir[0];
end;
//---------------------------------------------------------------------
function ValidDriveLetter(Drive: Char): Boolean;
begin
result:= not ((Ord(UpCase(Drive)) < 65) or (Ord(UpCase(Drive)) > 90));
end;
function ValidateDriveLetter(Drive: Char): Char;
begin
if ValidDriveLetter(Drive) then result:= UpCase(Drive) else result:= 'C';
end;
function DriveLetterToIndex(Drive: Char): Byte;
begin
Drive:= ValidateDriveLetter(Drive);
result:= (Ord(Drive) - 64);
end;
function DriveIndexToLetter(Drive: Byte): Char;
begin
if (Drive > 0) and (Drive < 27) then result:= UpCase(Chr(Drive))
else result:= 'C';
end;
function GetVolumeInformationX (Drive: Char; var V : TDriveInformation): Boolean;
var
EM : integer;
begin
EM := SetErrorMode (SEM_FAILCRITICALERRORS);
result:= FALSE;
Drive:= ValidateDriveLetter(Drive);
try
with V do
begin
SetLength (VolumeName, MAX_PATH);
SetLength (FileSystemName, MAX_PATH);
VolumeSerialNumber := 0;
MaximumComponentLength := 0;
FileSystemFlags := 0;
GetVolumeInformation (PChar (Drive+':\'), PChar (VolumeName), MAX_PATH,
@VolumeSerialNumber, MaximumComponentLength, FileSystemFlags,
PChar (FileSystemName), MAX_PATH);
end;
finally
SetErrorMode (EM);
end;
end;
function VWin32(CtlCode: TVWin32CtlCode; var Regs: TDiocRegisters): Boolean;
var
hDevice: THandle;
Count: DWORD;
begin
hDevice := CreateFile('\\.\VWIN32', 0, 0, nil, 0,
FILE_FLAG_DELETE_ON_CLOSE, 0);
Result := DeviceIoControl(hDevice, Ord(CtlCode), @Regs, SizeOf(Regs),
@Regs, SizeOf(Regs), Count, nil);
CloseHandle(hDevice);
end;
function GetDeviceParamBlock(Drive: Char; var ParamBlock: TDeviceParamBlock): Word;
var
Regs: TDiocRegisters;
begin
with Regs do
begin
EAX := $440D;
EBX := Ord(UpCase(Drive)) - Ord('@');
ECX := $0860;
EDX := LongInt(@ParamBlock);
VWin32(ccVWin32IntIoctl, Regs);
if (Flags and 1) <> 0 then
Result := LoWord(EAX)
else
Result := 0;
end;
end;
function SetDeviceParamBlock(Drive: Char; var ParamBlock: TDeviceParamBlock): Word;
var
Regs: TDiocRegisters;
begin
with Regs do
begin
EAX := $440D;
EBX := Ord(UpCase(Drive)) - Ord('@');
ECX := $0840;
EDX := LongInt(@ParamBlock);
VWin32(ccVWin32IntIoctl, Regs);
if (Flags and 1) <> 0 then
Result := LoWord(EAX)
else
Result := 0;
end;
end;
function FloppyReady(const Drive: char): Boolean;
var
DrvNum: byte;
EMode: Word;
begin
result := false;
DrvNum := ord(Drive);
if DrvNum >= ord('a') then dec(DrvNum,$20);
EMode := SetErrorMode(SEM_FAILCRITICALERRORS);
try
if DiskSize(DrvNum-$40) <> -1 then result := true
else messagebeep(0);
finally
SetErrorMode(EMode);
end;
end;
function CompareDiskStruct(Drive: Char; var BPC, SPC, BPS, FC, TC: Integer; var FS, TS, DSN: Int64): Boolean;
begin
result:= ((BPC = DriveBytesPerCluster(Drive)) and
(SPC = DriveSectorsPerCluster(Drive)) and
(BPS = DriveBytesPerSector(Drive)) and
(FC = DriveFreeClusters(Drive)) and
(TC = DriveTotalClusters(Drive)) and
(FS = DriveFreeSpace(Drive)) and
(TS = DriveTotalSpace(Drive)) and
(DSN = DriveSerialNumberInt(Drive)));
end;
end.