Link to home
Start Free TrialLog in
Avatar of wenfeng
wenfeng

asked on

Again, In 16-bit, how do I check whether Drive A is formatted or not?"

I asked this question just days before.
(Programming : Languages : C : Q.10236627 )
I accepted one of the answers, which is not correct after testing. So, I have to ask again.

In my program, I try to write sth to Drive A, so I need to check the status of A drive, the first is whether Drive A is formatted.  
I think _bios_disk can't work, this one always work no matter the drive A is formatted or not. _dos_open also can't. when I use this one to access A drive, it will give me the Abort, Retry, and Fail, if it's not formatted. I don't want my end user to see this message. besides, I will lose control.

Any idea to detect whether A is formatted or how to disable the Abort, Retry, and Fail, or and a handler?


Thanks
Wenfeng
Avatar of mmessuri
mmessuri
Flag of United States of America image

wenfeng:

Here is a quick example on how to install your own error handler.  This will allow you override the the Abort, Retry, and Fail error:

#include <stdio.h>
#include <dos.h>
#include <dir.h>
#include <process.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>

// globals

char tempdir[144];
int diskErr;

// prototypes

int diskErrorHandler(int errval, int ax, int bp, int si);
int restoreDir(char *s);

/* critical error handler for drive change - not working yet */

int testDisk(int n)
{
      void interrupt (*oldHarderr)();
      FILE *fp;
      char buffer[32];

      oldHarderr=getvect(0x24);
         harderr(diskErrorHandler);
      diskErr=0;
      getcwd(tempdir,80);
      sprintf(buffer,"%c:\\TEMP.DAT",n+'A');
     clearerr(fp);
      if((fp=fopen(buffer,"r")) != NULL) fclose(fp);
      setvect(0x24,oldHarderr);
      return(diskErr);
}

int diskErrorHandler(int errval, int ax, int bp, int si)
{
      unsigned di;
      int errorno;

      if(ax >=0) {
            di = _DI;
            errorno = di & 0x00FF;
            diskErr = di & 0x00FF;;
            restoreDir(tempdir);
      }
      hardretn(2);
      return 0;
}

int restoreDir(char *s)         /* restore a saved directory path */
{
      strupr(s);
      if(isalpha(s[0]) && s[1]==':') setdisk(s[0]-'A');
      chdir(s);
return 0;
}
Also note that normally you are not expected to grade an answer until you have tried it.
Avatar of KangaRoo
KangaRoo

I mentioned using the access() function in that question. See if your compiler supports it.
ASKER CERTIFIED SOLUTION
Avatar of KangaRoo
KangaRoo

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Hi, i hope, next programmm is a reply to you Q:
/*==========================================================*/
/* Name       : GetStatusDriveInt                           */
/* Descript   : Get Status of Drive                      */
/* Parameters : nDrive: 0-> A:, 1: B: ,                     */
/* Return     : -2: Disket not formatted,-1: not ready,0:OK */
/*==========================================================*/
int GetStatusDriveInt(int nDrive)
{
  int nRet = -1;
  struct SREGS sregs;
  union  REGS regs;
  char   szTemp[512];
  int    block[5];
                              //clear all
  memset(&sregs , 0, sizeof(sregs));
  memset(&regs , 0, sizeof(regs));
  memset(szTemp , 0, sizeof(szTemp));
  memset(block, 0, sizeof(block));

  block[2] = 1;
  block[3] =  FP_OFF(szTemp);
  block[4] =  FP_SEG(szTemp);

  sregs.ds = FP_SEG(block);
  regs.x.bx = FP_OFF(block);
//                     absread(as Interruption, vers 4.0 and more)
  regs.h.al = nDrive;                  //disk a/b
  regs.x.cx = -1;                  //data in block
  regs.x.dx = 0;                  //1-st Sector

  int86x(0x25, &regs, &regs, &sregs);      //read
  if (regs.h.ah == 0)                  //ok?
    {
      int nErr = 0;
      for (int i = 0, i < 512; i++)
      if (szTemp[i] != -10)
        break;
      nRet = i <  512 ? 0: -2;  //not formatted!
    }
  return nRet;
}
Alex