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
Solved

Formatting A Floppy Disk

Posted on 1998-11-15
12
255 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
Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

 
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

Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say thank you for being a part of the community.

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
Delphi selector screen 2 84
Can Viruses spread while transferring Binary data with Winsock 2 86
find a node in VST 2 71
scroll down TListBox component in Delphi 1 19
Objective: - This article will help user in how to convert their numeric value become words. How to use 1. You can copy this code in your Unit as function 2. than you can perform your function by type this code The Code   (CODE) The Im…
Introduction Raise your hands if you were as upset with FireMonkey as I was when I discovered that there was no TListview.  I use TListView in almost all of my applications I've written, and I was not going to compromise by resorting to TStringGrid…
Finds all prime numbers in a range requested and places them in a public primes() array. I've demostrated a template size of 30 (2 * 3 * 5) but larger templates can be built such 210  (2 * 3 * 5 * 7) or 2310  (2 * 3 * 5 * 7 * 11). The larger templa…

856 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