📄 msdos.c
字号:
if (MKDIR(tmproot, 0777) == -1) { Info(slide, 1, ((char *)slide, LoadFarString(CantCreateExtractDir), FnFilter1(tmproot))); free(tmproot); rootlen = 0; /* path didn't exist, tried to create, failed: */ /* file exists, or need 2+ subdir levels */ return MPN_ERR_SKIP; } } } if (add_dot) /* had just "x:", make "x:." */ tmproot[rootlen++] = '.'; tmproot[rootlen++] = '/'; tmproot[rootlen] = '\0'; if ((rootpath = (char *)realloc(tmproot, rootlen+1)) == NULL) { free(tmproot); rootlen = 0; return MPN_NOMEM; } Trace((stderr, "rootpath now = [%s]\n", FnFilter1(rootpath))); } return MPN_OK; }#endif /* !SFX || SFX_EXDIR *//*--------------------------------------------------------------------------- END: free rootpath, immediately prior to program exit. ---------------------------------------------------------------------------*/ if (FUNCTION == END) { Trace((stderr, "freeing rootpath\n")); if (rootlen > 0) { free(rootpath); rootlen = 0; } return MPN_OK; } return MPN_INVALID; /* should never reach */} /* end function checkdir() *//***********************//* Function isfloppy() *//***********************/static int isfloppy(nDrive) /* more precisely, is it removable? */ int nDrive;{ union REGS regs; regs.h.ah = 0x44; regs.h.al = 0x08; regs.h.bl = (uch)nDrive;#ifdef __EMX__ _int86(0x21, ®s, ®s); if (WREGS(regs,flags) & 1)#else intdos(®s, ®s); if (WREGS(regs,cflag)) /* error: do default a/b check instead */#endif { Trace((stderr, "error in DOS function 0x44 (AX = 0x%04x): guessing instead...\n", (unsigned int)(WREGS(regs,ax)))); return (nDrive == 1 || nDrive == 2)? TRUE : FALSE; } else return WREGS(regs,ax)? FALSE : TRUE;}/**************************//* Function z_dos_chmod() *//**************************/static int z_dos_chmod(__G__ fname, attributes) __GDEF ZCONST char *fname; int attributes;{ char *name; unsigned fnamelength; int errv; /* set file attributes: The DOS `chmod' system call requires to mask out the directory and volume_label attribute bits. And, a trailing '/' has to be removed from the directory name, the DOS `chmod' system call does not accept it. */ fnamelength = strlen(fname); if (fnamelength > 1 && fname[fnamelength-1] == '/' && fname[fnamelength-2] != ':' && (name = (char *)malloc(fnamelength)) != (char *)NULL) { strncpy(name, fname, fnamelength-1); name[fnamelength-1] = '\0'; } else { name = (char *)fname; fnamelength = 0; }#if defined(__TURBOC__) || (defined(__DJGPP__) && (__DJGPP__ >= 2))# if (defined(__BORLANDC__) && (__BORLANDC__ >= 0x0452))# define Chmod _rtl_chmod# else# define Chmod _chmod# endif errv = (Chmod(name, 1, attributes & (~FSUBDIR & ~FVOLID)) != (attributes & (~FSUBDIR & ~FVOLID)));# undef Chmod#else /* !(__TURBOC__ || (__DJGPP__ && __DJGPP__ >= 2)) */ errv = (_dos_setfileattr(name, attributes & (~FSUBDIR & ~FVOLID)) != 0);#endif /* ?(__TURBOC__ || (__DJGPP__ && __DJGPP__ >= 2)) */ if (errv) Info(slide, 1, ((char *)slide, LoadFarString(AttribsMayBeWrong))); if (fnamelength > 0) free(name); return errv;} /* end function z_dos_chmod() */#if (!defined(__GO32__) && !defined(__EMX__))typedef struct dosfcb { uch flag; /* ff to indicate extended FCB */ char res[5]; /* reserved */ uch vattr; /* attribute */ uch drive; /* drive (1=A, 2=B, ...) */ uch vn[11]; /* file or volume name */ char dmmy[5]; uch nn[11]; /* holds new name if renaming (else reserved) */ char dmmy2[9];} dos_fcb;/**************************//* Function volumelabel() *//**************************/static int volumelabel(newlabel) ZCONST char *newlabel;{#ifdef DEBUG char *p;#endif int len = strlen(newlabel); int fcbseg, dtaseg, fcboff, dtaoff, retv; dos_fcb fcb, dta, far *pfcb=&fcb, far *pdta=&dta; struct SREGS sregs; union REGS regs;/*--------------------------------------------------------------------------- Label the diskette specified by nLabelDrive using FCB calls. (Old ver- sions of MS-DOS and OS/2 DOS boxes can't use DOS function 3Ch to create labels.) Must use far pointers for MSC FP_* macros to work; must pad FCB filenames with spaces; and cannot include dot in 8th position. May or may not need to zero out FCBs before using; do so just in case. ---------------------------------------------------------------------------*/#ifdef WATCOMC_386 int truseg; memset(&sregs, 0, sizeof(sregs)); memset(®s, 0, sizeof(regs)); /* PMODE/W does not support extended versions of any dos FCB functions, */ /* so we have to use brute force, allocating real mode memory for them. */ regs.w.ax = 0x0100; regs.w.bx = (2 * sizeof(dos_fcb) + 15) >> 4; /* size in paragraphs */ int386(0x31, ®s, ®s); /* DPMI allocate DOS memory */ if (regs.w.cflag) return DF_MDY; /* no memory, return default */ truseg = regs.w.dx; /* protected mode selector */ dtaseg = regs.w.ax; /* real mode paragraph */ fcboff = 0; dtaoff = sizeof(dos_fcb);#ifdef XXX__MK_FP_IS_BROKEN /* XXX This code may not be trustworthy in general, though it is */ /* valid with DOS/4GW and PMODE/w, which is all we support for now. */ regs.w.ax = 6; regs.w.bx = truseg; int386(0x31, ®s, ®s); /* convert seg to linear address */ pfcb = (dos_fcb far *) (((ulg) regs.w.cx << 16) | regs.w.dx); /* pfcb = (dos_fcb far *) ((ulg) dtaseg << 4); */ pdta = pfcb + 1;#else pfcb = MK_FP(truseg, fcboff); pdta = MK_FP(truseg, dtaoff);#endif _fmemset((char far *)pfcb, 0, 2 * sizeof(dos_fcb)); /* we pass the REAL MODE paragraph to the dos interrupts: */ fcbseg = dtaseg;#else /* !WATCOMC_386 */ memset((char *)&dta, 0, sizeof(dos_fcb)); memset((char *)&fcb, 0, sizeof(dos_fcb)); fcbseg = FP_SEG(pfcb); fcboff = FP_OFF(pfcb); dtaseg = FP_SEG(pdta); dtaoff = FP_OFF(pdta);#endif /* ?WATCOMC_386 */#ifdef DEBUG for (p = (char *)&dta; (p - (char *)&dta) < sizeof(dos_fcb); ++p) if (*p) fprintf(stderr, "error: dta[%d] = %x\n", (p - (char *)&dta), *p); for (p = (char *)&fcb; (p - (char *)&fcb) < sizeof(dos_fcb); ++p) if (*p) fprintf(stderr, "error: fcb[%d] = %x\n", (p - (char *)&fcb), *p); printf("testing pointer macros:\n"); segread(&sregs); printf("cs = %x, ds = %x, es = %x, ss = %x\n", sregs.cs, sregs.ds, sregs.es, sregs.ss);#endif /* DEBUG */#if 0#ifdef __TURBOC__ bdosptr(0x1a, dta, DO_NOT_CARE);#else (intdosx method below)#endif#endif /* 0 */ /* set the disk transfer address for subsequent FCB calls */ sregs.ds = dtaseg; WREGS(regs,dx) = dtaoff; Trace((stderr, "segment:offset of pdta = %x:%x\n", dtaseg, dtaoff)); Trace((stderr, "&dta = %lx, pdta = %lx\n", (ulg)&dta, (ulg)pdta)); regs.h.ah = 0x1a; F_intdosx(®s, ®s, &sregs); /* fill in the FCB */ sregs.ds = fcbseg; WREGS(regs,dx) = fcboff; pfcb->flag = 0xff; /* extended FCB */ pfcb->vattr = 0x08; /* attribute: disk volume label */ pfcb->drive = (uch)nLabelDrive;#ifdef DEBUG Trace((stderr, "segment:offset of pfcb = %x:%x\n", (unsigned int)(sregs.ds), (unsigned int)(WREGS(regs,dx)))); Trace((stderr, "&fcb = %lx, pfcb = %lx\n", (ulg)&fcb, (ulg)pfcb)); Trace((stderr, "(2nd check: labelling drive %c:)\n", pfcb->drive-1+'A')); if (pfcb->flag != fcb.flag) fprintf(stderr, "error: pfcb->flag = %d, fcb.flag = %d\n", pfcb->flag, fcb.flag); if (pfcb->drive != fcb.drive) fprintf(stderr, "error: pfcb->drive = %d, fcb.drive = %d\n", pfcb->drive, fcb.drive); if (pfcb->vattr != fcb.vattr) fprintf(stderr, "error: pfcb->vattr = %d, fcb.vattr = %d\n", pfcb->vattr, fcb.vattr);#endif /* DEBUG */ /* check for existing label */ Trace((stderr, "searching for existing label via FCBs\n")); regs.h.ah = 0x11; /* FCB find first */#ifdef WATCOMC_386 _fstrncpy((char far *)&pfcb->vn, "???????????", 11);#else strncpy((char *)fcb.vn, "???????????", 11); /* i.e., "*.*" */#endif /* ?WATCOMC_386 */ Trace((stderr, "fcb.vn = %lx\n", (ulg)fcb.vn)); Trace((stderr, "regs.h.ah = %x, regs.x.dx = %04x, sregs.ds = %04x\n", (unsigned int)(regs.h.ah), (unsigned int)(WREGS(regs,dx)), (unsigned int)(sregs.ds))); Trace((stderr, "flag = %x, drive = %d, vattr = %x, vn = %s = %s.\n", fcb.flag, fcb.drive, fcb.vattr, fcb.vn, pfcb->vn)); F_intdosx(®s, ®s, &sregs);/*--------------------------------------------------------------------------- If not previously labelled, write a new label. Otherwise just rename, since MS-DOS 2.x has a bug that damages the FAT when the old label is deleted. ---------------------------------------------------------------------------*/ if (regs.h.al) { Trace((stderr, "no label found\n\n")); regs.h.ah = 0x16; /* FCB create file */#ifdef WATCOMC_386 _fstrncpy((char far *)pfcb->vn, newlabel, len); if (len < 11) _fstrncpy((char far *)(pfcb->vn+len), " ", 11-len);#else strncpy((char *)fcb.vn, newlabel, len); if (len < 11) /* fill with spaces */ strncpy((char *)(fcb.vn+len), " ", 11-len);#endif Trace((stderr, "fcb.vn = %lx pfcb->vn = %lx\n", (ulg)fcb.vn, (ulg)pfcb->vn)); Trace((stderr, "flag = %x, drive = %d, vattr = %x\n", fcb.flag, fcb.drive, fcb.vattr)); Trace((stderr, "vn = %s = %s.\n", fcb.vn, pfcb->vn)); F_intdosx(®s, ®s, &sregs); regs.h.ah = 0x10; /* FCB close file */ if (regs.h.al) { Trace((stderr, "unable to write volume name (AL = %x)\n", (unsigned int)(regs.h.al))); F_intdosx(®s, ®s, &sregs); retv = 1; } else { F_intdosx(®s, ®s, &sregs); Trace((stderr, "new volume label [%s] written\n", newlabel)); retv = 0; } } else { Trace((stderr, "found old label [%s]\n\n", dta.vn)); /* not term. */ regs.h.ah = 0x17; /* FCB rename */#ifdef WATCOMC_386 _fstrncpy((char far *)pfcb->vn, (char far *)pdta->vn, 11); _fstrncpy((char far *)pfcb->nn, newlabel, len); if (len < 11) _fstrncpy((char far *)(pfcb->nn+len), " ", 11-len);#else strncpy((char *)fcb.vn, (char *)dta.vn, 11); strncpy((char *)fcb.nn, newlabel, len); if (len < 11) /* fill with spaces */ strncpy((char *)(fcb.nn+len), " ", 11-len);#endif Trace((stderr, "fcb.vn = %lx pfcb->vn = %lx\n", (ulg)fcb.vn, (ulg)pfcb->vn)); Trace((stderr, "fcb.nn = %lx pfcb->nn = %lx\n", (ulg)fcb.nn, (ulg)pfcb->nn)); Trace((stderr, "flag = %x, drive = %d, vattr = %x\n", fcb.flag, fcb.drive, fcb.vattr)); Trace((stderr, "vn = %s = %s.\n", fcb.vn, pfcb->vn)); Trace((stderr, "nn = %s = %s.\n", fcb.nn, pfcb->nn)); F_intdosx(®s, ®s, &sregs); if (regs.h.al) { Trace((stderr, "Unable to change volume name (AL = %x)\n", (unsigned int)(regs.h.al))); retv = 1; } else { Trace((stderr, "volume label changed to [%s]\n", newlabel)); retv = 0; } }#ifdef WATCOMC_386 regs.w.ax = 0x0101; /* free dos memory */ regs.w.dx = truseg; int386(0x31, ®s, ®s);#endif return retv;} /* end function volumelabel() */#endif /* !__GO32__ && !__EMX__ */#if (defined(USE_EF_UT_TIME) || defined(TIMESTAMP))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -