1 { Version 050625. Copyright � Alexey A.Chernobaev, 2000-5 }
2
3 unit VFileSys;
4
5 interface
6
7 {$I VCheck.inc}
8
9 uses
10 {$IFNDEF V_WIN}{$IFNDEF UNIX}{$DEFINE V_WIN}{$ENDIF}{$ENDIF}
11 {$IFDEF V_WIN}Windows,{$ENDIF}
12 SysUtils, ExtType, ExtSys, VectStr, VectErr;
13
14 //{$IFNDEF V_WIN}{$IFNDEF UNIX}Error!{$ENDIF}{$ENDIF}
15
16 const
17 InvalidWinFileNameChars = ['"', '*', '?', '/', ':', '<', '>', '\', '|'];
18 {$IFDEF UNIX}
19 InvalidFileNameChars = ['*', '?', '/'];
20 {$ELSE}
21 InvalidFileNameChars = InvalidWinFileNameChars;
22 {$ENDIF}
23 InvalidFileMaskChars = InvalidFileNameChars - ['*', '?'];
24
25 MaxFileLen = 1023;
26
27 {$IFNDEF V_D4} // Delphi 3 or Free Pascal
IsPathDelimiternull28 function IsPathDelimiter(const S: String; Index: Integer): Boolean;
29 {$ENDIF} {V_D4}
30
31 {$IFNDEF V_D5}
32 // Delphi 3 or Delphi 4 or Free Pascal
IncludeTrailingBackslashnull33 function IncludeTrailingBackslash(const S: String): String;
ExcludeTrailingBackslashnull34 function ExcludeTrailingBackslash(const S: String): String;
35
36 {$IFDEF V_WIN}
SafeLoadLibrarynull37 function SafeLoadLibrary(const FileName: String;
38 ErrorMode: UINT{$IFDEF V_DEFAULTS} = SEM_NOOPENFILEERRORBOX{$ENDIF}): HMODULE;
39 {$ENDIF} {V_WIN}
40
41 {$ENDIF} {V_D5}
42
43 {$IFNDEF V_D6}
IncludeTrailingPathDelimiternull44 function IncludeTrailingPathDelimiter(const S: String): String;
ExcludeTrailingPathDelimiternull45 function ExcludeTrailingPathDelimiter(const S: String): String;
46 {$ENDIF} {V_D6}
47
48 {$IFDEF V_WIN}
SafeLoadLibraryWnull49 function SafeLoadLibraryW(const FileName: WideString;
50 ErrorMode: UINT{$IFDEF V_DEFAULTS} = SEM_NOOPENFILEERRORBOX{$ENDIF}): HMODULE;
51 {$ENDIF}
52
53 type
54 TFileBuf = array [0..MaxFileLen] of AnsiChar;
55 TFileBufW = array [0..MaxFileLen] of WideChar;
56
GetCurrentDirWnull57 function GetCurrentDirW: WideString;
SetCurrentDirWnull58 function SetCurrentDirW(const Dir: WideString): Boolean;
LastDelimiterWnull59 function LastDelimiterW(const Delimiters, W: WideString): Integer;
ChangeFileExtWnull60 function ChangeFileExtW(const FileName, Extension: WideString): WideString;
ExtractFilePathWnull61 function ExtractFilePathW(const FileName: WideString): WideString;
ExtractFileExtWnull62 function ExtractFileExtW(const FileName: WideString): WideString;
ExtractFileNameWnull63 function ExtractFileNameW(const FileName: WideString): WideString;
ExpandFileNameWnull64 function ExpandFileNameW(const FileName: WideString): WideString;
IncludePathDelimiterWnull65 function IncludePathDelimiterW(const S: WideString): WideString;
ExcludePathDelimiterWnull66 function ExcludePathDelimiterW(const S: WideString): WideString;
67
68 { why use pLastOSError: GetLastError will be altered by WideString cleaning
69 code (under Windows) }
70 {$IFDEF V_WIN}
71 {$ENDIF}
72
73 {$IFDEF UNIX}
74
UserNamenull75 //function UserName(uid: __uid_t): WideString;
76
77 //function GroupName(gid: __gid_t): WideString;
78 {$ENDIF}
79
80 function ValidateFileName(const FileName: String; MaxLen: Integer): String;
81
IsFileNameSyntaxValidnull82 function IsFileNameSyntaxValid(const FileName: WideString): Boolean;
83
IsAbsolutePathSyntaxValidnull84 function IsAbsolutePathSyntaxValid(const Path: WideString): Boolean;
85
GetTempDirnull86 function GetTempDir: String;
87
88 type
89 TFileLock = {$IFDEF UNIX}Integer{$ELSE}THandle{$ENDIF};
90
91 { ��������� ���� �� ������; � ������ ������ ���������� ���������� �����, �����
92 ���������� INVALID_HANDLE_VALUE (Linux: -1) }
93 { write-locks the given file; returns a file handle if successful or
94 INVALID_HANDLE_VALUE (Linux: -1) if failed }
95
96 {$IFDEF V_WIN}
GetTempDirWnull97 function GetTempDirW: WideString;
98
GetWindowsDirnull99 function GetWindowsDir: String;
GetWindowsDirWnull100 function GetWindowsDirW: WideString;
101
GetSystemDirnull102 function GetSystemDir: String;
GetSystemDirWnull103 function GetSystemDirW: WideString;
104
LockFileReadnull105 function LockFileRead(const FileName: String): THandle;
106
GetLongFileNamenull107 function GetLongFileName(const Name: String): String;
108 {$IFDEF V_D6}platform;{$ENDIF}
109 { ���������� "�������" ���, ��������������� ��������� "���������" ����� �����
110 ��� ���������� ���� ������ ������, ���� ���� ��� ���������� �� �������; �
111 ������� ����� ���������� "�������" ����� }
112 { returns the long name corresponding to the specified short file or directory
113 name or the empty string if the file or directory were not found; it's legal
114 to pass long names to the function }
115
116
117 {$ENDIF} {V_WIN}
118
119 {$IFDEF V_DELPHI}{$IFNDEF V_D6}
DirectoryExistsnull120 function DirectoryExists(const Name: String): Boolean;
121 {$ENDIF}{$ENDIF}
122
123 {$IFDEF V_DELPHI}{$IFNDEF V_D6}
ForceDirectoriesnull124 function ForceDirectories(Dir: String): Boolean;
125 {$ENDIF}{$ENDIF}
126
ExcludeFileExtnull127 function ExcludeFileExt(const Name: String): String;
ExcludeFileExtWnull128 function ExcludeFileExtW(const Name: WideString): WideString;
129 { ���������� ��� ����� ��� ���������� }
130 { excludes an extension from the given file name }
131
ShortenFileNamenull132 function ShortenFileName(const FileName: String; MaxLen: Integer;
133 DelimitChars: TCharSet{$IFDEF V_DEFAULTS} = []{$ENDIF}): String;
ShortenFileNameWnull134 function ShortenFileNameW(const FileName: WideString; MaxLen: Integer;
135 DelimitChars: TCharSet{$IFDEF V_DEFAULTS} = []{$ENDIF}): WideString;
136
GetModuleNameWnull137 function GetModuleNameW(Module: HMODULE): WideString;
138 { returns a name of a file which contains the specified module }
139
140 procedure ParseFileName(const FileName: String; var Path, Name: String);
141 procedure ParseFileNameW(const FileName: WideString; var Path, Name: WideString);
142
FirstItemDelimiterWnull143 function FirstItemDelimiterW(const Path: WideString): Integer;
144 { returns an index of the first PathDelim or '|' character (0 if not found) }
145
LastItemDelimiterWnull146 function LastItemDelimiterW(const Path: WideString): Integer;
147 { returns an index of the last PathDelim or '|' character (0 if not found) }
148
149 procedure ParseItemName(const FullItemName: String; var Path, Name: String);
150 procedure ParseItemNameW(const FullItemName: WideString; var Path,
151 Name: WideString);
152
GetItemNameWnull153 function GetItemNameW(const FullItemName: WideString): WideString;
GetItemPathWnull154 function GetItemPathW(const FullItemName: WideString): WideString;
155
CorrectFileNamenull156 function CorrectFileName(const Name: String;
157 DefaultChar: AnsiChar{$IFDEF V_DEFAULTS} = '_'{$ENDIF}): String;
CorrectFileNameWnull158 function CorrectFileNameW(const Name: WideString;
159 DefaultChar: WideChar{$IFDEF V_DEFAULTS} = '_'{$ENDIF}): WideString;
160
CorrectPathNamenull161 function CorrectPathName(const Name: String;
162 DefaultChar: AnsiChar{$IFDEF V_DEFAULTS} = '_'{$ENDIF}): String;
CorrectPathNameWnull163 function CorrectPathNameW(const Name: WideString;
164 DefaultChar: WideChar{$IFDEF V_DEFAULTS} = '_'{$ENDIF}): WideString;
165
GetStdFileExtnull166 function GetStdFileExt(const FileName: String): String;
167 { ���������� ���������� ����� ��� ��������� �����, ������ � ������ �������� }
168 { returns an extension portion of the given file name without a leading dot,
169 always in lowercase }
170
171 {$IFDEF V_DEFAULTS}
172
173 {$IFDEF V_WIN}
GetFilePropsnull174 function GetFileProps(const FileName: String; pSize: PInt64;
175 pModifyTime: PDateTime = nil; pCreationTime: PDateTime = nil;
176 pLastAccessTime: PDateTime = nil; pAttributes: PDWORD = nil;
177 pLastOSError: PDWORD = nil): Boolean;
178
GetFilePropsWnull179 function GetFilePropsW(const FileName: WideString; pSize: PInt64;
180 pModifyTime: PDateTime = nil; pCreationTime: PDateTime = nil;
181 pLastAccessTime: PDateTime = nil; pAttributes: PDWORD = nil;
182 pLastOSError: PDWORD = nil): Boolean;
183 {$ENDIF}
184
185 {$IFDEF UNIX}
GetFilePropsnull186 function GetFileProps(const FileName: String; pSize: PInt64;
187 pModifyTime: PDateTime = nil; pLastStatusChangeTime: PDateTime = nil;
188 pLastAccessTime: PDateTime = nil; pAttributes: PUInt32 = nil;
189 pUser: PUInt32 = nil; pGroup: PUInt32 = nil): Boolean;
190
GetFilePropsWnull191 function GetFilePropsW(const FileName: WideString; pSize: PInt64;
192 pModifyTime: PDateTime = nil; pLastStatusChangeTime: PDateTime = nil;
193 pLastAccessTime: PDateTime = nil; pAttributes: PUInt32 = nil;
194 pUser: PUInt32 = nil; pGroup: PUInt32 = nil): Boolean;
195
GetLinkTargetnull196 function GetLinkTarget(const PathOnly: String): String;
197 {$ENDIF} {LINUX}
198
199 {$ELSE}
200
201 {$ENDIF} {V_DEFAULTS}
202
IsRelativePathnull203 function IsRelativePath(const FileName: String): Boolean;
204
205 implementation
206
207 {$IFNDEF V_D4}
IsPathDelimiternull208 function IsPathDelimiter(const S: String; Index: Integer): Boolean;
209 begin
210 Result:=(Index > 0) and (Index <= Length(S)) and (S[Index] = PathDelim) and
211 (ByteType(S, Index) = mbSingleByte);
212 end;
213 {$ENDIF}
214
215 {$IFNDEF V_D5}
IncludeTrailingBackslashnull216 function IncludeTrailingBackslash(const S: String): String;
217 begin
218 Result:=S;
219 if not IsPathDelimiter(Result, Length(Result)) then
220 Result:=Result + PathDelim;
221 end;
222
ExcludeTrailingBackslashnull223 function ExcludeTrailingBackslash(const S: String): String;
224 begin
225 Result:=S;
226 if IsPathDelimiter(Result, Length(Result)) then
227 SetLength(Result, Length(Result) - 1);
228 end;
229
230 {$IFDEF V_WIN}
SafeLoadLibrarynull231 function SafeLoadLibrary(const FileName: String; ErrorMode: UINT): HMODULE;
232 var
233 OldMode: UINT;
234 FPUControlWord: Word;
235 begin
236 OldMode:=SetErrorMode(ErrorMode);
237 try
238 asm
239 FNSTCW FPUControlWord
240 end;
241 try
242 Result:=LoadLibrary(PChar(FileName));
243 finally
244 asm
245 FNCLEX
246 FLDCW FPUControlWord
247 end;
248 end;
249 finally
250 SetErrorMode(OldMode);
251 end;
252 end;
253 {$ENDIF} {V_WIN}
254
255 {$ENDIF} {V_D5}
256
257 {$IFNDEF V_D6}
IncludeTrailingPathDelimiternull258 function IncludeTrailingPathDelimiter(const S: String): String;
259 begin
260 Result:=IncludeTrailingBackslash(S);
261 end;
262
ExcludeTrailingPathDelimiternull263 function ExcludeTrailingPathDelimiter(const S: String): String;
264 begin
265 Result:=ExcludeTrailingBackslash(S);
266 end;
267 {$ENDIF} {V_D6}
268
269 {$IFDEF V_WIN}
SafeLoadLibraryWnull270 function SafeLoadLibraryW(const FileName: WideString; ErrorMode: UINT): HMODULE;
271 var
272 OldMode: UINT;
273 FPUControlWord: Word;
274 begin
275 if Win32Platform = VER_PLATFORM_WIN32_NT then begin
276 OldMode:=SetErrorMode(ErrorMode);
277 try
278 asm
279 FNSTCW FPUControlWord
280 end;
281 try
282 Result:=LoadLibraryW(PWideChar(FileName));
283 finally
284 asm
285 FNCLEX
286 FLDCW FPUControlWord
287 end;
288 end;
289 finally
290 SetErrorMode(OldMode);
291 end;
292 end
293 else
294 Result:=SafeLoadLibrary(FileName, ErrorMode);
295 end;
296 {$ENDIF}
297
GetCurrentDirWnull298 function GetCurrentDirW: WideString;
299 {$IFDEF V_WIN}
300 var
301 Sz: DWORD;
302 Buf: TFileBufW;
303 {$ENDIF}
304 begin
305 {$IFDEF V_WIN}
306 if Win32Platform = VER_PLATFORM_WIN32_NT then begin
307 Sz:=GetCurrentDirectoryW(SizeOf(Buf) div 2, Buf);
308 if (Sz > 0) and (Sz < SizeOf(Buf) div 2) then begin
309 SetWideString(Result, Buf, Sz);
310 Exit;
311 end;
312 end;
313 {$ENDIF}
314 Result:=GetCurrentDir;
315 end;
316
SetCurrentDirWnull317 function SetCurrentDirW(const Dir: WideString): Boolean;
318 begin
319 {$IFDEF V_WIN}
320 if Win32Platform = VER_PLATFORM_WIN32_NT then
321 Result:=SetCurrentDirectoryW(PWideChar(Dir))
322 else
323 {$ENDIF}
324 Result:=SetCurrentDir(Dir);
325 end;
326
LastDelimiterWnull327 function LastDelimiterW(const Delimiters, W: WideString): Integer;
328 var
329 L: Integer;
330 P: PWideChar;
331 begin
332 Result:=Length(W);
333 L:=Length(Delimiters);
334 P:=PWideChar(Delimiters);
335 while Result > 0 do begin
336 if (W[Result] <> #0) and (IndexOfValue16(P^, Smallint(W[Result]), L) >= 0) then
337 Exit;
338 Dec(Result);
339 end;
340 end;
341
ChangeFileExtWnull342 function ChangeFileExtW(const FileName, Extension: WideString): WideString;
343 var
344 I: Integer;
345 begin
346 I:=LastDelimiterW('.' + PathDelim + DriveDelim, FileName);
347 if (I = 0) or (FileName[I] <> '.') then
348 I:=MaxInt;
349 Result:=Copy(FileName, 1, I - 1) + Extension;
350 end;
351
ExtractFilePathWnull352 function ExtractFilePathW(const FileName: WideString): WideString;
353 var
354 I: Integer;
355 begin
356 I:=LastDelimiterW(PathDelim + DriveDelim, FileName);
357 Result:=Copy(FileName, 1, I);
358 end;
359
ExtractFileExtWnull360 function ExtractFileExtW(const FileName: WideString): WideString;
361 var
362 I: Integer;
363 begin
364 I:=LastDelimiterW('.' + PathDelim + DriveDelim, FileName);
365 if (I > 0) and (FileName[I] = '.') then
366 Result:=Copy(FileName, I, MaxInt)
367 else
368 Result:='';
369 end;
370
ExtractFileNameWnull371 function ExtractFileNameW(const FileName: WideString): WideString;
372 var
373 I: Integer;
374 begin
375 I:=LastDelimiterW(PathDelim + DriveDelim, FileName);
376 Result:=Copy(FileName, I + 1, MaxInt);
377 end;
378
ExpandFileNameWnull379 function ExpandFileNameW(const FileName: WideString): WideString;
380 {$IFDEF V_WIN}
381 var
382 L: DWORD;
383 LastDot: Boolean;
384 PW: PWideChar;
385 P: PChar;
386 BufW: TFileBufW;
387 Buf: TFileBuf absolute BufW;
388 begin
389 if FileName = '' then begin
390 {$IFNDEF V_AUTOINITSTRINGS}
391 Result:='';
392 {$ENDIF}
393 Exit;
394 end;
395 BufW[0]:=#0;
396 LastDot:=FileName[Length(FileName)] = '.';
397 if Win32Platform = VER_PLATFORM_WIN32_NT then begin
398 L:=GetFullPathNameW(Pointer(FileName), SizeOf(BufW) div 2, BufW, PW);
399 if (L = 0) or (L >= SizeOf(BufW) div 2) then begin
400 Result:=FileName;
401 Exit;
402 end;
403 Result:=LWideString(@BufW, L);
404 end
405 else begin
406 L:=GetFullPathName(PChar(String(FileName)), SizeOf(Buf), @Buf, P);
407 if (L = 0) or (L >= SizeOf(Buf)) then begin
408 Result:=FileName;
409 Exit;
410 end;
411 Result:=WideString(LString(@Buf, L));
412 end;
413 if LastDot then
414 Result:=Result + '.';
415 end;
416 {$ENDIF}
417 {$IFDEF UNIX}
418 begin
419 Result:=ExpandFileName(FileName);
420 end;
421 {$ENDIF}
422
IncludePathDelimiterWnull423 function IncludePathDelimiterW(const S: WideString): WideString;
424 begin
425 Result:=S;
426 if (Result = '') or (Result[Length(Result)] <> PathDelim) then
427 Result:=Result + PathDelim;
428 end;
429
ExcludePathDelimiterWnull430 function ExcludePathDelimiterW(const S: WideString): WideString;
431 var
432 L: Integer;
433 begin
434 Result:=S;
435 L:=Length(Result);
436 if (L > 0) and (Result[L] = PathDelim) then
437 SetLength(Result, L - 1);
438 end;
439
440
441
442 {$IFDEF V_WIN}
443
444 {$ENDIF}
445
ValidateFileNamenull446 function ValidateFileName(const FileName: String; MaxLen: Integer): String;
447 var
448 I: Integer;
449 begin
450 Result:=Copy(FileName, 1, MaxLen);
451 for I:=1 to Length(Result) do
452 if Result[I] in InvalidFileNameChars then
453 Result[I]:='_';
454 end;
455
456 {$IFDEF UNIX}
457
458 {$ENDIF} {LINUX}
459
IsFileNameSyntaxValidnull460 function IsFileNameSyntaxValid(const FileName: WideString): Boolean;
461 var
462 I: Integer;
463 {$IFDEF V_WIN}
464 Path: WideString;
465 {$ENDIF}
466 begin
467 Result:=False;
468 if FileName = '' then
469 Exit;
470 I:=LastDelimiterW(PathDelim + DriveDelim, FileName);
471 if WideContainsChars(Copy(FileName, I + 1, MaxInt), InvalidFileNameChars) then
472 Exit;
473 if I <= 0 then begin
474 Result:=True;
475 Exit;
476 end;
477 {$IFDEF V_WIN}
478 Path:=Copy(FileName, 1, I - 1);
479 if (FileName[I] = DriveDelim) and not IsAbsolutePathSyntaxValid(Path) then
480 Exit;
481 Result:=not WideContainsChars(Path, InvalidFileNameChars - [PathDelim, DriveDelim]);
482 {$ENDIF}
483 {$IFDEF UNIX}
484 Result:=not WideContainsChars(Copy(FileName, 1, I - 1), InvalidFileNameChars -
485 [PathDelim]);
486 {$ENDIF}
487 end;
488
IsAbsolutePathSyntaxValidnull489 function IsAbsolutePathSyntaxValid(const Path: WideString): Boolean;
490 begin
491 {$IFDEF V_WIN}
492 Result:=(Length(Path) >= 2) and
493 (
494 WideCharIn(Path[1], ASCIIAlpha) and (Path[2] = ':') or
495 (Path[1] = '\') and (Path[2] = '\')
496 ) and
497 (WideCharPos(':', Path, 3) = 0);
498 {$ENDIF}
499 {$IFDEF UNIX}
500 Result:=(Path <> '') and (Path[1] = '/');
501 {$ENDIF}
502 end;
503
504
GetTempDirnull505 function GetTempDir: String;
506 {$IFDEF V_WIN}
507 var
508 L: DWORD;
509 Buf: array [0..MAX_PATH] of AnsiChar;
510 {$ENDIF}
511 begin
512 {$IFDEF V_WIN}
513 L:=GetTempPath(SizeOf(Buf), Buf);
514 OSCheck((L > 0) and (L <= High(Buf)));
515 SetString(Result, Buf, L);
516 {$ENDIF}
517 {$IFDEF UNIX}
518 Result:=GetTempDir;
519 if Result = '' then
520 Result:='/tmp/'
521 else
522 if Result[Length(Result)] <> '/' then
523 Result:=Result + '/';
524 {$ENDIF}
525 end;
526
527
528 {$IFDEF V_WIN}
GetTempDirWnull529 function GetTempDirW: WideString;
530 var
531 L: DWORD;
532 Buf: array [0..MAX_PATH] of WideChar;
533 begin
534 if Win32Platform = VER_PLATFORM_WIN32_NT then begin
535 L:=GetTempPathW(SizeOf(Buf) div 2, Buf);
536 OSCheck((L > 0) and (L <= High(Buf)));
537 Result:=WideString(Buf);
538 end
539 else
540 Result:=GetTempDir;
541 end;
542
GetWindowsDirnull543 function GetWindowsDir: String;
544 var
545 L: UINT;
546 Buf: array [0..MAX_PATH] of AnsiChar;
547 begin
548 L:=GetWindowsDirectory(Buf, SizeOf(Buf));
549 OSCheck((L > 0) and (L <= High(Buf)));
550 SetString(Result, Buf, L);
551 end;
552
GetWindowsDirWnull553 function GetWindowsDirW: WideString;
554 var
555 L: UINT;
556 Buf: array [0..MAX_PATH] of WideChar;
557 begin
558 if Win32Platform = VER_PLATFORM_WIN32_NT then begin
559 L:=GetWindowsDirectoryW(Buf, SizeOf(Buf) div 2);
560 OSCheck((L > 0) and (L <= High(Buf)));
561 Result:=WideString(Buf);
562 end
563 else
564 Result:=GetWindowsDir;
565 end;
566
GetSystemDirnull567 function GetSystemDir: String;
568 var
569 L: UINT;
570 Buf: array [0..MAX_PATH] of AnsiChar;
571 begin
572 L:=GetSystemDirectory(Buf, SizeOf(Buf));
573 OSCheck((L > 0) and (L <= High(Buf)));
574 SetString(Result, Buf, L);
575 end;
576
GetSystemDirWnull577 function GetSystemDirW: WideString;
578 var
579 L: UINT;
580 Buf: array [0..MAX_PATH] of WideChar;
581 begin
582 if Win32Platform = VER_PLATFORM_WIN32_NT then begin
583 L:=GetSystemDirectoryW(Buf, SizeOf(Buf) div 2);
584 OSCheck((L > 0) and (L <= High(Buf)));
585 Result:=WideString(Buf);
586 end
587 else
588 Result:=GetSystemDir;
589 end;
590
LockFileReadnull591 function LockFileRead(const FileName: String): THandle;
592 begin
593 Result:=CreateFile(PChar(FileName), GENERIC_READ, 0, nil, OPEN_EXISTING,
594 FILE_FLAG_NO_BUFFERING, 0);
595 end;
596
GetLongFileNamenull597 function GetLongFileName(const Name: String): String;
598
ProcessExpandednull599 function ProcessExpanded(const ExpName: String): String;
600 var
601 I: Integer;
602 S, Path: String;
603 SR: TSearchRec;
604 begin
605 Result:=ExpName;
606 I:=Length(Result);
607 if I > 0 then begin
608 if Result[I] = '\' then begin
609 Dec(I);
610 if (I > 0) and (Result[I] = ':') then
611 Exit;
612 SetLength(Result, I);
613 end
614 else
615 if Result[I] = ':' then
616 Exit;
617 ParseFileName(Result, Path, S);
618 if (CharPos('*', S, 1) = 0) and (CharPos('?', S, 1) = 0) then begin
619 if SysUtils.FindFirst(Result, faAnyFile and not faVolumeID, SR) = 0 then
620 SysUtils.FindClose(SR)
621 else
622 Exit;
623 if SR.Name = '.' then // ������... can happen...
624 Exit;
625 if SysUtils.FindFirst(Path + SR.Name, faAnyFile and not faVolumeID, SR) = 0 then
626 SysUtils.FindClose(SR)
627 else // ���� ������... can happen too...
628 SR.Name:=S;
629 end
630 else
631 SR.Name:=S;
632 if Length(Path) < I then begin
633 if CharPos('~', Path, 1) > 0 then begin
634 Path:=ProcessExpanded(Path);
635 I:=Length(Path);
636 if (I > 0) and (Path[I] <> '\') then
637 Path:=Path + '\';
638 end;
639 Result:=Path + SR.Name;
640 end;
641 end;
642 end;
643
644 begin
645 Result:=Name;
646 if Result <> '' then begin
647 if Result[Length(Result)] = ':' then
648 Result:=Result + '\';
649 Result:=ExpandFileName(Result);
650 if CharPos('~', Result, 1) > 0 then
651 Result:=ProcessExpanded(Result);
652 end;
653 end;
654
655 {$ENDIF}
656
657 {$IFDEF V_DELPHI}{$IFNDEF V_D6}
DirectoryExistsnull658 function DirectoryExists(const Name: String): Boolean;
659 var
660 Code: DWORD;
661 begin
662 Code:=GetFileAttributes(PChar(Name));
663 Result:=(Code <> DWORD(-1)) and (Code and FILE_ATTRIBUTE_DIRECTORY <> 0);
664 end;
665 {$ENDIF}{$ENDIF}
666
667 {$IFDEF V_DELPHI}{$IFNDEF V_D6}
ForceDirectoriesnull668 function ForceDirectories(Dir: String): Boolean;
669 var
670 L: Integer;
671 E: EInOutError;
672 begin
673 Result:=True;
674 if Dir = '' then begin
675 E:=EInOutError.Create(SCreateDirError);
676 E.ErrorCode:=3;
677 raise E;
678 end;
679 L:=Length(Dir);
680 if IsPathDelimiter(Dir, L) then
681 SetLength(Dir, L - 1);
682 {$IFDEF V_WIN}
683 if (Length(Dir) < 3) or DirectoryExists(Dir) or (ExtractFilePath(Dir) = Dir) then
684 Exit; // avoid 'xyz:\' problem.
685 {$ENDIF}
686 {$IFDEF UNIX}
687 if (Dir = '') or DirectoryExists(Dir) then
688 Exit;
689 {$ENDIF}
690 Result:=ForceDirectories(ExtractFilePath(Dir)) and CreateDir(Dir);
691 end;
692 {$ENDIF}{$ENDIF}
693
ExcludeFileExtnull694 function ExcludeFileExt(const Name: String): String;
695 begin
696 Result:=Name;
697 SetLength(Result, Length(Result) - Length(ExtractFileExt(Name)));
698 end;
699
ExcludeFileExtWnull700 function ExcludeFileExtW(const Name: WideString): WideString;
701 begin
702 Result:=Name;
703 SetLength(Result, Length(Result) - Length(ExtractFileExtW(Name)));
704 end;
705
ShortenFileNamenull706 function ShortenFileName(const FileName: String; MaxLen: Integer;
707 DelimitChars: TCharSet): String;
708
709 procedure SetDots(FromIndex: Integer);
710 begin
711 Result[FromIndex]:='.';
712 Result[FromIndex - 1]:='.';
713 Result[FromIndex - 2]:='.';
714 end;
715
716 var
717 I, J, K, L, Len: Integer;
718 B: Boolean;
719 begin
720 Result:=FileName;
721 Len:=Length(Result);
722 if MaxLen < 4 then
723 MaxLen:=4;
724 L:=Len - MaxLen;
725 if L > 0 then begin
726 if DelimitChars = [] then
727 DelimitChars:=[PathDelim];
728 I:=CharInSetPos(DelimitChars, Result, 1);
729 if I > 0 then begin
730 J:=Len;
731 while (J > I) and not (Result[J] in DelimitChars) do Dec(J);
732 K:=J - I - 5; { how many chars in the "middle" can we delete }
733 if K > 0 then begin
734 if K >= L then begin
735 K:=L;
736 B:=True;
737 end
738 else
739 B:=False;
740 Dec(J, K);
741 Delete(Result, J, K);
742 SetDots(J - 1);
743 if B then
744 Exit;
745 end;
746 end;
747 SetLength(Result, MaxLen);
748 SetDots(MaxLen);
749 end;
750 end;
751
ShortenFileNameWnull752 function ShortenFileNameW(const FileName: WideString; MaxLen: Integer;
753 DelimitChars: TCharSet): WideString;
754
755 procedure SetDots(FromIndex: Integer);
756 begin
757 Result[FromIndex]:='.';
758 Result[FromIndex - 1]:='.';
759 Result[FromIndex - 2]:='.';
760 end;
761
762 var
763 I, J, K, L, Len: Integer;
764 B: Boolean;
765 begin
766 Result:=FileName;
767 Len:=Length(Result);
768 if MaxLen < 4 then
769 MaxLen:=4;
770 L:=Len - MaxLen;
771 if L > 0 then begin
772 if DelimitChars = [] then
773 DelimitChars:=[PathDelim];
774 I:=WideCharInSetPos(DelimitChars, Result, 1);
775 if I > 0 then begin
776 J:=Len;
777 while (J > I) and (Result[J] < #256) and
778 not (AnsiChar(Result[J]) in DelimitChars)
779 do
780 Dec(J);
781 K:=J - I - 5; { how many chars in the "middle" can we delete }
782 if K > 0 then begin
783 if K >= L then begin
784 K:=L;
785 B:=True;
786 end
787 else
788 B:=False;
789 Dec(J, K);
790 Delete(Result, J, K);
791 SetDots(J - 1);
792 if B then
793 Exit;
794 end;
795 end;
796 SetLength(Result, MaxLen);
797 SetDots(MaxLen);
798 end;
799 end;
800
GetModuleNameWnull801 function GetModuleNameW(Module: HMODULE): WideString;
802 begin
803 {$IFDEF V_WIN}
804 if Win32Platform = VER_PLATFORM_WIN32_NT then begin
805 SetLength(Result, MAX_PATH);
806 SetLength(Result, GetModuleFileNameW(Module, Pointer(Result), MAX_PATH));
807 end
808 else
809 {$ENDIF}
810 Result:=GetModuleName(Module);
811 end;
812
813 procedure ParseFileName(const FileName: String; var Path, Name: String);
814 var
815 I: Integer;
816 begin
817 I:=LastDelimiter(PathDelim + DriveDelim, FileName);
818 Path:=Copy(FileName, 1, I);
819 Name:=Copy(FileName, I + 1, MaxInt);
820 end;
821
822 procedure ParseFileNameW(const FileName: WideString; var Path, Name: WideString);
823 var
824 I: Integer;
825 begin
826 I:=LastDelimiterW(PathDelim + DriveDelim, FileName);
827 Path:=Copy(FileName, 1, I);
828 Name:=Copy(FileName, I + 1, MaxInt);
829 end;
830
FirstItemDelimiterWnull831 function FirstItemDelimiterW(const Path: WideString): Integer;
832 var
833 I: Integer;
834 begin
835 for I:=1 to Length(Path) do
836 if (Path[I] = PathDelim) or (Path[I] = '|') then begin
837 Result:=I;
838 Exit;
839 end;
840 Result:=0;
841 end;
842
LastItemDelimiterWnull843 function LastItemDelimiterW(const Path: WideString): Integer;
844 var
845 I: Integer;
846 begin
847 for I:=Length(Path) downto 1 do
848 if (Path[I] = PathDelim) or (Path[I] = '|') then begin
849 Result:=I;
850 Exit;
851 end;
852 Result:=0;
853 end;
854
855 const
856 ItemDelimiters = '|' + PathDelim + DriveDelim;
857
858 procedure ParseItemName(const FullItemName: String; var Path, Name: String);
859 var
860 I: Integer;
861 begin
862 I:=LastDelimiter(ItemDelimiters, FullItemName);
863 Path:=Copy(FullItemName, 1, I - 1);
864 Name:=Copy(FullItemName, I + 1, MaxInt);
865 end;
866
867 procedure ParseItemNameW(const FullItemName: WideString; var Path, Name: WideString);
868 var
869 I: Integer;
870 begin
871 I:=LastDelimiterW(ItemDelimiters, FullItemName);
872 Path:=Copy(FullItemName, 1, I - 1);
873 Name:=Copy(FullItemName, I + 1, MaxInt);
874 end;
875
GetItemNameWnull876 function GetItemNameW(const FullItemName: WideString): WideString;
877 begin
878 Result:=Copy(FullItemName, LastDelimiterW(ItemDelimiters, FullItemName) + 1, MaxInt);
879 end;
880
GetItemPathWnull881 function GetItemPathW(const FullItemName: WideString): WideString;
882 begin
883 Result:=Copy(FullItemName, 1, LastDelimiterW(ItemDelimiters, FullItemName) - 1);
884 end;
885
CorrectFilePathNamenull886 function CorrectFilePathName(const Name: String; DefaultChar: AnsiChar;
887 ProhibitedChars: TCharSet): String;
888 var
889 I: Integer;
890 C: AnsiChar;
891 begin
892 Result:=Name;
893 for I:=1 to Length(Name) do begin
894 C:=Name[I];
895 if C < #32 then
896 Result[I]:=DefaultChar
897 else if C in ProhibitedChars then begin
898 {$IFDEF V_WIN}
899 Case C of
900 '"': C:='''';
901 '<': C:=#$AB;
902 '>': C:=#$BB;
903 '|': C:=#$A6;
904 Else
905 C:=DefaultChar;
906 End;
907 Result[I]:=C;
908 {$ENDIF}
909 {$IFDEF UNIX}
910 Result[I]:=DefaultChar;
911 {$ENDIF}
912 end;
913 end; {for}
914 end;
915
CorrectFilePathNameWnull916 function CorrectFilePathNameW(const Name: WideString; DefaultChar: WideChar;
917 ProhibitedChars: TCharSet): WideString;
918 var
919 I: Integer;
920 W: WideChar;
921 begin
922 Result:=Name;
923 for I:=1 to Length(Name) do begin
924 W:=Name[I];
925 if W < #32 then
926 Result[I]:=DefaultChar
927 else if (W < #256) and (AnsiChar(W) in ProhibitedChars) then begin
928 {$IFDEF V_WIN}
929 Case AnsiChar(W) of
930 '"': W:='''';
931 '<': W:=#$AB;
932 '>': W:=#$BB;
933 '|': W:=#$A6;
934 Else
935 W:=DefaultChar;
936 End;
937 Result[I]:=W;
938 {$ENDIF}
939 {$IFDEF UNIX}
940 Result[I]:=DefaultChar;
941 {$ENDIF}
942 end;
943 end; {for}
944 end;
945
CorrectFileNamenull946 function CorrectFileName(const Name: String; DefaultChar: AnsiChar): String;
947 begin
948 Result:=CorrectFilePathName(Name, DefaultChar, InvalidFileNameChars);
949 end;
950
CorrectFileNameWnull951 function CorrectFileNameW(const Name: WideString; DefaultChar: WideChar): WideString;
952 begin
953 Result:=CorrectFilePathNameW(Name, DefaultChar, InvalidFileNameChars);
954 end;
955
CorrectPathNamenull956 function CorrectPathName(const Name: String; DefaultChar: AnsiChar): String;
957 begin
958 Result:=CorrectFilePathName(Name, DefaultChar, InvalidFileNameChars - [PathDelim]);
959 end;
960
CorrectPathNameWnull961 function CorrectPathNameW(const Name: WideString; DefaultChar: WideChar): WideString;
962 begin
963 Result:=CorrectFilePathNameW(Name, DefaultChar, InvalidFileNameChars - [PathDelim]);
964 end;
965
GetStdFileExtnull966 function GetStdFileExt(const FileName: String): String;
967 begin
968 Result:=AnsiLowerCase(Copy(ExtractFileExt(FileName), 2, MaxInt));
969 end;
970
971 {$IFDEF V_WIN}
972
973 {$ENDIF}
974
975 {$IFDEF UNIX}
976
977 {$ENDIF} {LINUX}
978
979 {$IFDEF V_WIN}
980 type
981 TReadFileSize =
982 {$IFDEF V_D3}{$IFNDEF V_D4}Integer{$ELSE}DWORD{$ENDIF}{$ELSE}DWORD{$ENDIF};
983 {$ENDIF}
984
985
IsRelativePathnull986 function IsRelativePath(const FileName: String): Boolean;
987 begin
988 {$IFDEF V_WIN}
989 Result:=(Length(FileName) > 1) and (FileName[2] <> ':');
990 {$ENDIF}
991 {$IFDEF UNIX}
992 Result:=(FileName <> '') and not (FileName[1] in [PathDelim, '~', '$']);
993 {$ENDIF}
994 end;
995
996 end.
997