ID Number: Q42773
5.00 5.10 6.00 6.00a 6.00ax 7.00
MS-DOS
Summary:
SYMPTOMS
With the run-time library in the Microsoft C Optimizing Compiler
versions 5.0, 5.1, 6.0, 6.0a, 6.0ax, and C/C++ version 7.0, a program
can open an existing file for both read and write when the floppy
disk is write-protected. The following statement may be used to open
the file:
handle = open( "a:\\test.dat", O_RDWR | O_TRUNC );
No error condition is returned and no hard error occurs. However,
later, when the program tries to write to the file handle or even
to close the file without writing, a hard error will occur with the
following message:
Writing protect error writing drive A:
Abort, Retry, Fail?
CAUSE
This is not a problem with the open() function in the Microsoft C
run-time library. The low-level DOS function call that is used to
implement open() does not check for a write-protect error. When the
file is to be closed by close(), the internal buffer has to be
flushed to the disk. No low-level DOS function can close a file
without flushing its associated buffer.
RESOLUTION
There is no direct way to detect the write-protect condition. An
indirect workaround is to open a file with the mode to be O_CREAT,
as follows:
open ( "a:\\chk00000.xxx", O_CREAT, S_IWRITE | S_IREAD) ;
A hard error will occur, which can be captured by a user-
implemented and installed hard-error handler. This handler will
override the printing of the hard-error message on the user screen.
The open() function does return -1 when it regains the control from
the hard-error handle. If the file was opened successfully, it may
be removed at the end of the program.
More Information:
The following sample program demonstrates checking of a write-
protected disk:
Sample Code
-----------
/* Compile options needed: none
*/
#include <fcntl.h>
#include <sys\types.h>
#include <sys\stat.h>
#include <io.h>
#include <stdio.h>
#include <dos.h>
void far handler ( unsigned, unsigned, unsigned far * ) ;
#define PROTECTED 1
#define OTHER 2
int Flag = 0 ;
char * ChkName = "a:\\qwlbqwsi.ufp" ; /* dummy file name */
void main( )
{
int FileHandle;
_harderr ( handler ); /* set up hard-error handler */
FileHandle = open ( ChkName, O_CREAT, S_IWRITE | S_IREAD );
if( FileHandle == -1 ) /* check write-protection */
{
switch( Flag ) /* may be set by handler */
{
case PROTECTED :
puts( "Disk in drive A: is write-protected." );
break;
case OTHER :
puts( "A another hard-error has occurred." );
break;
default :
puts( "Error opening file (non hard-error.)" );
}
}
else
{
puts( "Disk is not write-protected." );
close( FileHandle );
remove( ChkName ); /* delete the file */
}
}
/* Hard error routine should be as short as possible */
void far handler ( unsigned deverror, unsigned errcode,
unsigned far *devhdr )
{
if( errcode == 0 )
Flag = PROTECTED;
else
Flag = OTHER; /* like drive door is open */
_hardretn( 0 );
}
Note: The argument 0 to _hardretn() is not significant in this
program. Please refer to the "Microsoft C Run-Time Library Reference"
for more specific information regarding the _hardretn() function.
Additional reference words: 5.00 5.10 6.00 6.00a 6.00ax 7.00