dos.pp 25 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025
  1. {
  2. $Id$
  3. This file is part of the Free Pascal run time library.
  4. Copyright (c) 1999-2000 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 dos;
  13. interface
  14. { Include Win32 Consts,Types }
  15. {$I win32.inc}
  16. Const
  17. Max_Path = 260;
  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. {
  46. filerec.inc contains the definition of the filerec.
  47. textrec.inc contains the definition of the textrec.
  48. It is in a separate file to make it available in other units without
  49. having to use the DOS unit for it.
  50. }
  51. {$i filerec.inc}
  52. {$i textrec.inc}
  53. DateTime = packed record
  54. Year,
  55. Month,
  56. Day,
  57. Hour,
  58. Min,
  59. Sec : word;
  60. End;
  61. PWin32FindData = ^TWin32FindData;
  62. TWin32FindData = record
  63. dwFileAttributes: Cardinal;
  64. ftCreationTime: TFileTime;
  65. ftLastAccessTime: TFileTime;
  66. ftLastWriteTime: TFileTime;
  67. nFileSizeHigh: Cardinal;
  68. nFileSizeLow: Cardinal;
  69. dwReserved0: Cardinal;
  70. dwReserved1: Cardinal;
  71. cFileName: array[0..MAX_PATH - 1] of Char;
  72. cAlternateFileName: array[0..13] of Char;
  73. // The structure should be 320 bytes long...
  74. pad : system.integer;
  75. end;
  76. Searchrec = Packed Record
  77. FindHandle : THandle;
  78. W32FindData : TWin32FindData;
  79. ExcludeAttr : longint;
  80. time : longint;
  81. size : longint;
  82. attr : longint;
  83. name : string;
  84. end;
  85. registers = packed record
  86. case i : integer of
  87. 0 : (ax,f1,bx,f2,cx,f3,dx,f4,bp,f5,si,f51,di,f6,ds,f7,es,f8,flags,fs,gs : word);
  88. 1 : (al,ah,f9,f10,bl,bh,f11,f12,cl,ch,f13,f14,dl,dh : byte);
  89. 2 : (eax, ebx, ecx, edx, ebp, esi, edi : longint);
  90. end;
  91. Var
  92. DosError : integer;
  93. {Interrupt}
  94. Procedure Intr(intno: byte; var regs: registers);
  95. Procedure MSDos(var regs: registers);
  96. {Info/Date/Time}
  97. Function DosVersion: Word;
  98. Procedure GetDate(var year, month, mday, wday: word);
  99. Procedure GetTime(var hour, minute, second, sec100: word);
  100. procedure SetDate(year,month,day: word);
  101. Procedure SetTime(hour,minute,second,sec100: word);
  102. Procedure UnpackTime(p: longint; var t: datetime);
  103. Procedure PackTime(var t: datetime; var p: longint);
  104. {Exec}
  105. Procedure Exec(const path: pathstr; const comline: comstr);
  106. Function DosExitCode: word;
  107. {Disk}
  108. Function DiskFree(drive: byte) : int64;
  109. Function DiskSize(drive: byte) : int64;
  110. Procedure FindFirst(const path: pathstr; attr: word; var f: searchRec);
  111. Procedure FindNext(var f: searchRec);
  112. Procedure FindClose(Var f: SearchRec);
  113. {File}
  114. Procedure GetFAttr(var f; var attr: word);
  115. Procedure GetFTime(var f; var time: longint);
  116. Function FSearch(path: pathstr; dirlist: string): pathstr;
  117. Function FExpand(const path: pathstr): pathstr;
  118. Procedure FSplit(path: pathstr; var dir: dirstr; var name: namestr; var ext: extstr);
  119. {Environment}
  120. Function EnvCount: longint;
  121. Function EnvStr(index: integer): string;
  122. Function GetEnv(envvar: string): string;
  123. {Misc}
  124. Procedure SetFAttr(var f; attr: word);
  125. Procedure SetFTime(var f; time: longint);
  126. Procedure GetCBreak(var breakvalue: boolean);
  127. Procedure SetCBreak(breakvalue: boolean);
  128. Procedure GetVerify(var verify: boolean);
  129. Procedure SetVerify(verify: boolean);
  130. {Do Nothing Functions}
  131. Procedure SwapVectors;
  132. Procedure GetIntVec(intno: byte; var vector: pointer);
  133. Procedure SetIntVec(intno: byte; vector: pointer);
  134. Procedure Keep(exitcode: word);
  135. Const
  136. { allow EXEC to inherited handles from calling process,
  137. needed for FPREDIR in ide/text
  138. now set to true by default because
  139. other OS also pass open handles to childs
  140. finally reset to false after Florian's response PM }
  141. ExecInheritsHandles : BOOL = false;
  142. implementation
  143. uses strings;
  144. type
  145. OSVERSIONINFO = record
  146. dwOSVersionInfoSize : DWORD;
  147. dwMajorVersion : DWORD;
  148. dwMinorVersion : DWORD;
  149. dwBuildNumber : DWORD;
  150. dwPlatformId : DWORD;
  151. szCSDVersion : array[0..127] of char;
  152. end;
  153. LPOSVERSIONINFO = ^OSVERSIONINFO;
  154. var
  155. versioninfo : OSVERSIONINFO;
  156. kernel32dll : THandle;
  157. {******************************************************************************
  158. --- Conversion ---
  159. ******************************************************************************}
  160. function GetLastError : DWORD;
  161. external 'kernel32' name 'GetLastError';
  162. function FileTimeToDosDateTime(const ft :TFileTime;var data,time : word) : longbool;
  163. external 'kernel32' name 'FileTimeToDosDateTime';
  164. function DosDateTimeToFileTime(date,time : word;var ft :TFileTime) : longbool;
  165. external 'kernel32' name 'DosDateTimeToFileTime';
  166. function FileTimeToLocalFileTime(const ft : TFileTime;var lft : TFileTime) : longbool;
  167. external 'kernel32' name 'FileTimeToLocalFileTime';
  168. function LocalFileTimeToFileTime(const lft : TFileTime;var ft : TFileTime) : longbool;
  169. external 'kernel32' name 'LocalFileTimeToFileTime';
  170. type
  171. Longrec=packed record
  172. lo,hi : word;
  173. end;
  174. function Last2DosError(d:dword):integer;
  175. begin
  176. Last2DosError:=d;
  177. end;
  178. Function DosToWinAttr (Const Attr : Longint) : longint;
  179. begin
  180. DosToWinAttr:=Attr;
  181. end;
  182. Function WinToDosAttr (Const Attr : Longint) : longint;
  183. begin
  184. WinToDosAttr:=Attr;
  185. end;
  186. Function DosToWinTime (DTime:longint;Var Wtime : TFileTime):longbool;
  187. var
  188. lft : TFileTime;
  189. begin
  190. DosToWinTime:=DosDateTimeToFileTime(longrec(dtime).hi,longrec(dtime).lo,lft) and
  191. LocalFileTimeToFileTime(lft,Wtime);
  192. end;
  193. Function WinToDosTime (Const Wtime : TFileTime;var DTime:longint):longbool;
  194. var
  195. lft : TFileTime;
  196. begin
  197. WinToDosTime:=FileTimeToLocalFileTime(WTime,lft) and
  198. FileTimeToDosDateTime(lft,longrec(dtime).hi,longrec(dtime).lo);
  199. end;
  200. {******************************************************************************
  201. --- Dos Interrupt ---
  202. ******************************************************************************}
  203. procedure intr(intno : byte;var regs : registers);
  204. begin
  205. { !!!!!!!! }
  206. end;
  207. procedure msdos(var regs : registers);
  208. begin
  209. { !!!!!!!! }
  210. end;
  211. {******************************************************************************
  212. --- Info / Date / Time ---
  213. ******************************************************************************}
  214. function GetVersion : longint;
  215. external 'kernel32' name 'GetVersion';
  216. procedure GetLocalTime(var t : TSystemTime);
  217. external 'kernel32' name 'GetLocalTime';
  218. function SetLocalTime(const t : TSystemTime) : longbool;
  219. external 'kernel32' name 'SetLocalTime';
  220. function dosversion : word;
  221. begin
  222. dosversion:=GetVersion;
  223. end;
  224. procedure getdate(var year,month,mday,wday : word);
  225. var
  226. t : TSystemTime;
  227. begin
  228. GetLocalTime(t);
  229. year:=t.wYear;
  230. month:=t.wMonth;
  231. mday:=t.wDay;
  232. wday:=t.wDayOfWeek;
  233. end;
  234. procedure setdate(year,month,day : word);
  235. var
  236. t : TSystemTime;
  237. begin
  238. { we need the time set privilege }
  239. { so this function crash currently }
  240. {!!!!!}
  241. GetLocalTime(t);
  242. t.wYear:=year;
  243. t.wMonth:=month;
  244. t.wDay:=day;
  245. { only a quite good solution, we can loose some ms }
  246. SetLocalTime(t);
  247. end;
  248. procedure gettime(var hour,minute,second,sec100 : word);
  249. var
  250. t : TSystemTime;
  251. begin
  252. GetLocalTime(t);
  253. hour:=t.wHour;
  254. minute:=t.wMinute;
  255. second:=t.wSecond;
  256. sec100:=t.wMilliSeconds div 10;
  257. end;
  258. procedure settime(hour,minute,second,sec100 : word);
  259. var
  260. t : TSystemTime;
  261. begin
  262. { we need the time set privilege }
  263. { so this function crash currently }
  264. {!!!!!}
  265. GetLocalTime(t);
  266. t.wHour:=hour;
  267. t.wMinute:=minute;
  268. t.wSecond:=second;
  269. t.wMilliSeconds:=sec100*10;
  270. SetLocalTime(t);
  271. end;
  272. Procedure packtime(var t : datetime;var p : longint);
  273. Begin
  274. 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);
  275. End;
  276. Procedure unpacktime(p : longint;var t : datetime);
  277. Begin
  278. with t do
  279. begin
  280. sec:=(p and 31) shl 1;
  281. min:=(p shr 5) and 63;
  282. hour:=(p shr 11) and 31;
  283. day:=(p shr 16) and 31;
  284. month:=(p shr 21) and 15;
  285. year:=(p shr 25)+1980;
  286. end;
  287. End;
  288. {******************************************************************************
  289. --- Exec ---
  290. ******************************************************************************}
  291. function CreateProcess(lpApplicationName: PChar; lpCommandLine: PChar;
  292. lpProcessAttributes, lpThreadAttributes: PSecurityAttributes;
  293. bInheritHandles: BOOL; dwCreationFlags: DWORD; lpEnvironment: Pointer;
  294. lpCurrentDirectory: PChar; const lpStartupInfo: TStartupInfo;
  295. var lpProcessInformation: TProcessInformation): longbool;
  296. external 'kernel32' name 'CreateProcessA';
  297. function getExitCodeProcess(h:THandle;var code:longint):longbool;
  298. external 'kernel32' name 'GetExitCodeProcess';
  299. function WaitForSingleObject(hHandle: THandle; dwMilliseconds: DWORD): DWORD;
  300. external 'kernel32' name 'WaitForSingleObject';
  301. function CloseHandle(h : THandle) : longint;
  302. external 'kernel32' name 'CloseHandle';
  303. var
  304. lastdosexitcode : word;
  305. procedure exec(const path : pathstr;const comline : comstr);
  306. var
  307. SI: TStartupInfo;
  308. PI: TProcessInformation;
  309. Proc : THandle;
  310. l : Longint;
  311. AppPath,
  312. AppParam : array[0..255] of char;
  313. begin
  314. FillChar(SI, SizeOf(SI), 0);
  315. SI.cb:=SizeOf(SI);
  316. SI.wShowWindow:=1;
  317. Move(Path[1],AppPath,length(Path));
  318. AppPath[Length(Path)]:=#0;
  319. AppParam[0]:='-';
  320. AppParam[1]:=' ';
  321. Move(ComLine[1],AppParam[2],length(Comline));
  322. AppParam[Length(ComLine)+2]:=#0;
  323. if not CreateProcess(PChar(@AppPath), PChar(@AppParam),
  324. Nil, Nil, ExecInheritsHandles,$20, Nil, Nil, SI, PI) then
  325. begin
  326. DosError:=Last2DosError(GetLastError);
  327. exit;
  328. end;
  329. Proc:=PI.hProcess;
  330. CloseHandle(PI.hThread);
  331. if WaitForSingleObject(Proc, Infinite) <> $ffffffff then
  332. GetExitCodeProcess(Proc,l)
  333. else
  334. l:=-1;
  335. CloseHandle(Proc);
  336. LastDosExitCode:=l;
  337. end;
  338. function dosexitcode : word;
  339. begin
  340. dosexitcode:=lastdosexitcode;
  341. end;
  342. procedure getcbreak(var breakvalue : boolean);
  343. begin
  344. { !! No Win32 Function !! }
  345. end;
  346. procedure setcbreak(breakvalue : boolean);
  347. begin
  348. { !! No Win32 Function !! }
  349. end;
  350. procedure getverify(var verify : boolean);
  351. begin
  352. { !! No Win32 Function !! }
  353. end;
  354. procedure setverify(verify : boolean);
  355. begin
  356. { !! No Win32 Function !! }
  357. end;
  358. {******************************************************************************
  359. --- Disk ---
  360. ******************************************************************************}
  361. function GetDiskFreeSpace(drive:pchar;var sector_cluster,bytes_sector,
  362. freeclusters,totalclusters:longint):longbool;
  363. external 'kernel32' name 'GetDiskFreeSpaceA';
  364. type
  365. TGetDiskFreeSpaceEx = function(drive:pchar;var availableforcaller,
  366. total,free):longbool;stdcall;
  367. var
  368. GetDiskFreeSpaceEx : TGetDiskFreeSpaceEx;
  369. function diskfree(drive : byte) : int64;
  370. var
  371. disk : array[1..4] of char;
  372. secs,bytes,
  373. free,total : longint;
  374. qwtotal,qwfree,qwcaller : int64;
  375. begin
  376. if drive=0 then
  377. begin
  378. disk[1]:='\';
  379. disk[2]:=#0;
  380. end
  381. else
  382. begin
  383. disk[1]:=chr(drive+64);
  384. disk[2]:=':';
  385. disk[3]:='\';
  386. disk[4]:=#0;
  387. end;
  388. if assigned(GetDiskFreeSpaceEx) then
  389. begin
  390. if GetDiskFreeSpaceEx(@disk,qwcaller,qwtotal,qwfree) then
  391. diskfree:=qwfree
  392. else
  393. diskfree:=-1;
  394. end
  395. else
  396. begin
  397. if GetDiskFreeSpace(@disk,secs,bytes,free,total) then
  398. diskfree:=free*secs*bytes
  399. else
  400. diskfree:=-1;
  401. end;
  402. end;
  403. function disksize(drive : byte) : int64;
  404. var
  405. disk : array[1..4] of char;
  406. secs,bytes,
  407. free,total : longint;
  408. qwtotal,qwfree,qwcaller : int64;
  409. begin
  410. if drive=0 then
  411. begin
  412. disk[1]:='\';
  413. disk[2]:=#0;
  414. end
  415. else
  416. begin
  417. disk[1]:=chr(drive+64);
  418. disk[2]:=':';
  419. disk[3]:='\';
  420. disk[4]:=#0;
  421. end;
  422. if assigned(GetDiskFreeSpaceEx) then
  423. begin
  424. if GetDiskFreeSpaceEx(@disk,qwcaller,qwtotal,qwfree) then
  425. disksize:=qwtotal
  426. else
  427. disksize:=-1;
  428. end
  429. else
  430. begin
  431. if GetDiskFreeSpace(@disk,secs,bytes,free,total) then
  432. disksize:=total*secs*bytes
  433. else
  434. disksize:=-1;
  435. end;
  436. end;
  437. {******************************************************************************
  438. --- Findfirst FindNext ---
  439. ******************************************************************************}
  440. { Needed kernel calls }
  441. function FindFirstFile (lpFileName: PChar; var lpFindFileData: TWIN32FindData): THandle;
  442. external 'kernel32' name 'FindFirstFileA';
  443. function FindNextFile (hFindFile: THandle; var lpFindFileData: TWIN32FindData): LongBool;
  444. external 'kernel32' name 'FindNextFileA';
  445. function FindCloseFile (hFindFile: THandle): LongBool;
  446. external 'kernel32' name 'FindClose';
  447. Procedure StringToPchar (Var S : String);
  448. Var L : Longint;
  449. begin
  450. L:=ord(S[0]);
  451. Move (S[1],S[0],L);
  452. S[L]:=#0;
  453. end;
  454. procedure FindMatch(var f:searchrec);
  455. begin
  456. { Find file with correct attribute }
  457. While (F.W32FindData.dwFileAttributes and F.ExcludeAttr)<>0 do
  458. begin
  459. if not FindNextFile (F.FindHandle,F.W32FindData) then
  460. begin
  461. DosError:=Last2DosError(GetLastError);
  462. exit;
  463. end;
  464. end;
  465. { Convert some attributes back }
  466. f.size:=F.W32FindData.NFileSizeLow;
  467. f.attr:=WinToDosAttr(F.W32FindData.dwFileAttributes);
  468. WinToDosTime(F.W32FindData.ftLastWriteTime,f.Time);
  469. f.Name:=StrPas(@F.W32FindData.cFileName);
  470. end;
  471. procedure findfirst(const path : pathstr;attr : word;var f : searchRec);
  472. begin
  473. { no error }
  474. doserror:=0;
  475. F.Name:=Path;
  476. F.Attr:=attr;
  477. F.ExcludeAttr:=(not Attr) and ($1e); {hidden,sys,dir,volume}
  478. StringToPchar(f.name);
  479. { FindFirstFile is a Win32 Call }
  480. F.FindHandle:=FindFirstFile (pchar(@f.Name),F.W32FindData);
  481. If longint(F.FindHandle)=Invalid_Handle_value then
  482. begin
  483. DosError:=Last2DosError(GetLastError);
  484. exit;
  485. end;
  486. { Find file with correct attribute }
  487. FindMatch(f);
  488. end;
  489. procedure findnext(var f : searchRec);
  490. begin
  491. { no error }
  492. doserror:=0;
  493. if not FindNextFile (F.FindHandle,F.W32FindData) then
  494. begin
  495. DosError:=Last2DosError(GetLastError);
  496. exit;
  497. end;
  498. { Find file with correct attribute }
  499. FindMatch(f);
  500. end;
  501. procedure swapvectors;
  502. begin
  503. end;
  504. Procedure FindClose(Var f: SearchRec);
  505. begin
  506. If longint(F.FindHandle)<>Invalid_Handle_value then
  507. FindCloseFile(F.FindHandle);
  508. end;
  509. {******************************************************************************
  510. --- File ---
  511. ******************************************************************************}
  512. function GetFileTime(h : longint;creation,lastaccess,lastwrite : PFileTime) : longbool;
  513. external 'kernel32' name 'GetFileTime';
  514. function SetFileTime(h : longint;creation,lastaccess,lastwrite : PFileTime) : longbool;
  515. external 'kernel32' name 'SetFileTime';
  516. function SetFileAttributes(lpFileName : pchar;dwFileAttributes : longint) : longbool;
  517. external 'kernel32' name 'SetFileAttributesA';
  518. function GetFileAttributes(lpFileName : pchar) : longint;
  519. external 'kernel32' name 'GetFileAttributesA';
  520. procedure fsplit(path : pathstr;var dir : dirstr;var name : namestr;var ext : extstr);
  521. var
  522. dotpos,p1,i : longint;
  523. begin
  524. { allow slash as backslash }
  525. for i:=1 to length(path) do
  526. if path[i]='/' then path[i]:='\';
  527. { get drive name }
  528. p1:=pos(':',path);
  529. if p1>0 then
  530. begin
  531. dir:=path[1]+':';
  532. delete(path,1,p1);
  533. end
  534. else
  535. dir:='';
  536. { split the path and the name, there are no more path informtions }
  537. { if path contains no backslashes }
  538. while true do
  539. begin
  540. p1:=pos('\',path);
  541. if p1=0 then
  542. break;
  543. dir:=dir+copy(path,1,p1);
  544. delete(path,1,p1);
  545. end;
  546. { try to find out a extension }
  547. Ext:='';
  548. i:=Length(Path);
  549. DotPos:=256;
  550. While (i>0) Do
  551. Begin
  552. If (Path[i]='.') Then
  553. begin
  554. DotPos:=i;
  555. break;
  556. end;
  557. Dec(i);
  558. end;
  559. Ext:=Copy(Path,DotPos,255);
  560. Name:=Copy(Path,1,DotPos - 1);
  561. end;
  562. { <immobilizer> }
  563. function GetFullPathName(lpFileName: PChar; nBufferLength: Longint; lpBuffer: PChar; var lpFilePart : PChar):DWORD;
  564. external 'kernel32' name 'GetFullPathNameA';
  565. function FExpand(const path : pathstr) : pathstr;
  566. var value : Array[0..255] of char;
  567. tmp : PChar;
  568. p : string;
  569. i : Longint;
  570. begin
  571. { allow slash as backslash }
  572. p := path;
  573. for i:=1 to length(p) do
  574. if p[i]='/' then
  575. p[i]:='\';
  576. StringToPchar(p);
  577. {getmem(value, 255); lets avoid slow getmem PM
  578. getmem(tmp, 255); not necessary
  579. tmp only points to the filename part at function exit }
  580. GetFullPathName(@p, 255, value, tmp);
  581. FExpand := strpas(value);
  582. { freemem(value,255) this would be nice at least if we use getmem !! PM }
  583. end;
  584. function SearchPath(lpPath : PChar; lpFileName : PChar; lpExtension : PChar; nBufferLength : Longint; lpBuffer : PChar;
  585. var lpFilePart : PChar) : Longint; external 'kernel32' name 'SearchPathA';
  586. Function FSearch(path: pathstr; dirlist: string): pathstr;
  587. var temp : PChar;
  588. value : Array [0..255] of char;
  589. i : Longint;
  590. dir,dir2 : dirstr;
  591. lastchar : char;
  592. name : namestr;
  593. ext : extstr;
  594. begin
  595. fsearch:='';
  596. for i:=1 to length(path) do
  597. if path[i]='/' then
  598. path[i]:='\';
  599. fsplit(path,dir,name,ext);
  600. for i:=1 to length(dirlist) do
  601. if dirlist[i]='/' then
  602. dirlist[i]:='\';
  603. { allow slash as backslash }
  604. StringToPchar(name);
  605. StringToPchar(ext);
  606. repeat
  607. i:=pos(';',dirlist);
  608. while i=1 do
  609. begin
  610. delete(dirlist,1,1);
  611. i:=pos(';',dirlist);
  612. end;
  613. if i=0 then
  614. begin
  615. dir2:=dirlist;
  616. dirlist:='';
  617. end
  618. else
  619. begin
  620. dir2:=Copy(dirlist,1,i-1);
  621. dirlist:=Copy(dirlist,i+1,255);
  622. end;
  623. { don't add anything if dir2 is empty string }
  624. if dir2<>'' then
  625. lastchar:=dir2[length(dir2)]
  626. else
  627. lastchar:='\';
  628. if (lastchar<>'\') and (lastchar<>':') then
  629. dir2:=dir2+'\'+dir
  630. else
  631. dir2:=dir2+dir;
  632. StringToPchar(dir2);
  633. if SearchPath(@dir2, @name, @ext, 255, @value, temp)>0 then
  634. begin
  635. fsearch := strpas(value);
  636. exit;
  637. end;
  638. until dirlist='';
  639. end;
  640. { </immobilizer> }
  641. procedure getftime(var f;var time : longint);
  642. var
  643. ft : TFileTime;
  644. begin
  645. if GetFileTime(filerec(f).Handle,nil,nil,@ft) and
  646. WinToDosTime(ft,time) then
  647. exit
  648. else
  649. time:=0;
  650. end;
  651. procedure setftime(var f;time : longint);
  652. var
  653. ft : TFileTime;
  654. begin
  655. if DosToWinTime(time,ft) then
  656. SetFileTime(filerec(f).Handle,nil,nil,@ft);
  657. end;
  658. procedure getfattr(var f;var attr : word);
  659. var
  660. l : longint;
  661. begin
  662. doserror:=0;
  663. l:=GetFileAttributes(filerec(f).name);
  664. if l=$ffffffff then
  665. doserror:=getlasterror;
  666. attr:=l;
  667. end;
  668. procedure setfattr(var f;attr : word);
  669. begin
  670. doserror:=0;
  671. if not(SetFileAttributes(filerec(f).name,attr)) then
  672. doserror:=getlasterror;
  673. end;
  674. {******************************************************************************
  675. --- Environment ---
  676. ******************************************************************************}
  677. {
  678. The environment is a block of zero terminated strings
  679. terminated by a #0
  680. }
  681. function GetEnvironmentStrings : pchar;
  682. external 'kernel32' name 'GetEnvironmentStringsA';
  683. function FreeEnvironmentStrings(p : pchar) : longbool;
  684. external 'kernel32' name 'FreeEnvironmentStringsA';
  685. function envcount : longint;
  686. var
  687. hp,p : pchar;
  688. count : longint;
  689. begin
  690. p:=GetEnvironmentStrings;
  691. hp:=p;
  692. count:=0;
  693. while hp^<>#0 do
  694. begin
  695. { next string entry}
  696. hp:=hp+strlen(hp)+1;
  697. inc(count);
  698. end;
  699. FreeEnvironmentStrings(p);
  700. envcount:=count;
  701. end;
  702. Function EnvStr(index: integer): string;
  703. var
  704. hp,p : pchar;
  705. count,i : longint;
  706. begin
  707. { envcount takes some time in win32 }
  708. count:=envcount;
  709. { range checking }
  710. if (index<=0) or (index>count) then
  711. begin
  712. envstr:='';
  713. exit;
  714. end;
  715. p:=GetEnvironmentStrings;
  716. hp:=p;
  717. { retrive the string with the given index }
  718. for i:=2 to index do
  719. hp:=hp+strlen(hp)+1;
  720. envstr:=strpas(hp);
  721. FreeEnvironmentStrings(p);
  722. end;
  723. Function GetEnv(envvar: string): string;
  724. var
  725. s : string;
  726. i : longint;
  727. hp,p : pchar;
  728. begin
  729. getenv:='';
  730. p:=GetEnvironmentStrings;
  731. hp:=p;
  732. while hp^<>#0 do
  733. begin
  734. s:=strpas(hp);
  735. i:=pos('=',s);
  736. if upcase(copy(s,1,i-1))=upcase(envvar) then
  737. begin
  738. getenv:=copy(s,i+1,length(s)-i);
  739. break;
  740. end;
  741. { next string entry}
  742. hp:=hp+strlen(hp)+1;
  743. end;
  744. FreeEnvironmentStrings(p);
  745. end;
  746. {******************************************************************************
  747. --- Not Supported ---
  748. ******************************************************************************}
  749. Procedure keep(exitcode : word);
  750. Begin
  751. End;
  752. Procedure getintvec(intno : byte;var vector : pointer);
  753. Begin
  754. End;
  755. Procedure setintvec(intno : byte;vector : pointer);
  756. Begin
  757. End;
  758. function FreeLibrary(hLibModule : THANDLE) : longbool;
  759. external 'kernel32' name 'FreeLibrary';
  760. function GetVersionEx(var VersionInformation:OSVERSIONINFO) : longbool;
  761. external 'kernel32' name 'GetVersionExA';
  762. function LoadLibrary(lpLibFileName : pchar):THandle;
  763. external 'kernel32' name 'LoadLibraryA';
  764. function GetProcAddress(hModule : THandle;lpProcName : pchar) : pointer;
  765. external 'kernel32' name 'GetProcAddress';
  766. var
  767. oldexitproc : pointer;
  768. procedure dosexitproc;
  769. begin
  770. exitproc:=oldexitproc;
  771. if kernel32dll<>0 then
  772. FreeLibrary(kernel32dll);
  773. end;
  774. begin
  775. oldexitproc:=exitproc;
  776. exitproc:=@dosexitproc;
  777. versioninfo.dwOSVersionInfoSize:=sizeof(versioninfo);
  778. GetVersionEx(versioninfo);
  779. kernel32dll:=0;
  780. GetDiskFreeSpaceEx:=nil;
  781. if ((versioninfo.dwPlatformId=VER_PLATFORM_WIN32_WINDOWS) and
  782. (versioninfo.dwBuildNUmber>=1000)) or
  783. (versioninfo.dwPlatformId=VER_PLATFORM_WIN32_NT) then
  784. begin
  785. kernel32dll:=LoadLibrary('kernel32');
  786. if kernel32dll<>0 then
  787. GetDiskFreeSpaceEx:=TGetDiskFreeSpaceEx(GetProcAddress(kernel32dll,'GetDiskFreeSpaceExA'));
  788. end;
  789. end.
  790. {
  791. $Log$
  792. Revision 1.31 2000-01-24 21:57:56 florian
  793. * disksize/diskfree return now a int64
  794. Revision 1.30 2000/01/11 13:45:19 pierre
  795. * fsearch was still worng for multiple pathes
  796. Revision 1.29 2000/01/11 12:49:26 pierre
  797. * fsearch bugs and fexpand memory leak fixed
  798. Revision 1.28 2000/01/07 16:41:52 daniel
  799. * copyright 2000
  800. Revision 1.27 2000/01/07 16:32:34 daniel
  801. * copyright 2000 added
  802. Revision 1.26 1999/11/18 15:28:47 michael
  803. * Better and faster Fexpand, SearchPath fromPiotr Sawicki
  804. Revision 1.25 1999/10/14 08:57:51 peter
  805. * getfattr resets doserror
  806. Revision 1.24 1999/10/12 08:56:48 pierre
  807. * fix form bug660
  808. Revision 1.23 1999/09/22 12:34:05 pierre
  809. ExecInheritsHandles reset to false by default
  810. Revision 1.22 1999/09/21 13:24:32 pierre
  811. * typo error
  812. Revision 1.21 1999/09/21 12:37:09 pierre
  813. * Child inherits now file handles from parent in Exec by default
  814. Revision 1.20 1999/09/21 11:34:40 pierre
  815. + ExecInheritedHandles boolean
  816. Revision 1.19 1999/08/25 13:57:55 michael
  817. + Patched FSearch from Frank McCormick
  818. Revision 1.18 1999/08/12 09:24:14 michael
  819. Fixed win32finddata size; searchrec.excludeattr was overwritten.
  820. Revision 1.17 1999/05/16 17:08:59 peter
  821. * fixed driveletter checking
  822. Revision 1.16 1999/05/08 19:47:27 peter
  823. * check ioresult after getdir calls
  824. Revision 1.15 1999/04/28 11:42:52 peter
  825. + FileNameCaseSensetive boolean
  826. Revision 1.14 1999/04/08 12:23:07 peter
  827. * removed os.inc
  828. Revision 1.13 1998/11/16 15:48:53 peter
  829. * fixed longbool returns for api calls
  830. Revision 1.12 1998/10/27 10:55:55 michael
  831. * environment vars are case insensitive under WinNT/DOS
  832. Revision 1.11 1998/10/22 15:32:38 pierre
  833. * fsplit adapted to long filenames
  834. Revision 1.10 1998/10/16 14:20:06 peter
  835. * removed writelns
  836. Revision 1.9 1998/10/16 08:55:26 peter
  837. * findfirst is now more delphi alike
  838. Revision 1.8 1998/08/16 09:12:11 michael
  839. Corrected fexpand behaviour.
  840. Revision 1.7 1998/06/10 10:39:13 peter
  841. * working w32 rtl
  842. Revision 1.6 1998/06/08 23:07:45 peter
  843. * dos interface is now 100% compatible
  844. * fixed call PASCALMAIN which must be direct asm
  845. Revision 1.5 1998/05/06 12:36:50 michael
  846. + Removed log from before restored version.
  847. Revision 1.4 1998/04/27 14:01:38 florian
  848. * was uncompilable
  849. Revision 1.3 1998/04/26 22:37:02 florian
  850. + getftime, unpacktime, packtime
  851. Revision 1.2 1998/04/26 21:49:09 florian
  852. + first compiling and working version
  853. }