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

📄 newstuff.c

📁 开源DOS的C代码源程序
💻 C
📖 第 1 页 / 共 2 页
字号:
/****************************************************************/
/*                                                              */
/*                           newstuff.c                         */
/*                            DOS-C                             */
/*                                                              */
/*                       Copyright (c) 1996                     */
/*                          Svante Frey                         */
/*                      All Rights Reserved                     */
/*                                                              */
/* This file is part of DOS-C.                                  */
/*                                                              */
/* DOS-C is free software; you can redistribute it and/or       */
/* modify it under the terms of the GNU General Public License  */
/* as published by the Free Software Foundation; either version */
/* 2, or (at your option) any later version.                    */
/*                                                              */
/* DOS-C is distributed in the hope that it will be useful, but */
/* WITHOUT ANY WARRANTY; without even the implied warranty of   */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See    */
/* the GNU General Public License for more details.             */
/*                                                              */
/* You should have received a copy of the GNU General Public    */
/* License along with DOS-C; see the file COPYING.  If not,     */
/* write to the Free Software Foundation, 675 Mass Ave,         */
/* Cambridge, MA 02139, USA.                                    */
/****************************************************************/

#ifdef VERSION_STRINGS
static BYTE *mainRcsId =
    "$Id: newstuff.c,v 1.35 2004/05/23 20:06:51 bartoldeman Exp $";
#endif

#include        "portab.h"
#include        "globals.h"

/*
    TE-TODO: if called repeatedly by same process, 
    last allocation must be freed. if handle count < 20, copy back to PSP
*/
int SetJFTSize(UWORD nHandles)
{
  UWORD block, maxBlock, i;
  psp FAR *ppsp = MK_FP(cu_psp, 0);
  UBYTE FAR *newtab;

  if (nHandles <= ppsp->ps_maxfiles)
  {
    ppsp->ps_maxfiles = nHandles;
    return SUCCESS;
  }

  if ((DosMemAlloc
       ((nHandles + 0xf) >> 4, mem_access_mode, &block, &maxBlock)) < 0)
    return DE_NOMEM;

  ++block;
  newtab = MK_FP(block, 0);

  i = ppsp->ps_maxfiles;
  /* copy existing part and fill up new part by "no open file" */
  fmemcpy(newtab, ppsp->ps_filetab, i);
  fmemset(newtab + i, 0xff, nHandles - i);

  ppsp->ps_maxfiles = nHandles;
  ppsp->ps_filetab = newtab;

  return SUCCESS;
}

long DosMkTmp(BYTE FAR * pathname, UWORD attr)
{
  /* create filename from current date and time */
  char FAR *ptmp;
  unsigned long randvar;
  long rc;
  int loop;

  ptmp = pathname + fstrlen(pathname);
  if (ptmp == pathname || (ptmp[-1] != '\\' && ptmp[-1] != '/'))
    *ptmp++ = '\\';
  ptmp[8] = '\0';

  randvar = ((unsigned long)dos_getdate() << 16) | dos_gettime();

  loop = 0;
  do {
    unsigned long tmp = randvar++;
    int i;
    for(i = 7; i >= 0; tmp >>= 4, i--)
      ptmp[i] = ((char)tmp & 0xf) + 'A';

    /* DOS versions: > 5: characters A - P
       < 5: hex digits */
    if (os_major < 5)
      for (i = 0; i < 8; i++)
        ptmp[i] -= (ptmp[i] < 'A' + 10) ? '0' - 'A' : 10;

    /* only create new file -- 2001/09/22 ska*/
    rc = DosOpen(pathname, O_LEGACY | O_CREAT | O_RDWR, attr);
  } while (rc == DE_FILEEXISTS && loop++ < 0xfff);

  return rc;
}

#ifdef DEBUG
#define DEBUG_TRUENAME
#endif

#define drLetterToNr(dr) ((unsigned char)((dr) - 'A'))
/* Convert an uppercased drive letter into the drive index */
#define drNrToLetter(dr) ((dr) + 'A')
/* the other direction */

  /* In DOS there are no free-standing UNC paths, therefore there
     is always a logical drive letter associated with a path
     spec. This letter is also the index into the CDS */

/* 
	Definition of functions for the handling of the Current
	Directory Structure.

	MUX-11-23: Qualify Remote Filename
		DOS-0x60 calls this MUX functions to let the Network Redirector
		qualify the filename. According INTRSPY MS DOS 6 does not pre-
		process the passed in filename in any way (see attached transcripts).

	The DOS-60 interface TRUENAME looks like this:

	DosTruename(src, dest) {
		if (MUX-11-23(src, dest) != Error)
			return SUCCESS
		return local_truename(src, dest);
	}

	The CDS has the following entries:

    char cdsPath[CDSPATHLEN];
    	The fully-qualified current working directory of this drive.
    	The format is DOS <dr>:\[<path>{\<path>}]
		or UNC \<id>\[<path>{\<path>}].
		The drive <dr> indicates the physical drive letter and is the
		index into the blk_device[].

    UWORD cdsFlags;
    	Indicates what kind this logical drive is:
    		NETWORK: drive is NOT local \ If both are set, drive is IFS
    		PHYSICAL: drive is local    / If none is set, drive is non-existant
    		JOIN: drive is joined in as the path cdsPath. This Flag uses the
    			index into the CDS table to indicate the physical drive.
    		SUBST: drive substitutes the path cdsPath.
    		HIDDEN: drive is not included into the redirector's list.

    struct dpb FAR *cdsDpb;
    	Pointer to the DPB driving the physical drive. In DOS-C, the physical
    	drive letter is the index into the DPB[]. But for compatibly reason
    	this field will be set correctly.

	UWORD cdsStartCluster;
		For local drives only: This holds the cluster number of
		the start of the current working directory of this
		logical drive. If 0000h, it's the root directory; if
		0ffffh, the drive was never accessed and has to be read
		again.

	void FAR *cdsIFSrecord;
	UWORD cdsIFSparameter;
		For networked drives only: Holds pointer/parameters to/for IFS
		driver. (Well, I don't know.)

    UWORD cdsPathOff;
    	Number of characters of the cdsPath[], which are hidden. The
    	logical path is combined by the logical drive letter and the
    	cdsPath[] part, which is not hidden.

    IFS FAR *cdsIFSdrv;
    	Will be zeroed for local drives.

   Revision 1.2  1995/12/03 22:17:41  ska
   bugfix: Scanning of file name in 8.3 failed on "." and on longer names.

   Revision 1.1  1995/11/09 07:43:30  ska
   #

*/

#define PATH_ERROR goto errRet
#define PATHLEN 128


/* Map a logical path into a physical one.

	1) Uppercasing path.
	2) Flipping '/' -> '\\'.
	3) Removing empty directory components & ".".
	4) Processing ".." components.
	5) Convert path components into 8.3 convention.
	6) Make it fully-qualified.
	7) Map it to SUBST/UNC.
        8) Map to JOIN.

   Return:
   	*cdsItem will be point to the appropriate CDS entry. This will allow
   	the caller to aquire the DPB or the IFS informtion of this entry.
   	error number
   	Return value:
   		DE_FILENOTFND, or DE_PATHNOTFND (as described in RBIL)
   	If the output path pnfo->physPath exceeds the length MAX_PATH, the error
   	DE_FILENOTFND will be returned.
*/

/*
 * Added support for external and internal calls.
 * Clean buffer before use. Make the true path and expand file names.
 * Example: *.* -> ????????.??? as in the currect way.
 * MSD returns \\D.\A.\????????.??? with SHSUCDX. So, this code is not
 * compatible MSD Func 60h.
 */

/*TE TODO:

    experimenting with NUL on MSDOS 7.0 (win95)
    
                        WIN95           FREEDOS
    TRUENAME NUL        C:/NUL             OK
    TRUENAME .\NUL      C:\DOS\NUL         
    TRUENAME ..\NUL     C:\NUL
    TRUENAME ..\..\NUL  path not found
    TRUENAME Z:NUL      invalid drive (not lastdrive!!)
    TRUENAME A:NUL      A:/NUL             OK
    TRUENAME A:\NUL     A:\NUL

*/

#ifdef DEBUG_TRUENAME
#define tn_printf(x) printf x
#else
#define tn_printf(x)
#endif

#define PNE_WILDCARD 1
#define PNE_DOT 2

#define addChar(c) \
{ \
  if (p >= dest + SFTMAX) PATH_ERROR; /* path too long */	\
  *p++ = c; \
}

/* helper for truename: parses either name or extension */
STATIC int parse_name_ext(int i, const char FAR **src, char **cp, char *dest)
{
  int retval = SUCCESS;
  char *p = *cp;
  char c;
  
  while(1) switch(c=*(*src)++)
  {
    case '.':
      retval |= PNE_DOT;
      /* fall through */
    case '/':
    case '\\':
    case '\0':
      *cp = p;
      return retval;
    case '*':
      retval |= PNE_WILDCARD;
      /* register the wildcard, even if no '?' is appended */
      if (i) do
      {
        addChar('?');
      } while(--i);
      /** Alternative implementation:
          if (i)
          {
            if (dest + SFTMAX - *p < i)
              PATH_ERROR;
            fmemset(p, '?', i);
            p += i;
          }		**/
      break;
    case '?':
      retval |= PNE_WILDCARD;
      /* fall through */
    default:
      if (i) {	/* name length in limits */
        --i;
        addChar(c);
      }
  }
  
 errRet:
  return -1;
}

COUNT truename(const char FAR * src, char * dest, COUNT mode)
{
  COUNT i;
  struct dhdr FAR *dhp;
  const char FAR *froot;
  COUNT result;
  int gotAnyWildcards = 0;
  struct cds FAR *cdsEntry;
  char *p = dest;	  /* dynamic pointer into dest */
  char *rootPos;
  char src0;
  enum { DONT_ADD, ADD, ADD_UNLESS_LAST } addSep;

  tn_printf(("truename(%S)\n", src));

  /* First, adjust the source pointer */
  src = adjust_far(src);

  /* In opposite of the TRUENAME shell command, an empty string is
     rejected by MS DOS 6 */
  src0 = src[0];
  if (src0 == '\0')
    return DE_FILENOTFND;

  if (src0 == '\\' && src[1] == '\\') {
    const char FAR *unc_src = src;
    /* Flag UNC paths and short circuit processing.  Set current LDT   */
    /* to sentinel (offset 0xFFFF) for redirector processing.          */
    tn_printf(("Truename: UNC detected\n"));
    do {
      src0 = unc_src[0];
      addChar(src0);
      unc_src++;
    } while (src0);
    current_ldt = (struct cds FAR *)MK_FP(0xFFFF,0xFFFF);
    tn_printf(("Returning path: \"%s\"\n", dest));
    /* Flag as network - drive bits are empty but shouldn't get */
    /* referenced for network with empty current_ldt.           */
    return IS_NETWORK;
  }
  
  /* Do we have a drive?                                          */
  if (src[1] == ':')
    result = drLetterToNr(DosUpFChar(src0));
  else
    result = default_drive;

  cdsEntry = get_cds(result);
  if (cdsEntry == NULL)
    return DE_PATHNOTFND;

⌨️ 快捷键说明

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