?
Solved

·is the unit a CD ROM ?

Posted on 1999-07-19
23
Medium Priority
?
352 Views
Last Modified: 2010-04-06
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
Comment
Question by:bryan7
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 13
  • 10
23 Comments
 
LVL 17

Accepted Solution

by:
inthe earned 80 total points
ID: 1389609
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
 
LVL 17

Expert Comment

by:inthe
ID: 1389610
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
 
LVL 3

Author Comment

by:bryan7
ID: 1389611
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
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 
LVL 17

Expert Comment

by:inthe
ID: 1389612
have to have a search for that one it is unusual request :-)
be back later with details..
0
 
LVL 17

Expert Comment

by:inthe
ID: 1389613
heck ,what am i doing just change the result to be:
     Result := (lpTotalNumberOfClusters - lpNumberOfFreeClusters) * lpSectorsPerCluster * lpBytesPerSector
to get total number of clusters used
     
0
 
LVL 3

Author Comment

by:bryan7
ID: 1389614
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
 
LVL 3

Author Comment

by:bryan7
ID: 1389615
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
 
LVL 17

Expert Comment

by:inthe
ID: 1389616
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
 
LVL 3

Author Comment

by:bryan7
ID: 1389617
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
 
LVL 17

Expert Comment

by:inthe
ID: 1389618
without trying it on multipe systems first i can gaurantee nothing,though i dont see what programs installed will make a difference .

0
 
LVL 3

Author Comment

by:bryan7
ID: 1389619
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
 
LVL 17

Expert Comment

by:inthe
ID: 1389620
i'll be back ;-)
0
 
LVL 3

Author Comment

by:bryan7
ID: 1389621
enmm.. does ""i'll be back ;-)"" mean you'll be back with an answer =) ?
0
 
LVL 17

Expert Comment

by:inthe
ID: 1389622
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
 
LVL 17

Expert Comment

by:inthe
ID: 1389623
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
 
LVL 3

Author Comment

by:bryan7
ID: 1389624
thanx a lot..

both methods worked alright.. which should I use ?
0
 
LVL 17

Expert Comment

by:inthe
ID: 1389625
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
 
LVL 3

Author Comment

by:bryan7
ID: 1389626
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
 
LVL 17

Expert Comment

by:inthe
ID: 1389627
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
 
LVL 3

Author Comment

by:bryan7
ID: 1389628
=) hmm.. have an idea.. we can use msdos..

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

assuimg e is the cd..



0
 
LVL 17

Expert Comment

by:inthe
ID: 1389629
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
 
LVL 3

Author Comment

by:bryan7
ID: 1389630
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
 
LVL 17

Expert Comment

by:inthe
ID: 1389631
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

Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

The uses clause is one of those things that just tends to grow and grow. Most of the time this is in the main form, as it's from this form that all others are called. If you have a big application (including many forms), the uses clause in the in…
Creating an auto free TStringList The TStringList is a basic and frequently used object in Delphi. On many occasions, you may want to create a temporary list, process some items in the list and be done with the list. In such cases, you have to…
Have you created a query with information for a calendar? ... and then, abra-cadabra, the calendar is done?! I am going to show you how to make that happen. Visualize your data!  ... really see it To use the code to create a calendar from a q…
In this video, Percona Director of Solution Engineering Jon Tobin discusses the function and features of Percona Server for MongoDB. How Percona can help Percona can help you determine if Percona Server for MongoDB is the right solution for …
Suggested Courses

718 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question