TYPE WildExpandRegisters = RECORD CASE INTEGER OF 1: (AX, BX, CX, DX, BP, SI, DI, DS, ES, Flags : INTEGER); 2: (AL, AH, BL, BH, CL, CH, DL, DH : BYTE) END; CONST WildExpandFlagCarry = $0001; TYPE WildExpandMsDosBlock = RECORD Reserved01 : ARRAY [1..21] OF BYTE; FileAttributes : BYTE; FileTime : INTEGER; FileDate : INTEGER; FileSizeLow : INTEGER; FileSizeHigh : INTEGER; FileName : ARRAY [1..13] OF CHAR END; CONST WildExpandPathLength = 255; TYPE WildExpandPathSpec = STRING [WildExpandPathLength]; WildExpandHistory = RECORD MSDosBlock : WildExpandMsDosBlock; LeadingInformation : WildExpandPathSpec; CurrentlyValid : BOOLEAN; END; VAR WildExpandHistoryBlock : WildExpandHistory; FUNCTION WildExpandInitialize ( PathName : WildExpandPathSpec; MatchAttr : INTEGER) : BOOLEAN; VAR LastSlashIndex : INTEGER; OldDTA : ^ CHAR; Registers : WildExpandRegisters; SearchIndex : INTEGER; BEGIN { Obtain leading path spec information. } LastSlashIndex := 0; FOR SearchIndex := 1 TO Length (PathName) DO IF (PathName [SearchIndex] = '/') OR (PathName [SearchIndex] = '\') OR (PathName [SearchIndex] = ':') THEN LastSlashIndex := SearchIndex ELSE PathName [SearchIndex] := UpCase (PathName [SearchIndex]); WildExpandHistoryBlock.LeadingInformation := Copy (PathName, 1, LastSlashIndex); { If the pattern ends in a terminator, assume *.* } IF LastSlashIndex = Length (PathName) THEN Insert ('*.*', PathName, Length (PathName) + 1); { Save the current disk transfer address. } Registers.AH := $2F; MsDos (Registers); OldDTA := Ptr (Registers.ES, Registers.BX); { Have MS-DOS initialize the block. } Registers.AH := $1A; Registers.DS := Seg (WildExpandHistoryBlock.MSDosBlock); Registers.DX := Ofs (WildExpandHistoryBlock.MSDosBlock); MsDos (Registers); PathName := PathName + #$00; Registers.AH := $4E; Registers.DS := Seg (PathName [1]); Registers.DX := Ofs (PathName [1]); Registers.CX := MatchAttr; MsDos (Registers); { But '.' and '..' are not desired } WHILE ((Registers.Flags AND WildExpandFlagCarry) = 0) AND (WildExpandHistoryBlock.MSDosBlock.FileName [1] = '.') DO BEGIN Registers.AH := $4F; MsDos (Registers) END; WildExpandHistoryBlock.CurrentlyValid := (Registers.Flags AND WildExpandFlagCarry) = 0; { Reset the disk transfer address. } Registers.AH := $1A; Registers.DS := Seg (OldDTA ^); Registers.DX := Ofs (OldDTA ^); MsDos (Registers); { Return whether successful. } WildExpandInitialize := WildExpandHistoryBlock.CurrentlyValid END; PROCEDURE WildExpandContinue {011} (VAR ResultName : WildExpandPathSpec; {011} VAR ResultAttr : INTEGER); {011} VAR Registers : WildExpandRegisters; ScanIndex : INTEGER; OldDTA : ^ CHAR; BEGIN IF NOT WildExpandHistoryBlock.CurrentlyValid THEN BEGIN { Save the current disk transfer address. } Registers.AH := $2F; MsDos (Registers); OldDTA := Ptr (Registers.ES, Registers.BX); { Get the next path specification. } Registers.AH := $1A; Registers.DS := Seg (WildExpandHistoryBlock.MSDosBlock); Registers.DX := Ofs (WildExpandHistoryBlock.MSDosBlock); MsDos (Registers); Registers.AH := $4F; MsDos (Registers); WildExpandHistoryBlock.CurrentlyValid := (Registers.Flags AND WildExpandFlagCarry) = 0; { Reset the disk transfer address. } Registers.AH := $1A; Registers.DS := Seg (OldDTA ^); Registers.DX := Ofs (OldDTA ^); MsDos (Registers) END; IF WildExpandHistoryBlock.CurrentlyValid THEN BEGIN ScanIndex := 1; WHILE WildExpandHistoryBlock.MsDosBlock.FileName [ScanIndex] <> #$00 DO ScanIndex := ScanIndex + 1; ResultName := WildExpandHistoryBlock.LeadingInformation + {011} Copy (WildExpandHistoryBlock.MsDosBlock.FileName, 1, ScanIndex - 1); ResultAttr := WildExpandHistoryBlock.MsDosBlock.FileAttributes; {011} WildExpandHistoryBlock.CurrentlyValid := FALSE END ELSE BEGIN {011} ResultName := ''; {011} ResultAttr := 0 {011} END {011} END;