/[projects]/dao/DelphiScanner/Components/tpsystools_4.04/source/StSystem.pas
ViewVC logotype

Annotation of /dao/DelphiScanner/Components/tpsystools_4.04/source/StSystem.pas

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2671 - (hide annotations) (download)
Tue Aug 25 18:15:15 2015 UTC (8 years, 10 months ago) by torben
File size: 55793 byte(s)
Added tpsystools component
1 torben 2671 // Upgraded to Delphi 2009: Sebastian Zierer
2    
3     (* ***** BEGIN LICENSE BLOCK *****
4     * Version: MPL 1.1
5     *
6     * The contents of this file are subject to the Mozilla Public License Version
7     * 1.1 (the "License"); you may not use this file except in compliance with
8     * the License. You may obtain a copy of the License at
9     * http://www.mozilla.org/MPL/
10     *
11     * Software distributed under the License is distributed on an "AS IS" basis,
12     * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13     * for the specific language governing rights and limitations under the
14     * License.
15     *
16     * The Original Code is TurboPower SysTools
17     *
18     * The Initial Developer of the Original Code is
19     * TurboPower Software
20     *
21     * Portions created by the Initial Developer are Copyright (C) 1996-2002
22     * the Initial Developer. All Rights Reserved.
23     *
24     * Contributor(s):
25     *
26     * ***** END LICENSE BLOCK ***** *)
27    
28     {*********************************************************}
29     {* SysTools: StSystem.pas 4.04 *}
30     {*********************************************************}
31     {* SysTools: Assorted system level routines *}
32     {*********************************************************}
33    
34     {$I StDefine.inc}
35    
36     unit StSystem;
37    
38     interface
39    
40     uses
41     Windows, SysUtils, Classes,
42     {$IFDEF Version6} {$WARN UNIT_PLATFORM OFF} {$ENDIF}
43     FileCtrl,
44     {$IFDEF Version6} {$WARN UNIT_PLATFORM ON} {$ENDIF}
45     StConst, StBase, StUtils, StDate, StStrL;
46    
47     {$IFNDEF VERSION6}
48     const
49     PathDelim = '\';
50     DriveDelim = ':';
51     PathSep = ';';
52     {$ENDIF VERSION6}
53     const
54     StPathDelim = PathDelim; { Delphi/Linux constant }
55     StPathSep = PathSep; { Delphi/Linux constant }
56     StDriveDelim = DriveDelim;
57     StDosPathDelim = '\';
58     StUnixPathDelim = '/';
59     StDosPathSep = ';';
60     StUnixPathSep = ':';
61     StDosAnyFile = '*.*';
62     StUnixAnyFile = '*';
63     StAnyFile = {$IFDEF LINUX} StUnixAnyFile; {$ELSE} StDosAnyFile; {$ENDIF}
64     StThisDir = '.';
65     StParentDir = '..';
66    
67    
68     type
69     DiskClass = ( Floppy360, Floppy720, Floppy12, Floppy144, OtherFloppy,
70     HardDisk, RamDisk, UnknownDisk, InvalidDrive, RemoteDrive, CDRomDisk );
71     {This enumerated type defines the nine classes of disks that can be
72     identified by GetDiskClass, as well as several types used as error
73     indications}
74    
75     PMediaIDType = ^MediaIDType;
76     MediaIDType = packed record
77     {This type describes the information that DOS 4.0 or higher writes
78     in the boot sector of a disk when it is formatted}
79     InfoLevel : Word; {Reserved for future use}
80     SerialNumber : LongInt; {Disk serial number}
81     VolumeLabel : array[0..10] of Char; {Disk volume label}
82     FileSystemID : array[0..7] of Char; {String for internal use by the OS}
83     end;
84    
85     TIncludeItemFunc = function (const SR : TSearchRec;
86     ForInclusion : Boolean; var Abort : Boolean) : Boolean;
87     {Function type for the routine passed to EnumerateFiles and
88     EnumerateDirectories. It will be called in two ways: to request
89     confirmation to include the entity described in SR into the
90     string list (ForInclusion = true); or to ask whether to recurse
91     into a particular subdirectory (ForInclusion = false).}
92    
93     {**** Routine Declarations ****}
94    
95    
96     {CopyFile}
97     function CopyFile(const SrcPath, DestPath : String) : Cardinal;
98     {-Copy a file.}
99    
100     {CreateTempFile}
101     function CreateTempFile(const aFolder : String;
102     const aPrefix : String) : String;
103     {-Creates a temporary file.}
104    
105     {DeleteVolumeLabel}
106     function DeleteVolumeLabel(Drive : Char) : Cardinal;
107     {-Deletes an existing volume label on Drive. Returns 0 for success,
108     or OS error code.}
109    
110     {EnumerateDirectories}
111     procedure EnumerateDirectories(const StartDir : String; FL : TStrings; {!!.02}
112     SubDirs : Boolean;
113     IncludeItem : TIncludeItemFunc);
114     {-Retrieves the complete path name of directories on requested file
115     system path.}
116    
117     {EnumerateFiles}
118     procedure EnumerateFiles(const StartDir : String; FL : TStrings; {!!.02}
119     SubDirs : Boolean;
120     IncludeItem : TIncludeItemFunc);
121     {-Retrieves the complete path name of files in a requested file system path.}
122    
123     {FileHandlesLeft}
124     function FileHandlesLeft(MaxHandles : Cardinal) : Cardinal;
125     {-Return the number of available file handles.}
126    
127     {FileMatchesMask}
128     function FileMatchesMask(const FileName, FileMask : String ) : Boolean;
129     {-see if FileName matches FileMask}
130    
131     {FileTimeToStDateTime}
132     function FileTimeToStDateTime(FileTime : LongInt) : TStDateTimeRec;
133     {-Converts a DOS date-time value to TStDate and TStTime values.}
134    
135     {FindNthSlash}
136     function FindNthSlash( const Path : String; n : Integer ) : Integer;
137     { return the position of the character just before the nth slash }
138    
139     {FlushOsBuffers}
140     function FlushOsBuffers(Handle : Integer) : Boolean;
141     {-Flush the OS buffers for the specified file handle.}
142    
143     {GetCurrentUser}
144     function GetCurrentUser : String;
145     {-Obtains current logged in username}
146    
147     {GetDiskClass}
148     function GetDiskClass(Drive : Char) : DiskClass;
149     {-Return the disk class for the specified drive.}
150    
151     {GetDiskInfo}
152     function GetDiskInfo(Drive : Char; var ClustersAvailable, TotalClusters,
153     BytesPerSector, SectorsPerCluster : Cardinal) : Boolean;
154     {-Return technical information about the specified drive.}
155    
156     {GetDiskSpace}
157     {$IFDEF CBuilder}
158     function GetDiskSpace(Drive : Char;
159     var UserSpaceAvail : Double; {space available to user}
160     var TotalSpaceAvail : Double; {total space available}
161     var DiskSize : Double) : Boolean;{disk size}
162     {-Return space information about the drive.}
163     {$ELSE}
164     function GetDiskSpace(Drive : Char;
165     var UserSpaceAvail : Comp; {space available to user}
166     var TotalSpaceAvail : Comp; {total space available}
167     var DiskSize : Comp) : Boolean;{disk size}
168     {-Return space information about the drive.}
169     {$ENDIF}
170    
171     {GetFileCreateDate}
172     function GetFileCreateDate(const FileName : String) :
173     TDateTime;
174     {-Obtains file system time of file creation.}
175    
176     {GetFileLastAccess}
177     function GetFileLastAccess(const FileName : String) :
178     TDateTime;
179     {-Obtains file system time of last file access.}
180    
181     {GetFileLastModify}
182     function GetFileLastModify(const FileName : String) :
183     TDateTime;
184     {-Obtains file system time of last file modification.}
185    
186     {GetHomeFolder}
187     function GetHomeFolder(aForceSlash : Boolean) : String;
188     {-Obtains the "Home Folder" for the current user}
189    
190     {$IFNDEF CBuilder}
191     {GetLongPath}
192     function GetLongPath(const APath : String) : String;
193     {-Returns the long filename version of a provided path.}
194     {$ENDIF}
195    
196     {GetMachineName}
197     function GetMachineName : String;
198     {-Returns the "Machine Name" for the current computer }
199    
200     {GetMediaID}
201     function GetMediaID(Drive : Char; var MediaIDRec : MediaIDType) : Cardinal;
202     {-Get the media information (Volume Label, Serial Number) for the specified drive}
203    
204     {GetParentFolder}
205     function GetParentFolder(const APath : String; aForceSlash : Boolean) : String;
206     {-return the parent directory for the provided directory }
207    
208     {GetShortPath}
209     function GetShortPath(const APath : String) : String;
210     {-Returns the short filename version of a provided path.}
211    
212     {GetSystemFolder}
213     function GetSystemFolder(aForceSlash : Boolean) : String;
214     {-Returns the path to the Windows "System" folder".)
215    
216     {GetTempFolder}
217     function GetTempFolder(aForceSlash : boolean) : String;
218     {-Returns the path to the system temporary folder.}
219    
220     {GetWindowsFolder}
221     function GetWindowsFolder(aForceSlash : boolean) : String;
222     {-Returns the path to the main "Windows" folder.}
223    
224     {GetWorkingFolder}
225     function GetWorkingFolder(aForceSlash : boolean) : String;
226     {-Returns the current working directory.}
227    
228     {GlobalDateTimeToLocal}
229     function GlobalDateTimeToLocal(const UTC: TStDateTimeRec; MinOffset: Integer): TStDateTimeRec; {!!.02}
230     {-adjusts a global date/time (UTC) to the local date/time}
231    
232     {IsDirectory}
233     function IsDirectory(const DirName : String) : Boolean;
234     {-Return True if DirName is a directory.}
235    
236     {IsDirectoryEmpty}
237     function IsDirectoryEmpty(const S : String) : Integer;
238     {-checks if there are any entries in the directory}
239    
240     {IsDriveReady}
241     function IsDriveReady(Drive : Char) : Boolean;
242     {-determine if requested drive is accessible }
243    
244     {IsFile}
245     function IsFile(const FileName : String) : Boolean;
246     {-Determines if the provided path specifies a file.}
247    
248     {IsFileArchive}
249     function IsFileArchive(const S : String) : Integer;
250     {-checks if file's archive attribute is set}
251    
252     {IsFileHidden}
253     function IsFileHidden(const S : String) : Integer;
254     {-checks if file's hidden attribute is set}
255    
256     {IsFileReadOnly}
257     function IsFileReadOnly(const S : String) : Integer;
258     {-checks if file's readonly attribute is set}
259    
260     {IsFileSystem}
261     function IsFileSystem(const S : String) : Integer;
262     {-checks if file's system attribute is set}
263    
264     {LocalDateTimeToGlobal}
265     function LocalDateTimeToGlobal(const DT1: TStDateTimeRec; MinOffset: Integer): TStDateTimeRec; {!!.02}
266     {-adjusts a local date/time to the global (UTC) date/time}
267    
268     {ReadVolumeLabel}
269     function ReadVolumeLabel(var VolName : String; Drive : Char) : Cardinal;
270     {-Get the volume label for the specified drive.}
271    
272     {SameFile}
273     function SameFile(const FilePath1, FilePath2 : String; var ErrorCode : Integer) : Boolean;
274     {-Return True if FilePath1 and FilePath2 refer to the same physical file.}
275    
276     {SetMediaID} {!!!! does not work on NT/2000 !!!!}
277     function SetMediaID(Drive : Char; var MediaIDRec : MediaIDType) : Cardinal;
278     {-Set the media ID record for the specified drive.}
279    
280     {SplitPath}
281     procedure SplitPath(const APath : String; Parts : TStrings);
282     {-Splits the provided path into its component sub-paths}
283    
284     {StDateTimeToFileTime}
285     function StDateTimeToFileTime(const FileTime : TStDateTimeRec) : LongInt; {!!.02}
286     {-Converts an TStDate and TStTime to a DOS date-time value.}
287    
288     {StDateTimeToUnixTime}
289     function StDateTimeToUnixTime(const DT1 : TStDateTimeRec) : Longint; {!!.02}
290     {-converts a TStDateTimeRec to a time in Unix base (1970)}
291    
292     {UnixTimeToStDateTime}
293     function UnixTimeToStDateTime(UnixTime : Longint) : TStDateTimeRec;
294     {-converts a time in Unix base (1970) to a TStDateTimeRec}
295    
296     {ValidDrive}
297     function ValidDrive(Drive : Char) : Boolean;
298     {-Determine if the drive is a valid drive.}
299    
300     {WriteVolumeLabel}
301     function WriteVolumeLabel(const VolName : String; Drive : Char) : Cardinal;
302     {-Sets the volume label for the specified drive.}
303    
304     (*
305     {$EXTERNALSYM GetLongPathNameA}
306     function GetLongPathNameA(lpszShortPath: PAnsiChar; lpszLongPath: PAnsiChar;
307     cchBuffer: DWORD): DWORD; stdcall;
308     {$EXTERNALSYM GetLongPathNameW}
309     function GetLongPathNameW(lpszShortPath: PWideChar; lpszLongPath: PWideChar;
310     cchBuffer: DWORD): DWORD; stdcall;
311     {$EXTERNALSYM GetLongPathName}
312     function GetLongPathName(lpszShortPath: PChar; lpszLongPath: PChar;
313     cchBuffer: DWORD): DWORD; stdcall;
314     *)
315    
316     implementation
317    
318     const
319     FILE_ANY_ACCESS = 0;
320     METHOD_BUFFERED = 0;
321     IOCTL_DISK_BASE = $00000007;
322     VWIN32_DIOC_DOS_IOCTL = 1;
323     IOCTL_DISK_GET_MEDIA_TYPES = ((IOCTL_DISK_BASE shl 16) or
324     (FILE_ANY_ACCESS shl 14) or ($0300 shl 2) or METHOD_BUFFERED);
325    
326     procedure StChDir(const S: String); {!!.02}
327     { wrapper for Delphi ChDir to handle a bug in D6}
328     {$IFDEF VER140}
329     var
330     Rslt : Integer;
331     {$ENDIF}
332     begin
333     {$IFNDEF VER140}
334     Chdir(S);
335     {$ELSE}
336     {$I-}
337     Chdir(S);
338     if IOResult <> 0 then begin
339     Rslt := GetLastError;
340     SetInOutRes(Rslt);
341     end;
342     {$I+}
343     {$ENDIF}
344     end;
345    
346     {CopyFile}
347     function CopyFile(const SrcPath, DestPath : String) : Cardinal;
348     {-Copy the file specified by SrcPath into DestPath. DestPath must specify
349     a complete filename, it may not be the name of a directory without the
350     file portion. This a low level routine, and the input pathnames are not
351     checked for validity.}
352     const
353     BufferSize = 4 * 1024;
354    
355     var
356     BytesRead, BytesWritten : LongInt;
357     FileDate : LongInt;
358     Src, Dest, Mode, SaveFAttr : Integer;
359     Buffer : Pointer;
360    
361     begin
362     {$IFDEF Version6} {$WARN SYMBOL_PLATFORM OFF} {$ENDIF}
363     Src := 0;
364     Dest := 0;
365     Buffer := nil;
366     Result := 1;
367     try
368     GetMem(Buffer, BufferSize);
369     Mode := FileMode and $F0;
370     SaveFAttr := FileGetAttr(SrcPath);
371     if SaveFAttr < 0 then begin
372     Result := 1;
373     Exit;
374     end;
375     Src := FileOpen(SrcPath, Mode);
376     if Src < 0 then begin
377     Result := 1; {unable to access SrcPath}
378     Exit;
379     end;
380     Dest := FileCreate(DestPath);
381     if Dest < 0 then begin
382     Result := 2; {unable to open DestPath}
383     Exit;
384     end;
385     repeat
386     BytesRead := FileRead(Src, Buffer^, BufferSize);
387     if (BytesRead = -1) then begin
388     Result := 3; {error reading from Src}
389     Exit;
390     end;
391     BytesWritten := FileWrite(Dest, Buffer^, BytesRead);
392     if (BytesWritten = -1) or
393     (BytesWritten <> BytesRead) then begin
394     Result := 4; {error writing to Dest}
395     Exit;
396     end;
397     until BytesRead < BufferSize;
398     FileDate := FileGetDate(Src);
399     if FileDate = -1 then begin
400     Result := 5; {error getting SrcPath's Date/Time}
401     Exit;
402     end;
403     FileSetDate(Dest, FileDate);
404     FileSetAttr(DestPath, SaveFAttr);
405     Result := 0;
406     finally
407     if Assigned(Buffer) then
408     FreeMem(Buffer, BufferSize);
409     if Src > 0 then FileClose(Src);
410     if Dest > 0 then begin
411     FileClose(Dest);
412     if Result <> 0 then SysUtils.DeleteFile(DestPath);
413     end;
414     end;
415     {$IFDEF Version6} {$WARN SYMBOL_PLATFORM ON} {$ENDIF}
416     end;
417    
418     {CreateTempFile}
419     function CreateTempFile(const aFolder : String;
420     const aPrefix : String) : String;
421     {-Creates a temporary file.}
422     var
423     TempFileNameZ : array [0..MAX_PATH] of Char;
424     TempDir : String;
425     begin
426     TempDir := aFolder;
427     if not DirectoryExists(TempDir) then
428     TempDir := GetTempFolder(True);
429     if not DirectoryExists(TempDir) then
430     TempDir := GetWorkingFolder(True);
431    
432     if (GetTempFileName(PChar(TempDir), PChar(aPrefix), 0,
433     TempFileNameZ) = 0)
434     then
435     {$IFDEF Version6}
436     RaiseLastOSError;
437     {$ELSE}
438     RaiseLastWin32Error;
439     {$ENDIF}
440     Result := TempFileNameZ;
441     end;
442    
443    
444     {DeleteVolumeLabel}
445     function DeleteVolumeLabel(Drive : Char) : Cardinal;
446     {-Deletes an existing volume label on Drive. Returns 0 for success,
447     or OS error code.}
448     var
449     Root : array[0..3] of Char;
450     begin
451     StrCopy(Root, '%:\');
452     Root[0] := Drive;
453     if Windows.SetVolumeLabel(Root, '') then
454     Result := 0
455     else Result := GetLastError;
456     end;
457    
458     {EnumerateDirectories}
459     procedure EnumerateDirectories(const StartDir : String; FL : TStrings; {!!.02}
460     SubDirs : Boolean;
461     IncludeItem : TIncludeItemFunc);
462     {-Retrieves the complete path name of directories on requested file
463     system path.}
464     var
465     Abort : Boolean;
466     procedure SearchBranch;
467     var
468     SR : TSearchRec;
469     Error : SmallInt;
470     Dir : String;
471     begin
472     Error := FindFirst(StDosAnyFile, faDirectory, SR);
473     if Error = 0 then begin
474     GetDir(0, Dir);
475     if Dir[Length(Dir)] <> StDosPathDelim then
476     Dir := Dir + StDosPathDelim;
477     Abort := False;
478     while (Error = 0) and not Abort do begin
479     try
480     if (@IncludeItem = nil) or (IncludeItem(SR, true, Abort)) then begin
481     if (SR.Attr and faDirectory = faDirectory) and
482     (SR.Name <> StThisDir) and (SR.Name <> StParentDir) then
483     FL.Add(Dir + SR.Name);
484     end;
485     except
486     on EOutOfMemory do
487     raise EOutOfMemory.Create(stscSysStringListFull);
488     end;
489     Error := FindNext(SR);
490     end;
491     FindClose(SR);
492     end;
493    
494     if not Abort and SubDirs then begin
495     Error := FindFirst(StDosAnyFile, faDirectory, SR);
496     if Error = 0 then begin
497     Abort := False;
498     while (Error = 0) and not Abort do begin
499     if ((SR.Attr and faDirectory = faDirectory) and
500     (SR.Name <> StThisDir) and (SR.Name <> StParentDir)) then begin
501     if (@IncludeItem = nil) or (IncludeItem(SR, false, Abort)) then begin
502     StChDir(SR.Name);
503     SearchBranch;
504     StChDir(StParentDir);
505     end;
506     end;
507     Error := FindNext(SR);
508     end;
509     FindClose(SR);
510    
511     end;
512     end;
513     end;
514    
515     var
516     OrgDir : String;
517    
518     begin
519     if IsDirectory(StartDir) then
520     begin
521     GetDir(0, OrgDir);
522     try
523     StChDir(StartDir);
524     SearchBranch;
525     finally
526     StChDir(OrgDir);
527     end;
528     end else
529     raise Exception.Create(stscSysBadStartDir);
530     end;
531    
532     {EnumerateFiles}
533     procedure EnumerateFiles(const StartDir : String; {!!.02}
534     FL : TStrings;
535     SubDirs : Boolean;
536     IncludeItem : TIncludeItemFunc);
537     {-Retrieves the complete path name of files in a requested file system path.}
538     var
539     Abort : Boolean;
540    
541     procedure SearchBranch;
542     var
543     SR : TSearchRec;
544     Error : SmallInt;
545     Dir : String;
546     begin
547     Error := FindFirst(StDosAnyFile, faAnyFile, SR);
548     if Error = 0 then begin
549     GetDir(0, Dir);
550     if Dir[Length(Dir)] <> StDosPathDelim then
551     Dir := Dir + StDosPathDelim;
552    
553     Abort := False;
554     while (Error = 0) and not Abort do begin
555     try
556     if (@IncludeItem = nil) or (IncludeItem(SR, true, Abort)) then
557     FL.Add(Dir + SR.Name);
558     except
559     on EOutOfMemory do
560     begin
561     raise EOutOfMemory.Create(stscSysStringListFull);
562     end;
563     end;
564     Error := FindNext(SR);
565     end;
566     FindClose(SR);
567     end;
568    
569    
570     if not Abort and SubDirs then begin
571     Error := FindFirst(StDosAnyFile, faAnyFile, SR);
572     if Error = 0 then begin
573     Abort := False;
574     while (Error = 0) and not Abort do begin
575     if ((SR.Attr and faDirectory = faDirectory) and
576     (SR.Name <> StThisDir) and (SR.Name <> StParentDir)) then begin
577     if (@IncludeItem = nil) or (IncludeItem(SR, false, Abort)) then begin
578     StChDir(SR.Name);
579     SearchBranch;
580     StChDir(StParentDir);
581     end;
582     end;
583     Error := FindNext(SR);
584     end;
585     FindClose(SR);
586     end;
587     end;
588     end;
589    
590     var
591     OrgDir : String;
592    
593     begin
594     if IsDirectory(StartDir) then
595     begin
596     GetDir(0, OrgDir);
597     try
598     StChDir(StartDir);
599     SearchBranch;
600     finally
601     StChDir(OrgDir);
602     end;
603     end else
604     raise Exception.Create(stscSysBadStartDir);
605     end;
606    
607    
608     {FileHandlesLeft}
609     {.$HINTS OFF}
610     function FileHandlesLeft(MaxHandles : Cardinal) : Cardinal;
611     {-Returns the number of available file handles. In 32-bit, this can be a
612     large number. Use MaxHandles to limit the number of handles counted.
613     The maximum is limited by HandleLimit - you can increase HandleLimit if
614     you wish. A temp file is required because Win95 seems to have some
615     limit on the number of times you can open NUL.}
616     const
617     HandleLimit = 1024;
618     type
619     PHandleArray = ^THandleArray;
620     THandleArray = array[0..Pred(HandleLimit)] of Integer;
621     var
622     Handles : PHandleArray;
623     MaxH, I : Integer;
624     TempPath, TempFile : PChar;
625     begin
626     Result := 0;
627     MaxH := MinLong(HandleLimit, MaxHandles);
628     TempFile := nil;
629     TempPath := nil;
630     Handles := nil;
631     try
632     TempFile := StrAlloc(MAX_PATH+1); {!!.01}
633     TempPath := StrAlloc(MAX_PATH+1); {!!.01}
634     GetMem(Handles, MaxH * SizeOf(Integer));
635     GetTempPath(MAX_PATH, TempPath); {!!.01}
636     GetTempFileName(TempPath, 'ST', 0, TempFile);
637     for I := 0 to Pred(MaxH) do begin
638     Handles^[I] := CreateFile(TempFile, 0, FILE_SHARE_READ, nil,
639     OPEN_EXISTING, FILE_FLAG_DELETE_ON_CLOSE, 0);
640     if Handles^[I] <> LongInt(INVALID_HANDLE_VALUE) then
641     Inc(Result) else Break;
642     end;
643     for I := 0 to Pred(Result) do
644     FileClose(Handles^[I]);
645     finally
646     if Assigned(Handles) then
647     FreeMem(Handles, MaxH * SizeOf(Integer));
648     StrDispose(TempFile);
649     StrDispose(TempPath);
650     end;
651     end;
652     {.$HINTS ON}
653    
654     { -------------------------------------------------------------------------- }
655     function StPatternMatch(const Source : string; iSrc : Integer; {!!.02}
656     const Pattern : string; iPat : Integer ) : Boolean; {!!.02}
657     { recursive routine to see if the source string matches
658     the pattern. Both ? and * wildcard characters are allowed.
659     Compares Source from iSrc to Length(Source) to
660     Pattern from iPat to Length(Pattern)}
661     var
662     Matched : Boolean;
663     k : Integer;
664     begin
665     {$R-}
666     if Length( Source ) = 0 then begin
667     Result := Length( Pattern ) = 0;
668     Exit;
669     end;
670    
671     if iPat = 1 then begin
672     if ( CompareStr( Pattern, StDosAnyFile) = 0 ) or
673     ( CompareStr( Pattern, StUnixAnyFile ) = 0 ) then begin
674     Result := True;
675     Exit;
676     end;
677     end;
678    
679     if Length( Pattern ) = 0 then begin
680     Result := (Length( Source ) - iSrc + 1 = 0);
681     Exit;
682     end;
683    
684     while True do begin
685     if ( Length( Source ) < iSrc ) and
686     ( Length( Pattern ) < iPat ) then begin
687     Result := True;
688     Exit;
689     end;
690    
691     if Length( Pattern ) < iPat then begin
692     Result := False;
693     Exit;
694     end;
695    
696     if (iPat <= Length(Pattern)) and (Pattern[iPat] = '*') then begin
697     k := iPat;
698     if ( Length( Pattern ) < iPat + 1 ) then begin
699     Result := True;
700     Exit;
701     end;
702    
703     while True do begin
704     Matched := StPatternMatch( Source, k, Pattern, iPat + 1 );
705     if Matched or ( Length( Source ) < k ) then begin
706     Result := Matched;
707     Exit;
708     end;
709     inc( k );
710     end;
711     end
712     else begin
713     if ((Pattern[iPat] = '?') and
714     ( Length( Source ) <> iSrc - 1 ) ) or
715     ( Pattern[iPat] = Source[iSrc] ) then begin
716     inc( iPat );
717     inc( iSrc );
718     end
719     else begin
720     Result := False;
721     Exit;
722     end;
723     end;
724     end;
725     {$R+}
726     end;
727    
728     {FileMatchesMask}
729     function FileMatchesMask(const FileName, FileMask : String ) : Boolean;
730     {-see if FileName matches FileMask}
731     var
732     DirMatch : Boolean;
733     MaskDir : String;
734     LFN, LFM : String;
735     begin
736     LFN := UpperCase( FileName );
737     LFM := UpperCase( FileMask );
738     MaskDir := ExtractFilePath( LFN );
739     if MaskDir = '' then
740     DirMatch := True
741     else
742     DirMatch := StPatternMatch( ExtractFilePath( LFN ), 1, MaskDir, 1 );
743    
744     Result := DirMatch and StPatternMatch( ExtractFileName( LFN ), 1,
745     ExtractFileName( LFM ), 1 );
746     end;
747    
748     {FileTimeToStDateTime}
749     function FileTimeToStDateTime(FileTime : LongInt) : TStDateTimeRec;
750     {-Converts a DOS date-time value to TStDate and TStTime values.}
751    
752     var
753     DDT : TDateTime;
754     begin
755     DDT := FileDateToDateTime(FileTime);
756     Result.D := DateTimeToStDate(DDT);
757     Result.T := DateTimeToStTime(DDT);
758     end;
759    
760     {FindNthSlash}
761     function FindNthSlash(const Path : String; n : Integer) : Integer;
762     { return the position of the character just before the nth slash }
763     var
764     i : Integer;
765     Len : Integer;
766     iSlash : Integer;
767     begin
768     Len := Length( Path );
769     Result := Len;
770     iSlash := 0;
771     i := 1;
772     while i <= Len do begin
773     if Path[i] = StPathDelim then begin
774     inc( iSlash );
775     if iSlash = n then begin
776     Result := pred( i );
777     break;
778     end;
779     end;
780     inc( i );
781     end;
782     end;
783    
784     {FlushOsBuffers}
785     {-Flush the OS buffers for the specified file handle.}
786     function FlushOsBuffers(Handle : Integer) : Boolean;
787     {-Flush the OS's buffers for the specified file}
788     begin
789     Result := FlushFileBuffers(Handle);
790     if not Result then
791     {$IFDEF Version6}
792     RaiseLastOSError;
793     {$ELSE}
794     RaiseLastWin32Error;
795     {$ENDIF}
796     end;
797    
798     {GetCurrentUser}
799     function GetCurrentUser : String;
800     {-Obtains current logged in username}
801     var
802     Size : DWORD;
803     UserNameZ : array [0..511] of Char;
804     begin
805     Size := Length(UserNameZ);
806     if not GetUserName(UserNameZ, Size) then
807     {$IFDEF Version6}
808     RaiseLastOSError;
809     {$ELSE}
810     RaiseLastWin32Error;
811     {$ENDIF}
812     // SetString(Result, UserNameZ, Size); {!!.02}
813     SetString(Result, UserNameZ, StrLen(UserNameZ)); {!!.02}
814     end;
815    
816     {GetDiskClass}
817     function GetDiskClass(Drive : Char) : DiskClass;
818     {-Return the disk class for the specified drive.}
819     type
820     TMediaType =
821     ( Unknown, { Format is unknown }
822     F5_1Pt2_512, { 5.25", 1.2MB, 512 bytes/sector }
823     F3_1Pt44_512, { 3.5", 1.44MB, 512 bytes/sector }
824     F3_2Pt88_512, { 3.5", 2.88MB, 512 bytes/sector }
825     F3_20Pt8_512, { 3.5", 20.8MB, 512 bytes/sector }
826     F3_720_512, { 3.5", 720KB, 512 bytes/sector }
827     F5_360_512, { 5.25", 360KB, 512 bytes/sector }
828     F5_320_512, { 5.25", 320KB, 512 bytes/sector }
829     F5_320_1024, { 5.25", 320KB, 1024 bytes/sector }
830     F5_180_512, { 5.25", 180KB, 512 bytes/sector }
831     F5_160_512, { 5.25", 160KB, 512 bytes/sector }
832     RemovableMedia, { Removable media other than floppy }
833     FixedMedia ); { Fixed hard disk media }
834    
835     PDiskGeometry = ^TDiskGeometry;
836     TDiskGeometry = record
837     Cylinders1 : DWORD;
838     Cylinders2 : Integer;
839     MediaType : TMediaType;
840     TracksPerCylinder : DWORD;
841     SectorsPerTrack : DWORD;
842     BytesPerSector : DWORD;
843     end;
844    
845     var
846     Root : array[0..3] of Char;
847     Root2 : array[0..6] of Char;
848     ReturnedByteCount,
849     SectorsPerCluster,
850     BytesPerSector,
851     NumberOfFreeClusters,
852     TotalNumberOfClusters : DWORD;
853     SupportedGeometry : array[1..20] of TDiskGeometry;
854     HDevice : THandle;
855     I : Integer;
856     VerInfo : TOSVersionInfo;
857     Found : Boolean;
858     begin
859     FillChar(VerInfo, SizeOf(TOSVersionInfo), #0);
860     VerInfo.dwOSVersionInfoSize := SizeOf(TOSVersionInfo);
861    
862     Result := InvalidDrive;
863     Found := False;
864     StrCopy(Root, '%:\');
865     Root[0] := Drive;
866     case GetDriveType(Root) of
867     0 : Result := UnknownDisk;
868     1 : Result := InvalidDrive;
869     DRIVE_REMOVABLE :
870     begin
871     GetVersionEx(VerInfo);
872     if VerInfo.dwPlatformID = VER_PLATFORM_WIN32_NT then begin
873     StrCopy(Root2, '\\.\%:');
874     Root2[4] := Drive;
875     HDevice := CreateFile(Root2, 0, FILE_SHARE_READ,
876     nil, OPEN_ALWAYS, 0, 0);
877     if HDevice = INVALID_HANDLE_VALUE then Exit;
878     if not DeviceIoControl(HDevice, IOCTL_DISK_GET_MEDIA_TYPES, nil, 0,
879     @SupportedGeometry, SizeOf(SupportedGeometry), ReturnedByteCount, nil)
880     then Exit;
881     for I := 1 to (ReturnedByteCount div SizeOf(TDiskGeometry)) do begin
882     case SupportedGeometry[I].MediaType of
883     F5_1Pt2_512 : begin
884     Result := Floppy12;
885     Exit;
886     end;
887     F3_1Pt44_512 : begin
888     Result := Floppy144;
889     Exit;
890     end;
891     F3_720_512 : begin
892     Result := Floppy720;
893     Found := True;
894     end;
895     F5_360_512 : begin
896     Result := Floppy360;
897     Found := True;
898     end;
899     end;
900     end;
901     if Found then Exit;
902     Result := OtherFloppy;
903     end else begin
904     GetDiskFreeSpace(Root, SectorsPerCluster, BytesPerSector,
905     NumberOfFreeClusters, TotalNumberOfClusters);
906     case TotalNumberOfClusters of
907     354 : Result := Floppy360;
908     713,
909     1422 : Result := Floppy720;
910     2371 : Result := Floppy12;
911     2847 : Result := Floppy144;
912     else Result := OtherFloppy;
913     end;
914     end;
915     end;
916     DRIVE_FIXED : Result := HardDisk;
917     DRIVE_REMOTE : Result := RemoteDrive;
918     DRIVE_CDROM : Result := CDRomDisk;
919     DRIVE_RAMDISK : Result := RamDisk;
920     end;
921     end;
922    
923     {GetDiskInfo}
924     function GetDiskInfo(Drive : Char; var ClustersAvailable, TotalClusters,
925     BytesPerSector, SectorsPerCluster : Cardinal) : Boolean;
926     {-Return technical information about the specified drive.}
927     var
928     Root : String;
929     begin
930     if Drive <> ' ' then begin
931     Root := Char(System.Upcase(Drive)) + ':\';
932     Result := GetDiskFreeSpace(PChar(Root), DWORD(SectorsPerCluster),
933     DWORD(BytesPerSector), DWORD(ClustersAvailable), DWORD(TotalClusters));
934     end else
935     Result := GetDiskFreeSpace(nil, DWORD(SectorsPerCluster),
936     DWORD(BytesPerSector), DWORD(ClustersAvailable), DWORD(TotalClusters));
937     end;
938    
939    
940     {GetDiskSpace}
941     {$IFDEF CBuilder}
942     function GetDiskSpace(Drive : Char;
943     var UserSpaceAvail : Double; {space available to user}
944     var TotalSpaceAvail : Double; {total space available}
945     var DiskSize : Double) : Boolean;{disk size}
946     {-Return space information about the drive.}
947     type
948     TGetDiskFreeSpace = function (Drive : PChar;
949     var UserFreeBytes : Comp;
950     var TotalBytes : Comp;
951     var TotalFreeBytes : Comp) : Bool; stdcall;
952     LH = packed record L,H : word; end;
953     var
954     UserFree, Total, Size : Comp;
955     VerInfo : TOSVersionInfo;
956     LibHandle : THandle;
957     GDFS : TGetDiskFreeSpace;
958     Root : String;
959     begin
960     Result := False;
961     {get the version info}
962     FillChar(VerInfo, SizeOf(TOSVersionInfo), #0);
963     VerInfo.dwOSVersionInfoSize := SizeOf(VerInfo);
964     if GetVersionEx(VerInfo) then begin
965     with VerInfo do begin
966     if ((dwPlatformId = VER_PLATFORM_WIN32_WINDOWS) and
967     (LH(dwBuildNumber).L <> 1000)) or
968     ((dwPlatformId = VER_PLATFORM_WIN32_NT) and
969     (dwMajorVersion >= 4)) then begin
970     LibHandle := LoadLibrary('KERNEL32.DLL');
971     try
972     if (LibHandle <> 0) then begin
973     @GDFS := GetProcAddress(LibHandle, 'GetDiskFreeSpaceEx'+{$IFDEF UNICODE}'W'{$ELSE}'A'{$ENDIF});
974     if Assigned(GDFS) then begin
975     Root := Char(Upcase(Drive)) + ':\';
976     if GDFS(PChar(Root), UserFree, Size, Total) then begin
977     UserSpaceAvail := UserFree;
978     DiskSize := Size;
979     TotalSpaceAvail := Total;
980     Result := true;
981     end;
982     end;
983     end;
984    
985     finally
986     FreeLibrary(LibHandle);
987     end;
988     end;
989     end;
990     end;
991     end;
992     {$ELSE}
993     function GetDiskSpace(Drive : Char;
994     var UserSpaceAvail : Comp; {space available to user}
995     var TotalSpaceAvail : Comp; {total space available}
996     var DiskSize : Comp) : Boolean;{disk size}
997     {-Return space information about the drive.}
998     type
999     TGetDiskFreeSpace = function (Drive : PChar;
1000     var UserFreeBytes : Comp;
1001     var TotalBytes : Comp;
1002     var TotalFreeBytes : Comp) : Bool; stdcall;
1003     LH = packed record L,H : word; end;
1004     var
1005     CA, TC, BPS, SPC : Cardinal;
1006     VerInfo : TOSVersionInfo;
1007     LibHandle : THandle;
1008     GDFS : TGetDiskFreeSpace;
1009     Root : String;
1010     begin
1011     Result := false;
1012     {get the version info}
1013     FillChar(VerInfo, SizeOf(TOSVersionInfo), #0);
1014     VerInfo.dwOSVersionInfoSize := SizeOf(VerInfo);
1015     if GetVersionEx(VerInfo) then begin
1016     with VerInfo do begin
1017     if ((dwPlatformId = VER_PLATFORM_WIN32_WINDOWS) and
1018     (LH(dwBuildNumber).L <> 1000)) or
1019     ((dwPlatformId = VER_PLATFORM_WIN32_NT) and
1020     (dwMajorVersion >= 4)) then begin
1021     LibHandle := LoadLibrary('KERNEL32.DLL');
1022     try
1023     if (LibHandle <> 0) then begin
1024     @GDFS := GetProcAddress(LibHandle, 'GetDiskFreeSpaceEx'+{$IFDEF UNICODE}'W'{$ELSE}'A'{$ENDIF});
1025     if Assigned(GDFS) then begin
1026     Root := Char(System.Upcase(Drive)) + ':\';
1027     if GDFS(PChar(Root), UserSpaceAvail, DiskSize, TotalSpaceAvail) then
1028     Result := true;
1029     end;
1030     end;
1031    
1032     finally
1033     FreeLibrary(LibHandle);
1034     end;
1035     end;
1036     end;
1037     end;
1038    
1039     if not Result then begin
1040     if GetDiskInfo(Drive, CA, TC, BPS, SPC) then begin
1041     Result := true;
1042     DiskSize := BPS;
1043     DiskSize := DiskSize * SPC * TC;
1044     TotalSpaceAvail := BPS;
1045     TotalSpaceAvail := TotalSpaceAvail * SPC * CA;
1046     UserSpaceAvail := TotalSpaceAvail;
1047     end;
1048     end;
1049     end;
1050     {$ENDIF}
1051    
1052     function GetFileCreateDate(const FileName : String) :
1053     TDateTime;
1054     {-Obtains file system time of file creation.}
1055     {!!.01 - Rewritten}
1056     var
1057     Rslt : Integer;
1058     SR : TSearchRec;
1059     FTime : Integer;
1060     begin
1061     Result := 0.0;
1062     Rslt := FindFirst(FileName, faAnyFile, SR);
1063     if Rslt = 0 then begin
1064     {$IFDEF Version6} {$WARN SYMBOL_PLATFORM OFF} {$ENDIF}
1065     FileTimeToDosDateTime(SR.FindData.ftCreationTime,
1066     LongRec(FTime).Hi, LongRec(FTime).Lo);
1067     {$IFDEF Version6} {$WARN SYMBOL_PLATFORM ON} {$ENDIF}
1068     Result := FileDateToDateTime(FTime);
1069     FindClose(SR);
1070     end;
1071     {!!.01 - End Rewritten}
1072     end;
1073    
1074     {GetFileLastAccess}
1075     function GetFileLastAccess(const FileName : String) :
1076     TDateTime;
1077     {-Obtains file system time of last file access.}
1078     {!!.01 - Rewritten}
1079     var
1080     Rslt : Integer;
1081     SR : TSearchRec;
1082     FTime : Integer;
1083     begin
1084     Result := 0.0;
1085     Rslt := FindFirst(FileName, faAnyFile, SR);
1086     if Rslt = 0 then begin
1087     {$IFDEF Version6} {$WARN SYMBOL_PLATFORM OFF} {$ENDIF}
1088     FileTimeToDosDateTime(SR.FindData.ftLastAccessTime,
1089     LongRec(FTime).Hi, LongRec(FTime).Lo);
1090     {$IFDEF Version6} {$WARN SYMBOL_PLATFORM ON} {$ENDIF}
1091     Result := FileDateToDateTime(FTime);
1092     FindClose(SR);
1093     end;
1094     {!!.01 - End Rewritten}
1095     end;
1096    
1097     {GetFileLastModify}
1098     function GetFileLastModify(const FileName : String) :
1099     TDateTime;
1100     {-Obtains file system time of last file modification.}
1101     {!!.01 - Rewritten}
1102     var
1103     Rslt : Integer;
1104     SR : TSearchRec;
1105     FTime : Integer;
1106     begin
1107     Result := 0.0;
1108     Rslt := FindFirst(FileName, faAnyFile, SR);
1109     if Rslt = 0 then begin
1110     {$IFDEF Version6} {$WARN SYMBOL_PLATFORM OFF} {$ENDIF}
1111     FileTimeToDosDateTime(SR.FindData.ftLastWriteTime,
1112     LongRec(FTime).Hi, LongRec(FTime).Lo);
1113     {$IFDEF Version6} {$WARN SYMBOL_PLATFORM ON} {$ENDIF}
1114     Result := FileDateToDateTime(FTime);
1115     FindClose(SR);
1116     end;
1117     {!!.01 - End Rewritten}
1118     end;
1119    
1120     {GetHomeFolder}
1121     function GetHomeFolder(aForceSlash : boolean) : String;
1122     {-Obtains the "Home Folder" for the current user}
1123     var
1124     Size : integer;
1125     Path : String;
1126     Buffer : PChar;
1127     begin
1128     Size := GetEnvironmentVariable('HOMEDRIVE', nil, 0);
1129     GetMem(Buffer, Size * SizeOf(Char));
1130     try
1131     SetString(Result, Buffer, GetEnvironmentVariable('HOMEDRIVE',
1132     Buffer, Size));
1133     finally
1134     FreeMem(Buffer);
1135     end;
1136    
1137     Size := GetEnvironmentVariable('HOMEPATH', nil, 0);
1138     GetMem(Buffer, Size * SizeOf(Char));
1139     try
1140     SetString(Path, Buffer, GetEnvironmentVariable('HOMEPATH',
1141     Buffer, Size));
1142     finally
1143     FreeMem(Buffer);
1144     end;
1145    
1146     if Path = '' then
1147     Path := GetWorkingFolder(aForceSlash);
1148    
1149     if aForceSlash and (Result[length(Result)] <> StDosPathDelim) then
1150     Path := Path + StDosPathDelim;
1151     if (Path[1] <> StDosPathDelim) then
1152     Result := Result + StDosPathDelim + Path
1153     else
1154     Result := Result + Path;
1155     end;
1156    
1157     function GetLongPathName(lpszShortPath: PChar; lpszLongPath: PChar;
1158     cchBuffer: DWORD): DWORD;
1159     var
1160     PathBuf : PChar;
1161     Len, i : Integer;
1162     FD : TWIN32FindData;
1163     FH : THandle;
1164     ResBuf : String;
1165     begin
1166     if not Assigned(lpszShortPath) then begin
1167     SetLastError(ERROR_INVALID_PARAMETER);
1168     Result := 0;
1169     Exit;
1170     end;
1171    
1172     { Check whether the input path is valid. }
1173     if (GetFileAttributes(lpszShortPath) = $FFFFFFFF) then begin
1174     Result := 0;
1175     Exit;
1176     end;
1177    
1178     Len := StrLen(lpszShortPath);
1179     PathBuf := StrAlloc(Len + 1);
1180     try
1181     StrCopy(PathBuf, lpszShortPath);
1182     ResBuf := '';
1183    
1184     i := 0;
1185     { Check for Drive Letter }
1186     if (IsCharAlpha(PathBuf[0])) and (PathBuf[1] = DriveDelim) and (Len > 3) then begin
1187     repeat
1188     ResBuf := ResBuf + PathBuf[i];
1189     Inc(i);
1190     until PathBuf[i] = StPathDelim;
1191     ResBuf := ResBuf + StPathDelim;
1192     end;
1193    
1194     { Check for UNC Path }
1195     if (PathBuf[0] = StPathDelim) and (PathBuf[1] = StPathDelim) then begin
1196     { extract machine name }
1197     ResBuf := '\\';
1198     i := 2;
1199     repeat
1200     ResBuf := ResBuf + PathBuf[i];
1201     Inc(i);
1202     until PathBuf[i] = StPathDelim;
1203     ResBuf := ResBuf + StPathDelim;
1204     Inc(i);
1205    
1206     { extract share name }
1207     repeat
1208     ResBuf := ResBuf + PathBuf[i];
1209     Inc(i);
1210     until PathBuf[i] = StPathDelim;
1211     ResBuf := ResBuf + StPathDelim;
1212     Inc(i);
1213     end;
1214    
1215     { move past current delimiter } {!!.01}
1216     Inc(i); {!!.01}
1217    
1218     { find next occurrence of path delimiter }
1219     while i < Len do begin
1220     if (PathBuf[i] = StPathDelim) then begin
1221     PathBuf[i] := #0;
1222     FH := FindFirstFile(PathBuf, FD);
1223     if FH <> INVALID_HANDLE_VALUE then begin
1224     ResBuf := ResBuf + StrPas(FD.cFileName) + StPathDelim;
1225     Windows.FindClose(FH);
1226     end;
1227     PathBuf[i] := StPathDelim;
1228    
1229     end;
1230     Inc(i);
1231     end;
1232    
1233     { one mo' time for the entire string: }
1234     FH := FindFirstFile(PathBuf, FD);
1235     if FH <> INVALID_HANDLE_VALUE then begin
1236     ResBuf := ResBuf + StrPas(FD.cFileName);
1237     Windows.FindClose(FH);
1238     end;
1239    
1240     Result := Length(ResBuf);
1241    
1242     if Assigned(lpszLongPath) and (cchBuffer >= DWord(Length(ResBuf))) then begin
1243     StrPCopy(lpszLongPath, ResBuf);
1244     end;
1245     finally
1246     StrDispose(PathBuf);
1247     end;
1248     end;
1249    
1250     {GetLongPath}
1251     function GetLongPath(const APath : String) : String;
1252     {-Returns the long filename version of a provided path.}
1253     var
1254     Size : integer;
1255     Buffer : PChar;
1256     begin
1257     Buffer := nil;
1258     Size := GetLongPathName(PChar(APath), Buffer, 0);
1259     Buffer := StrAlloc(Size);
1260     try
1261     SetString(Result, Buffer, GetLongPathName(PChar(APath), Buffer, Size));
1262     finally
1263     if Assigned(Buffer) then
1264     StrDispose(Buffer);
1265     end;
1266     end;
1267    
1268     {GetMachineName}
1269     function GetMachineName : String;
1270     {-Returns the "Machine Name" for the current computer }
1271     var
1272     Size : DWORD;
1273     MachineNameZ : array [0..MAX_COMPUTERNAME_LENGTH] of Char;
1274     begin
1275     Size := Length(MachineNameZ);
1276     if not GetComputerName(MachineNameZ, Size) then
1277     {$IFDEF Version6}
1278     RaiseLastOSError;
1279     {$ELSE}
1280     RaiseLastWin32Error;
1281     {$ENDIF}
1282     // SetString(Result, MachineNameZ, Size); {!!.02}
1283     SetString(Result, MachineNameZ, StrLen(MachineNameZ)); {!!.02}
1284     end;
1285    
1286     {GetMediaID}
1287     function GetMediaID(Drive : Char; var MediaIDRec : MediaIDType) : Cardinal;
1288     {-Get the media information (Volume Label, Serial Number) for the specified drive}
1289     var
1290     VolBuf, FSNameBuf : PChar;
1291     VolSiz, FSNSiz : Integer;
1292     Root : String;
1293     SN, ML, Flags : DWORD;
1294     begin
1295     VolSiz := Length(MediaIDRec.VolumeLabel){ + 1}; //SZ: why +1??
1296     FSNSiz := Length(MediaIDRec.FileSystemID){ + 1};
1297    
1298     Root := Char(System.Upcase(Drive)) + ':\';
1299    
1300     VolBuf := nil;
1301     FSNameBuf := nil;
1302    
1303     try
1304     VolBuf := StrAlloc(VolSiz);
1305     FSNameBuf := StrAlloc(FSNSiz);
1306     Result := 0;
1307     if GetVolumeInformation(PChar(Root), VolBuf, VolSiz, @SN, ML, Flags, FSNameBuf, FSNSiz) then begin
1308     StrCopy(MediaIDRec.FileSystemID, FSNameBuf);
1309     StrCopy(MediaIDRec.VolumeLabel, VolBuf);
1310     MediaIDRec.SerialNumber := SN;
1311    
1312     end else
1313     Result := GetLastError;
1314     finally
1315     if Assigned(VolBuf) then
1316     StrDispose(VolBuf);
1317     if Assigned(FSNameBuf) then
1318     StrDispose(FSNameBuf);
1319     end;
1320     end;
1321    
1322     {!!.02 -- Added }
1323     function StAddBackSlash(const DirName : string) : string;
1324     { Add a default slash to a directory name }
1325     const
1326     DelimSet : set of AnsiChar = [StPathDelim, ':', #0];
1327     begin
1328     Result := DirName;
1329     if Length(DirName) = 0 then
1330     Exit;
1331     {$IFDEF UNICODE}
1332     if not CharInSet(DirName[Length(DirName)], DelimSet) then
1333     Result := DirName + StPathDelim;
1334     {$ELSE}
1335     if not (DirName[Length(DirName)] in DelimSet) then
1336     Result := DirName + StPathDelim;
1337     {$ENDIF}
1338     end;
1339     {!!.02 -- End Added }
1340    
1341     {GetParentFolder}
1342     function GetParentFolder(const APath : String; aForceSlash : Boolean) : String;
1343     {-return the parent directory for the provided directory }
1344     begin
1345     Result := ExpandFileName(StAddBackSlash(APath) + StParentDir); {!!.02}
1346     if aForceSlash and (Result[length(Result)] <> StDosPathDelim) then
1347     Result := Result + StDosPathDelim;
1348     end;
1349    
1350     {GetShortPath}
1351     function GetShortPath(const APath : String) : String;
1352     {-Returns the short filename version of a provided path.}
1353     var
1354     Size : integer;
1355     Buffer : PChar;
1356     begin
1357     Buffer := nil;
1358     Size := GetShortPathName(PChar(APath), Buffer, 0);
1359     Buffer := StrAlloc(Size);
1360     try
1361     SetString(Result, Buffer, GetShortPathName(PChar(APath), Buffer, Size));
1362     finally
1363     if Assigned(Buffer) then
1364     StrDispose(Buffer);
1365     end;
1366     end;
1367    
1368     {GetSystemFolder}
1369     function GetSystemFolder(aForceSlash : boolean) : String;
1370     {-Returns the path to the Windows "System" folder".}
1371     var
1372     Size : integer;
1373     Buffer : PChar;
1374     begin
1375     Size := GetSystemDirectory(nil, 0);
1376     Buffer := StrAlloc(Size);
1377     try
1378     SetString(Result, Buffer, GetSystemDirectory(Buffer, Size));
1379     finally
1380     StrDispose(Buffer);
1381     end;
1382     if aForceSlash and (Result[length(Result)] <> StDosPathDelim) then
1383     Result := Result + StDosPathDelim;
1384     end;
1385    
1386     {GetTempFolder}
1387     function GetTempFolder(aForceSlash : boolean) : String;
1388     {-Returns the path to the system temporary folder.}
1389     var
1390     Size : integer;
1391     Buffer : PChar;
1392     begin
1393     Size := GetTempPath(0, nil);
1394     Buffer := StrAlloc(Size);
1395     try
1396     SetString(Result, Buffer, GetTempPath(Size, Buffer));
1397     finally
1398     StrDispose(Buffer);
1399     end;
1400     if aForceSlash and (Result[length(Result)] <> StDosPathDelim) then
1401     Result := Result + StDosPathDelim;
1402     end;
1403    
1404     {GetWindowsFolder}
1405     function GetWindowsFolder(aForceSlash : boolean) : String;
1406     {-Returns the path to the main "Windows" folder.}
1407     var
1408     Size : integer;
1409     Buffer : PChar;
1410     begin
1411     Size := GetWindowsDirectory(nil, 0);
1412     Buffer := StrAlloc(Size);
1413     try
1414     SetString(Result, Buffer, GetWindowsDirectory(Buffer, Size));
1415     finally
1416     StrDispose(Buffer);
1417     end;
1418     if aForceSlash and (Result[length(Result)] <> StDosPathDelim) then
1419     Result := Result + StDosPathDelim;
1420     end;
1421    
1422     {GetWorkingFolder}
1423     function GetWorkingFolder(aForceSlash : boolean) : String;
1424     {-Returns the current working directory.}
1425     begin
1426     Result := ExpandFileName(StThisDir);
1427     if aForceSlash and (Result[length(Result)] <> StDosPathDelim) then
1428     Result := Result + StDosPathDelim;
1429     end;
1430    
1431     {GlobalDateTimeToLocal}
1432     function GlobalDateTimeToLocal(const UTC: TStDateTimeRec; MinOffset: Integer): TStDateTimeRec; {!!.02}
1433     {-adjusts a global date/time (UTC) to the local date/time}
1434     {$IFNDEF VERSION4}
1435     const
1436     TIME_ZONE_ID_INVALID = DWORD($FFFFFFFF);
1437     TIME_ZONE_ID_UNKNOWN = 0;
1438     TIME_ZONE_ID_STANDARD = 1;
1439     TIME_ZONE_ID_DAYLIGHT = 2;
1440     {$ENDIF}
1441     var
1442     Minutes : LongInt;
1443     TZ : TTimeZoneInformation;
1444     begin
1445     Minutes := (UTC.D * MinutesInDay) + (UTC.T div 60);
1446     case GetTimeZoneInformation(TZ) of
1447     TIME_ZONE_ID_UNKNOWN :
1448     Minutes := Minutes - TZ.Bias;
1449     TIME_ZONE_ID_INVALID :
1450     Minutes := Minutes - MinOffset;
1451     TIME_ZONE_ID_STANDARD:
1452     Minutes := Minutes - (TZ.Bias + TZ.StandardBias);
1453     TIME_ZONE_ID_DAYLIGHT:
1454     Minutes := Minutes - (TZ.Bias + TZ.DaylightBias);
1455     end;
1456    
1457     Result.D := (Minutes div MinutesInDay);
1458     Result.T := ((Minutes mod MinutesInDay) * SecondsInMinute) + (UTC.T mod SecondsInMinute);
1459     end;
1460    
1461     {IsDirectory}
1462     function IsDirectory(const DirName : String) : Boolean;
1463     {-Return true if DirName is a directory}
1464     var
1465     Attrs : DWORD; {!!.01}
1466     begin
1467     Result := False;
1468     Attrs := GetFileAttributes(PChar(DirName));
1469     if Attrs <> DWORD(-1) then {!!.01}
1470     Result := (FILE_ATTRIBUTE_DIRECTORY and Attrs <> 0);
1471     end;
1472    
1473     {IsDirectoryEmpty}
1474     function IsDirectoryEmpty(const S : String) : Integer;
1475     {-checks if there are any entries in the directory}
1476     var
1477     SR : TSearchRec;
1478     R : Integer;
1479     DS : String;
1480     begin
1481     Result := 1;
1482     if IsDirectory(S) then begin
1483     DS := AddBackSlashL(S);
1484     R := Abs(FindFirst(DS + StDosAnyFile, faAnyFile, SR));
1485     if R <> 18 then begin
1486     if (R = 0) then
1487     repeat
1488     if (SR.Attr and faDirectory = faDirectory) then begin
1489     if (SR.Name <> StThisDir) and (SR.Name <> StParentDir) then begin
1490     Result := 0;
1491     break;
1492     end;
1493     end else begin
1494     Result := 0;
1495     break;
1496     end;
1497     R := Abs(FindNext(SR));
1498     until R = 18;
1499     end;
1500     FindClose(SR);
1501     end else
1502     Result := -1;
1503     end;
1504    
1505     {IsDriveReady}
1506     function IsDriveReady(Drive : Char) : Boolean;
1507     {-determine if requested drive is accessible }
1508     var
1509     Root : String;
1510     VolName : PChar;
1511     Flags, MaxLength : DWORD;
1512     NameSize : Integer;
1513     begin
1514     Result := False;
1515     NameSize := 0;
1516     Root := System.Upcase(Drive) + ':\' ;
1517     VolName := StrAlloc(MAX_PATH);
1518    
1519     try
1520     if GetVolumeInformation(PChar(Root), VolName, MAX_PATH,
1521     nil, MaxLength, Flags, nil, NameSize) then
1522     Result := True;
1523     finally
1524     if Assigned(VolName) then
1525     StrDispose(VolName);
1526     end;
1527     end;
1528    
1529     {IsFile}
1530     function IsFile(const FileName : String) : Boolean;
1531     {-Determines if the provided path specifies a file.}
1532     var
1533     Attrs : DWORD; {!!.02}
1534     begin
1535     Result := False;
1536     Attrs := GetFileAttributes(PChar(FileName));
1537     if Attrs <> DWORD(-1) then {!!.02}
1538     Result := (Attrs and FILE_ATTRIBUTE_DIRECTORY) <> FILE_ATTRIBUTE_DIRECTORY;
1539     end;
1540    
1541     {IsFileArchive}
1542     function IsFileArchive(const S : String) : Integer;
1543     {-checks if file's archive attribute is set}
1544     begin
1545     {$IFDEF Version6} {$WARN SYMBOL_PLATFORM OFF} {$ENDIF}
1546     if FileExists(S) then
1547     Result := Integer((FileGetAttr(S) and faArchive) = faArchive)
1548     else
1549     Result := -1;
1550     {$IFDEF Version6} {$WARN SYMBOL_PLATFORM ON} {$ENDIF}
1551     end;
1552    
1553     {IsFileHidden}
1554     function IsFileHidden(const S : String) : Integer;
1555     {-checks if file's hidden attribute is set}
1556     begin
1557     {$IFDEF Version6} {$WARN SYMBOL_PLATFORM OFF} {$ENDIF}
1558     if FileExists(S) then
1559     Result := Integer((FileGetAttr(S) and faHidden) = faHidden)
1560     else
1561     Result := -1;
1562     {$IFDEF Version6} {$WARN SYMBOL_PLATFORM ON} {$ENDIF}
1563     end;
1564    
1565     {IsFileReadOnly}
1566     function IsFileReadOnly(const S : String) : Integer;
1567     {-checks if file's readonly attribute is set}
1568     begin
1569     {$IFDEF Version6} {$WARN SYMBOL_PLATFORM OFF} {$ENDIF}
1570     if FileExists(S) then
1571     Result := Integer((FileGetAttr(S) and faReadOnly) = faReadOnly)
1572     else
1573     Result := -1;
1574     {$IFDEF Version6} {$WARN SYMBOL_PLATFORM ON} {$ENDIF}
1575     end;
1576    
1577     {IsFileSystem}
1578     function IsFileSystem(const S : String) : Integer;
1579     {-checks if file's system attribute is set}
1580     begin
1581     {$IFDEF Version6} {$WARN SYMBOL_PLATFORM OFF} {$ENDIF}
1582     if FileExists(S) then
1583     Result := Integer((FileGetAttr(S) and faSysFile) = faSysFile)
1584     else
1585     Result := -1;
1586     {$IFDEF Version6} {$WARN SYMBOL_PLATFORM ON} {$ENDIF}
1587     end;
1588    
1589     {LocalDateTimeToGlobal}
1590     function LocalDateTimeToGlobal(const DT1: TStDateTimeRec; MinOffset: Integer): TStDateTimeRec; {!!.02}
1591     {-adjusts a local date/time to the global (UTC) date/time}
1592     {$IFNDEF VERSION4}
1593     const
1594     TIME_ZONE_ID_INVALID = DWORD($FFFFFFFF);
1595     TIME_ZONE_ID_UNKNOWN = 0;
1596     TIME_ZONE_ID_STANDARD = 1;
1597     TIME_ZONE_ID_DAYLIGHT = 2;
1598     {$ENDIF}
1599     var
1600     Minutes : LongInt;
1601     TZ : TTimeZoneInformation;
1602     begin
1603     Minutes := (DT1.D * MinutesInDay) + (DT1.T div 60);
1604     case GetTimeZoneInformation(TZ) of
1605     TIME_ZONE_ID_UNKNOWN : { Time Zone transition dates not used }
1606     Minutes := Minutes + TZ.Bias;
1607     TIME_ZONE_ID_INVALID :
1608     Minutes := Minutes + MinOffset;
1609     TIME_ZONE_ID_STANDARD:
1610     Minutes := Minutes + (TZ.Bias + TZ.StandardBias);
1611     TIME_ZONE_ID_DAYLIGHT:
1612     Minutes := Minutes + (TZ.Bias + TZ.DaylightBias);
1613     end;
1614    
1615     Result.D := (Minutes div MinutesInDay);
1616     Result.T := ((Minutes mod MinutesInDay) * SecondsInMinute) + (DT1.T mod SecondsInMinute);
1617     end;
1618    
1619     {ReadVolumeLabel}
1620     function ReadVolumeLabel(var VolName : String; Drive : Char) : Cardinal;
1621     {-Get the volume label for the specified drive.}
1622     var
1623     Root : String;
1624     Flags, MaxLength : DWORD;
1625     NameSize : Integer;
1626     begin
1627     NameSize := 0;
1628     Root := Drive + ':\';
1629     if Length(VolName) < 12 then
1630     SetLength(VolName, 12);
1631     if GetVolumeInformation(PChar(Root), PChar(VolName), Length(VolName),
1632     nil, MaxLength, Flags, nil, NameSize)
1633     then begin
1634     SetLength(VolName, StrLen(PChar(VolName)));
1635     Result := 0;
1636     end
1637     else begin
1638     VolName := '';
1639     Result := GetLastError;
1640     end;
1641     end;
1642    
1643     {SameFile}
1644     function SameFile(const FilePath1, FilePath2 : String;
1645     var ErrorCode : Integer) : Boolean;
1646     {-Return true if FilePath1 and FilePath2 refer to the same physical file.
1647     Error codes:
1648     0 - Success (no error)
1649     1 - Invalid FilePath1
1650     2 - Invalid FilePath2
1651     3 - Error on FileSetAttr/FileGetAttr }
1652     var
1653     Attr1, Attr2, NewAttr : Integer;
1654    
1655    
1656     function DirectoryExists(const Name : String): Boolean;
1657     var
1658     Code : DWORD; {!!.02}
1659     Buf : array[0..MAX_PATH] of Char; {!!.01}
1660     begin
1661     StrPLCopy(Buf, Name, Length(Buf)-1);
1662     Code := GetFileAttributes(Buf);
1663     Result := (Code <> DWORD(-1)) and {!!.02}
1664     (FILE_ATTRIBUTE_DIRECTORY and Code <> 0); {!!.02}
1665     end;
1666    
1667     begin
1668     {$IFDEF Version6} {$WARN SYMBOL_PLATFORM OFF} {$ENDIF}
1669     Result := False;
1670     ErrorCode := 0;
1671     Attr1 := FileGetAttr(FilePath1);
1672     if Attr1 < 0 then begin
1673     ErrorCode := 1;
1674     Exit;
1675     end;
1676     Attr2 := FileGetAttr(FilePath2);
1677     if Attr2 < 0 then begin
1678     {leave ErrorCode at 0 if file not found but path is valid}
1679     if not DirectoryExists(ExtractFilePath(FilePath2)) then
1680     ErrorCode := 2;
1681     Exit;
1682     end;
1683     if Attr1 <> Attr2 then
1684     Exit;
1685     if ((Attr1 and faArchive) = 0) then
1686     NewAttr := Attr1 or faArchive
1687     else
1688     NewAttr := Attr1 and (not faArchive);
1689     if FileSetAttr(FilePath1, NewAttr) <> 0 then begin
1690     ErrorCode := 3;
1691     Exit;
1692     end;
1693     Attr2 := FileGetAttr(FilePath2);
1694     if Attr2 < 0 then
1695     ErrorCode := 3;
1696    
1697     Result := (Attr2 = NewAttr) or (Attr2 = $80);
1698     { If the attribute is set to $00, Win32 automatically sets it to $80. }
1699    
1700     if FileSetAttr(FilePath1, Attr1) <> 0 then
1701     ErrorCode := 3;
1702     {$IFDEF Version6} {$WARN SYMBOL_PLATFORM ON} {$ENDIF}
1703     end;
1704    
1705     {SetMediaID} {!!!! Does not work on NT/2000 !!!!}
1706     function SetMediaID(Drive : Char; var MediaIDRec : MediaIDType) : Cardinal;
1707     {-Set the media ID record for the specified drive.}
1708     type
1709     DevIOCtlRegisters = record
1710     reg_EBX : LongInt;
1711     reg_EDX : LongInt;
1712     reg_ECX : LongInt;
1713     reg_EAX : LongInt;
1714     reg_EDI : LongInt;
1715     reg_ESI : LongInt;
1716     reg_Flags : LongInt;
1717     end;
1718     var
1719     PMid : PMediaIDType;
1720     Regs : DevIOCtlRegisters;
1721     CB : DWord;
1722     HDevice : THandle;
1723     SA : TSecurityAttributes;
1724     begin
1725     PMid := @MediaIDRec;
1726     with SA do begin
1727     nLength := SizeOf(SA);
1728     lpSecurityDescriptor := nil;
1729     bInheritHandle := True;
1730     end;
1731     with Regs do begin
1732     reg_EAX := $440D;
1733     reg_EBX := Ord(System.UpCase(Drive)) - (Ord('A') - 1);
1734     reg_ECX := $0846;
1735     reg_EDX := LongInt(PMid);
1736     end;
1737     HDevice := CreateFile('\\.\vwin32', GENERIC_READ, FILE_SHARE_READ or FILE_SHARE_WRITE,
1738     Pointer(@SA), OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
1739     if HDevice <> INVALID_HANDLE_VALUE then begin
1740     if DeviceIOControl(HDevice, VWIN32_DIOC_DOS_IOCTL, Pointer(@Regs), SizeOf(Regs),
1741     Pointer(@Regs), SizeOf(Regs), CB, nil)
1742     then
1743     Result := 0
1744     else
1745     Result := GetLastError;
1746     CloseHandle(HDevice);
1747     end else
1748     Result := GetLastError;
1749     end;
1750    
1751     {SplitPath}
1752     procedure SplitPath(const APath : String; Parts : TStrings);
1753     {-Splits the provided path into its component sub-paths}
1754     var
1755     i : Integer;
1756     iStart : Integer;
1757     iStartSlash : Integer;
1758     Path, SubPath : String;
1759     begin
1760     Path := APath;
1761     if Path = '' then Exit;
1762     if not Assigned(Parts) then Exit;
1763    
1764     if Path[ Length( Path ) ] = StPathDelim then
1765     Delete( Path, Length( APath ), 1 );
1766     iStart := 1;
1767     iStartSlash := 1;
1768     repeat
1769     {find the Slash at iStartSlash}
1770     i := FindNthSlash( Path, iStartSlash );
1771     {get the subpath}
1772     SubPath := Copy( Path, iStart, i - iStart + 1 );
1773     iStart := i + 2;
1774     inc( iStartSlash );
1775     Parts.Add( SubPath );
1776     until ( i = Length( Path ) );
1777     end;
1778    
1779     {StDateTimeToFileTime}
1780     function StDateTimeToFileTime(const FileTime : TStDateTimeRec) : LongInt; {!!.02}
1781     {-Converts an TStDate and TStTime to a DOS date-time value.}
1782     var
1783     DDT : TDateTime;
1784     begin
1785     DDT := Int(StDateToDateTime(FileTime.D)) + Frac(StTimeToDateTime(FileTime.T));
1786     Result := DateTimeToFileDate(DDT);
1787     end;
1788    
1789     {StDateTimeToUnixTime}
1790     function StDateTimeToUnixTime(const DT1 : TStDateTimeRec) : Longint; {!!.02}
1791     {-converts a TStDateTimeRec to a time in Unix base (1970)}
1792     begin
1793     Result := ((DT1.D - Date1970) * SecondsInDay) + DT1.T;
1794     end;
1795    
1796     {UnixTimeToStDateTime}
1797     function UnixTimeToStDateTime(UnixTime : Longint) : TStDateTimeRec;
1798     {-converts a time in Unix base (1970) to a TStDateTimeRec}
1799     begin
1800     Result.D := Date1970 + (UnixTime div SecondsInDay);
1801     Result.T := UnixTime mod SecondsInDay;
1802     end;
1803    
1804     {ValidDrive}
1805     function ValidDrive(Drive : Char) : Boolean;
1806     {-Determine if the drive is a valid drive.}
1807     var
1808     DriveBits : LongInt;
1809     DriveLtr : Char;
1810     begin
1811     DriveLtr := System.UpCase(Drive);
1812     DriveBits := GetLogicalDrives shr (Ord(DriveLtr)-Ord('A'));
1813     Result := LongFlagIsSet(DriveBits, $00000001);
1814     end;
1815    
1816     {WriteVolumeLabel}
1817     function WriteVolumeLabel(const VolName : String; Drive : Char) : Cardinal;
1818     {-Sets the volume label for the specified drive.}
1819     var
1820     Temp : String;
1821     Vol : array[0..11] of Char;
1822     Root : array[0..3] of Char;
1823     begin
1824     Temp := VolName;
1825     StrCopy(Root, '%:\');
1826     Root[0] := Drive;
1827     if Length(Temp) > 11 then
1828     SetLength(Temp, 11);
1829     StrPCopy(Vol, Temp);
1830     if Windows.SetVolumeLabel(Root, Vol) then
1831     Result := 0
1832     else Result := GetLastError;
1833     end;
1834    
1835    
1836     end.
1837    
1838    
1839    
1840    
1841    
1842    
1843    

  ViewVC Help
Powered by ViewVC 1.1.20