123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858 |
- {
- This file is part of the Free Pascal run time library.
- Copyright (c) 1999-2004 by the Free Pascal development team.
- Dos unit for BP7 compatible RTL
- See the file COPYING.FPC, included in this distribution,
- for details about the copyright.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- **********************************************************************}
- unit dos;
- interface
- Const
- Max_Path = 260;
- Type
- PWinFileTime = ^TWinFileTime;
- TWinFileTime = record
- dwLowDateTime,
- dwHighDateTime : DWORD;
- end;
- PWinFindData = ^TWinFindData;
- TWinFindData = record
- dwFileAttributes: DWORD;
- ftCreationTime: TWinFileTime;
- ftLastAccessTime: TWinFileTime;
- ftLastWriteTime: TWinFileTime;
- nFileSizeHigh: DWORD;
- nFileSizeLow: DWORD;
- dwReserved0: DWORD;
- dwReserved1: DWORD;
- cFileName: array[0..MAX_PATH-1] of Char;
- cAlternateFileName: array[0..15] of Char;
- // The structure should be 320 bytes long...
- pad : system.integer;
- end;
- Searchrec = Record
- FindHandle : THandle;
- WinFindData : TWinFindData;
- ExcludeAttr : longint;
- time : longint;
- size : longint;
- attr : longint;
- name : string;
- end;
- {$i dosh.inc}
- Const
- { allow EXEC to inherited handles from calling process,
- needed for FPREDIR in ide/text
- now set to true by default because
- other OS also pass open handles to childs
- finally reset to false after Florian's response PM }
- ExecInheritsHandles : Longbool = false;
- implementation
- uses
- strings;
- {$DEFINE HAS_GETMSCOUNT}
- {$DEFINE HAS_GETSHORTNAME}
- {$DEFINE HAS_GETLONGNAME}
- {$DEFINE FPC_FEXPAND_UNC} (* UNC paths are supported *)
- {$DEFINE FPC_FEXPAND_DRIVES} (* Full paths begin with drive specification *)
- {$I dos.inc}
- const
- INVALID_HANDLE_VALUE = THandle(-1);
- VER_PLATFORM_WIN32s = 0;
- VER_PLATFORM_WIN32_WINDOWS = 1;
- VER_PLATFORM_WIN32_NT = 2;
- type
- OSVERSIONINFO = record
- dwOSVersionInfoSize : DWORD;
- dwMajorVersion : DWORD;
- dwMinorVersion : DWORD;
- dwBuildNumber : DWORD;
- dwPlatformId : DWORD;
- szCSDVersion : array[0..127] of char;
- end;
- var
- kernel32dll : THandle;
- {******************************************************************************
- --- Conversion ---
- ******************************************************************************}
- function GetLastError : DWORD;
- stdcall; external 'kernel32' name 'GetLastError';
- function FileTimeToDosDateTime(const ft :TWinFileTime;var data,time : word) : longbool;
- stdcall; external 'kernel32' name 'FileTimeToDosDateTime';
- function DosDateTimeToFileTime(date,time : word;var ft :TWinFileTime) : longbool;
- stdcall; external 'kernel32' name 'DosDateTimeToFileTime';
- function FileTimeToLocalFileTime(const ft : TWinFileTime;var lft : TWinFileTime) : longbool;
- stdcall; external 'kernel32' name 'FileTimeToLocalFileTime';
- function LocalFileTimeToFileTime(const lft : TWinFileTime;var ft : TWinFileTime) : longbool;
- stdcall; external 'kernel32' name 'LocalFileTimeToFileTime';
- function GetTickCount : longint;
- stdcall;external 'kernel32' name 'GetTickCount';
- function GetMsCount: int64;
- begin
- GetMsCount := cardinal (GetTickCount);
- end;
- type
- Longrec=packed record
- lo,hi : word;
- end;
- function Last2DosError(d:dword):integer;
- begin
- case d of
- 87 : { Parameter invalid -> Data invalid }
- Last2DosError:=13;
- else
- Last2DosError:=d;
- end;
- end;
- Function DosToWinAttr (Const Attr : Longint) : longint;
- begin
- DosToWinAttr:=Attr;
- end;
- Function WinToDosAttr (Const Attr : Longint) : longint;
- begin
- WinToDosAttr:=Attr;
- end;
- Function DosToWinTime (DTime:longint;Var Wtime : TWinFileTime):longbool;
- var
- lft : TWinFileTime;
- begin
- DosToWinTime:=DosDateTimeToFileTime(longrec(dtime).hi,longrec(dtime).lo,lft) and
- LocalFileTimeToFileTime(lft,Wtime);
- end;
- Function WinToDosTime (Const Wtime : TWinFileTime;var DTime:longint):longbool;
- var
- lft : TWinFileTime;
- begin
- WinToDosTime:=FileTimeToLocalFileTime(WTime,lft) and
- FileTimeToDosDateTime(lft,longrec(dtime).hi,longrec(dtime).lo);
- end;
- {******************************************************************************
- --- Info / Date / Time ---
- ******************************************************************************}
- type
- TSystemTime = record
- wYear,
- wMonth,
- wDayOfWeek,
- wDay,
- wHour,
- wMinute,
- wSecond,
- wMilliseconds: Word;
- end;
- function GetVersion : longint;
- stdcall; external 'kernel32' name 'GetVersion';
- procedure GetLocalTime(var t : TSystemTime);
- stdcall; external 'kernel32' name 'GetLocalTime';
- function SetLocalTime(const t : TSystemTime) : longbool;
- stdcall; external 'kernel32' name 'SetLocalTime';
- function dosversion : word;
- begin
- dosversion:=GetVersion and $ffff;
- end;
- procedure getdate(var year,month,mday,wday : word);
- var
- t : TSystemTime;
- begin
- GetLocalTime(t);
- year:=t.wYear;
- month:=t.wMonth;
- mday:=t.wDay;
- wday:=t.wDayOfWeek;
- end;
- procedure setdate(year,month,day : word);
- var
- t : TSystemTime;
- begin
- { we need the time set privilege }
- { so this function crash currently }
- {!!!!!}
- GetLocalTime(t);
- t.wYear:=year;
- t.wMonth:=month;
- t.wDay:=day;
- { only a quite good solution, we can loose some ms }
- SetLocalTime(t);
- end;
- procedure gettime(var hour,minute,second,sec100 : word);
- var
- t : TSystemTime;
- begin
- GetLocalTime(t);
- hour:=t.wHour;
- minute:=t.wMinute;
- second:=t.wSecond;
- sec100:=t.wMilliSeconds div 10;
- end;
- procedure settime(hour,minute,second,sec100 : word);
- var
- t : TSystemTime;
- begin
- { we need the time set privilege }
- { so this function crash currently }
- {!!!!!}
- GetLocalTime(t);
- t.wHour:=hour;
- t.wMinute:=minute;
- t.wSecond:=second;
- t.wMilliSeconds:=sec100*10;
- SetLocalTime(t);
- end;
- {******************************************************************************
- --- Exec ---
- ******************************************************************************}
- type
- PProcessInformation = ^TProcessInformation;
- TProcessInformation = record
- hProcess: THandle;
- hThread: THandle;
- dwProcessId: DWORD;
- dwThreadId: DWORD;
- end;
- function CreateProcess(lpApplicationName: PChar; lpCommandLine: PChar;
- lpProcessAttributes, lpThreadAttributes: Pointer;
- bInheritHandles: Longbool; dwCreationFlags: DWORD; lpEnvironment: Pointer;
- lpCurrentDirectory: PChar; const lpStartupInfo: TStartupInfo;
- var lpProcessInformation: TProcessInformation): longbool;
- stdcall; external 'kernel32' name 'CreateProcessA';
- function getExitCodeProcess(h:THandle;var code:longint):longbool;
- stdcall; external 'kernel32' name 'GetExitCodeProcess';
- function WaitForSingleObject(hHandle: THandle; dwMilliseconds: DWORD): DWORD;
- stdcall; external 'kernel32' name 'WaitForSingleObject';
- function CloseHandle(h : THandle) : longint;
- stdcall; external 'kernel32' name 'CloseHandle';
- procedure exec(const path : pathstr;const comline : comstr);
- var
- SI: TStartupInfo;
- PI: TProcessInformation;
- l : Longint;
- { Maximum length of both short string is
- 2x255 = 510, plus possibly two double-quotes,
- two spaces and the final #0, makes 515 chars }
- CommandLine : array[0..515] of char;
- has_no_double_quote : boolean;
- begin
- DosError:=0;
- FillChar(SI, SizeOf(SI), 0);
- SI.cb:=SizeOf(SI);
- SI.wShowWindow:=1;
- { always surround the name of the application by quotes
- so that long filenames will always be accepted. But don't
- do it if there are already double quotes, since Win32 does not
- like double quotes which are duplicated!
- }
- has_no_double_quote:=pos('"',path)=0;
- if has_no_double_quote then
- begin
- CommandLine[0]:='"';
- l:=1;
- end
- else
- l:=0;
- Move(Path[1],CommandLine[l],length(Path));
- l:=l+length(Path);
- if has_no_double_quote then
- begin
- CommandLine[l]:='"';
- inc(l);
- end;
- { Add two spaces }
- CommandLine[l]:=' ';
- inc(l);
- CommandLine[l]:=' ';
- inc(l);
- { Add comline string }
- Move(ComLine[1],CommandLine[l],length(Comline));
- l:=l+length(ComLine);
- { Terminate string }
- CommandLine[l]:=#0;
- if not CreateProcess(nil, PChar(@CommandLine),
- Nil, Nil, ExecInheritsHandles,$20, Nil, Nil, SI, PI) then
- begin
- DosError:=Last2DosError(GetLastError);
- exit;
- end;
- if WaitForSingleObject(PI.hProcess,dword($ffffffff))<>$ffffffff then
- GetExitCodeProcess(PI.hProcess,l)
- else
- l:=-1;
- CloseHandle(PI.hProcess);
- CloseHandle(PI.hThread);
- LastDosExitCode:=l;
- end;
- {******************************************************************************
- --- Disk ---
- ******************************************************************************}
- function GetDiskFreeSpace(drive:pchar;var sector_cluster,bytes_sector,
- freeclusters,totalclusters:DWORD):longbool;
- stdcall; external 'kernel32' name 'GetDiskFreeSpaceA';
- type
- TGetDiskFreeSpaceEx = function(drive:pchar;var availableforcaller,
- total,free):longbool;stdcall;
- var
- GetDiskFreeSpaceEx : TGetDiskFreeSpaceEx;
- function diskfree(drive : byte) : int64;
- var
- disk : array[1..4] of char;
- secs,bytes,
- free,total : DWORD;
- qwtotal,qwfree,qwcaller : int64;
- begin
- if drive=0 then
- begin
- disk[1]:='\';
- disk[2]:=#0;
- end
- else
- begin
- disk[1]:=chr(drive+64);
- disk[2]:=':';
- disk[3]:='\';
- disk[4]:=#0;
- end;
- if assigned(GetDiskFreeSpaceEx) then
- begin
- if GetDiskFreeSpaceEx(@disk,qwcaller,qwtotal,qwfree) then
- diskfree:=qwfree
- else
- diskfree:=-1;
- end
- else
- begin
- if GetDiskFreeSpace(@disk,secs,bytes,free,total) then
- diskfree:=int64(free)*secs*bytes
- else
- diskfree:=-1;
- end;
- end;
- function disksize(drive : byte) : int64;
- var
- disk : array[1..4] of char;
- secs,bytes,
- free,total : DWORD;
- qwtotal,qwfree,qwcaller : int64;
- begin
- if drive=0 then
- begin
- disk[1]:='\';
- disk[2]:=#0;
- end
- else
- begin
- disk[1]:=chr(drive+64);
- disk[2]:=':';
- disk[3]:='\';
- disk[4]:=#0;
- end;
- if assigned(GetDiskFreeSpaceEx) then
- begin
- if GetDiskFreeSpaceEx(@disk,qwcaller,qwtotal,qwfree) then
- disksize:=qwtotal
- else
- disksize:=-1;
- end
- else
- begin
- if GetDiskFreeSpace(@disk,secs,bytes,free,total) then
- disksize:=int64(total)*secs*bytes
- else
- disksize:=-1;
- end;
- end;
- {******************************************************************************
- --- Findfirst FindNext ---
- ******************************************************************************}
- { Needed kernel calls }
- function FindFirstFile (lpFileName: PChar; var lpFindFileData: TWinFindData): THandle;
- stdcall; external 'kernel32' name 'FindFirstFileA';
- function FindNextFile (hFindFile: THandle; var lpFindFileData: TWinFindData): LongBool;
- stdcall; external 'kernel32' name 'FindNextFileA';
- function FindCloseFile (hFindFile: THandle): LongBool;
- stdcall; external 'kernel32' name 'FindClose';
- Procedure StringToPchar (Var S : String);
- Var L : Longint;
- begin
- L:=ord(S[0]);
- Move (S[1],S[0],L);
- S[L]:=#0;
- end;
- Procedure PCharToString (Var S : String);
- Var L : Longint;
- begin
- L:=strlen(pchar(@S[0]));
- Move (S[0],S[1],L);
- S[0]:=char(l);
- end;
- procedure FindMatch(var f:searchrec);
- begin
- { Find file with correct attribute }
- While (F.WinFindData.dwFileAttributes and DWORD(F.ExcludeAttr))<>0 do
- begin
- if not FindNextFile (F.FindHandle,F.WinFindData) then
- begin
- DosError:=Last2DosError(GetLastError);
- if DosError=2 then
- DosError:=18;
- exit;
- end;
- end;
- { Convert some attributes back }
- f.size:=F.WinFindData.NFileSizeLow;
- f.attr:=WinToDosAttr(F.WinFindData.dwFileAttributes);
- WinToDosTime(F.WinFindData.ftLastWriteTime,f.Time);
- f.Name:=StrPas(@F.WinFindData.cFileName);
- end;
- procedure findfirst(const path : pathstr;attr : word;var f : searchRec);
- begin
- fillchar(f,sizeof(f),0);
- { no error }
- doserror:=0;
- F.Name:=Path;
- F.Attr:=attr;
- F.ExcludeAttr:=(not Attr) and ($1e); {hidden,sys,dir,volume}
- StringToPchar(f.name);
- { FindFirstFile is a Win32 Call }
- F.WinFindData.dwFileAttributes:=DosToWinAttr(f.attr);
- F.FindHandle:=FindFirstFile (pchar(@f.Name),F.WinFindData);
- If F.FindHandle=Invalid_Handle_value then
- begin
- DosError:=Last2DosError(GetLastError);
- if DosError=2 then
- DosError:=18;
- exit;
- end;
- { Find file with correct attribute }
- FindMatch(f);
- end;
- procedure findnext(var f : searchRec);
- begin
- { no error }
- doserror:=0;
- if not FindNextFile (F.FindHandle,F.WinFindData) then
- begin
- DosError:=Last2DosError(GetLastError);
- if DosError=2 then
- DosError:=18;
- exit;
- end;
- { Find file with correct attribute }
- FindMatch(f);
- end;
- Procedure FindClose(Var f: SearchRec);
- begin
- If F.FindHandle<>Invalid_Handle_value then
- FindCloseFile(F.FindHandle);
- end;
- {******************************************************************************
- --- File ---
- ******************************************************************************}
- function GetWinFileTime(h : longint;creation,lastaccess,lastwrite : PWinFileTime) : longbool;
- stdcall; external 'kernel32' name 'GetFileTime';
- function SetWinFileTime(h : longint;creation,lastaccess,lastwrite : PWinFileTime) : longbool;
- stdcall; external 'kernel32' name 'SetFileTime';
- function SetFileAttributes(lpFileName : pchar;dwFileAttributes : longint) : longbool;
- stdcall; external 'kernel32' name 'SetFileAttributesA';
- function GetFileAttributes(lpFileName : pchar) : longint;
- stdcall; external 'kernel32' name 'GetFileAttributesA';
- { <immobilizer> }
- function GetFullPathName(lpFileName: PChar; nBufferLength: Longint; lpBuffer: PChar; var lpFilePart : PChar):DWORD;
- stdcall; external 'kernel32' name 'GetFullPathNameA';
- function GetShortPathName(lpszLongPath:pchar; lpszShortPath:pchar; cchBuffer:DWORD):DWORD;
- stdcall; external 'kernel32' name 'GetShortPathNameA';
- Function FSearch(path: pathstr; dirlist: string): pathstr;
- var
- p1 : longint;
- s : searchrec;
- newdir : pathstr;
- begin
- { No wildcards allowed in these things }
- if (pos('?',path)<>0) or (pos('*',path)<>0) then
- begin
- fsearch:='';
- exit;
- end;
- { check if the file specified exists }
- findfirst(path,anyfile and not(directory),s);
- if doserror=0 then
- begin
- findclose(s);
- fsearch:=path;
- exit;
- end;
- findclose(s);
- { allow slash as backslash }
- DoDirSeparators(dirlist);
- repeat
- p1:=pos(';',dirlist);
- if p1<>0 then
- begin
- newdir:=copy(dirlist,1,p1-1);
- delete(dirlist,1,p1);
- end
- else
- begin
- newdir:=dirlist;
- dirlist:='';
- end;
- if (newdir<>'') and (not (newdir[length(newdir)] in [DirectorySeparator,DriveSeparator])) then
- newdir:=newdir+DirectorySeparator;
- findfirst(newdir+path,anyfile and not(directory),s);
- if doserror=0 then
- newdir:=newdir+path
- else
- newdir:='';
- findclose(s);
- until (dirlist='') or (newdir<>'');
- fsearch:=newdir;
- end;
- procedure getftime(var f;var time : longint);
- var
- ft : TWinFileTime;
- begin
- doserror:=0;
- if GetWinFileTime(filerec(f).Handle,nil,nil,@ft) and
- WinToDosTime(ft,time) then
- exit
- else
- begin
- DosError:=Last2DosError(GetLastError);
- time:=0;
- end;
- end;
- procedure setftime(var f;time : longint);
- var
- ft : TWinFileTime;
- begin
- doserror:=0;
- if DosToWinTime(time,ft) and
- SetWinFileTime(filerec(f).Handle,nil,nil,@ft) then
- exit
- else
- DosError:=Last2DosError(GetLastError);
- end;
- procedure getfattr(var f;var attr : word);
- var
- l : longint;
- s : RawByteString;
- begin
- doserror:=0;
- s:=ToSingleByteFileSystemEncodedFileName(filerec(f).name);
- l:=GetFileAttributes(pchar(s));
- if l=longint($ffffffff) then
- begin
- doserror:=getlasterror;
- attr:=0;
- end
- else
- attr:=l and $ffff;
- end;
- procedure setfattr(var f;attr : word);
- var s : RawByteString;
- begin
- { Fail for setting VolumeId }
- if (attr and VolumeID)<>0 then
- doserror:=5
- else
- begin
- s:=ToSingleByteFileSystemEncodedFileName(filerec(f).name);
- if SetFileAttributes(pchar(s),attr) then
- doserror:=0
- else
- doserror:=getlasterror;
- end;
- end;
- { change to short filename if successful win32 call PM }
- function GetShortName(var p : String) : boolean;
- var
- buffer : array[0..255] of char;
- ret : longint;
- begin
- {we can't mess with p, because we have to return it if call is
- unsuccesfully.}
- if Length(p)>0 then {copy p to array of char}
- move(p[1],buffer[0],length(p));
- buffer[length(p)]:=chr(0);
- {Should return value load loaddoserror?}
- ret:=GetShortPathName(@buffer,@buffer,255);
- if (Ret > 0) and (Ret <= 255) then
- begin
- Move (Buffer, P [1], Ret);
- byte (P [0]) := Ret;
- GetShortName := true;
- end
- else
- GetShortName := false;
- end;
- { change to long filename if successful DOS call PM }
- function GetLongName(var p : String) : boolean;
- var
- SR: SearchRec;
- FullFN, FinalFN, TestFN: string;
- Found: boolean;
- SPos: byte;
- begin
- if Length (P) = 0 then
- GetLongName := false
- else
- begin
- FullFN := FExpand (P); (* Needed to be done at the beginning to get proper case for all parts *)
- SPos := 1;
- if (Length (FullFN) > 2) then
- if (FullFN [2] = DriveSeparator) then
- SPos := 4
- else
- if (FullFN [1] = DirectorySeparator) and (FullFN [2] = DirectorySeparator) then
- begin
- SPos := 3;
- while (Length (FullFN) > SPos) and (FullFN [SPos] <> DirectorySeparator) do
- Inc (SPos);
- if SPos >= Length (FullFN) then
- SPos := 1
- else
- begin
- Inc (SPos);
- while (Length (FullFN) >= SPos) and (FullFN [SPos] <> DirectorySeparator) do
- Inc (SPos);
- if SPos <= Length (FullFN) then
- Inc (SPos);
- end;
- end;
- FinalFN := Copy (FullFN, 1, Pred (SPos));
- Delete (FullFN, 1, Pred (SPos));
- Found := true;
- while (FullFN <> '') and Found do
- begin
- SPos := Pos (DirectorySeparator, FullFN);
- TestFN := Copy (FullFN, 1, Pred (SPos));
- Delete (FullFN, 1, Pred (SPos));
- FindFirst (FinalFN + TestFN, AnyFile, SR);
- if DosError <> 0 then
- Found := false
- else
- begin
- FinalFN := FinalFN + SR.Name;
- if (FullFN <> '') and (FullFN [1] = DirectorySeparator) then
- begin
- FinalFN := FinalFN + DirectorySeparator;
- Delete (FullFN, 1, 1);
- end;
- end;
- FindClose (SR);
- end;
- if Found then
- begin
- GetLongName := true;
- P := FinalFN;
- end
- else
- GetLongName := false
- end;
- end;
- {******************************************************************************
- --- Environment ---
- ******************************************************************************}
- {
- The environment is a block of zero terminated strings
- terminated by a #0
- }
- function GetEnvironmentStrings : pchar;
- stdcall; external 'kernel32' name 'GetEnvironmentStringsA';
- function FreeEnvironmentStrings(p : pchar) : longbool;
- stdcall; external 'kernel32' name 'FreeEnvironmentStringsA';
- {$push}
- { GetEnvironmentStrings cannot be checked by CheckPointer function }
- {$checkpointer off}
- function envcount : longint;
- var
- hp,p : pchar;
- count : longint;
- begin
- p:=GetEnvironmentStrings;
- hp:=p;
- count:=0;
- while hp^<>#0 do
- begin
- { next string entry}
- hp:=hp+strlen(hp)+1;
- inc(count);
- end;
- FreeEnvironmentStrings(p);
- envcount:=count;
- end;
- Function EnvStr (Index: longint): string;
- var
- hp,p : pchar;
- count,i : longint;
- begin
- { envcount takes some time in win32 }
- count:=envcount;
- { range checking }
- if (index<=0) or (index>count) then
- begin
- envstr:='';
- exit;
- end;
- p:=GetEnvironmentStrings;
- hp:=p;
- { retrive the string with the given index }
- for i:=2 to index do
- hp:=hp+strlen(hp)+1;
- envstr:=strpas(hp);
- FreeEnvironmentStrings(p);
- end;
- Function GetEnv(envvar: string): string;
- var
- s : string;
- i : longint;
- hp,p : pchar;
- begin
- getenv:='';
- p:=GetEnvironmentStrings;
- hp:=p;
- while hp^<>#0 do
- begin
- s:=strpas(hp);
- i:=pos('=',s);
- if upcase(copy(s,1,i-1))=upcase(envvar) then
- begin
- { getenv:=copy(s,i+1,length(s)-i);
- this limits the size to 255-(i+1) }
- getenv:=strpas(hp+i);
- break;
- end;
- { next string entry}
- hp:=hp+strlen(hp)+1;
- end;
- FreeEnvironmentStrings(p);
- end;
- {$pop}
- function GetModuleHandle(p : PChar) : PtrUInt;
- stdcall; external 'kernel32' name 'GetModuleHandleA';
- function GetVersionEx(var VersionInformation:OSVERSIONINFO) : longbool;
- stdcall; external 'kernel32' name 'GetVersionExA';
- function GetProcAddress(hModule : THandle;lpProcName : pchar) : pointer;
- stdcall; external 'kernel32' name 'GetProcAddress';
- begin
- GetDiskFreeSpaceEx:=nil;
- kernel32dll:=GetModuleHandle('kernel32');
- if kernel32dll<>0 then
- GetDiskFreeSpaceEx:=TGetDiskFreeSpaceEx(GetProcAddress(kernel32dll,'GetDiskFreeSpaceExA'));
- end.
|