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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2671 - (show annotations) (download)
Tue Aug 25 18:15:15 2015 UTC (8 years, 9 months ago) by torben
File size: 55793 byte(s)
Added tpsystools component
1 // 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