Microsoft KB Archive/42773

{|
 * width="100%"|

PRB: Opening a C File When Disk Is Write-Protected

 * }

Q42773

-

The information in this article applies to:


 * The C Run-Time (CRT), included with:
 * Microsoft C/C++ for MS-DOS, versions 5.1, 6.0, 6.0a, 6.0ax, 7.0
 * Microsoft Visual C++, versions 1.0, 1.5

-

SYMPTOMS
Under MS-DOS, 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( &quot;a:\\test.dat&quot;, O_RDWR | O_TRUNC ); No error condition is returned and no hard error occurs. Later, however, 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 MS-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 MS-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 ( &quot;a:\\chk00000.xxx&quot;, 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.

Sample Code
The following sample program demonstrates checking of a write- protected disk:

/* Compile options needed: none void far handler ( unsigned, unsigned, unsigned far * ) ; int Flag = 0 ; char * ChkName = &quot;a:\\qwlbqwsi.ufp&quot; ; /* 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( &quot;Disk in drive A: is write-protected.&quot; ); break; case OTHER : puts( &quot;Another hard-error has occurred.&quot; ); break; default : puts( &quot;Error opening file (non hard-error.)&quot; ); }  }   else {      puts( &quot;Disk is not write-protected.&quot; ); close( FileHandle ); remove( ChkName );         /* delete the file */ } } /* Hard error routine should be as short as possible */
 * 1) include 
 * 2) include 
 * 3) include 
 * 4) include 
 * 5) include 
 * 6) include 
 * 1) include 
 * 1) define PROTECTED 1
 * 2) define OTHER    2

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 your Microsoft C run-time library reference manual for more specific information regarding the _hardretn function.

Additional query words: 1.00 1.50 5.10 6.00 6.00a 6.00ax 7.00

Keywords : kb16bitonly kbprb

Issue type : kbprb

Technology : kbVCsearch kbAudDeveloper kbCRT