tags:

views:

409

answers:

4

Hi.

I need to know if my program can write files to the disk (HDD, floppy, flash, CD) from where it is running. I have tried something like:

     {$I-}
     Rewrite(myFile);                                       
     {$I+}
  Result:= (IOResult = 0);

The problem is that if the disk is read-only, Windows gives me an error message telling me that

"appName.exe - Write Protect Error The disk cannot be written to because it is write protected. Please remove the write protection from the volume USB_BOOT in drive D:. Cancel TryAgain Continue"

How can I test for write access without raising any error/warning messages? Thanks.


Edit:

Ok. The "bug" has nothing to do with the above mentioned piece of code. I only thought that it appears there. I move the code to the read-only disk and ran it from there. The bug appears in a function called "CreateShortcutEx", on this line:

 MyPFile.Save(PWChar(WFileName),False);

MyPFile is declared like this:

var
 MyObject  : IUnknown;
 MySLink   : IShellLink;
 MyPFile   : IPersistFile;
 Directory : String;
 WFileName : WideString;
 MyReg     : TRegIniFile;
begin
 MyObject := CreateComObject(CLSID_ShellLink);
 MySLink  := MyObject as IShellLink;
 MyPFile  := MyObject as IPersistFile;
 .....
end;

So, why is MyPFile trying to write to the application's drive (the one that is read-only) if the WFileName parameter is "C:\documents and settings\bla bla" ?

+9  A: 

Call the Windows API SetErrorMode() function to disable the error message box.

Edit:

I just tried, and this:

procedure TForm1.Button1Click(Sender: TObject);
var
  Str: TStream;
  OldMode: Cardinal;
begin
  OldMode := SetErrorMode(SEM_FAILCRITICALERRORS);

  try
    try
      Str := TFileStream.Create('z:\foo.txt', fmOpenReadWrite);
      try

      finally
        Str.Free;
      end;
    except end;
  finally
    SetErrorMode(OldMode);
  end;
end;

works as expected.

mghie
Works for me now also.
Altar
Error mode must be restored! I fixed the code accordingly.
gabr
@gabr: Of course, thanks for fixing this.
mghie
A: 

What happens when you put your code inside an try/except?

Also, you can try (something like) this:

function CanWrite: boolean;
begin
  result := true;
  with TStringList.Create do
  try
    SaveToFile('file.txt');
  except
    result := false;
  finally
    Free;
  end;
end;

Sorry, but I don't code in Delphi anymore and I don't have Delphi installed anywhere.

eKek0
A: 

There exist a small freeware "Drive ready?" utility (dready.com) written by Horst Schaeffer that also can check write access. I have not tested it but as far as I can see this could be used as a solution; call it for instance as "DREADY C: /W" and check the return value.

hlovdal
A: 

Not really pretty but this seems to work for me.



function CanWrite(drive: string): boolean;
    var
        OldMode: Cardinal;
    begin
        OldMode := SetErrorMode(SEM_FAILCRITICALERRORS);
        try
            with TStringList.Create do
                try
                    SaveToFile(drive + ':\file.txt');
                    result := true;

                    try
                        deletefile(drive + ':\file.txt');
                    except
                    end;
                except
                    result := false;
                end;
        finally
            SetErrorMode(OldMode);
        end;
end;

Call to it with



if CanWrite('g') = true then
    begin
        showmessage('Can Write');
    end
    else
    begin
        showmessage('Can not write');
end;

David Kittell