Solved

Formatting A Floppy Disk

Posted on 1998-11-15
12
252 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
Comment Utility
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
Comment Utility
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
Comment Utility
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
 
LVL 27

Expert Comment

by:kretzschmar
Comment Utility
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
Comment Utility
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
Comment Utility
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
Why You Should Analyze Threat Actor TTPs

After years of analyzing threat actor behavior, it’s become clear that at any given time there are specific tactics, techniques, and procedures (TTPs) that are particularly prevalent. By analyzing and understanding these TTPs, you can dramatically enhance your security program.

 

Author Comment

by:elkiors
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

Suggested Solutions

A lot of questions regard threads in Delphi.   One of the more specific questions is how to show progress of the thread.   Updating a progressbar from inside a thread is a mistake. A solution to this would be to send a synchronized message to the…
This article explains how to create forms/units independent of other forms/units object names in a delphi project. Have you ever created a form for user input in a Delphi project and then had the need to have that same form in a other Delphi proj…
This demo shows you how to set up the containerized NetScaler CPX with NetScaler Management and Analytics System in a non-routable Mesos/Marathon environment for use with Micro-Services applications.
This video demonstrates how to create an example email signature rule for a department in a company using CodeTwo Exchange Rules. The signature will be inserted beneath users' latest emails in conversations and will be displayed in users' Sent Items…

772 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

Need Help in Real-Time?

Connect with top rated Experts

11 Experts available now in Live!

Get 1:1 Help Now