|
@@ -292,9 +292,156 @@ type
|
|
|
|
|
|
|
|
|
|
function do_diskdata(drive : byte; Free : boolean) : Int64;
|
|
function do_diskdata(drive : byte; Free : boolean) : Int64;
|
|
|
|
+var
|
|
|
|
+ blocksize, freeblocks, totblocks : longword;
|
|
|
|
+
|
|
|
|
+ { Get disk data via old int21/36 (GET FREE DISK SPACE). It's always supported
|
|
|
|
+ even if it returns wrong values for volumes > 2GB and for cdrom drives when
|
|
|
|
+ in pure DOS. Note that it's also the only way to get some data on WinNTs. }
|
|
|
|
+ function DiskData_36 : boolean;
|
|
|
|
+ begin
|
|
|
|
+ DiskData_36:=false;
|
|
|
|
+ dosregs.dl:=drive;
|
|
|
|
+ dosregs.ah:=$36;
|
|
|
|
+ msdos(dosregs);
|
|
|
|
+ if dosregs.ax=$FFFF then exit;
|
|
|
|
+
|
|
|
|
+ blocksize:=dosregs.ax*dosregs.cx;
|
|
|
|
+ freeblocks:=dosregs.bx;
|
|
|
|
+ totblocks:=dosregs.dx;
|
|
|
|
+ Diskdata_36:=true;
|
|
|
|
+ end;
|
|
|
|
+
|
|
|
|
+ { Get disk data via int21/7303 (FAT32 - GET EXTENDED FREE SPACE ON DRIVE).
|
|
|
|
+ It is supported by win9x even in pure DOS }
|
|
|
|
+ function DiskData_7303 : boolean;
|
|
|
|
+ var
|
|
|
|
+ s : shortstring;
|
|
|
|
+ rec : ExtendedFat32FreeSpaceRec;
|
|
|
|
+ begin
|
|
|
|
+ DiskData_7303:=false;
|
|
|
|
+ s:=chr(drive+$40)+':\'+#0;
|
|
|
|
+
|
|
|
|
+ rec.Strucversion:=0;
|
|
|
|
+ rec.RetSize := 0;
|
|
|
|
+ dosregs.dx:=Ofs(s[1]);
|
|
|
|
+ dosregs.ds:=Seg(s[1]);
|
|
|
|
+ dosregs.di:=Ofs(Rec);
|
|
|
|
+ dosregs.es:=Seg(Rec);
|
|
|
|
+ dosregs.cx:=Sizeof(ExtendedFat32FreeSpaceRec);
|
|
|
|
+ dosregs.ax:=$7303;
|
|
|
|
+ msdos(dosregs);
|
|
|
|
+ if (dosregs.flags and fcarry) <> 0 then
|
|
|
|
+ exit;
|
|
|
|
+ if Rec.RetSize = 0 then
|
|
|
|
+ exit;
|
|
|
|
+
|
|
|
|
+ blocksize:=rec.SecPerClus*rec.BytePerSec;
|
|
|
|
+ freeblocks:=rec.AvailAllocUnits;
|
|
|
|
+ totblocks:=rec.TotalAllocUnits;
|
|
|
|
+ DiskData_7303:=true;
|
|
|
|
+ end;
|
|
|
|
+
|
|
|
|
+ { Get disk data asking to MSCDEX. Pure DOS returns wrong values with
|
|
|
|
+ int21/7303 or int21/36 if the drive is a CDROM drive }
|
|
|
|
+ function DiskData_CDROM : boolean;
|
|
|
|
+ var req : TRequestHeader;
|
|
|
|
+ sectreq : TCDSectSizeReq;
|
|
|
|
+ sizereq : TCDVolSizeReq;
|
|
|
|
+ i : integer;
|
|
|
|
+ status,byteswritten : word;
|
|
|
|
+ drnum : byte;
|
|
|
|
+ begin
|
|
|
|
+ DiskData_CDROM:=false;
|
|
|
|
+ exit;
|
|
|
|
+ { TODO: implement }
|
|
|
|
+(* drnum:=drive-1; //for MSCDEX, 0 = a, 1 = b etc, unlike int21/36
|
|
|
|
+
|
|
|
|
+ { Is this a CDROM drive? }
|
|
|
|
+ dosregs.ax:=$150b;
|
|
|
|
+ dosregs.cx:=drnum;
|
|
|
|
+ realintr($2f,dosregs);
|
|
|
|
+ if (dosregs.bx<>$ADAD) or (dosregs.ax=0) then
|
|
|
|
+ exit; // no, it isn't
|
|
|
|
+
|
|
|
|
+ { Prepare the request header to send to the cdrom driver }
|
|
|
|
+ FillByte(req,sizeof(req),0);
|
|
|
|
+ req.length:=sizeof(req);
|
|
|
|
+ req.command:=IOCTL_INPUT;
|
|
|
|
+ req.transf_ofs:=tb_offset+sizeof(req); //CDROM control block will follow
|
|
|
|
+ req.transf_seg:=tb_segment; //the request header
|
|
|
|
+ req.numbytes:=sizeof(sectreq);
|
|
|
|
+
|
|
|
|
+ { We're asking the sector size }
|
|
|
|
+ sectreq.func:=CDFUNC_SECTSIZE;
|
|
|
|
+ sectreq.mode:=0; //cooked
|
|
|
|
+ sectreq.secsize:=0;
|
|
|
|
+
|
|
|
|
+ for i:=1 to 2 do
|
|
|
|
+ begin
|
|
|
|
+ { Send the request to the cdrom driver }
|
|
|
|
+ dosmemput(tb_segment,tb_offset,req,sizeof(req));
|
|
|
|
+ dosmemput(tb_segment,tb_offset+sizeof(req),sectreq,sizeof(sectreq));
|
|
|
|
+ dosregs.ax:=$1510;
|
|
|
|
+ dosregs.cx:=drnum;
|
|
|
|
+ dosregs.es:=tb_segment;
|
|
|
|
+ dosregs.bx:=tb_offset;
|
|
|
|
+ realintr($2f,dosregs);
|
|
|
|
+ dosmemget(tb_segment,tb_offset+3,status,2);
|
|
|
|
+ { status = $800F means "disk changed". Try once more. }
|
|
|
|
+ if (status and $800F) <> $800F then break;
|
|
|
|
+ end;
|
|
|
|
+ dosmemget(tb_segment,tb_offset+$12,byteswritten,2);
|
|
|
|
+ if (status<>$0100) or (byteswritten<>sizeof(sectreq)) then
|
|
|
|
+ exit; //An error occurred
|
|
|
|
+ dosmemget(tb_segment,tb_offset+sizeof(req),sectreq,sizeof(sectreq));
|
|
|
|
+
|
|
|
|
+ { Update the request header for the next request }
|
|
|
|
+ req.numbytes:=sizeof(sizereq);
|
|
|
|
+
|
|
|
|
+ { We're asking the volume size (in blocks) }
|
|
|
|
+ sizereq.func:=CDFUNC_VOLSIZE;
|
|
|
|
+ sizereq.size:=0;
|
|
|
|
+
|
|
|
|
+ { Send the request to the cdrom driver }
|
|
|
|
+ dosmemput(tb_segment,tb_offset,req,sizeof(req));
|
|
|
|
+ dosmemput(tb_segment,tb_offset+sizeof(req),sizereq,sizeof(sizereq));
|
|
|
|
+ dosregs.ax:=$1510;
|
|
|
|
+ dosregs.cx:=drnum;
|
|
|
|
+ dosregs.es:=tb_segment;
|
|
|
|
+ dosregs.bx:=tb_offset;
|
|
|
|
+ realintr($2f,dosregs);
|
|
|
|
+ dosmemget(tb_segment,tb_offset,req,sizeof(req));
|
|
|
|
+ if (req.status<>$0100) or (req.numbytes<>sizeof(sizereq)) then
|
|
|
|
+ exit; //An error occurred
|
|
|
|
+ dosmemget(tb_segment,tb_offset+sizeof(req)+1,sizereq.size,4);
|
|
|
|
+
|
|
|
|
+ blocksize:=sectreq.secsize;
|
|
|
|
+ freeblocks:=0; //always 0 for a cdrom
|
|
|
|
+ totblocks:=sizereq.size;
|
|
|
|
+ DiskData_CDROM:=true;*)
|
|
|
|
+ end;
|
|
|
|
+
|
|
begin
|
|
begin
|
|
- {TODO: implement}
|
|
|
|
- runerror(304);
|
|
|
|
|
|
+ if drive=0 then
|
|
|
|
+ begin
|
|
|
|
+ dosregs.ax:=$1900; //get current default drive
|
|
|
|
+ msdos(dosregs);
|
|
|
|
+ drive:=dosregs.al+1;
|
|
|
|
+ end;
|
|
|
|
+
|
|
|
|
+ if not DiskData_CDROM then
|
|
|
|
+ if not DiskData_7303 then
|
|
|
|
+ if not DiskData_36 then
|
|
|
|
+ begin
|
|
|
|
+ do_diskdata:=-1;
|
|
|
|
+ exit;
|
|
|
|
+ end;
|
|
|
|
+ do_diskdata:=blocksize;
|
|
|
|
+ if free then
|
|
|
|
+ do_diskdata:=do_diskdata*freeblocks
|
|
|
|
+ else
|
|
|
|
+ do_diskdata:=do_diskdata*totblocks;
|
|
end;
|
|
end;
|
|
|
|
|
|
function diskfree(drive : byte) : int64;
|
|
function diskfree(drive : byte) : int64;
|