Solved

Formatting A Floppy Disk

Posted on 1998-11-15
12
254 Views
Last Modified: 2010-04-04
How do I Quick Format a floppy disk in the background. I got this code from a previously answered Q but it pulls up the windows format dialog. I need to do it completely in the background. Code that will just erase all files and directories from a floppy will do just as well.

   const
           SHFMT_ID_DEFAULT = $FFFF;
           SHFMT_OPT_QUICKFORMAT = $0000;
           SHFMT_OPT_FULL = $0001;
           SHFMT_OPT_SYSONLY = $0002;
           SHFMT_ERROR = $FFFFFFFF;
           SHFMT_CANCEL = $FFFFFFFE;
           SHFMT_NOFORMAT = $FFFFFFFD;

function SHFormatDrive(Handle: HWND; Drive, ID, Options: Word): LongInt;
  stdcall; external 'shell32.dll' name 'SHFormatDrive'

procedure TForm1.btnFormatDiskClick(Sender: TObject);
var
  Code: LongInt;
begin
  Code:= SHFormatDrive(Handle, 0, SHFMT_ID_DEFAULT, SHFMT_OPT_QUICKFORMAT);
  if Code < 0 then
    ShowMessage('Could not format floppy drive');
end;

Sorry about the lack of points, it's all I've got.

Darren
0
Comment
Question by:elkiors
  • 6
  • 5
12 Comments
 
LVL 20

Expert Comment

by:Madshi
ID: 1346874
I think with SHFormatDrive you can't prevent the dialog from appearing. So you can either delete all files and directories. That's quite simple. Just a recursive function with a FindFirstFile/FindNextFile/FindClose loop. But I wouldn't do it this way, because it could take a lot of time and some files could be locked somehow (e.g. currently opened by a program)...

So you could call the dos format program (perhaps with SW_HIDE as show parameter to prevent the dos box from appearing). Or you could write a little format function yourself. But that's quite annoying, because you'll have to write completely different functions for win95/98 and for winNT.
If you nevertheless want to write your own format routine, tell me for which system (one or all or...). Then I can give you some hints. Sorry, have no full source code...  :-(

Regards, Madshi.
0
 

Author Comment

by:elkiors
ID: 1346875
Hi Madshi,

I've nearly completed the recursive Delete File way of doing the erase, but like you said, it's fraught with problems.

Can you give me any ideas on using the dos format method?

Darren

0
 
LVL 20

Accepted Solution

by:
Madshi earned 30 total points
ID: 1346876
Darren,

you can start experimenting with this code...

procedure runCommandCom;
var si : TStartupInfo;
    pi : TProcessInformation;
begin
  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:\autoexec.2 >c:\test.txt',nil,nil,false,0,nil,nil,si,pi) then begin
    CloseHandle(pi.hThread); CloseHandle(pi.hProcess);
  end else AlertInfo(LastErrStr);
end;

Regards, Madshi.
0
Netscaler Common Configuration How To guides

If you use NetScaler you will want to see these guides. The NetScaler How To Guides show administrators how to get NetScaler up and configured by providing instructions for common scenarios and some not so common ones.

 
LVL 27

Expert Comment

by:kretzschmar
ID: 1346877
hi elkiors,

a other method

procedure TForm1.Button1Click(Sender: TObject);
var ok : integer;
begin
  ok :=  winexec('command.com /c c:\windows\command\format.com a: /Q < c:\windows\command\one_disk.txt',SW_HIDE);
end;

the one_disk.txt contains

[return]
[return]
n
[return]

[return] means the key on keyboard

meikl
0
 

Author Comment

by:elkiors
ID: 1346878
Madshi: thanks for the response, unfortunately it's going to be a few days before I can look at the code ... but I'll let you know.

Kretzschmar: I'll evaluate your comment too.

Cheers
Darren



0
 

Author Comment

by:elkiors
ID: 1346879
Hi all,

I've finally managed to get the time to evaluate both your responses.

Madshi: I got an undeclared error for the AlertInfo proc. I commented it out for the compile.

Meikl: I tried your version too. Having looked up WinExec in the help, I see that Madshi's method is for pure 32bit versions, since I'm running D3 then I suppose that is the way I should jump.

However ... Neither of them work. If I show the window and use the age old pause key, the format command tells me that the floppy is in use by another process. What's going on?

Enough time has gone for me to be given some more points so I can finally make this question worthwile(ish)

Also, when the window opens the first line (before the format command is executed) contains the message:

Parameter value not in allowed range

I see this message alot, both at work and at home. Is it anything that I should be concerned about?
0
 

Author Comment

by:elkiors
ID: 1346880
Madshi:

I've finally managed to get it to work, it seems I'd neglected to do a FindClose in my code. Unfortunately, because it's running as a seperate thread, my app is continuing, which I don't want, how do I pause the execution of my app thread until the format routine has finished?

Darren.

0
 
LVL 20

Expert Comment

by:Madshi
ID: 1346881
Just call "WaitForSingleObject(pi.hProcess)". Of course you must close the handle behind this call, not before it...
The problem is, if you call WaitForSingleObject, this call will not return unless the created process has really finished. That means, your application won't process any messages. And that means, your main window won't redraw, can't be move/sized or whatever.
So you should think about putting this WaitForSingleObject into a execute method of the TThread object. And in your main thread you should create an instance of this TThread object and then build a message loop like "while not formatReady do Application.ProcessMessages". Of course you should set this formatReady variable to false before creating the thread and in the thread you should set this value to true after WaitForSingleObject returns. Quite complicated, isn't it? But it's the best way. Sorry, have no complete sources for you. But should be able to put this all together by yourself, right?

Regards, Madshi.
0
 

Author Comment

by:elkiors
ID: 1346882
erm ... I've never done anything with multiple threads before .. ever ! I've never done anything with windows messaging either, only events.

Any further help would be greatly appreciated.


0
 
LVL 20

Expert Comment

by:Madshi
ID: 1346883
And this all for 30 points...   :-(

Ok, here comes a complete source about how to handle our messages while waiting on another process.

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-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 notepad 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 notepad...';
  ZeroMemory(@si,sizeOf(si)); si.cb:=sizeOf(si);
  if CreateProcess(nil,'c:\windows\notepad.exe',nil,nil,false,0,nil,nil,si,pi) then begin
    caption:='notepad 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 notepad...';
        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:='notepad stopped...';
      finally Free end;
    CloseHandle(pi.hThread); CloseHandle(pi.hProcess); // Never forget to close handles...
    caption:='ready...';
  end else caption:='could not start notepad...';
end;

end.

Regards, Madshi.
0
 

Author Comment

by:elkiors
ID: 1346884
Wow, Madshi: That's exactly what I needed. I can now mull over the code and work out how it does it. Yes I have asked for alot for 30 points ... I've got a total of 18 points to my name so because you've been so helpful and only too happy to help me out despite the minimal rewards ... have a look for the question I'm about to post. It's got my 18 points on it all you need to do is 'answer' it and the points are yours along with an 'A' grade.

Sorry but I can't do much more than that other than to say thanks and I hope I can help you out in the future.

Kindest Regards

Darren
0
 
LVL 20

Expert Comment

by:Madshi
ID: 1346885
No problem... Please keep your 18 points. They don't make the difference. I can't buy something with these points. It's only a kind of hiscore. So don't worry. It wasn't meant that serious...  :-)

Regards, Madshi.
0

Featured Post

PRTG Network Monitor: Intuitive Network Monitoring

Network Monitoring is essential to ensure that computer systems and network devices are running. Use PRTG to monitor LANs, servers, websites, applications and devices, bandwidth, virtual environments, remote systems, IoT, and many more. PRTG is easy to set up & use.

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…
Have you ever had your Delphi form/application just hanging while waiting for data to load? This is the article to read if you want to learn some things about adding threads for data loading in the background. First, I'll setup a general applica…
Established in 1997, Technology Architects has become one of the most reputable technology solutions companies in the country. TA have been providing businesses with cost effective state-of-the-art solutions and unparalleled service that is designed…

832 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