home *** CD-ROM | disk | FTP | other *** search
- /* CDtest 1.0
-
- Tests if simultaneous I/O corrupts CD-ROM reading. If so, likely causes are the
- PCI RZ-1000 EIDE chip, the CMD PCIO640B EIDE chip or a faulty DMA controller.
- Runs under DOS, DESQview, Windows, NT and OS/2 in DOS emulation mode.
-
- This program may be copied freely and used for any purpose except military.
- (c) copyright 1995 by
- Roedy Green
- Canadian Mind Products
- #601 - 1330 Burrard Street
- Vancouver, BC Canada V6Z 2B8
- (604) 685-8412
- Internet Roedy@bix.com
-
- compiled under SMALL model
-
- It works by reading a set of files repeatedly from the CD-ROM drive
- and computing a checksum on each file. It reads the same set of
- files multiple times with as much I/o as possible
- interfering. It ensures the same checksum is computed each time.
-
-
- Version history
-
- 1.0- first version, cloned and modified from EIDEtest
- */
-
- /* D E F I N E S */
-
- #define BufferSizeInBytes 31744
- /* size of buffer for reading the files.
- This size should generate lots of physical I/O.
- Smaller sizes might come out of cache.
- Bigger sizes do only a few big I/Os */
-
- #define TestSizeInBytes 7616560L
- /* aggregate bytes to read for the test per pass, spread over many files. */
-
- #define MaxFiles 2000
- /* maximum number of files on CDROM that will be processed.
- Up to this many will have checksums computed.
- Usually TestSizeInBytes will be the limiting factor. */
-
- #define StartDecorate "\xb0\xb1\xb2\xdb"
- /* line of pretty blobs in oemfont to attract attention */
- #define EndDecorate "\xdb\xb2\xb1\xb0"
-
- #define Esc '\x1b'
-
- /* T Y P E D E F S */
-
- typedef unsigned short WORD;
-
- typedef unsigned char BYTE;
-
- typedef enum BOOL
- {
- FALSE, TRUE
- } BOOL;
-
- typedef enum TESTRESULT
- {
- PASS, FAIL, INCOMPLETE
- } TESTRESULT;
-
- typedef unsigned int ATTRIB;
-
- typedef char ATTRIBPATTERN [7];
-
- /* I N C L U D E S */
-
- #include <stdlib.h>
- // e.g. exit, min, max
-
- #include <stdio.h>
- // e.g. FILE, printf, fopen
-
- #include <conio.h>
- // e.g. getch kbhit crlscr
-
- #include <alloc.h>
- // e.g. malloc free
-
- #include <dos.h>
- // _dos_findfirst _dos_findnext
-
- #include <string.h>
- // strcpy
-
- /* G L O B A L S */
-
- char WildCard[] = "E:\\*.*";
- /* Wildcard to describe all files on the EIDE CD-ROM */
-
- /* P R O T O T Y P E S */
-
- int main( int argc, char *argv[] );
- void Banner ( void );
- void beep (void );
- int pause ( void );
- int DoesOSDoSimultaneousIO ( void );
- int CheckForEsc ( void );
-
- /* ***************************************** */
-
- /* C L A S S D E C L A R A T I O N */
-
- class FILETREE
- {
- /* class to process a set of files matching a wildcard */
- public:
-
- FILETREE() {};
-
- ~FILETREE() {};
-
- void ForEachFile(char * WildCard, ATTRIBPATTERN AttribPattern, BOOL Recurse );
- /* calls ProcessOneFile for each match
- * ADVSHR
- * e.g. C:\XXX\*.TXT, "?00+1-", TRUE if /S style apply recursively to subdirs */
-
- /* attribute pattern string is of form:
- * ADVSHR A-archive D-directory V-volume S-system H-hidden R-read-only
- * "ADVSHR"
- * "?00+1-" <-- example
- * ?=ignore, irrelevant.
- * 1=must be 1
- * 0=must be 0
- * +=must have some 1s, all plus slots many not be 0
- * -=must have some 0s, all minus slots may not be 1 */
-
-
- virtual BOOL ProcessOneFile ( char * QualFileName, long FileSize ) = 0;
- /* returns true to abort entire process.
- Code to process one file, custom-written for each use. */
-
- protected:
-
- BOOL Stop; /* true if we want to stop ForEachFile early */
-
- void ProcessSubs( char * WildCard );
- /* recursively process all files in all subdirs matching the
- * given wildcard pattern.
- * WildCard will be of form C:\xxx\*.TXT */
-
- void ProcessFiles ( char * WildCard );
- /* process all files matching given WildCard. No recursion.
- * WildCard will be of form C:\xxx\*.TXT */
-
- char * Join ( char * Result, char * WildCard, char * SubDir, char * FileName );
- /* append Subdir and FileName onto WildCard,
- * e.g. C:\xxx\*.* , yyy , a.b -> C:\xxx\yyy\a.b
- * Subdir or FileName might be null */
-
- BOOL FineAttribFilter[64];
- /* whether to accept each of 64 possible
- * attributes. Built by invoking the
- * ProbeAttribFilter function with each of the
- * 64 possible attributes. */
-
- ATTRIB CoarseAttribFilter;
- /* Attribute mask to grossly filter out files never wanted. DOS behaves a
- * little strangely when fed a coarse filter. It completely ignores the
- * read-only and archive bits. If you ask for DIRs, you get normal files
- * too. But, if you ask for Vol, you DON'T get anything but VOL. It is
- * all bizarrely asymmetric. We ignore this, and carry on as if DOS were
- * consistent. It comes out ok in the wash, since the FineAttribFilter
- * filters the mess DOS gives us. */
-
- void InitAttribFilters (ATTRIBPATTERN AttribPattern);
- /* calculate FineAttribFilter and CoarseAttribFilter */
-
- BOOL ProbeAttribFilter(ATTRIB Attrib, ATTRIBPATTERN AttribPattern);
- /* returns true if given attribute
- bit pattern is acceptable according to AttribPattern */
-
- };
-
- /*********************/
-
- class CRC
- {
- /* calculate 16-bit checksums */
- public:
-
- CRC(void) { work = 0; }
-
- ~CRC() { }
-
- WORD Result(void) { return work; }
-
- void Reset(void) { work = 0; }
-
- void Append( BYTE *String, WORD Length );
-
- static int InitCRCTable(WORD Poly = 0x8408);
- /* usually we would use Poly = 0x8408, the 16-bit CCITT polynomial.
- build lookup table to help compute the CRC function.
- Only needs be called once. */
-
- protected:
-
- static WORD CRCTable[256];
- /* magic numbers used to compute CRC .
- table of constants. Only one copy needed */
-
- WORD work;
- /* where we accumulate the crc */
-
- };
-
- /* ***************************************** */
-
- class VERIFY : public FILETREE
- {
- /* class to repeatedly read files off the CD-ROM and make sure they are
- the same each time. Computes and compares checksums */
- public:
-
- VERIFY(void);
-
- ~VERIFY() {};
-
- void VERIFY::Phase1 ( void );
-
- void VERIFY::Phase2 ( void );
-
- void DisplayResults( void );
-
- BOOL ProcessOneFile ( char * QualFileName, long FileSize );
- /* returns true to abort entire process.
- Computes checksum for one file.
- It gets passed a fully qualified FileName and its size */
-
- CRC OneFileCRC;
- /* CRC object to compute CRC for current file. */
-
- int Phase; /* 1=compute CRC or 2=verify CRC */
-
- TESTRESULT TestResult;
- /* result of the entire test */
-
- BOOL TestDone;
- /* true if no more processing to do */
-
- WORD ExpectedCRC [MaxFiles];
- /* CRC expected for each file */
-
- int FileIndex; /* which file we are processing on CD ROM */
-
- long ToGo;
- /* How many more bytes we need to read for the pass.
- We don't read the entire CD-ROM, just the first 7 MB or so */
-
- };
-
- /* ***************************************** */
-
- /* S T A T I C D E F I N I T I O N S */
-
- /* must define, as opposed to declare, static variables in class
- in order to allocate static RAM for them. */
-
- WORD CRC::CRCTable[256];
- int dummy = CRC::InitCRCTable();
-
- /* ***************************************** */
-
- /* F U N C T I O N D E F I N I T I O N S */
-
- int main( int argc, char *argv[] )
-
- {
- Banner();
-
- if ( argc != 2 /* 0=CDtest.Exe 1=E: */ )
- {
- printf("Oops! usage: CDtest E:"
- "\nwhere E: is the EIDE CD-ROM to test.");
- exit (2);
- }
-
- /* replace first letter of WildCard with Drive Letter */
- /* e.g. WildCard might now read: E:\*.* */
- WildCard[0] = *argv[1];
-
- VERIFY Verify; /* object to do all the CD-ROM reading tests */
-
- printf("\nInsert any CD-ROM in drive %s", argv[1]);
-
- if ( pause() == 2 ) Verify.TestDone = TRUE; /* user ESC abort */
-
- /* do Phase 1 */
- Verify.Phase1();
- beep(); /* announce Phase1 over */
-
- /* do Phase 2 */
- Verify.Phase2();
- beep(); /* announce Phase2 over */
-
- Verify.DisplayResults(); /* report good or bad news */
-
- return (int) Verify.TestResult ; /* 0 = pass, 1 = fail, 2 = incomplete */
-
- } /* end main */
-
-
- /*****************/
-
- void Banner(void)
- {
- /* display copyright banner. */
-
- clrscr(); /* clear screen */
-
- printf("\n" StartDecorate " CDtest 1.0 " EndDecorate
- "\n"
- "\nFreeware to test for the flawed EIDE controllers such as the"
- "\nPC-Tech RZ-1000 and the CMD PCIO640B."
- "\nRuns under DESQview, Windows, Windows For WorkGroups, Windows-95, NT"
- "\nand OS/2 all in DOS emulation mode."
- "\n"
- "\nCopyright (c) 1995 Canadian Mind Products"
- "\n#601 - 1330 Burrard Street, Vancouver BC CANADA V6Z 2B8 (604) 685-8412"
- "\nInternet: Roedy@bix.com <Roedy Green>"
- "\nMay be used freely for non-military use only."
- "\n\n");
-
- } /* end Banner */
-
- /*****************/
-
- VERIFY::VERIFY(void)
- {
- /* constructor */
- TestResult = INCOMPLETE;
- TestDone = FALSE;
- FileIndex = 0;
- ToGo =TestSizeInBytes;
-
- }
- /*****************/
-
- void VERIFY::Phase1 ( void )
- {
- Phase = 1;
-
- if (TestDone) return;
-
- clrscr(); /* clear screen */
-
- printf("\n" StartDecorate " PHASE 1 " EndDecorate
- "\n"
- "\nDuring phase 1, do not run any other programs."
- "\nEspecially avoid using the tape or floppy drive."
- "\nShutdown all background programs BEFORE you proceed."
- "\nIf you can't get them all, not to worry;"
- "\n");
-
- if ( pause() == 2 )
- {
- TestDone = TRUE;
- return; /* user abort */
- }
- printf("\nPhase 1 in progress. Please stand by...\n");
-
-
- /* read about 7 Mb of files, computing checksums. User may abort by hitting ESC */
- FileIndex = 0;
- ToGo =TestSizeInBytes;
- ForEachFile ( WildCard,/* ADVSHR */ "?000??", TRUE /* recurse */ );
- return;
- } /* end Phase1 */
-
-
- /*****************/
-
- void VERIFY::Phase2 ( void )
-
- {
- if (TestDone) return;
-
- clrscr(); /* clear screen */
-
- Phase = 2;
-
- switch (DoesOSDoSimultaneousIO())
- {
-
- case 0: /* DOS */
- clrscr(); /* clear screen */
- printf( "\n" StartDecorate " PHASE 2 " EndDecorate
- "\n"
- "\nDURING phase 2, do as many of these tests as you can"
- "\nto generate simultaneous I/O:"
- "\n"
- "\n- Backup some files to floppy with MWBackup, MSBackup, Norton Backup"
- "\n or other high performance floppy backup program with fast-mode"
- "\n simultaneous disk I/O configured."
- "\n- Backup a file using your mag tape backup software with fast-mode"
- "\n simultaneous disk I/O configured."
- "\n- Exercise any simultaneous I/O devices e.g. modem, mouse or sound card."
- "\n");
- break;
-
- case 1: /* OS */
- clrscr(); /* clear screen */
- printf( "\n" StartDecorate " PHASE 2 " EndDecorate
- "\n"
- "\nDURING phase 2, do as many of these tests as you can"
- "\nto generate simultaneous I/O:"
- "\n"
- "\n- Format a floppy."
- "\n- Backup some files to floppy with MWBackup, MSBackup, Norton Backup"
- "\n or other high performance floppy backup program with fast-mode"
- "\n simultaneous disk I/O configured."
- "\n- Backup a file using your mag tape backup software with fast-mode"
- "\n simultaneous disk I/O configured."
- "\n- Scan a document with your scanner."
- "\n- Browse some files on other hard disks and CD-ROM."
- "\n- Exercise any simultaneous I/O devices e.g. modem, mouse or sound card."
- "\n");
- break;
-
- case 2: /* esc */
- TestDone = TRUE;
- return;
- }
-
-
- printf("\nYour experiments may run slowly because of CDtest's disk overhead."
- "\n"
- "\nBEGIN YOUR EXPERIMENTS NOW!"
- "\n"
- "\nTake all the time you want -- days even."
- "\nWhen you have finished all your tests, come back and hit the space bar."
- "\n"
- "\nPhase 2 in progress..."
- "\n");
-
- while ( ! TestDone )
- {
- /* keep repeating the test till user hits ESC or space bar */
- FileIndex = 0;
- ToGo = TestSizeInBytes;
- ForEachFile ( WildCard,/* ADVSHR */ "?000??", TRUE /* recurse */ );
- }
- return;
- } /* Phase2 */
-
- /*****************/
-
- void VERIFY::DisplayResults( void )
- {
-
- clrscr(); /* clear screen */
-
- printf( "\n" StartDecorate " TEST RESULTS " EndDecorate
- "\n");
-
- switch (TestResult)
- {
- case PASS:
- printf("\nCDtest passed. No flaws found."
- "\nYou may still have a flawed EIDE controller chip with a"
- "\nsuccessful software bypass."
- "\nKeep in mind, that unless you carefully followed the"
- " instructions on the,"
- "\nscreen, the results of this test are meaningless."
- "\n");
- break;
-
- case FAIL:
- printf("\nCDtest failed."
- "\nIf you have a PCI motherboard the failure is probably due to a faultly"
- "\nPC-Tech RZ-1000 or CMD PCIO640B EIDE controller chip."
- "\nIt could also be due to overheating, a faulty DMA controller,"
- "\nor software bugs.");
- break;
-
- case INCOMPLETE:
- default:
- printf("\nCDtest not completed."
- "\nPossibly a user abort or problems reading the CD-ROM drive."
- "\n");
- break;
-
- }
- printf("\nPlease admire the test results.\n");
- pause();
-
- } /* end DisplayResults */
-
- /* ***************************************** */
-
- BOOL VERIFY::ProcessOneFile ( char * QualFileName, long FileSize )
- {
- /* Gets called once for each file on the CD-ROM matching
- WildCard and attribute filter.
- It opens the file, and computes the checksum.
- In Phase 1, computes checksums. In Phase 2, verifies them */
-
- FILE *TempFile;
-
- BYTE *Buffer = new BYTE [BufferSizeInBytes];
-
- if (FileSize)
- {
- TempFile = fopen(QualFileName,"rb"); /* read binary mode */
- if (TempFile )
- {
- /* got an acceptable file, start a fresh checksum */
- OneFileCRC.Reset();
-
- size_t BytesActuallyRead;
- size_t BytesToRead;
- long ToGoInThisFile = min ( FileSize, ToGo );
-
- /* read test file, till eof, or we have enough bytes, failure or user abort */
- while (ToGoInThisFile && !TestDone)
- {
- BytesToRead = (size_t) min ( (long) BufferSizeInBytes ,ToGoInThisFile );
- BytesActuallyRead = fread(Buffer, 1, BytesToRead, TempFile);
- if (BytesActuallyRead == BytesToRead)
- {
- OneFileCRC.Append(Buffer,BytesActuallyRead);
- ToGo -= BytesActuallyRead;
- ToGoInThisFile -= BytesActuallyRead;
- }
- else
- {
- TestResult = FAIL;
- TestDone = TRUE;
- break;
- }
-
- if (CheckForEsc()) TestDone = TRUE;
- /* check for user abort every block read */
- }
- fclose(TempFile);
- }
- else
- {
- /* file would not open */
- TestResult = FAIL;
- TestDone = TRUE;
- }
- }
- else /* NOP */; /* ignore 0-length files */
-
- if (!TestDone) switch (Phase)
- {
- case 1:
- /* save computed checksum */
- ExpectedCRC [FileIndex++] = OneFileCRC.Result();
- break;
-
- case 2:
- /* ensure checksum is same as last time */
- if (ExpectedCRC [FileIndex++] == OneFileCRC.Result())
- TestResult = PASS;
- else
- {
- /* crc check failed */
- TestResult = FAIL;
- TestDone = TRUE;
- }
- break;
- }
-
-
- delete Buffer;
-
- return (BOOL) ((ToGo <= 0) || (FileIndex >= MaxFiles) || TestDone);
- /* quit calling this function as soon as enough bytes read,
- enough files read,
- or test aborted by user or test failure. */
-
- } /* end ProcessOneFile */
-
- /* ***************************************** */
-
- void beep (void)
- {
- /* long beep to attract attention */
- printf("\x07\x07\x07\x07");
- } /* end beep */
-
- /*****************/
-
- int pause (void)
- {
- /*
- returns 1=user hit space
- returns 2=user hit ESC
- */
- int Result = 0;
- /* pause until the user hits the space bar */
- printf ("\nWhen you are ready to proceed, hit the space bar; hit ESC to abort");
-
- while (!Result)
- {
- switch (getch())
- {
- case ' ':
- Result = 1; /* space we are done */
- break;
- case Esc:
- Result = 2; /* Esc, Abort */
- break;
- default:
- printf("\x07" ); /* beep to indicate char ignored. */
- break;
- }
- }
- printf("\r \n\n");
- /* erase the prompt line, to ack the space bar */
- return Result;
-
- } /* end pause */
-
- /*****************/
-
- int DoesOSDoSimultaneousIO (void)
- {
-
- /*
- returns 0= no, DESQiew, Windows,...
- returns 1= yes. OS/2, NT...
- returns 2=user hit ESC
- */
- int Result = -1;
-
- printf( "\nDoes your operating system do more than one I/O at a time?"
- "\nAnswer N for DOS, DESQview, Windows, Windows for Workgroups or Windows-95."
- "\nAnswer Y for OS/2, Warp, NT, Linux, SCO XENIX or UNIX.");
- /* don't advertise the ESC possibility */
-
- while (Result == -1)
- {
- switch (getch())
- {
- case 'N':
- case 'n':
- Result = 0; /* No */
- break;
- case 'Y':
- case 'y':
- Result = 1; /* Yes */
- break;
- case Esc:
- Result = 2; /* Esc, Abort */
- break;
- default:
- printf("\x07" ); /* beep to indicate char ignored. */
- break;
- }
- }
-
- return Result;
-
- } /* end DoesOSDoSimultaneousIO */
-
- /* ***************************************** */
-
- int CheckForEsc (void)
- {
-
- /*
- returns 0=user did nothing. We don't wait for him to hit a key.
- returns 1=user hit space
- returns 2=user hit ESC
- */
- int Result = 0;
-
- if (kbhit())
- {
- switch (getch())
- {
- case ' ':
- Result = 1; /* space we are done */
- break;
- case Esc:
- Result = 2; /* Esc, Abort */
- break;
- default:
- printf("\x07" ); /* beep to indicate char ignored. */
- Result = 0;
- break;
- }
- }
- else
- Result = 0; /* no key hit */
- return Result;
-
- } /* end CheckForEsc */
-
- /* ***************************************** */
-
- int CRC::InitCRCTable (WORD Poly)
- {
- WORD i;
- WORD crc;
-
- /* usually we would use Poly = 0x8408, the 16-bit CCITT polynomial */
-
- for (i = 0; i < 256; i++)
- {
- crc = (WORD) i;
- /* ^ is bitwise XOR */
- crc = (crc >> 1) ^ ((crc & 1) ? Poly : 0);
- crc = (crc >> 1) ^ ((crc & 1) ? Poly : 0);
- crc = (crc >> 1) ^ ((crc & 1) ? Poly : 0);
- crc = (crc >> 1) ^ ((crc & 1) ? Poly : 0);
- crc = (crc >> 1) ^ ((crc & 1) ? Poly : 0);
- crc = (crc >> 1) ^ ((crc & 1) ? Poly : 0);
- crc = (crc >> 1) ^ ((crc & 1) ? Poly : 0);
- crc = (crc >> 1) ^ ((crc & 1) ? Poly : 0);
-
- CRCTable[i] = crc;
-
- }
- return 0; /* dummy */
-
- } /* end InitCRCTable */
-
- /* ***************************************** */
-
- void CRC::Append ( BYTE* String, WORD Length )
- {
- /* cumulatively compute the CRC of this string. */
- /* string may contain nulls */
-
- /* character of the string, start with len byte */
-
- while (Length--)
- work = (work >> 8) ^ CRCTable[(work & 0xff) ^ *String++];
- /* ^ is bitwise XOR */
-
- } /* end Append */
-
- /* ***************************************** */
-
- void FILETREE::ForEachFile (char * WildCard, ATTRIBPATTERN AttribPattern, BOOL Recurse )
- {
- Stop = FALSE;
- InitAttribFilters(AttribPattern);
-
- if (Recurse) ProcessSubs(WildCard);
- else ProcessFiles(WildCard);
-
- } /* end ForEachFile */
-
- /* ***************************************** */
-
- void FILETREE::ProcessSubs(char *WildCard)
- /* We recursively process all WildCard-matching ordinary files and all
- * subdirs of this dir. Since we
- * are processing recursively we use new rather than the stack to avoid
- * overflowing it. Wildcard describes files, not subdirs. */
-
- {
- struct find_t * Hit = new struct find_t;
- /* a subdir found by _dos_findnext */
-
- char * FindSubsWildCard = new char [FILENAME_MAX];
-
- char * SubWildCard = new char [FILENAME_MAX];
-
- if (WildCard && WildCard[0]) /* not null */
- {
- ProcessFiles(WildCard); /* process ordinary files first */
-
- /* ignore file part when searching for dirs.
- * e.g. E:/MyDir/*.* to search for any subdirs.
- * Process only Subdirs, including hidden, system etc. subdirs.
- * Ignore all hits but true subdirs.
- * User's FineAttribFilter is irrelevant */
- if (!Stop && _dos_findfirst(Join ( FindSubsWildCard, WildCard, NULL, "*.*"),
- (_A_SUBDIR | _A_ARCH | _A_RDONLY | _A_HIDDEN | _A_SYSTEM),
- Hit) == 0)
- do
- {
- if ((Hit->attrib & _A_SUBDIR) && Hit->name[0] != '.')
- {
- /* e.g. E:/MyDir/MySub/*.TXT */
- ProcessSubs(Join(SubWildCard, WildCard, Hit->name, NULL ));
- /* recursively */
- }
- }
- while (!Stop && _dos_findnext(Hit) == 0);
- }
- delete FindSubsWildCard;
- delete SubWildCard;
- delete Hit;
-
- } /* end ProcessSubs */
-
- /* ***************************************** */
-
- void FILETREE::ProcessFiles( char * WildCard )
- {
- /* non-recursively process files in directory described by WildCard. */
- struct find_t * Hit = new struct find_t;
- /* a file found by _dos_findnext */
-
- char * QualFileName = new char [FILENAME_MAX];
-
- if (WildCard && WildCard[0]) /* not null */
- if (_dos_findfirst(WildCard, CoarseAttribFilter, Hit) == 0)
- do
- {
- if (FineAttribFilter[Hit->attrib])
- {
- if (ProcessOneFile
- (Join(QualFileName, WildCard, NULL, Hit->name),
- Hit->size ))
- {
- Stop = TRUE;
- break;
- }
- }
- } while (_dos_findnext(Hit) == 0);
-
- delete QualFileName;
- delete Hit;
-
- } /* end ProcessFiles */
-
- /* ***************************************** */
-
- void FILETREE::InitAttribFilters (ATTRIBPATTERN AttribPattern)
- {
- /* Prepare FineAttribFilter so we don't have to keep invoking the
- * slow ProbeAttribFilter function.
- * Also prepare CoarseAttribFilter -- special types of files
- * EVER wanted.
- * We can use CoarseAttribFilter to get DOS to do some gross filtering. */
- ATTRIB Attrib;
- CoarseAttribFilter = 0;
- for (Attrib = 0; Attrib < 64; Attrib++)
- {
- if ((FineAttribFilter[Attrib] = ProbeAttribFilter(Attrib, AttribPattern)))
- CoarseAttribFilter |= Attrib;
- }
- } /* end InitAttribFilters */
-
- /* ***************************************** */
-
- BOOL FILETREE::ProbeAttribFilter(ATTRIB Attrib, ATTRIBPATTERN AttribPattern)
- {
- /* true if Attrib matches the given string pattern .
- * attribute pattern string is of form:
- * ADVSHR A-archive D-directory V-volume S-system H-hidden R-read-only
- * "ADVSHR"
- * "?00+1-" <-- example
- * ?=ignore, irrelevant.
- * 1=must be 1
- * 0=must be 0
- * +=must have some 1s, all plus slots many not be 0
- * -=must have some 0s, all minus slots may not be 1 */
-
- BOOL Bit;
- BOOL NeedPlus = FALSE; /* no + seen yet, so no need for 1s in + slots */
- BOOL NeedMinus = FALSE; /* ditto for minus */
- int i;
- WORD PlusCount = 0;
- WORD MinusCount = 0;
-
- /* work right to left comparing the Pattern char string with the Attrib bits */
- for (i = 5; i >= 0; i--)
- {
- Bit = (BOOL) (((WORD) Attrib >> (5 - i)) & 1);
- switch (AttribPattern[i])
- {
- case '1':
- if (!Bit)
- return (FALSE);
- break;
- case '0':
- if (Bit)
- return (FALSE);
- break;
- case '+':
- NeedPlus = TRUE;
- if (Bit)
- PlusCount++;
- break;
- case '-':
- NeedMinus = TRUE;
- if (!Bit)
- MinusCount++;
- break;
- case '?':
- break;
- default:
- printf(
- "\n Programmer error: Invalid WildCard attribute specifier string: %s.\n",
- AttribPattern);
- exit(99);
- } /* end switch */
- } /* end for */
- if (NeedPlus && (PlusCount == 0))
- return (FALSE);
- if (NeedMinus && (MinusCount == 0))
- return (FALSE);
- return (TRUE);
-
- } /* end ProbeAttribFilter */
-
- /* ***************************************** */
-
- char * FILETREE::Join(char *Result, char *WildCard, char *SubDir, char *FileName)
-
- {
- /* Glue Wildcard, Subdir and FileName together */
- /* SubDir and FileName might be null */
- char Drive[_MAX_DRIVE];
- char Dir[_MAX_DIR];
- char Fname[_MAX_FNAME];
- char Ext[_MAX_EXT];
-
- _splitpath(WildCard, Drive, Dir, Fname, Ext);
- /* Dir will usually have lead and trail backslash */
-
- if (SubDir) strcat(Dir, SubDir);
-
- if (FileName) _makepath(Result, Drive, Dir, FileName, NULL);
- else _makepath(Result, Drive, Dir, Fname, Ext);
- return Result;
-
- } /* end Join */
-
- /* ***************************************** */
-
- /* -30- */
-