dmisc.pas 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854
  1. {
  2. $Id$
  3. This file is part of the Free Pascal run time library.
  4. Copyright (c) 1993,97 by the Free Pascal development team.
  5. Dos unit for BP7 compatible RTL
  6. See the file COPYING.FPC, included in this distribution,
  7. for details about the copyright.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  11. **********************************************************************}
  12. unit dmisc;
  13. interface
  14. uses
  15. windows,sysutils;
  16. Const
  17. Max_Path = 255;
  18. {Bitmasks for CPU Flags}
  19. fcarry = $0001;
  20. fparity = $0004;
  21. fauxiliary = $0010;
  22. fzero = $0040;
  23. fsign = $0080;
  24. foverflow = $0800;
  25. {Bitmasks for file attribute}
  26. readonly = $01;
  27. hidden = $02;
  28. sysfile = $04;
  29. volumeid = $08;
  30. directory = $10;
  31. archive = $20;
  32. anyfile = $3F;
  33. {File Status}
  34. fmclosed = $D7B0;
  35. fminput = $D7B1;
  36. fmoutput = $D7B2;
  37. fminout = $D7B3;
  38. Type
  39. { Needed for Win95 LFN Support }
  40. ComStr = String[255];
  41. PathStr = String[255];
  42. DirStr = String[255];
  43. NameStr = String[255];
  44. ExtStr = String[255];
  45. FileRec = TFileRec;
  46. DateTime = packed record
  47. Year,
  48. Month,
  49. Day,
  50. Hour,
  51. Min,
  52. Sec : word;
  53. End;
  54. PWin32FindData = ^TWin32FindData;
  55. TWin32FindData = packed record
  56. dwFileAttributes: Cardinal;
  57. ftCreationTime: TFileTime;
  58. ftLastAccessTime: TFileTime;
  59. ftLastWriteTime: TFileTime;
  60. nFileSizeHigh: Cardinal;
  61. nFileSizeLow: Cardinal;
  62. dwReserved0: Cardinal;
  63. dwReserved1: Cardinal;
  64. cFileName: array[0..MAX_PATH - 1] of Char;
  65. cAlternateFileName: array[0..13] of Char;
  66. end;
  67. Searchrec = Packed Record
  68. FindHandle : THandle;
  69. W32FindData : TWin32FindData;
  70. time : longint;
  71. size : longint;
  72. attr : longint;
  73. name : string;
  74. end;
  75. registers = packed record
  76. case i : integer of
  77. 0 : (ax,f1,bx,f2,cx,f3,dx,f4,bp,f5,si,f51,di,f6,ds,f7,es,f8,flags,fs,gs : word);
  78. 1 : (al,ah,f9,f10,bl,bh,f11,f12,cl,ch,f13,f14,dl,dh : byte);
  79. 2 : (eax, ebx, ecx, edx, ebp, esi, edi : longint);
  80. end;
  81. Var
  82. DosError : integer;
  83. {Interrupt}
  84. Procedure Intr(intno: byte; var regs: registers);
  85. Procedure MSDos(var regs: registers);
  86. {Info/Date/Time}
  87. Function DosVersion: Word;
  88. Procedure GetDate(var year, month, mday, wday: word);
  89. Procedure GetTime(var hour, minute, second, sec100: word);
  90. procedure SetDate(year,month,day: word);
  91. Procedure SetTime(hour,minute,second,sec100: word);
  92. Procedure UnpackTime(p: longint; var t: datetime);
  93. Procedure PackTime(var t: datetime; var p: longint);
  94. {Exec}
  95. Procedure Exec(const path: pathstr; const comline: comstr);
  96. Function DosExitCode: word;
  97. {Disk}
  98. Function DiskFree(drive: byte) : longint;
  99. Function DiskSize(drive: byte) : longint;
  100. Procedure FindFirst(const path: pathstr; attr: word; var f: searchRec);
  101. Procedure FindNext(var f: searchRec);
  102. Procedure FindClose(Var f: SearchRec);
  103. {File}
  104. Procedure GetFAttr(var f; var attr: word);
  105. Procedure GetFTime(var f; var time: longint);
  106. Function FSearch(path: pathstr; dirlist: string): pathstr;
  107. Function FExpand(const path: pathstr): pathstr;
  108. Procedure FSplit(path: pathstr; var dir: dirstr; var name: namestr; var ext: extstr);
  109. {Environment}
  110. Function EnvCount: longint;
  111. Function EnvStr(index: integer): string;
  112. Function GetEnv(envvar: string): string;
  113. {Misc}
  114. Procedure SetFAttr(var f; attr: word);
  115. Procedure SetFTime(var f; time: longint);
  116. Procedure GetCBreak(var breakvalue: boolean);
  117. Procedure SetCBreak(breakvalue: boolean);
  118. Procedure GetVerify(var verify: boolean);
  119. Procedure SetVerify(verify: boolean);
  120. {Do Nothing Functions}
  121. Procedure SwapVectors;
  122. Procedure GetIntVec(intno: byte; var vector: pointer);
  123. Procedure SetIntVec(intno: byte; vector: pointer);
  124. Procedure Keep(exitcode: word);
  125. implementation
  126. uses strings,globals;
  127. {******************************************************************************
  128. --- Conversion ---
  129. ******************************************************************************}
  130. function GetLastError : DWORD;
  131. external 'kernel32' name 'GetLastError';
  132. function FileTimeToDosDateTime(const ft :TFileTime;var data,time : word) : boolean;
  133. external 'kernel32' name 'FileTimeToDosDateTime';
  134. function DosDateTimeToFileTime(date,time : word;var ft :TFileTime) : boolean;
  135. external 'kernel32' name 'DosDateTimeToFileTime';
  136. function FileTimeToLocalFileTime(const ft : TFileTime;var lft : TFileTime) : boolean;
  137. external 'kernel32' name 'FileTimeToLocalFileTime';
  138. function LocalFileTimeToFileTime(const lft : TFileTime;var ft : TFileTime) : boolean;
  139. external 'kernel32' name 'LocalFileTimeToFileTime';
  140. type
  141. Longrec=packed record
  142. lo,hi : word;
  143. end;
  144. function Last2DosError(d:dword):integer;
  145. begin
  146. Last2DosError:=d;
  147. end;
  148. Function DosToWinAttr (Const Attr : Longint) : longint;
  149. begin
  150. DosToWinAttr:=Attr;
  151. end;
  152. Function WinToDosAttr (Const Attr : Longint) : longint;
  153. begin
  154. WinToDosAttr:=Attr;
  155. end;
  156. Function DosToWinTime (DTime:longint;Var Wtime : TFileTime):boolean;
  157. var
  158. lft : TFileTime;
  159. begin
  160. DosToWinTime:=DosDateTimeToFileTime(longrec(dtime).hi,longrec(dtime).lo,lft) and
  161. LocalFileTimeToFileTime(lft,Wtime);
  162. end;
  163. Function WinToDosTime (Const Wtime : TFileTime;var DTime:longint):boolean;
  164. var
  165. lft : TFileTime;
  166. begin
  167. WinToDosTime:=FileTimeToLocalFileTime(WTime,lft) and
  168. FileTimeToDosDateTime(lft,longrec(dtime).hi,longrec(dtime).lo);
  169. end;
  170. {******************************************************************************
  171. --- Dos Interrupt ---
  172. ******************************************************************************}
  173. procedure intr(intno : byte;var regs : registers);
  174. begin
  175. { !!!!!!!! }
  176. end;
  177. procedure msdos(var regs : registers);
  178. begin
  179. { !!!!!!!! }
  180. end;
  181. {******************************************************************************
  182. --- Info / Date / Time ---
  183. ******************************************************************************}
  184. function GetVersion : longint;
  185. external 'kernel32' name 'GetVersion';
  186. procedure GetLocalTime(var t : TSystemTime);
  187. external 'kernel32' name 'GetLocalTime';
  188. function SetLocalTime(const t : TSystemTime) : boolean;
  189. external 'kernel32' name 'SetLocalTime';
  190. function dosversion : word;
  191. begin
  192. dosversion:=GetVersion;
  193. end;
  194. procedure getdate(var year,month,mday,wday : word);
  195. var
  196. t : TSystemTime;
  197. begin
  198. GetLocalTime(t);
  199. year:=t.wYear;
  200. month:=t.wMonth;
  201. mday:=t.wDay;
  202. wday:=t.wDayOfWeek;
  203. end;
  204. procedure setdate(year,month,day : word);
  205. var
  206. t : TSystemTime;
  207. begin
  208. { we need the time set privilege }
  209. { so this function crash currently }
  210. {!!!!!}
  211. GetLocalTime(t);
  212. t.wYear:=year;
  213. t.wMonth:=month;
  214. t.wDay:=day;
  215. { only a quite good solution, we can loose some ms }
  216. SetLocalTime(t);
  217. end;
  218. procedure gettime(var hour,minute,second,sec100 : word);
  219. var
  220. t : TSystemTime;
  221. begin
  222. GetLocalTime(t);
  223. hour:=t.wHour;
  224. minute:=t.wMinute;
  225. second:=t.wSecond;
  226. sec100:=t.wMilliSeconds div 10;
  227. end;
  228. procedure settime(hour,minute,second,sec100 : word);
  229. var
  230. t : TSystemTime;
  231. begin
  232. { we need the time set privilege }
  233. { so this function crash currently }
  234. {!!!!!}
  235. GetLocalTime(t);
  236. t.wHour:=hour;
  237. t.wMinute:=minute;
  238. t.wSecond:=second;
  239. t.wMilliSeconds:=sec100*10;
  240. SetLocalTime(t);
  241. end;
  242. Procedure packtime(var t : datetime;var p : longint);
  243. Begin
  244. p:=(t.sec shr 1)+(t.min shl 5)+(t.hour shl 11)+(t.day shl 16)+(t.month shl 21)+((t.year-1980) shl 25);
  245. End;
  246. Procedure unpacktime(p : longint;var t : datetime);
  247. Begin
  248. with t do
  249. begin
  250. sec:=(p and 31) shl 1;
  251. min:=(p shr 5) and 63;
  252. hour:=(p shr 11) and 31;
  253. day:=(p shr 16) and 31;
  254. month:=(p shr 21) and 15;
  255. year:=(p shr 25)+1980;
  256. end;
  257. End;
  258. {******************************************************************************
  259. --- Exec ---
  260. ******************************************************************************}
  261. var
  262. lastdosexitcode : word;
  263. procedure exec(const path : pathstr;const comline : comstr);
  264. var
  265. SI: TStartupInfo;
  266. PI: TProcessInformation;
  267. Proc : THandle;
  268. l : Longint;
  269. AppPath,
  270. AppParam : array[0..255] of char;
  271. begin
  272. FillChar(SI, SizeOf(SI), 0);
  273. SI.cb:=SizeOf(SI);
  274. SI.wShowWindow:=1;
  275. Move(Path[1],AppPath,length(Path));
  276. AppPath[Length(Path)]:=#0;
  277. AppParam[0]:='-';
  278. AppParam[1]:=' ';
  279. Move(ComLine[1],AppParam[2],length(Comline));
  280. AppParam[Length(ComLine)+2]:=#0;
  281. if not CreateProcess(PChar(@AppPath), PChar(@AppParam), Nil, Nil, False,$20, Nil, Nil, SI, PI) then
  282. begin
  283. DosError:=Last2DosError(GetLastError);
  284. exit;
  285. end;
  286. Proc:=PI.hProcess;
  287. CloseHandle(PI.hThread);
  288. if WaitForSingleObject(Proc, Infinite) <> $ffffffff then
  289. GetExitCodeProcess(Proc,l)
  290. else
  291. l:=-1;
  292. CloseHandle(Proc);
  293. LastDosExitCode:=l;
  294. end;
  295. function dosexitcode : word;
  296. begin
  297. dosexitcode:=lastdosexitcode;
  298. end;
  299. procedure getcbreak(var breakvalue : boolean);
  300. begin
  301. { !! No Win32 Function !! }
  302. end;
  303. procedure setcbreak(breakvalue : boolean);
  304. begin
  305. { !! No Win32 Function !! }
  306. end;
  307. procedure getverify(var verify : boolean);
  308. begin
  309. { !! No Win32 Function !! }
  310. end;
  311. procedure setverify(verify : boolean);
  312. begin
  313. { !! No Win32 Function !! }
  314. end;
  315. {******************************************************************************
  316. --- Disk ---
  317. ******************************************************************************}
  318. function diskfree(drive : byte) : longint;
  319. var
  320. disk : array[1..4] of char;
  321. secs,bytes,
  322. free,total : longint;
  323. begin
  324. if drive=0 then
  325. begin
  326. disk[1]:='\';
  327. disk[2]:=#0;
  328. end
  329. else
  330. begin
  331. disk[1]:=chr(drive+64);
  332. disk[2]:=':';
  333. disk[3]:='\';
  334. disk[4]:=#0;
  335. end;
  336. if GetDiskFreeSpace(@disk,secs,bytes,free,total) then
  337. diskfree:=free*secs*bytes
  338. else
  339. diskfree:=-1;
  340. end;
  341. function disksize(drive : byte) : longint;
  342. var
  343. disk : array[1..4] of char;
  344. secs,bytes,
  345. free,total : longint;
  346. begin
  347. if drive=0 then
  348. begin
  349. disk[1]:='\';
  350. disk[2]:=#0;
  351. end
  352. else
  353. begin
  354. disk[1]:=chr(drive+64);
  355. disk[2]:=':';
  356. disk[3]:='\';
  357. disk[4]:=#0;
  358. end;
  359. if GetDiskFreeSpace(@disk,secs,bytes,free,total) then
  360. disksize:=total*secs*bytes
  361. else
  362. disksize:=-1;
  363. end;
  364. {******************************************************************************
  365. --- Findfirst FindNext ---
  366. ******************************************************************************}
  367. { Needed kernel calls }
  368. function FindFirstFile (lpFileName: PChar; var lpFindFileData: TWIN32FindData): THandle;
  369. external 'kernel32' name 'FindFirstFileA';
  370. function FindNextFile (hFindFile: THandle; var lpFindFileData: TWIN32FindData): Boolean;
  371. external 'kernel32' name 'FindNextFileA';
  372. function FindCloseFile (hFindFile: THandle): Boolean;
  373. external 'kernel32' name 'FindClose';
  374. Procedure StringToPchar (Var S : String);
  375. Var L : Longint;
  376. begin
  377. L:=ord(S[0]);
  378. Move (S[1],S[0],L);
  379. S[L]:=#0;
  380. end;
  381. procedure FindMatch(var f:searchrec);
  382. Var
  383. TheAttr : Longint;
  384. begin
  385. TheAttr:=DosToWinAttr(F.Attr);
  386. { Find file with correct attribute }
  387. While (F.W32FindData.dwFileAttributes and TheAttr)=0 do
  388. begin
  389. if not FindNextFile (F.FindHandle,F.W32FindData) then
  390. begin
  391. DosError:=Last2DosError(GetLastError);
  392. exit;
  393. end;
  394. end;
  395. { Convert some attributes back }
  396. f.size:=F.W32FindData.NFileSizeLow;
  397. f.attr:=WinToDosAttr(F.W32FindData.dwFileAttributes);
  398. WinToDosTime(F.W32FindData.ftLastWriteTime,f.Time);
  399. f.Name:=StrPas(@F.W32FindData.cFileName);
  400. end;
  401. procedure findfirst(const path : pathstr;attr : word;var f : searchRec);
  402. begin
  403. { no error }
  404. doserror:=0;
  405. F.Name:=Path;
  406. F.Attr:=attr;
  407. StringToPchar(f.name);
  408. { FindFirstFile is a Win32 Call. }
  409. F.FindHandle:=FindFirstFile (pchar(@f.Name),F.W32FindData);
  410. If longint(F.FindHandle)=Invalid_Handle_value then
  411. begin
  412. DosError:=Last2DosError(GetLastError);
  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. exit;
  426. end;
  427. { Find file with correct attribute }
  428. FindMatch(f);
  429. end;
  430. procedure swapvectors;
  431. begin
  432. end;
  433. Procedure FindClose(Var f: SearchRec);
  434. begin
  435. If longint(F.FindHandle)<>Invalid_Handle_value then
  436. FindCloseFile(F.FindHandle);
  437. end;
  438. {******************************************************************************
  439. --- File ---
  440. ******************************************************************************}
  441. function GetFileTime(h : longint;creation,lastaccess,lastwrite : PFileTime) : boolean;
  442. external 'kernel32' name 'GetFileTime';
  443. function SetFileTime(h : longint;creation,lastaccess,lastwrite : PFileTime) : boolean;
  444. external 'kernel32' name 'SetFileTime';
  445. function SetFileAttributes(lpFileName : pchar;dwFileAttributes : longint) : boolean;
  446. external 'kernel32' name 'SetFileAttributesA';
  447. function GetFileAttributes(lpFileName : pchar) : longint;
  448. external 'kernel32' name 'GetFileAttributesA';
  449. procedure fsplit(path : pathstr;var dir : dirstr;var name : namestr;var ext : extstr);
  450. var
  451. p1,i : longint;
  452. begin
  453. { allow slash as backslash }
  454. for i:=1 to length(path) do
  455. if path[i]='/' then path[i]:='\';
  456. { get drive name }
  457. p1:=pos(':',path);
  458. if p1>0 then
  459. begin
  460. dir:=path[1]+':';
  461. delete(path,1,p1);
  462. end
  463. else
  464. dir:='';
  465. { split the path and the name, there are no more path informtions }
  466. { if path contains no backslashes }
  467. while true do
  468. begin
  469. p1:=pos('\',path);
  470. if p1=0 then
  471. break;
  472. dir:=dir+copy(path,1,p1);
  473. delete(path,1,p1);
  474. end;
  475. { try to find out a extension }
  476. p1:=pos('.',path);
  477. if p1>0 then
  478. begin
  479. ext:=copy(path,p1,4);
  480. delete(path,p1,length(path)-p1+1);
  481. end
  482. else
  483. ext:='';
  484. name:=path;
  485. end;
  486. function fexpand(const path : pathstr) : pathstr;
  487. var
  488. s,pa : string[79];
  489. i,j : longint;
  490. begin
  491. getdir(0,s);
  492. pa:=upper(path);
  493. { allow slash as backslash }
  494. for i:=1 to length(pa) do
  495. if pa[i]='/' then
  496. pa[i]:='\';
  497. if (length(pa)>1) and (pa[1] in ['A'..'Z']) and (pa[2]=':') then
  498. begin
  499. { we must get the right directory }
  500. getdir(ord(pa[1])-ord('A')+1,s);
  501. if (ord(pa[0])>2) and (pa[3]<>'\') then
  502. if pa[1]=s[1] then
  503. pa:=s+'\'+copy (pa,3,length(pa))
  504. else
  505. pa:=pa[1]+':\'+copy (pa,3,length(pa))
  506. end
  507. else
  508. if pa[1]='\' then
  509. pa:=s[1]+':'+pa
  510. else if s[0]=#3 then
  511. pa:=s+pa
  512. else
  513. pa:=s+'\'+pa;
  514. { Turbo Pascal gives current dir on drive if only drive given as parameter! }
  515. if length(pa) = 2 then
  516. begin
  517. getdir(byte(pa[1])-64,s);
  518. pa := s;
  519. end;
  520. {First remove all references to '\.\'}
  521. while pos ('\.\',pa)<>0 do
  522. delete (pa,pos('\.\',pa),2);
  523. {Now remove also all references to '\..\' + of course previous dirs..}
  524. repeat
  525. i:=pos('\..\',pa);
  526. if i<>0 then
  527. begin
  528. j:=i-1;
  529. while (j>1) and (pa[j]<>'\') do
  530. dec (j);
  531. if pa[j+1] = ':' then j := 3;
  532. delete (pa,j,i-j+3);
  533. end;
  534. until i=0;
  535. { Turbo Pascal gets rid of a \.. at the end of the path }
  536. { Now remove also any reference to '\..' at end of line
  537. + of course previous dir.. }
  538. i:=pos('\..',pa);
  539. if i<>0 then
  540. begin
  541. if i = length(pa) - 2 then
  542. begin
  543. j:=i-1;
  544. while (j>1) and (pa[j]<>'\') do
  545. dec (j);
  546. delete (pa,j,i-j+3);
  547. end;
  548. pa := pa + '\';
  549. end;
  550. { Remove End . and \}
  551. if (length(pa)>0) and (pa[length(pa)]='.') then
  552. dec(byte(pa[0]));
  553. { if only the drive + a '\' is left then the '\' should be left to prevtn the program
  554. accessing the current directory on the drive rather than the root!}
  555. { if the last char of path = '\' then leave it in as this is what TP does! }
  556. if ((length(pa)>3) and (pa[length(pa)]='\')) and (path[length(path)] <> '\') then
  557. dec(byte(pa[0]));
  558. { if only a drive is given in path then there should be a '\' at the
  559. end of the string given back }
  560. if length(path) = 2 then pa := pa + '\';
  561. fexpand:=pa;
  562. end;
  563. Function FSearch(path: pathstr; dirlist: string): pathstr;
  564. var
  565. i,p1 : longint;
  566. s : searchrec;
  567. newdir : pathstr;
  568. begin
  569. { No wildcards allowed in these things }
  570. if (pos('?',path)<>0) or (pos('*',path)<>0) then
  571. fsearch:=''
  572. else
  573. begin
  574. { allow slash as backslash }
  575. for i:=1 to length(dirlist) do
  576. if dirlist[i]='/' then dirlist[i]:='\';
  577. repeat
  578. p1:=pos(';',dirlist);
  579. if p1=0 then
  580. begin
  581. newdir:=copy(dirlist,1,p1-1);
  582. delete(dirlist,1,p1);
  583. end
  584. else
  585. begin
  586. newdir:=dirlist;
  587. dirlist:='';
  588. end;
  589. if (newdir<>'') and (not (newdir[length(newdir)] in ['\',':'])) then
  590. newdir:=newdir+'\';
  591. findfirst(newdir+path,anyfile,s);
  592. if doserror=0 then
  593. newdir:=newdir+path
  594. else
  595. newdir:='';
  596. until (dirlist='') or (newdir<>'');
  597. fsearch:=newdir;
  598. end;
  599. end;
  600. procedure getftime(var f;var time : longint);
  601. var
  602. ft : TFileTime;
  603. begin
  604. if GetFileTime(filerec(f).Handle,nil,nil,@ft) and
  605. WinToDosTime(ft,time) then
  606. exit
  607. else
  608. time:=0;
  609. end;
  610. procedure setftime(var f;time : longint);
  611. var
  612. ft : TFileTime;
  613. begin
  614. if DosToWinTime(time,ft) then
  615. SetFileTime(filerec(f).Handle,nil,nil,@ft);
  616. end;
  617. procedure getfattr(var f;var attr : word);
  618. var
  619. l : longint;
  620. begin
  621. l:=GetFileAttributes(filerec(f).name);
  622. if l=$ffffffff then
  623. doserror:=getlasterror;
  624. attr:=l;
  625. end;
  626. procedure setfattr(var f;attr : word);
  627. begin
  628. doserror:=0;
  629. if not(SetFileAttributes(filerec(f).name,attr)) then
  630. doserror:=getlasterror;
  631. end;
  632. {******************************************************************************
  633. --- Environment ---
  634. ******************************************************************************}
  635. {
  636. The environment is a block of zero terminated strings
  637. terminated by a #0
  638. }
  639. function GetEnvironmentStrings : pchar;
  640. external 'kernel32' name 'GetEnvironmentStringsA';
  641. function FreeEnvironmentStrings(p : pchar) : boolean;
  642. external 'kernel32' name 'FreeEnvironmentStringsA';
  643. function envcount : longint;
  644. var
  645. hp,p : pchar;
  646. count : longint;
  647. begin
  648. p:=GetEnvironmentStrings;
  649. hp:=p;
  650. count:=0;
  651. while hp^<>#0 do
  652. begin
  653. { next string entry}
  654. hp:=hp+strlen(hp)+1;
  655. inc(count);
  656. end;
  657. FreeEnvironmentStrings(p);
  658. envcount:=count;
  659. end;
  660. Function EnvStr(index: integer): string;
  661. var
  662. hp,p : pchar;
  663. count,i : longint;
  664. begin
  665. { envcount takes some time in win32 }
  666. count:=envcount;
  667. { range checking }
  668. if (index<=0) or (index>count) then
  669. begin
  670. envstr:='';
  671. exit;
  672. end;
  673. p:=GetEnvironmentStrings;
  674. hp:=p;
  675. { retrive the string with the given index }
  676. for i:=2 to index do
  677. hp:=hp+strlen(hp)+1;
  678. envstr:=strpas(hp);
  679. FreeEnvironmentStrings(p);
  680. end;
  681. Function GetEnv(envvar: string): string;
  682. var
  683. s : string;
  684. i : longint;
  685. hp,p : pchar;
  686. begin
  687. getenv:='';
  688. p:=GetEnvironmentStrings;
  689. hp:=p;
  690. while hp^<>#0 do
  691. begin
  692. s:=strpas(hp);
  693. i:=pos('=',s);
  694. if copy(s,1,i-1)=envvar then
  695. begin
  696. getenv:=copy(s,i+1,length(s)-i);
  697. break;
  698. end;
  699. { next string entry}
  700. hp:=hp+strlen(hp)+1;
  701. end;
  702. FreeEnvironmentStrings(p);
  703. end;
  704. {******************************************************************************
  705. --- Not Supported ---
  706. ******************************************************************************}
  707. Procedure keep(exitcode : word);
  708. Begin
  709. End;
  710. Procedure getintvec(intno : byte;var vector : pointer);
  711. Begin
  712. End;
  713. Procedure setintvec(intno : byte;vector : pointer);
  714. Begin
  715. End;
  716. end.
  717. {
  718. $Log$
  719. Revision 1.1 1998-09-18 16:03:38 florian
  720. * some changes to compile with Delphi
  721. }