[Webinar] Streamline your web hosting managementRegister Today

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 358
  • Last Modified:

·is the unit a CD ROM ?

How can I know if unit D..E.. is a CD ROM and not a HD or something else ?

in the case of the cdrom, how do I know the full space ocuppied ?

thanx
0
bryan7
Asked:
bryan7
  • 13
  • 10
1 Solution
 
intheCommented:
hi bryan,

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls;

type
 TForm1 = class(TForm)
   Button1: TButton;
   Label1: TLabel;
   procedure Button1Click(Sender: TObject);
 end;

var
 Form1: TForm1;

implementation

Uses ShellApi;
    {$R *.DFM}

procedure TForm1.Button1Click(Sender: Object);
var
       n : byte;
     drv : string;
 drives  : set of 0..25;
const
     drt : array [0..6] of string = ('Unknown','Unknown','Floppy Disk','Local Drive',
                                         'Network Drive','CD-Rom',
                                         'RAM-Disk');
    begin
       integer(drives):=getlogicaldrives;
       for n := 0 to 25 do
            if n in drives then begin
               drv:=char(n+ord('A'))+':\';
               if(drt[getdrivetype(pchar(drv))] = 'CD-Rom') then
 Label1.Caption := 'Drive '+ Drv + ' is the CD-Rom Drive';
end;
end;

end.
0
 
intheCommented:
for the free space ,cluster info use

function LibreEnDisco( const Drive : Char ) : LongInt;
 var
    lpRootPathName          : PChar;      { address of root path }
    lpSectorsPerCluster     : DWORD;      { address of sectors per cluster }
    lpBytesPerSector        : DWORD;      { address of bytes per sector }
    lpNumberOfFreeClusters  : DWORD;      { address of number of free clusters }
    lpTotalNumberOfClusters : DWORD;      { address of total number of clusters }
 begin
       lpRootPathName := PChar( Drive + ':\' );
       if Windows.GetDiskFreeSpace( lpRootPathName,
                                    lpSectorsPerCluster,
                                    lpBytesPerSector,
                                    lpNumberOfFreeClusters,
                                    lpTotalNumberOfClusters ) then
          Result := lpNumberOfFreeClusters * lpBytesPerSector * lpSectorsPerCluster
       else
          Result := -1;
 end;


and call like:

Label1.Caption:=IntToStr( LibreEnDisco('c') );

0
 
bryan7Author Commented:
Hi.. thanks for the quick reply.. I need to know the Ocuppied space in the CD, no the free.. it's just for the cd..
0
Free Tool: SSL Checker

Scans your site and returns information about your SSL implementation and certificate. Helpful for debugging and validating your SSL configuration.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 
intheCommented:
have to have a search for that one it is unusual request :-)
be back later with details..
0
 
intheCommented:
heck ,what am i doing just change the result to be:
     Result := (lpTotalNumberOfClusters - lpNumberOfFreeClusters) * lpSectorsPerCluster * lpBytesPerSector
to get total number of clusters used
     
0
 
bryan7Author Commented:
worked fine.. though it didn't work for the 2nd partition on the HD, since it says about 400 Mb when it's 2.57 Gb .. though that doesn't mind since it's only the CD Rom which I need to know..

thanx

bryan
0
 
bryan7Author Commented:
Hi again.. is there any posibility that it doesn't work in any system ? it should always work, since my program will be on a cdrom and it will be sold, and it won't run if it's not in a CD and the total occupied space in the CD is bigger than it should. ..

so, I mean, my program won't run if the cdrom's total space detection reports a different space than it is.. so it should never fail..
0
 
intheCommented:
well to be honest i cant test on all systems so cant give true answer to that but what i do know about the space ,cdroms have diferent bytes for space size for instance:
i have a old serialnumber routine and in its use the
 
Buffer   : Array [0..511] of Byte;   //  = 512 Bytes
// The size of one sector can be found out with GetDiskFreeSpace // (normaly = 512 bytes, CD-ROMs = 2048 bytes).
so the size will appear different if on a harddrive.
i make music and data cdroms like 90% of the uk top20 every  week  for a living so i should be right :-)
0
 
bryan7Author Commented:
hmm, "systems".. I mean, not in different OS's..  just win9x and maybe NT, I mean, if the system configuration..programs installed.. or anything, could make that function fail, reporting a wrong size..

I really need to be sure it'll work, cause the program will be solt in a CD, and when my program starts it will check the space used in the CD, and if it's more than, let's say, 300 Mb, then the program will stop..

thanx
0
 
intheCommented:
without trying it on multipe systems first i can gaurantee nothing,though i dont see what programs installed will make a difference .

0
 
bryan7Author Commented:
emm, then.. isn't there a way that will sure always work ? it's enough to check only the CD Rom.. don't worry about HD or any other devide.. I just need to be sure for a CD
0
 
intheCommented:
i'll be back ;-)
0
 
bryan7Author Commented:
enmm.. does ""i'll be back ;-)"" mean you'll be back with an answer =) ?
0
 
intheCommented:
everything you could want to know about drives:

http://www.efg2.com/lab/library/delphi/io/DisksDrives.htm

couldnt find any other routines that would be better,they're all pretty much the same.
0
 
intheCommented:
here a function to play around with that may also be a help:


unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

function GetDiskFreeSpaceEx(lpDirectoryName: PAnsiChar;
  var lpFreeBytesAvailableToCaller : Integer;
  var lpTotalNumberOfBytes: Integer;
  var lpTotalNumberOfFreeBytes: Integer) : bool;
  stdcall;
  external kernel32
  name 'GetDiskFreeSpaceExA';


procedure GetDiskSizeAvail(TheDrive : PChar;
                           var TotalBytes : double;
                           var TotalFree : double);
var
  AvailToCall : integer;
  TheSize : integer;
  FreeAvail : integer;
begin
  GetDiskFreeSpaceEx(TheDrive,
                     AvailToCall,
                     TheSize,
                     FreeAvail);
{$IFOPT Q+}
 {$DEFINE TURNOVERFLOWON}
 {$Q-}
{$ENDIF}
  if TheSize >= 0 then
    TotalBytes := TheSize else
  if TheSize = -1 then begin
    TotalBytes := $7FFFFFFF;
    TotalBytes := TotalBytes * 2;
    TotalBytes := TotalBytes + 1;
  end else
  begin
    TotalBytes := $7FFFFFFF;
    TotalBytes := TotalBytes + abs($7FFFFFFF - TheSize);
  end;

  if AvailToCall >= 0 then
    TotalFree := AvailToCall else
  if AvailToCall = -1 then begin
    TotalFree := $7FFFFFFF;
    TotalFree := TotalFree * 2;
    TotalFree := TotalFree + 1;
  end else
  begin
    TotalFree := $7FFFFFFF;
    TotalFree := TotalFree + abs($7FFFFFFF - AvailToCall);
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  TotalBytes : double;
  TotalFree : double;
begin
  GetDiskSizeAvail('F:\',  //F:\ IS MY CDR WRITER
                   TotalBytes,
                   TotalFree);
  ShowMessage(FloatToStr(TotalBytes));
  ShowMessage(FloatToStr(TotalFree));
end;

end.
0
 
bryan7Author Commented:
thanx a lot..

both methods worked alright.. which should I use ?
0
 
intheCommented:
i would say the last one i posted only because it is neater solution :-)
you could always mix the 2 then have your own written function.
it really is your choice they both work fine.
may i ask what is your program for?
0
 
bryan7Author Commented:
my program.. look:
where I'm working, they had "developed" a full Multimedia CD ROM, about the island where I live.. history,,pics.. etc.. but it was ALL IN HTML .. lol, so my boss wanted me to pass it all to a program.. ..-= *Delphi* =-..  heh, then I've had to somehow "emulate" the pages.. and all the contents.. and, of course, much more faster and with many features..

about this cd-rom question.. ok: I want to add some copy-protection.. if you think.. normally a cd-pirate always sells FULL cd's, I mean, with lots of programs. .. usually ocuppying almost the whole CD..

ok, my program will check how much space is used in the CD, and if it's much more than it should ( it's about 350...400 Mb now.. with mp3's.. pics.. etc ) then my program will show a warning and just stop..

this cd is of course gonna be sold, like the older one, so.. I must be sure that those functions won't fail...

Imagine that someone has bought the cd and can't run it because the functions are reporting a wrong size.. hehhe..  

also, it won't run if it detects that it wasn't started from a CD ..

ok.. ok.. this is not a very good protection.. sure some cracker could easily crack the code.. or use a hasr disk folder as a cd.. but, well.. it's always some protection.. not perfect.. but at least... it's something.. ;)

bryan


0
 
intheCommented:
sounds interesting..

just thinking another way could have been to get a directory listing of the cd and saving it as a file on the cd then when the user installs/runs the cd you could do another directory listing and save to temp dir and compare the file sizes of the 2 dir listings.
i have no idea offhand about coding it and probably take too long to do the dir "search and compare" but its another way that would be accurate.
anyway make a million <g>
Regards
0
 
bryan7Author Commented:
=) hmm.. have an idea.. we can use msdos..

Dir e:\ /s > c:\blabla.txt

assuimg e is the cd..



0
 
intheCommented:
ahh yes
and i think this is going to be more accurate than reading the cd used space size ,cause if its 1 byte out you know someone has tampered with your prog :-)
0
 
bryan7Author Commented:
yep.. but.. it won't look nice opening a dos box.. is there any way to hide it ? hide it.. I don't mean show it minimized on the task bar.. then hide the button and window.. so the user can't see that I'm doing that..
0
 
intheCommented:
you have to use something like this unit of madshi's:
unit runThread_;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private-Deklarationen}
  public
    { Public-Deklarationen}
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

type TRunThread = class(TThread)
  private
    processHandle : cardinal;
    processReady  : boolean;
    waitingThread : cardinal;
    procedure Execute; override;
  end;

procedure TRunThread.Execute;
begin
  WaitForSingleObject(processHandle,INFINITE);   // This call does not return, unless copy is stopped
  processReady:=true;                            // Set "processReady" flag for main thread
  PostThreadMessage(waitingThread,WM_NULL,0,0);  // Wake up main thread
                                                 // If you call Application.HandleMessage (see below) in the
                                                 // main thread, the main thread is sleeping the most time in
                                                 // winAPI "waitMessage". So we send a "dummy" message in order
                                                 // to let the main thread return from Application.HandleMessage
end;

procedure TForm1.Button1Click(Sender: TObject);
var si : TStartupInfo;
    pi : TProcessInformation;
begin
  caption:='start copy...';
  ZeroMemory(@si,sizeOf(si)); si.cb:=sizeOf(si);
  si.dwFlags:=STARTF_USESHOWWINDOW; si.wShowWindow:=SW_HIDE;
  if CreateProcess(nil,'c:\command.com /c copy c:\autoexec.bat c:\test.bat >c:\output.txt',nil,nil,false,0,nil,nil,si,pi) then begin
    caption:='copy started...';
    with TRunThread.Create(true) do         // create the thread object, but do not start it now...
      try
        processHandle:=pi.hProcess;         // tell the thread what process it has to watch
        processReady:=false;                // flag for the loop (see below)
        waitingThread:=GetCurrentThreadID;  // the current threadID for the wakeup message (see above)
        caption:='wait for copy...';
        Resume;                             // now all information is prepared; so let's start the thread
        repeat
          Application.HandleMessage;        // message loop
        until Application.Terminated or processReady;  // continue with normal program when either the
                                                       // started process has stopped or our program is closed
        caption:='copy stopped...';
      finally Free end;
    CloseHandle(pi.hThread); CloseHandle(pi.hProcess); // Never forget to close handles...
    caption:='ready...';
  end else caption:='could not start copy...';
end;

end

that may do it,though ive never tried..have a go and see
0

Featured Post

Learn to develop an Android App

Want to increase your earning potential in 2018? Pad your resume with app building experience. Learn how with this hands-on course.

  • 13
  • 10
Tackle projects and never again get stuck behind a technical roadblock.
Join Now