Microsoft KB Archive/42773

From BetaArchive Wiki

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( "a:\\test.dat", 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 ( "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.

Sample Code

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

/* 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( "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 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


Last Reviewed: May 8, 2001
© 2001 Microsoft Corporation. All rights reserved. Terms of Use.