📄 find.c
字号:
/* find.c - MSDOS find first and next matching files
*
* 09-Dec-1986 bw Added DOS5 support
* 24-Feb-1987 bw Define findclose() function.
* 30-Oct-1987 bw Change 'DOS5' to 'OS2'
* 08-Dec-1988 mz Add net enum
*/
#if defined (DOS)
#include <dos.h>
#include <string.h>
#include "..\h\tools.h"
/* ffirst - begin find enumeration given a pattern
*
* file char pointer to name string with pattern in last component.
* attr inclusive attributes for search
* fbuf pointer to buffer for find stuff
*
* returns (DOS) TRUE if error, FALSE if success
* (OS2) error code or NO_ERROR
*/
/* fnext - continue find enumeration
*
* fbuf pointer to find buffer
*
* returns (DOS) TRUE if error, FALSE if success
* (OS2) error code or NO_ERROR
*/
/* findclose - release system resources upon find completion
*
* Allows z runtime and filesystem to release resources
*
* fbuf pointer to find buffer
*/
ffirst (file, attr, fbuf)
char *file;
int attr;
struct findType *fbuf;
{
union REGS regs;
#if ( defined(M_I86CM) || defined (M_I86LM) || defined (M_I86HM) )
struct SREGS sregs;
#endif
/* point DTA to buffer */
regs.h.ah = 0x1A;
#if (defined(M_I86CM) || defined(M_I86LM) || defined(M_I86HM))
segread(&sregs);
sregs.ds = FP_SEG(fbuf);
regs.x.dx = FP_OFF(fbuf);
intdosx(®s, ®s, &sregs);
#else
regs.x.dx = (unsigned) fbuf;
intdos (®s, ®s);
#endif
/* issue find first call */
regs.h.ah = 0x4e;
regs.x.cx = attr;
#if (defined(M_I86CM) || defined(M_I86LM) || defined(M_I86HM))
segread(&sregs);
sregs.ds = FP_SEG(file);
regs.x.dx = FP_OFF(file);
intdosx(®s, ®s, &sregs);
#else
regs.x.dx = (unsigned) file;
intdos (®s, ®s);
#endif
if (!regs.x.cflag)
strlwr (fbuf->name);
return regs.x.cflag;
}
fnext (fbuf)
struct findType *fbuf;
{
union REGS regs;
#if ( defined(M_I86CM) || defined (M_I86LM) || defined (M_I86HM) )
struct SREGS sregs;
#endif
/* point DTA to buffer */
regs.h.ah = 0x1A;
#if (defined(M_I86CM) || defined(M_I86LM) || defined(M_I86HM))
segread(&sregs);
sregs.ds = FP_SEG(fbuf);
regs.x.dx = FP_OFF(fbuf);
intdosx(®s, ®s, &sregs);
#else
regs.x.dx = (unsigned) fbuf;
intdos (®s, ®s);
#endif
/* issue find next call */
regs.h.ah = 0x4F;
#if (defined(M_I86CM) || defined(M_I86LM) || defined(M_I86HM))
sregs.ds = FP_SEG(fbuf);
intdosx(®s, ®s, &sregs);
#else
intdos (®s, ®s);
#endif
if (!regs.x.cflag)
strlwr (fbuf->name);
return regs.x.cflag;
}
void findclose (fbuf)
struct findType *fbuf;
{
}
#elif defined(OS2) || defined(NT)
#define INCL_DOSERRORS
#define INCL_DOSMODULEMGR
#if defined(OS2)
#include <os2.h>
#elif defined(NT)
#include <nt.h>
#include <ntrtl.h>
#include <nturtl.h>
#include <windows.h>
#endif
#include "..\h\tools.h"
#include <malloc.h>
#include <string.h>
#include <stdio.h>
#if defined (OS2)
#include <netcons.h>
#include <neterr.h>
#include <server.h>
#include <shares.h>
#include <access.h>
#include <wksta.h>
#elif defined (NT)
#define _LM_
#include <lmcons.h>
#include <lmerr.h>
#include <lmserver.h>
#include <lmshare.h>
#include <lmaccess.h>
#include <lmwksta.h>
#endif
#define CCHPAT 128
#if defined(OS2)
#define STATUS_OK NO_ERROR
#define NO_MORE_FILES ERROR_NO_MORE_FILES
typedef struct share_info_1 SHARE_INFO_1;
typedef struct server_info_0 SERVER_INFO_100;
#define SV_NAME sv0_name
#define CLOSEFIND DosFindClose
#elif defined(NT)
#define SRCHATTR (FILE_ATTRIBUTE_HIDDEN | \
FILE_ATTRIBUTE_SYSTEM | \
FILE_ATTRIBUTE_DIRECTORY)
static BOOL AttributesMatch( NPFIND fbuf );
#define CLOSEFIND FindClose
#define SV_NAME sv100_name
#endif
#if defined(OS2)
HANDLE hmodOEM;
#endif
HANDLE hmodAPI;
#if defined(OS2)
USHORT (pascal FAR *pNetServerGetInfo) (const char FAR *,
short,
char FAR *,
unsigned short,
unsigned short FAR *);
USHORT (pascal FAR *pNetServerEnum) (const char FAR *,
short,
char FAR *,
unsigned short,
unsigned short FAR *,
unsigned short FAR *);
USHORT (pascal FAR *pNetShareEnum) (const char FAR *,
short,
char FAR *,
unsigned short,
unsigned short FAR *,
unsigned short FAR *);
#elif defined (NT)
NET_API_STATUS (NET_API_FUNCTION
*pNetServerEnum) (
IN LPTSTR servername OPTIONAL,
IN DWORD level,
OUT LPBYTE *bufptr,
IN DWORD prefmaxlen,
OUT LPDWORD entriesread,
OUT LPDWORD totalentries,
IN DWORD servertype,
IN LPTSTR domain OPTIONAL,
IN OUT LPDWORD resume_handle OPTIONAL
);
NET_API_STATUS (NET_API_FUNCTION
*pNetServerGetInfo) (
IN LPTSTR servername OPTIONAL,
IN DWORD level,
OUT LPBYTE *bufptr
);
NET_API_STATUS (NET_API_FUNCTION
*pNetShareEnum) (
IN LPTSTR servername,
IN DWORD level,
OUT LPBYTE *bufptr,
IN DWORD prefmaxlen,
OUT LPDWORD entriesread,
OUT LPDWORD totalentries,
IN OUT LPDWORD resume_handle
);
#endif
typedef SERVER_INFO_100 SI;
typedef struct serverbuf {
USHORT csi; /* count of si's in array */
USHORT isiLast; /* index of last returned server */
int attr; /* attribute of search */
BYTE szPattern[CCHPAT]; /* pattern for matching */
SI asi[1]; /* array of server blocks */
} SB;
typedef SB FAR * PSB;
typedef SHARE_INFO_1 SHI;
typedef struct sharebuf {
USHORT cshi; /* count of shi's in array */
USHORT ishiLast; /* index of last returned share */
int attr; /* attribute of search */
BYTE szServer[CCHPAT]; /* server name */
BYTE szPattern[CCHPAT]; /* pattern for matching */
SHI ashi[1]; /* array of share blocks */
} SHB;
typedef SHB FAR * PSHB;
static int usFileFindNext (struct findType *fbuf);
static int usSharFindFirst (char *npsz, int attr, struct findType *fbuf);
static int usSharFindNext (struct findType *fbuf);
static int usServFindFirst (char *npsz, int attr, struct findType *fbuf);
static int usServFindNext (struct findType *fbuf);
static int usLoadNet (void);
#if defined(OS2)
#define InNetServerGetInfo (*pNetServerGetInfo)
#define InNetServerEnum (*pNetServerEnum)
#define InNetShareEnum (*pNetShareEnum)
#elif defined(NT)
static InNetServerGetInfo (const char *pszServer,
short sLevel,
char *pbBuffer,
unsigned short cbBuffer,
unsigned short *pcbTotalAvail);
static InNetServerEnum (const char *pszServer,
short sLevel,
char * pbBuffer,
unsigned short cbBuffer,
unsigned short *pcEntriesRead,
unsigned short *pcTotalAvail);
static InNetShareEnum (const char *pszServer,
short sLevel,
char * pbBuffer,
unsigned short cbBuffer,
unsigned short *pcEntriesRead,
unsigned short *pcTotalAvail);
#endif
/* returns error code or NO_ERROR
*/
int ffirst (char *file, int attr, struct findType *fbuf)
{
int erc;
fbuf->type = FT_DONE;
{ char *p = file;
#if !defined(NT) || defined(_LM_)
char *p1;
#else
UNREFERENCED_PARAMETER( attr );
#endif // !NT || _LM_
/* We need to handle the following cases:
*
* [D:]\\pattern
* [D:]\\machine\pattern
* [D:]\\machine\share\pattern
* [D:]path\pattern
*/
/* skip drive
*/
if (p[0] != 0 && p[1] == ':')
p += 2;
#if !defined(NT) || defined(_LM_)
/* If UNC present
*/
if (fPathChr (p[0]) && fPathChr (p[1]))
/* If not fully specified then set up server enumerate
*/
if (*(p1 = strbscan (p + 2, "/\\")) == 0) {
erc = usLoadNet ();
if (erc == 0)
erc = usServFindFirst (p, attr, fbuf);
goto casefix;
}
else {
p1 = strbskip (p1, "/\\");
if (*strbscan (p1, "/\\") == 0) {
erc = usLoadNet ();
if (erc == 0)
erc = usSharFindFirst (p, attr, fbuf);
goto casefix;
}
}
#endif // !NT || _LM_
}
fbuf->type = FT_FILE;
#if defined(OS2)
{ unsigned SearchCount = 1;
fbuf->type = FT_FILE;
fbuf->dir_handle = 0xFFFF; /* Give me a directory handle */
erc = DosFindFirst
( file , /* File path name */
(PHDIR)&fbuf->dir_handle, /* Directory search handle */
attr & A_ALL & ~A_V , /* Search attribute */
(PFILEFINDBUF)&fbuf->create_date,
/* Result buffer */
sizeof(*fbuf) - sizeof(fbuf->dir_handle) ,
/* Result buffer length */
(PUSHORT)&SearchCount, /* # of entries to find */
0L /* Reserved (must be zero) */
);
}
#elif defined(NT)
{
fbuf->attr = attr;
erc = ( ( fbuf->dir_handle = FindFirstFile( file, &( fbuf->fbuf ) ) ) == (HANDLE)-1 ) ? 1 : 0;
if ( (!erc) && !AttributesMatch( fbuf ) ) {
erc = fnext( fbuf );
}
}
#endif
casefix:
if (
#if defined(OS2)
erc == NO_ERROR
#elif defined(NT)
fbuf->dir_handle != (HANDLE)-1
#endif
)
if (!IsMixedCaseSupported (file))
strlwr (PFT_FOUNDNAME(fbuf));
else
SETFLAG (fbuf->type, FT_MIX);
return erc;
}
fnext (struct findType *fbuf)
{
int erc;
switch (fbuf->type & FT_MASK ) {
case FT_FILE:
erc = usFileFindNext (fbuf);
break;
#if !defined(NT) || defined(_LM_)
case FT_SERV:
erc = usServFindNext (fbuf);
break;
case FT_SHAR:
erc = usSharFindNext (fbuf);
break;
#endif // !NT || _LM_
default:
erc = ERROR_NO_MORE_FILES;
}
if (erc == NO_ERROR && !TESTFLAG (fbuf->type, FT_MIX))
strlwr (PFT_FOUNDNAME(fbuf));
return erc;
}
void findclose (struct findType *fbuf)
{
switch (fbuf->type & FT_MASK ) {
case FT_FILE:
CLOSEFIND (fbuf->dir_handle);
break;
#if !defined(NT) || defined(_LM_)
case FT_SERV:
case FT_SHAR:
#if defined(OS2)
DosFreeSeg ((SEL) fbuf->dir_handle);
#else
free( (void *)fbuf->dir_handle );
#endif
break;
#endif // !NT || _LM_
}
fbuf->type = FT_DONE;
}
#if defined(NT)
static BOOL AttributesMatch( NPFIND fbuf )
{
//
// We emulate the OS/2 behaviour of attribute matching. The semantics
// are evil, so I provide no explanation.
//
fbuf->fbuf.dwFileAttributes &= (0x000000FF & ~(FILE_ATTRIBUTE_NORMAL));
if (! ((fbuf->fbuf.dwFileAttributes & SRCHATTR) & ~(fbuf->attr))) {
return TRUE;
} else {
return FALSE;
}
}
#endif //NT
/* Find next routines
*/
static int
usFileFindNext (struct findType *fbuf)
{
#if defined(OS2)
unsigned SearchCount = 1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -