⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dosfns.c

📁 GNU FreeDOS兼容MS DOS很好的东东.
💻 C
📖 第 1 页 / 共 3 页
字号:
      (strlen(PriPathName) >= sizeof(current_ldt->cdsCurrentPath)))    return DE_PATHNOTFND;#if defined(CHDIR_DEBUG)  printf("Remote Chdir: n='%Fs' p='%Fs\n", s, PriPathName);#endif  /* now get fs to change to new          */  /* directory                            */  result = (result & IS_NETWORK ? network_redirector(REM_CHDIR) :            dos_cd(PriPathName));#if defined(CHDIR_DEBUG)  printf("status = %04x, new_path='%Fs'\n", result, cdsd->cdsCurrentPath);#endif  if (result != SUCCESS)    return result;/*   Copy the path to the current directory   structure.        Some redirectors do not write back to the CDS.        SHSUCdX needs this. jt*/  fstrcpy(current_ldt->cdsCurrentPath, PriPathName);  if (FP_OFF(current_ldt) != 0xFFFF)  {     fstrcpy(current_ldt->cdsCurrentPath, PriPathName);     if (PriPathName[7] == 0)       current_ldt->cdsCurrentPath[8] = 0; /* Need two Zeros at the end */  }  return SUCCESS;}STATIC VOID pop_dmp(dmatch FAR * dmp){  dmp->dm_attr_fnd = (BYTE) SearchDir.dir_attrib;  dmp->dm_time = SearchDir.dir_time;  dmp->dm_date = SearchDir.dir_date;  dmp->dm_size = (LONG) SearchDir.dir_size;  ConvertName83ToNameSZ(dmp->dm_name, (BYTE FAR *) SearchDir.dir_name);}COUNT DosFindFirst(UCOUNT attr, BYTE FAR * name){  int rc;  register dmatch FAR *dmp = dta;  rc = truename(name, PriPathName,                CDS_MODE_CHECK_DEV_PATH | CDS_MODE_ALLOW_WILDCARDS);  if (rc < SUCCESS)    return rc;  /* /// Added code here to do matching against device names.     DOS findfirst will match exact device names if the     filename portion (excluding the extension) contains     a valid device name.     Credits: some of this code was ripped off from truename()     in newstuff.c.     - Ron Cemer */  SAttr = (BYTE) attr;#if defined(FIND_DEBUG)  printf("Remote Find: n='%Fs\n", PriPathName);#endif  dta = &sda_tmp_dm;  memset(&sda_tmp_dm, 0, sizeof(dmatch)+sizeof(struct dirent));  if (rc & IS_NETWORK)    rc = network_redirector_fp(REM_FINDFIRST, current_ldt);  else if (rc & IS_DEVICE)  {    const char *p;    COUNT i;    /* Found a matching device. Hence there cannot be wildcards. */    SearchDir.dir_attrib = D_DEVICE;    SearchDir.dir_time = dos_gettime();    SearchDir.dir_date = dos_getdate();    p = (char *)FP_OFF(get_root(PriPathName));    memset(SearchDir.dir_name, ' ', FNAME_SIZE + FEXT_SIZE);    for (i = 0; i < FNAME_SIZE && *p && *p != '.'; i++)      SearchDir.dir_name[i] = *p++;    rc = SUCCESS;    /* /// End of additions.  - Ron Cemer ; heavily edited - Bart Oldeman */  }  else    rc = dos_findfirst(attr, PriPathName);  dta = dmp;  if (rc == SUCCESS)  {    fmemcpy(dta, &sda_tmp_dm, 21);    pop_dmp(dmp);  }  return rc;}COUNT DosFindNext(void){  COUNT rc;  register dmatch FAR *dmp = dta;  /* findnext will always fail on a device name device name or volume id */  if (dmp->dm_attr_fnd & (D_DEVICE | D_VOLID))    return DE_NFILES;/* *  The new version of SHSUCDX 1.0 looks at the dm_drive byte to *  test 40h. I used RamView to see location MSD 116:04be and *  FD f??:04be, the byte set with 0xc4 = Remote/Network drive 4. *  Ralf Brown docs for dos 4eh say bit 7 set == remote so what is *  bit 6 for?  *  SHSUCDX Mod info say "test redir not network bit". *  Just to confuse the rest, MSCDEX sets bit 5 too. * *  So, assume bit 6 is redirector and bit 7 is network. *  jt *  Bart: dm_drive can be the drive _letter_. *  but better just stay independent of it: we only use *  bit 7 to detect a network drive; the rest untouched. *  RBIL says that findnext can only return one error type anyway *  (12h, DE_NFILES) */#if 0  printf("findnext: %d\n", dmp->dm_drive);#endif  fmemcpy(&sda_tmp_dm, dmp, 21);  memset(&SearchDir, 0, sizeof(struct dirent));  dta = &sda_tmp_dm;  rc = (sda_tmp_dm.dm_drive & 0x80) ?    network_redirector_fp(REM_FINDNEXT, &sda_tmp_dm) : dos_findnext();  dta = dmp;  if (rc == SUCCESS)  {    fmemcpy(dmp, &sda_tmp_dm, 21);    pop_dmp(dmp);  }  return rc;}COUNT DosGetFtime(COUNT hndl, date * dp, time * tp){  sft FAR *s;/*sfttbl FAR *sp;*/  /* Get the SFT block that contains the SFT      */  if (FP_OFF(s = get_sft(hndl)) == (size_t) - 1)    return DE_INVLDHNDL;  /* If SFT entry refers to a device, return the date and time of opening */  if (s->sft_flags & (SFT_FDEVICE | SFT_FSHARED))  {    *dp = s->sft_date;    *tp = s->sft_time;    return SUCCESS;  }  /* call file system handler                     */  return dos_getftime(s->sft_status, dp, tp);}COUNT DosSetFtimeSft(int sft_idx, date dp, time tp){  /* Get the SFT block that contains the SFT      */  sft FAR *s = idx_to_sft(sft_idx);  if (FP_OFF(s) == (size_t) - 1)    return DE_INVLDHNDL;  /* If SFT entry refers to a device, do nothing */  if (s->sft_flags & SFT_FDEVICE)    return SUCCESS;  s->sft_flags |= SFT_FDATE;  s->sft_date = dp;  s->sft_time = tp;  if (s->sft_flags & SFT_FSHARED)    return SUCCESS;  /* call file system handler                     */  return dos_setftime(s->sft_status, dp, tp);}COUNT DosGetFattr(BYTE FAR * name){  COUNT result;  result = truename(name, PriPathName, CDS_MODE_CHECK_DEV_PATH);  if (result < SUCCESS)    return result;  /* /// Added check for "d:\", which returns 0x10 (subdirectory) under DOS.       - Ron Cemer */           /* Theoretically: If the redirectory's qualify function               doesn't return nonsense this check can be reduced to               PriPathname[3] == 0, because local path names always               have the three-byte string ?:\ and UNC path shouldn't               validy consist of just two slashes.               -- 2001/09/03 ska*/  if (PriPathName[3] == '\0')    return 0x10;  if (result & IS_NETWORK)    return network_redirector(REM_GETATTRZ);  if (result & IS_DEVICE)    return DE_FILENOTFND;/* /// Use truename()'s result, which we already have in PriPathName.       I copy it to tmp_name because PriPathName is global and seems       to get trashed somewhere in transit.       The reason for using truename()'s result is that dos_?etfattr()       are very low-level functions and don't handle full path expansion       or cleanup, such as converting "c:\a\b\.\c\.." to "C:\A\B".       - Ron Cemer*//*          memcpy(SecPathName,PriPathName,sizeof(SecPathName));          return dos_getfattr(SecPathName, attrp);*/    /* no longer true. dos_getfattr() is        A) intelligent (uses dos_open) anyway       B) there are some problems with MAX_PARSE, i.e. if PATH ~= 64       and TRUENAME adds a C:, which leeds to trouble.        the problem was discovered, when VC did something like       fd = DosOpen(filename,...)       jc can't_copy_dialog;       attr = DosGetAttrib(filename);       jc can't_copy_dialog;       and suddenly, the filehandle stays open       shit.       tom     */  return dos_getfattr(PriPathName);}/* This function is almost identical to DosGetFattr().   Maybe it is nice to join both functions.       -- 2001/09/03 ska*/COUNT DosSetFattr(BYTE FAR * name, UWORD attrp){  COUNT result;  result = truename(name, PriPathName, CDS_MODE_CHECK_DEV_PATH);  if (result < SUCCESS)    return result;  if (result & IS_NETWORK)    return remote_setfattr(attrp);  if (result & IS_DEVICE)    return DE_FILENOTFND;/* /// Use truename()'s result, which we already have in PriPathName.       I copy it to tmp_name because PriPathName is global and seems       to get trashed somewhere in transit.       - Ron Cemer*//*          memcpy(SecPathName,PriPathName,sizeof(SecPathName));          return dos_setfattr(SecPathName, attrp);                    see DosGetAttr()*/  return dos_setfattr(PriPathName, attrp);}UBYTE DosSelectDrv(UBYTE drv){  current_ldt = get_cds(drv);  if (current_ldt != NULL)    default_drive = drv;  return lastdrive;}COUNT DosDelete(BYTE FAR * path, int attrib){  COUNT result;  result = truename(path, PriPathName, CDS_MODE_CHECK_DEV_PATH);  if (result < SUCCESS)    return result;  if (result & IS_NETWORK)    return network_redirector(REM_DELETE);  if (result & IS_DEVICE)    return DE_FILENOTFND;  return dos_delete(PriPathName, attrib);}COUNT DosRenameTrue(BYTE * path1, BYTE * path2, int attrib){  if (path1[0] != path2[0])  {    return DE_DEVICE; /* not same device */  }  if (FP_OFF(current_ldt) == 0xFFFF || (current_ldt->cdsFlags & CDSNETWDRV))    return network_redirector(REM_RENAME);  return dos_rename(path1, path2, attrib);}COUNT DosRename(BYTE FAR * path1, BYTE FAR * path2){  COUNT result;  result = truename(path2, SecPathName, CDS_MODE_CHECK_DEV_PATH);  if (result < SUCCESS)    return result;  if ((result & (IS_NETWORK | IS_DEVICE)) == IS_DEVICE)    return DE_FILENOTFND;  result = truename(path1, PriPathName, CDS_MODE_CHECK_DEV_PATH);  if (result < SUCCESS)    return result;  if ((result & (IS_NETWORK | IS_DEVICE)) == IS_DEVICE)    return DE_FILENOTFND;  return DosRenameTrue(PriPathName, SecPathName, D_ALL);}COUNT DosMkRmdir(const char FAR * dir, int action){  COUNT result;  result = truename(dir, PriPathName, CDS_MODE_CHECK_DEV_PATH);  if (result < SUCCESS)    return result;  if (result & IS_NETWORK)    return network_redirector(action == 0x39 ? REM_MKDIR : REM_RMDIR);  if (result & IS_DEVICE)    return DE_ACCESS;  return (action == 0x39 ? dos_mkdir : dos_rmdir)(PriPathName);}/* /// Added for SHARE.  - Ron Cemer */COUNT DosLockUnlock(COUNT hndl, LONG pos, LONG len, COUNT unlock){  sft FAR *s;  /* Get the SFT block that contains the SFT      */  if (FP_OFF(s = get_sft(hndl)) == (size_t) - 1)    return DE_INVLDHNDL;  if (s->sft_flags & SFT_FSHARED)    return remote_lock_unlock(s, pos, len, unlock);  /* Invalid function unless SHARE is installed or remote. */  if (!IsShareInstalled())    return DE_INVLDFUNC;  /* Lock violation if this SFT entry does not support locking. */  if (s->sft_shroff < 0)    return DE_LOCK;  /* Let SHARE do the work. */  return share_lock_unlock(cu_psp, s->sft_shroff, pos, len, unlock);}/* /// End of additions for SHARE.  - Ron Cemer *//* * This seems to work well. *//* check for a device   returns device header if match, else returns NULL   can only match character devices (as only they have names) */struct dhdr FAR *IsDevice(const char FAR * fname){  struct dhdr FAR *dhp;  const char FAR *froot = get_root(fname);  int i;/* /// BUG!!! This is absolutely wrong.  A filename of "NUL.LST" must be       treated EXACTLY the same as a filename of "NUL".  The existence or       content of the extension is irrelevent in determining whether a       filename refers to a device.       - Ron Cemer  // if we have an extension, can't be a device <--- WRONG.  if (*froot != '.')  {*//*  BUGFIX: MSCD000<00> should be handled like MSCD000<20> TE     ie the 8 character device name may be padded with spaces ' ' or NULs '\0'    Note: fname is assumed an ASCIIZ string (ie not padded, unknown length)    but the name in the device header is assumed FNAME_SIZE and padded.  KJD*/  /* check for names that will never be devices to avoid checking all device headers.     only the file name (not path nor extension) need be checked, "" == root or empty name   */  if ( (*froot == '\0') ||       ((*froot=='.') && ((*(froot+1)=='\0') || (*(froot+2)=='\0' && *(froot+1)=='.')))     )  {    return NULL;  }  /* cycle through all device headers checking for match */  for (dhp = (struct dhdr FAR *)&nul_dev; dhp != (struct dhdr FAR *)-1;       dhp = dhp->dh_next)  {    if (!(dhp->dh_attr & ATTR_CHAR))  /* if this is block device, skip */      continue;    for (i = 0; i < FNAME_SIZE; i++)    {      unsigned char c1 = (unsigned char)froot[i];      /* ignore extensions and handle filenames shorter than FNAME_SIZE */      if (c1 == '.' || c1 == '\0')      {        /* check if remainder of device name consists of spaces or nulls */        for (; i < FNAME_SIZE; i++)        {          unsigned char c2 = dhp->dh_name[i];          if (c2 != ' ' && c2 != '\0')            break;        }        break;      }      if (DosUpFChar(c1) != DosUpFChar(dhp->dh_name[i]))        break;    }    /* if found a match then return device header */    if (i == FNAME_SIZE)      return dhp;  }  return NULL;}/* /// Added for SHARE.  - Ron Cemer */BOOL IsShareInstalled(void){  extern unsigned char ASMPASCAL share_check(void);  if (!share_installed && share_check() == 0xff)    share_installed = TRUE;  return share_installed;}/* /// End of additions for SHARE.  - Ron Cemer */COUNT DosTruename(const char FAR *src, char FAR *dest){  /* RBIL: The buffer has be unchanged, if the call fails.     Therefore, the name is created in an internal buffer     and copied into the user buffer only on success.  */    COUNT rc = truename(src, PriPathName, CDS_MODE_ALLOW_WILDCARDS);  if (rc >= SUCCESS)    fstrcpy(dest, PriPathName);  return rc;}STATIC int remote_lock_unlock(sft FAR *sftp,     /* SFT for file */                              unsigned long ofs, /* offset into file */                              unsigned long len, /* length (in bytes) of region to lock or unlock */                              int unlock)                                 /* one to unlock; zero to lock */{  struct  {    unsigned long ofs, len;    int unlock;  } param_block;  param_block.ofs = ofs;  param_block.len = len;  param_block.unlock = unlock;  return (int)network_redirector_mx(REM_LOCK, sftp, &param_block);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -