dos.pp 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813
  1. {
  2. This file is part of the Free Pascal run time library.
  3. Copyright (c) 1999-2004 by the Free Pascal development team.
  4. Dos unit for BP7 compatible RTL
  5. See the file COPYING.FPC, included in this distribution,
  6. for details about the copyright.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10. **********************************************************************}
  11. unit dos;
  12. interface
  13. Const
  14. Max_Path = 260;
  15. Type
  16. TWin32Handle = longint;
  17. PWin32FileTime = ^TWin32FileTime;
  18. TWin32FileTime = record
  19. dwLowDateTime,
  20. dwHighDateTime : DWORD;
  21. end;
  22. PWin32FindData = ^TWin32FindData;
  23. TWin32FindData = record
  24. dwFileAttributes: Cardinal;
  25. ftCreationTime: TWin32FileTime;
  26. ftLastAccessTime: TWin32FileTime;
  27. ftLastWriteTime: TWin32FileTime;
  28. nFileSizeHigh: Cardinal;
  29. nFileSizeLow: Cardinal;
  30. dwReserved0: Cardinal;
  31. dwReserved1: Cardinal;
  32. cFileName: array[0..MAX_PATH - 1] of Char;
  33. cAlternateFileName: array[0..13] of Char;
  34. // The structure should be 320 bytes long...
  35. pad : system.integer;
  36. end;
  37. Searchrec = Packed Record
  38. FindHandle : TWin32Handle;
  39. W32FindData : TWin32FindData;
  40. ExcludeAttr : longint;
  41. time : longint;
  42. size : longint;
  43. attr : longint;
  44. name : string;
  45. end;
  46. {$i dosh.inc}
  47. Const
  48. { allow EXEC to inherited handles from calling process,
  49. needed for FPREDIR in ide/text
  50. now set to true by default because
  51. other OS also pass open handles to childs
  52. finally reset to false after Florian's response PM }
  53. ExecInheritsHandles : Longbool = false;
  54. implementation
  55. uses
  56. strings;
  57. {$DEFINE HAS_GETMSCOUNT}
  58. {$DEFINE HAS_GETSHORTNAME}
  59. {$DEFINE HAS_GETLONGNAME}
  60. {$DEFINE FPC_FEXPAND_UNC} (* UNC paths are supported *)
  61. {$DEFINE FPC_FEXPAND_DRIVES} (* Full paths begin with drive specification *)
  62. {$I dos.inc}
  63. const
  64. INVALID_HANDLE_VALUE = longint($ffffffff);
  65. VER_PLATFORM_WIN32s = 0;
  66. VER_PLATFORM_WIN32_WINDOWS = 1;
  67. VER_PLATFORM_WIN32_NT = 2;
  68. type
  69. OSVERSIONINFO = record
  70. dwOSVersionInfoSize : DWORD;
  71. dwMajorVersion : DWORD;
  72. dwMinorVersion : DWORD;
  73. dwBuildNumber : DWORD;
  74. dwPlatformId : DWORD;
  75. szCSDVersion : array[0..127] of char;
  76. end;
  77. var
  78. versioninfo : OSVERSIONINFO;
  79. kernel32dll : TWin32Handle;
  80. {******************************************************************************
  81. --- Conversion ---
  82. ******************************************************************************}
  83. function GetLastError : DWORD;
  84. stdcall; external 'kernel32' name 'GetLastError';
  85. function FileTimeToDosDateTime(const ft :TWin32FileTime;var data,time : word) : longbool;
  86. stdcall; external 'kernel32' name 'FileTimeToDosDateTime';
  87. function DosDateTimeToFileTime(date,time : word;var ft :TWin32FileTime) : longbool;
  88. stdcall; external 'kernel32' name 'DosDateTimeToFileTime';
  89. function FileTimeToLocalFileTime(const ft : TWin32FileTime;var lft : TWin32FileTime) : longbool;
  90. stdcall; external 'kernel32' name 'FileTimeToLocalFileTime';
  91. function LocalFileTimeToFileTime(const lft : TWin32FileTime;var ft : TWin32FileTime) : longbool;
  92. stdcall; external 'kernel32' name 'LocalFileTimeToFileTime';
  93. function GetTickCount : longint;
  94. stdcall;external 'kernel32' name 'GetTickCount';
  95. function GetMsCount: int64;
  96. begin
  97. GetMsCount := cardinal (GetTickCount);
  98. end;
  99. type
  100. Longrec=packed record
  101. lo,hi : word;
  102. end;
  103. function Last2DosError(d:dword):integer;
  104. begin
  105. case d of
  106. 87 : { Parameter invalid -> Data invalid }
  107. Last2DosError:=13;
  108. else
  109. Last2DosError:=d;
  110. end;
  111. end;
  112. Function DosToWinAttr (Const Attr : Longint) : longint;
  113. begin
  114. DosToWinAttr:=Attr;
  115. end;
  116. Function WinToDosAttr (Const Attr : Longint) : longint;
  117. begin
  118. WinToDosAttr:=Attr;
  119. end;
  120. Function DosToWinTime (DTime:longint;Var Wtime : TWin32FileTime):longbool;
  121. var
  122. lft : TWin32FileTime;
  123. begin
  124. DosToWinTime:=DosDateTimeToFileTime(longrec(dtime).hi,longrec(dtime).lo,lft) and
  125. LocalFileTimeToFileTime(lft,Wtime);
  126. end;
  127. Function WinToDosTime (Const Wtime : TWin32FileTime;var DTime:longint):longbool;
  128. var
  129. lft : TWin32FileTime;
  130. begin
  131. WinToDosTime:=FileTimeToLocalFileTime(WTime,lft) and
  132. FileTimeToDosDateTime(lft,longrec(dtime).hi,longrec(dtime).lo);
  133. end;
  134. {******************************************************************************
  135. --- Info / Date / Time ---
  136. ******************************************************************************}
  137. type
  138. TSystemTime = record
  139. wYear,
  140. wMonth,
  141. wDayOfWeek,
  142. wDay,
  143. wHour,
  144. wMinute,
  145. wSecond,
  146. wMilliseconds: Word;
  147. end;
  148. function GetVersion : longint;
  149. stdcall; external 'kernel32' name 'GetVersion';
  150. procedure GetLocalTime(var t : TSystemTime);
  151. stdcall; external 'kernel32' name 'GetLocalTime';
  152. function SetLocalTime(const t : TSystemTime) : longbool;
  153. stdcall; external 'kernel32' name 'SetLocalTime';
  154. function dosversion : word;
  155. begin
  156. dosversion:=GetVersion and $ffff;
  157. end;
  158. procedure getdate(var year,month,mday,wday : word);
  159. var
  160. t : TSystemTime;
  161. begin
  162. GetLocalTime(t);
  163. year:=t.wYear;
  164. month:=t.wMonth;
  165. mday:=t.wDay;
  166. wday:=t.wDayOfWeek;
  167. end;
  168. procedure setdate(year,month,day : word);
  169. var
  170. t : TSystemTime;
  171. begin
  172. { we need the time set privilege }
  173. { so this function crash currently }
  174. {!!!!!}
  175. GetLocalTime(t);
  176. t.wYear:=year;
  177. t.wMonth:=month;
  178. t.wDay:=day;
  179. { only a quite good solution, we can loose some ms }
  180. SetLocalTime(t);
  181. end;
  182. procedure gettime(var hour,minute,second,sec100 : word);
  183. var
  184. t : TSystemTime;
  185. begin
  186. GetLocalTime(t);
  187. hour:=t.wHour;
  188. minute:=t.wMinute;
  189. second:=t.wSecond;
  190. sec100:=t.wMilliSeconds div 10;
  191. end;
  192. procedure settime(hour,minute,second,sec100 : word);
  193. var
  194. t : TSystemTime;
  195. begin
  196. { we need the time set privilege }
  197. { so this function crash currently }
  198. {!!!!!}
  199. GetLocalTime(t);
  200. t.wHour:=hour;
  201. t.wMinute:=minute;
  202. t.wSecond:=second;
  203. t.wMilliSeconds:=sec100*10;
  204. SetLocalTime(t);
  205. end;
  206. {******************************************************************************
  207. --- Exec ---
  208. ******************************************************************************}
  209. type
  210. PProcessInformation = ^TProcessInformation;
  211. TProcessInformation = record
  212. hProcess: TWin32Handle;
  213. hThread: TWin32Handle;
  214. dwProcessId: DWORD;
  215. dwThreadId: DWORD;
  216. end;
  217. function CreateProcess(lpApplicationName: PChar; lpCommandLine: PChar;
  218. lpProcessAttributes, lpThreadAttributes: Pointer;
  219. bInheritHandles: Longbool; dwCreationFlags: DWORD; lpEnvironment: Pointer;
  220. lpCurrentDirectory: PChar; const lpStartupInfo: TStartupInfo;
  221. var lpProcessInformation: TProcessInformation): longbool;
  222. stdcall; external 'kernel32' name 'CreateProcessA';
  223. function getExitCodeProcess(h:TWin32Handle;var code:longint):longbool;
  224. stdcall; external 'kernel32' name 'GetExitCodeProcess';
  225. function WaitForSingleObject(hHandle: TWin32Handle; dwMilliseconds: DWORD): DWORD;
  226. stdcall; external 'kernel32' name 'WaitForSingleObject';
  227. function CloseHandle(h : TWin32Handle) : longint;
  228. stdcall; external 'kernel32' name 'CloseHandle';
  229. procedure exec(const path : pathstr;const comline : comstr);
  230. var
  231. SI: TStartupInfo;
  232. PI: TProcessInformation;
  233. Proc : TWin32Handle;
  234. l : Longint;
  235. CommandLine : array[0..511] of char;
  236. AppParam : array[0..255] of char;
  237. pathlocal : string;
  238. begin
  239. DosError := 0;
  240. FillChar(SI, SizeOf(SI), 0);
  241. SI.cb:=SizeOf(SI);
  242. SI.wShowWindow:=1;
  243. { always surroound the name of the application by quotes
  244. so that long filenames will always be accepted. But don't
  245. do it if there are already double quotes, since Win32 does not
  246. like double quotes which are duplicated!
  247. }
  248. if pos('"',path) = 0 then
  249. pathlocal:='"'+path+'"'
  250. else
  251. pathlocal := path;
  252. Move(Pathlocal[1],CommandLine,length(Pathlocal));
  253. AppParam[0]:=' ';
  254. AppParam[1]:=' ';
  255. Move(ComLine[1],AppParam[2],length(Comline));
  256. AppParam[Length(ComLine)+2]:=#0;
  257. { concatenate both pathnames }
  258. Move(Appparam[0],CommandLine[length(Pathlocal)],strlen(Appparam)+1);
  259. if not CreateProcess(nil, PChar(@CommandLine),
  260. Nil, Nil, ExecInheritsHandles,$20, Nil, Nil, SI, PI) then
  261. begin
  262. DosError:=Last2DosError(GetLastError);
  263. exit;
  264. end;
  265. Proc:=PI.hProcess;
  266. CloseHandle(PI.hThread);
  267. if WaitForSingleObject(Proc, dword($ffffffff)) <> $ffffffff then
  268. GetExitCodeProcess(Proc,l)
  269. else
  270. l:=-1;
  271. CloseHandle(Proc);
  272. LastDosExitCode:=l;
  273. end;
  274. {******************************************************************************
  275. --- Disk ---
  276. ******************************************************************************}
  277. function GetDiskFreeSpace(drive:pchar;var sector_cluster,bytes_sector,
  278. freeclusters,totalclusters:longint):longbool;
  279. stdcall; external 'kernel32' name 'GetDiskFreeSpaceA';
  280. type
  281. TGetDiskFreeSpaceEx = function(drive:pchar;var availableforcaller,
  282. total,free):longbool;stdcall;
  283. var
  284. GetDiskFreeSpaceEx : TGetDiskFreeSpaceEx;
  285. function diskfree(drive : byte) : int64;
  286. var
  287. disk : array[1..4] of char;
  288. secs,bytes,
  289. free,total : longint;
  290. qwtotal,qwfree,qwcaller : int64;
  291. begin
  292. if drive=0 then
  293. begin
  294. disk[1]:='\';
  295. disk[2]:=#0;
  296. end
  297. else
  298. begin
  299. disk[1]:=chr(drive+64);
  300. disk[2]:=':';
  301. disk[3]:='\';
  302. disk[4]:=#0;
  303. end;
  304. if assigned(GetDiskFreeSpaceEx) then
  305. begin
  306. if GetDiskFreeSpaceEx(@disk,qwcaller,qwtotal,qwfree) then
  307. diskfree:=qwfree
  308. else
  309. diskfree:=-1;
  310. end
  311. else
  312. begin
  313. if GetDiskFreeSpace(@disk,secs,bytes,free,total) then
  314. diskfree:=int64(free)*secs*bytes
  315. else
  316. diskfree:=-1;
  317. end;
  318. end;
  319. function disksize(drive : byte) : int64;
  320. var
  321. disk : array[1..4] of char;
  322. secs,bytes,
  323. free,total : longint;
  324. qwtotal,qwfree,qwcaller : int64;
  325. begin
  326. if drive=0 then
  327. begin
  328. disk[1]:='\';
  329. disk[2]:=#0;
  330. end
  331. else
  332. begin
  333. disk[1]:=chr(drive+64);
  334. disk[2]:=':';
  335. disk[3]:='\';
  336. disk[4]:=#0;
  337. end;
  338. if assigned(GetDiskFreeSpaceEx) then
  339. begin
  340. if GetDiskFreeSpaceEx(@disk,qwcaller,qwtotal,qwfree) then
  341. disksize:=qwtotal
  342. else
  343. disksize:=-1;
  344. end
  345. else
  346. begin
  347. if GetDiskFreeSpace(@disk,secs,bytes,free,total) then
  348. disksize:=int64(total)*secs*bytes
  349. else
  350. disksize:=-1;
  351. end;
  352. end;
  353. {******************************************************************************
  354. --- Findfirst FindNext ---
  355. ******************************************************************************}
  356. { Needed kernel calls }
  357. function FindFirstFile (lpFileName: PChar; var lpFindFileData: TWIN32FindData): TWin32Handle;
  358. stdcall; external 'kernel32' name 'FindFirstFileA';
  359. function FindNextFile (hFindFile: TWin32Handle; var lpFindFileData: TWIN32FindData): LongBool;
  360. stdcall; external 'kernel32' name 'FindNextFileA';
  361. function FindCloseFile (hFindFile: TWin32Handle): LongBool;
  362. stdcall; external 'kernel32' name 'FindClose';
  363. Procedure StringToPchar (Var S : String);
  364. Var L : Longint;
  365. begin
  366. L:=ord(S[0]);
  367. Move (S[1],S[0],L);
  368. S[L]:=#0;
  369. end;
  370. Procedure PCharToString (Var S : String);
  371. Var L : Longint;
  372. begin
  373. L:=strlen(pchar(@S[0]));
  374. Move (S[0],S[1],L);
  375. S[0]:=char(l);
  376. end;
  377. procedure FindMatch(var f:searchrec);
  378. begin
  379. { Find file with correct attribute }
  380. While (F.W32FindData.dwFileAttributes and cardinal(F.ExcludeAttr))<>0 do
  381. begin
  382. if not FindNextFile (F.FindHandle,F.W32FindData) then
  383. begin
  384. DosError:=Last2DosError(GetLastError);
  385. if DosError=2 then
  386. DosError:=18;
  387. exit;
  388. end;
  389. end;
  390. { Convert some attributes back }
  391. f.size:=F.W32FindData.NFileSizeLow;
  392. f.attr:=WinToDosAttr(F.W32FindData.dwFileAttributes);
  393. WinToDosTime(F.W32FindData.ftLastWriteTime,f.Time);
  394. f.Name:=StrPas(@F.W32FindData.cFileName);
  395. end;
  396. procedure findfirst(const path : pathstr;attr : word;var f : searchRec);
  397. begin
  398. fillchar(f,sizeof(f),0);
  399. { no error }
  400. doserror:=0;
  401. F.Name:=Path;
  402. F.Attr:=attr;
  403. F.ExcludeAttr:=(not Attr) and ($1e); {hidden,sys,dir,volume}
  404. StringToPchar(f.name);
  405. { FindFirstFile is a Win32 Call }
  406. F.W32FindData.dwFileAttributes:=DosToWinAttr(f.attr);
  407. F.FindHandle:=FindFirstFile (pchar(@f.Name),F.W32FindData);
  408. If longint(F.FindHandle)=Invalid_Handle_value then
  409. begin
  410. DosError:=Last2DosError(GetLastError);
  411. if DosError=2 then
  412. DosError:=18;
  413. exit;
  414. end;
  415. { Find file with correct attribute }
  416. FindMatch(f);
  417. end;
  418. procedure findnext(var f : searchRec);
  419. begin
  420. { no error }
  421. doserror:=0;
  422. if not FindNextFile (F.FindHandle,F.W32FindData) then
  423. begin
  424. DosError:=Last2DosError(GetLastError);
  425. if DosError=2 then
  426. DosError:=18;
  427. exit;
  428. end;
  429. { Find file with correct attribute }
  430. FindMatch(f);
  431. end;
  432. Procedure FindClose(Var f: SearchRec);
  433. begin
  434. If longint(F.FindHandle)<>Invalid_Handle_value then
  435. FindCloseFile(F.FindHandle);
  436. end;
  437. {******************************************************************************
  438. --- File ---
  439. ******************************************************************************}
  440. function GeTWin32FileTime(h : longint;creation,lastaccess,lastwrite : PWin32FileTime) : longbool;
  441. stdcall; external 'kernel32' name 'GetFileTime';
  442. function SeTWin32FileTime(h : longint;creation,lastaccess,lastwrite : PWin32FileTime) : longbool;
  443. stdcall; external 'kernel32' name 'SetFileTime';
  444. function SetFileAttributes(lpFileName : pchar;dwFileAttributes : longint) : longbool;
  445. stdcall; external 'kernel32' name 'SetFileAttributesA';
  446. function GetFileAttributes(lpFileName : pchar) : longint;
  447. stdcall; external 'kernel32' name 'GetFileAttributesA';
  448. { <immobilizer> }
  449. function GetFullPathName(lpFileName: PChar; nBufferLength: Longint; lpBuffer: PChar; var lpFilePart : PChar):DWORD;
  450. stdcall; external 'kernel32' name 'GetFullPathNameA';
  451. function GetShortPathName(lpszLongPath:pchar; lpszShortPath:pchar; cchBuffer:DWORD):DWORD;
  452. stdcall; external 'kernel32' name 'GetShortPathNameA';
  453. Function FSearch(path: pathstr; dirlist: string): pathstr;
  454. var
  455. i,p1 : longint;
  456. s : searchrec;
  457. newdir : pathstr;
  458. begin
  459. { check if the file specified exists }
  460. findfirst(path,anyfile and not(directory),s);
  461. if doserror=0 then
  462. begin
  463. findclose(s);
  464. fsearch:=path;
  465. exit;
  466. end;
  467. { No wildcards allowed in these things }
  468. if (pos('?',path)<>0) or (pos('*',path)<>0) then
  469. fsearch:=''
  470. else
  471. begin
  472. { allow slash as backslash }
  473. for i:=1 to length(dirlist) do
  474. if dirlist[i]='/' then dirlist[i]:='\';
  475. repeat
  476. p1:=pos(';',dirlist);
  477. if p1<>0 then
  478. begin
  479. newdir:=copy(dirlist,1,p1-1);
  480. delete(dirlist,1,p1);
  481. end
  482. else
  483. begin
  484. newdir:=dirlist;
  485. dirlist:='';
  486. end;
  487. if (newdir<>'') and (not (newdir[length(newdir)] in ['\',':'])) then
  488. newdir:=newdir+'\';
  489. findfirst(newdir+path,anyfile and not(directory),s);
  490. if doserror=0 then
  491. newdir:=newdir+path
  492. else
  493. newdir:='';
  494. until (dirlist='') or (newdir<>'');
  495. fsearch:=newdir;
  496. end;
  497. findclose(s);
  498. end;
  499. { </immobilizer> }
  500. procedure getftime(var f;var time : longint);
  501. var
  502. ft : TWin32FileTime;
  503. begin
  504. doserror:=0;
  505. if GeTWin32FileTime(filerec(f).Handle,nil,nil,@ft) and
  506. WinToDosTime(ft,time) then
  507. exit
  508. else
  509. begin
  510. DosError:=Last2DosError(GetLastError);
  511. time:=0;
  512. end;
  513. end;
  514. procedure setftime(var f;time : longint);
  515. var
  516. ft : TWin32FileTime;
  517. begin
  518. doserror:=0;
  519. if DosToWinTime(time,ft) and
  520. SeTWin32FileTime(filerec(f).Handle,nil,nil,@ft) then
  521. exit
  522. else
  523. DosError:=Last2DosError(GetLastError);
  524. end;
  525. procedure getfattr(var f;var attr : word);
  526. var
  527. l : longint;
  528. begin
  529. doserror:=0;
  530. l:=GetFileAttributes(filerec(f).name);
  531. if l=longint($ffffffff) then
  532. begin
  533. doserror:=getlasterror;
  534. attr:=0;
  535. end
  536. else
  537. attr:=l and $ffff;
  538. end;
  539. procedure setfattr(var f;attr : word);
  540. begin
  541. { Fail for setting VolumeId }
  542. if (attr and VolumeID)<>0 then
  543. doserror:=5
  544. else
  545. if SetFileAttributes(filerec(f).name,attr) then
  546. doserror:=0
  547. else
  548. doserror:=getlasterror;
  549. end;
  550. { change to short filename if successful win32 call PM }
  551. function GetShortName(var p : String) : boolean;
  552. var
  553. buffer : array[0..255] of char;
  554. ret : longint;
  555. begin
  556. {we can't mess with p, because we have to return it if call is
  557. unsuccesfully.}
  558. if Length(p)>0 then {copy p to array of char}
  559. move(p[1],buffer[0],length(p));
  560. buffer[length(p)]:=chr(0);
  561. {Should return value load loaddoserror?}
  562. ret:=GetShortPathName(@buffer,@buffer,255);
  563. if ret=0 then
  564. p:=strpas(buffer);
  565. GetShortName:=ret<>0;
  566. end;
  567. { change to long filename if successful DOS call PM }
  568. function GetLongName(var p : String) : boolean;
  569. var
  570. lfn,sfn : array[0..255] of char;
  571. filename : pchar;
  572. ret : longint;
  573. begin
  574. {contrary to shortname, SDK does not mention input buffer can be equal
  575. to output.}
  576. if Length(p)>0 then {copy p to array of char}
  577. move(p[1],sfn[0],length(p));
  578. sfn[length(p)]:=chr(0);
  579. fillchar(lfn,sizeof(lfn),#0);
  580. filename:=nil;
  581. {Should return value load loaddoserror?}
  582. ret:=GetFullPathName(@sfn,255,@lfn,filename);
  583. if ret=0 then
  584. p:=strpas(lfn); {lfn here returns full path, filename only fn}
  585. GetLongName:=ret<>0;
  586. end;
  587. {******************************************************************************
  588. --- Environment ---
  589. ******************************************************************************}
  590. {
  591. The environment is a block of zero terminated strings
  592. terminated by a #0
  593. }
  594. function GetEnvironmentStrings : pchar;
  595. stdcall; external 'kernel32' name 'GetEnvironmentStringsA';
  596. function FreeEnvironmentStrings(p : pchar) : longbool;
  597. stdcall; external 'kernel32' name 'FreeEnvironmentStringsA';
  598. function envcount : longint;
  599. var
  600. hp,p : pchar;
  601. count : longint;
  602. begin
  603. p:=GetEnvironmentStrings;
  604. hp:=p;
  605. count:=0;
  606. while hp^<>#0 do
  607. begin
  608. { next string entry}
  609. hp:=hp+strlen(hp)+1;
  610. inc(count);
  611. end;
  612. FreeEnvironmentStrings(p);
  613. envcount:=count;
  614. end;
  615. Function EnvStr (Index: longint): string;
  616. var
  617. hp,p : pchar;
  618. count,i : longint;
  619. begin
  620. { envcount takes some time in win32 }
  621. count:=envcount;
  622. { range checking }
  623. if (index<=0) or (index>count) then
  624. begin
  625. envstr:='';
  626. exit;
  627. end;
  628. p:=GetEnvironmentStrings;
  629. hp:=p;
  630. { retrive the string with the given index }
  631. for i:=2 to index do
  632. hp:=hp+strlen(hp)+1;
  633. envstr:=strpas(hp);
  634. FreeEnvironmentStrings(p);
  635. end;
  636. Function GetEnv(envvar: string): string;
  637. var
  638. s : string;
  639. i : longint;
  640. hp,p : pchar;
  641. begin
  642. getenv:='';
  643. p:=GetEnvironmentStrings;
  644. hp:=p;
  645. while hp^<>#0 do
  646. begin
  647. s:=strpas(hp);
  648. i:=pos('=',s);
  649. if upcase(copy(s,1,i-1))=upcase(envvar) then
  650. begin
  651. getenv:=copy(s,i+1,length(s)-i);
  652. break;
  653. end;
  654. { next string entry}
  655. hp:=hp+strlen(hp)+1;
  656. end;
  657. FreeEnvironmentStrings(p);
  658. end;
  659. function FreeLibrary(hLibModule : TWin32Handle) : longbool;
  660. stdcall; external 'kernel32' name 'FreeLibrary';
  661. function GetVersionEx(var VersionInformation:OSVERSIONINFO) : longbool;
  662. stdcall; external 'kernel32' name 'GetVersionExA';
  663. function LoadLibrary(lpLibFileName : pchar):TWin32Handle;
  664. stdcall; external 'kernel32' name 'LoadLibraryA';
  665. function GetProcAddress(hModule : TWin32Handle;lpProcName : pchar) : pointer;
  666. stdcall; external 'kernel32' name 'GetProcAddress';
  667. var
  668. oldexitproc : pointer;
  669. procedure dosexitproc;
  670. begin
  671. exitproc:=oldexitproc;
  672. if kernel32dll<>0 then
  673. FreeLibrary(kernel32dll);
  674. end;
  675. begin
  676. oldexitproc:=exitproc;
  677. exitproc:=@dosexitproc;
  678. versioninfo.dwOSVersionInfoSize:=sizeof(versioninfo);
  679. GetVersionEx(versioninfo);
  680. kernel32dll:=0;
  681. GetDiskFreeSpaceEx:=nil;
  682. if ((versioninfo.dwPlatformId=VER_PLATFORM_WIN32_WINDOWS) and
  683. (versioninfo.dwBuildNUmber>=1000)) or
  684. (versioninfo.dwPlatformId=VER_PLATFORM_WIN32_NT) then
  685. begin
  686. kernel32dll:=LoadLibrary('kernel32');
  687. if kernel32dll<>0 then
  688. GetDiskFreeSpaceEx:=TGetDiskFreeSpaceEx(GetProcAddress(kernel32dll,'GetDiskFreeSpaceExA'));
  689. end;
  690. end.