dos.pp 26 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070
  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. function GetShortName(var p : String) : boolean;
  120. function GetLongName(var p : String) : boolean;
  121. {Environment}
  122. Function EnvCount: longint;
  123. Function EnvStr(index: integer): string;
  124. Function GetEnv(envvar: string): string;
  125. {Misc}
  126. Procedure SetFAttr(var f; attr: word);
  127. Procedure SetFTime(var f; time: longint);
  128. Procedure GetCBreak(var breakvalue: boolean);
  129. Procedure SetCBreak(breakvalue: boolean);
  130. Procedure GetVerify(var verify: boolean);
  131. Procedure SetVerify(verify: boolean);
  132. {Do Nothing Functions}
  133. Procedure SwapVectors;
  134. Procedure GetIntVec(intno: byte; var vector: pointer);
  135. Procedure SetIntVec(intno: byte; vector: pointer);
  136. Procedure Keep(exitcode: word);
  137. Const
  138. { allow EXEC to inherited handles from calling process,
  139. needed for FPREDIR in ide/text
  140. now set to true by default because
  141. other OS also pass open handles to childs
  142. finally reset to false after Florian's response PM }
  143. ExecInheritsHandles : BOOL = false;
  144. implementation
  145. uses strings;
  146. type
  147. OSVERSIONINFO = record
  148. dwOSVersionInfoSize : DWORD;
  149. dwMajorVersion : DWORD;
  150. dwMinorVersion : DWORD;
  151. dwBuildNumber : DWORD;
  152. dwPlatformId : DWORD;
  153. szCSDVersion : array[0..127] of char;
  154. end;
  155. LPOSVERSIONINFO = ^OSVERSIONINFO;
  156. var
  157. versioninfo : OSVERSIONINFO;
  158. kernel32dll : THandle;
  159. {******************************************************************************
  160. --- Conversion ---
  161. ******************************************************************************}
  162. function GetLastError : DWORD;
  163. external 'kernel32' name 'GetLastError';
  164. function FileTimeToDosDateTime(const ft :TFileTime;var data,time : word) : longbool;
  165. external 'kernel32' name 'FileTimeToDosDateTime';
  166. function DosDateTimeToFileTime(date,time : word;var ft :TFileTime) : longbool;
  167. external 'kernel32' name 'DosDateTimeToFileTime';
  168. function FileTimeToLocalFileTime(const ft : TFileTime;var lft : TFileTime) : longbool;
  169. external 'kernel32' name 'FileTimeToLocalFileTime';
  170. function LocalFileTimeToFileTime(const lft : TFileTime;var ft : TFileTime) : longbool;
  171. external 'kernel32' name 'LocalFileTimeToFileTime';
  172. type
  173. Longrec=packed record
  174. lo,hi : word;
  175. end;
  176. function Last2DosError(d:dword):integer;
  177. begin
  178. Last2DosError:=d;
  179. end;
  180. Function DosToWinAttr (Const Attr : Longint) : longint;
  181. begin
  182. DosToWinAttr:=Attr;
  183. end;
  184. Function WinToDosAttr (Const Attr : Longint) : longint;
  185. begin
  186. WinToDosAttr:=Attr;
  187. end;
  188. Function DosToWinTime (DTime:longint;Var Wtime : TFileTime):longbool;
  189. var
  190. lft : TFileTime;
  191. begin
  192. DosToWinTime:=DosDateTimeToFileTime(longrec(dtime).hi,longrec(dtime).lo,lft) and
  193. LocalFileTimeToFileTime(lft,Wtime);
  194. end;
  195. Function WinToDosTime (Const Wtime : TFileTime;var DTime:longint):longbool;
  196. var
  197. lft : TFileTime;
  198. begin
  199. WinToDosTime:=FileTimeToLocalFileTime(WTime,lft) and
  200. FileTimeToDosDateTime(lft,longrec(dtime).hi,longrec(dtime).lo);
  201. end;
  202. {******************************************************************************
  203. --- Dos Interrupt ---
  204. ******************************************************************************}
  205. procedure intr(intno : byte;var regs : registers);
  206. begin
  207. { !!!!!!!! }
  208. end;
  209. procedure msdos(var regs : registers);
  210. begin
  211. { !!!!!!!! }
  212. end;
  213. {******************************************************************************
  214. --- Info / Date / Time ---
  215. ******************************************************************************}
  216. function GetVersion : longint;
  217. external 'kernel32' name 'GetVersion';
  218. procedure GetLocalTime(var t : TSystemTime);
  219. external 'kernel32' name 'GetLocalTime';
  220. function SetLocalTime(const t : TSystemTime) : longbool;
  221. external 'kernel32' name 'SetLocalTime';
  222. function dosversion : word;
  223. begin
  224. dosversion:=GetVersion;
  225. end;
  226. procedure getdate(var year,month,mday,wday : word);
  227. var
  228. t : TSystemTime;
  229. begin
  230. GetLocalTime(t);
  231. year:=t.wYear;
  232. month:=t.wMonth;
  233. mday:=t.wDay;
  234. wday:=t.wDayOfWeek;
  235. end;
  236. procedure setdate(year,month,day : word);
  237. var
  238. t : TSystemTime;
  239. begin
  240. { we need the time set privilege }
  241. { so this function crash currently }
  242. {!!!!!}
  243. GetLocalTime(t);
  244. t.wYear:=year;
  245. t.wMonth:=month;
  246. t.wDay:=day;
  247. { only a quite good solution, we can loose some ms }
  248. SetLocalTime(t);
  249. end;
  250. procedure gettime(var hour,minute,second,sec100 : word);
  251. var
  252. t : TSystemTime;
  253. begin
  254. GetLocalTime(t);
  255. hour:=t.wHour;
  256. minute:=t.wMinute;
  257. second:=t.wSecond;
  258. sec100:=t.wMilliSeconds div 10;
  259. end;
  260. procedure settime(hour,minute,second,sec100 : word);
  261. var
  262. t : TSystemTime;
  263. begin
  264. { we need the time set privilege }
  265. { so this function crash currently }
  266. {!!!!!}
  267. GetLocalTime(t);
  268. t.wHour:=hour;
  269. t.wMinute:=minute;
  270. t.wSecond:=second;
  271. t.wMilliSeconds:=sec100*10;
  272. SetLocalTime(t);
  273. end;
  274. Procedure packtime(var t : datetime;var p : longint);
  275. Begin
  276. 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);
  277. End;
  278. Procedure unpacktime(p : longint;var t : datetime);
  279. Begin
  280. with t do
  281. begin
  282. sec:=(p and 31) shl 1;
  283. min:=(p shr 5) and 63;
  284. hour:=(p shr 11) and 31;
  285. day:=(p shr 16) and 31;
  286. month:=(p shr 21) and 15;
  287. year:=(p shr 25)+1980;
  288. end;
  289. End;
  290. {******************************************************************************
  291. --- Exec ---
  292. ******************************************************************************}
  293. function CreateProcess(lpApplicationName: PChar; lpCommandLine: PChar;
  294. lpProcessAttributes, lpThreadAttributes: PSecurityAttributes;
  295. bInheritHandles: BOOL; dwCreationFlags: DWORD; lpEnvironment: Pointer;
  296. lpCurrentDirectory: PChar; const lpStartupInfo: TStartupInfo;
  297. var lpProcessInformation: TProcessInformation): longbool;
  298. external 'kernel32' name 'CreateProcessA';
  299. function getExitCodeProcess(h:THandle;var code:longint):longbool;
  300. external 'kernel32' name 'GetExitCodeProcess';
  301. function WaitForSingleObject(hHandle: THandle; dwMilliseconds: DWORD): DWORD;
  302. external 'kernel32' name 'WaitForSingleObject';
  303. function CloseHandle(h : THandle) : longint;
  304. external 'kernel32' name 'CloseHandle';
  305. var
  306. lastdosexitcode : longint;
  307. procedure exec(const path : pathstr;const comline : comstr);
  308. var
  309. SI: TStartupInfo;
  310. PI: TProcessInformation;
  311. Proc : THandle;
  312. l : Longint;
  313. AppPath,
  314. AppParam : array[0..255] of char;
  315. begin
  316. FillChar(SI, SizeOf(SI), 0);
  317. SI.cb:=SizeOf(SI);
  318. SI.wShowWindow:=1;
  319. Move(Path[1],AppPath,length(Path));
  320. AppPath[Length(Path)]:=#0;
  321. AppParam[0]:='-';
  322. AppParam[1]:=' ';
  323. Move(ComLine[1],AppParam[2],length(Comline));
  324. AppParam[Length(ComLine)+2]:=#0;
  325. if not CreateProcess(PChar(@AppPath), PChar(@AppParam),
  326. Nil, Nil, ExecInheritsHandles,$20, Nil, Nil, SI, PI) then
  327. begin
  328. DosError:=Last2DosError(GetLastError);
  329. exit;
  330. end;
  331. Proc:=PI.hProcess;
  332. CloseHandle(PI.hThread);
  333. if WaitForSingleObject(Proc, Infinite) <> $ffffffff then
  334. GetExitCodeProcess(Proc,l)
  335. else
  336. l:=-1;
  337. CloseHandle(Proc);
  338. LastDosExitCode:=l;
  339. end;
  340. function dosexitcode : word;
  341. begin
  342. dosexitcode:=lastdosexitcode and $ffff;
  343. end;
  344. procedure getcbreak(var breakvalue : boolean);
  345. begin
  346. { !! No Win32 Function !! }
  347. end;
  348. procedure setcbreak(breakvalue : boolean);
  349. begin
  350. { !! No Win32 Function !! }
  351. end;
  352. procedure getverify(var verify : boolean);
  353. begin
  354. { !! No Win32 Function !! }
  355. end;
  356. procedure setverify(verify : boolean);
  357. begin
  358. { !! No Win32 Function !! }
  359. end;
  360. {******************************************************************************
  361. --- Disk ---
  362. ******************************************************************************}
  363. function GetDiskFreeSpace(drive:pchar;var sector_cluster,bytes_sector,
  364. freeclusters,totalclusters:longint):longbool;
  365. external 'kernel32' name 'GetDiskFreeSpaceA';
  366. type
  367. TGetDiskFreeSpaceEx = function(drive:pchar;var availableforcaller,
  368. total,free):longbool;stdcall;
  369. var
  370. GetDiskFreeSpaceEx : TGetDiskFreeSpaceEx;
  371. function diskfree(drive : byte) : int64;
  372. var
  373. disk : array[1..4] of char;
  374. secs,bytes,
  375. free,total : longint;
  376. qwtotal,qwfree,qwcaller : int64;
  377. begin
  378. if drive=0 then
  379. begin
  380. disk[1]:='\';
  381. disk[2]:=#0;
  382. end
  383. else
  384. begin
  385. disk[1]:=chr(drive+64);
  386. disk[2]:=':';
  387. disk[3]:='\';
  388. disk[4]:=#0;
  389. end;
  390. if assigned(GetDiskFreeSpaceEx) then
  391. begin
  392. if GetDiskFreeSpaceEx(@disk,qwcaller,qwtotal,qwfree) then
  393. diskfree:=qwfree
  394. else
  395. diskfree:=-1;
  396. end
  397. else
  398. begin
  399. if GetDiskFreeSpace(@disk,secs,bytes,free,total) then
  400. diskfree:=int64(free)*secs*bytes
  401. else
  402. diskfree:=-1;
  403. end;
  404. end;
  405. function disksize(drive : byte) : int64;
  406. var
  407. disk : array[1..4] of char;
  408. secs,bytes,
  409. free,total : longint;
  410. qwtotal,qwfree,qwcaller : int64;
  411. begin
  412. if drive=0 then
  413. begin
  414. disk[1]:='\';
  415. disk[2]:=#0;
  416. end
  417. else
  418. begin
  419. disk[1]:=chr(drive+64);
  420. disk[2]:=':';
  421. disk[3]:='\';
  422. disk[4]:=#0;
  423. end;
  424. if assigned(GetDiskFreeSpaceEx) then
  425. begin
  426. if GetDiskFreeSpaceEx(@disk,qwcaller,qwtotal,qwfree) then
  427. disksize:=qwtotal
  428. else
  429. disksize:=-1;
  430. end
  431. else
  432. begin
  433. if GetDiskFreeSpace(@disk,secs,bytes,free,total) then
  434. disksize:=int64(total)*secs*bytes
  435. else
  436. disksize:=-1;
  437. end;
  438. end;
  439. {******************************************************************************
  440. --- Findfirst FindNext ---
  441. ******************************************************************************}
  442. { Needed kernel calls }
  443. function FindFirstFile (lpFileName: PChar; var lpFindFileData: TWIN32FindData): THandle;
  444. external 'kernel32' name 'FindFirstFileA';
  445. function FindNextFile (hFindFile: THandle; var lpFindFileData: TWIN32FindData): LongBool;
  446. external 'kernel32' name 'FindNextFileA';
  447. function FindCloseFile (hFindFile: THandle): LongBool;
  448. external 'kernel32' name 'FindClose';
  449. Procedure StringToPchar (Var S : String);
  450. Var L : Longint;
  451. begin
  452. L:=ord(S[0]);
  453. Move (S[1],S[0],L);
  454. S[L]:=#0;
  455. end;
  456. Procedure PCharToString (Var S : String);
  457. Var L : Longint;
  458. begin
  459. L:=strlen(pchar(@S[0]));
  460. Move (S[0],S[1],L);
  461. S[0]:=char(l);
  462. end;
  463. procedure FindMatch(var f:searchrec);
  464. begin
  465. { Find file with correct attribute }
  466. While (F.W32FindData.dwFileAttributes and F.ExcludeAttr)<>0 do
  467. begin
  468. if not FindNextFile (F.FindHandle,F.W32FindData) then
  469. begin
  470. DosError:=Last2DosError(GetLastError);
  471. exit;
  472. end;
  473. end;
  474. { Convert some attributes back }
  475. f.size:=F.W32FindData.NFileSizeLow;
  476. f.attr:=WinToDosAttr(F.W32FindData.dwFileAttributes);
  477. WinToDosTime(F.W32FindData.ftLastWriteTime,f.Time);
  478. f.Name:=StrPas(@F.W32FindData.cFileName);
  479. end;
  480. procedure findfirst(const path : pathstr;attr : word;var f : searchRec);
  481. begin
  482. { no error }
  483. doserror:=0;
  484. F.Name:=Path;
  485. F.Attr:=attr;
  486. F.ExcludeAttr:=(not Attr) and ($1e); {hidden,sys,dir,volume}
  487. StringToPchar(f.name);
  488. { FindFirstFile is a Win32 Call }
  489. F.FindHandle:=FindFirstFile (pchar(@f.Name),F.W32FindData);
  490. If longint(F.FindHandle)=Invalid_Handle_value then
  491. begin
  492. DosError:=Last2DosError(GetLastError);
  493. exit;
  494. end;
  495. { Find file with correct attribute }
  496. FindMatch(f);
  497. end;
  498. procedure findnext(var f : searchRec);
  499. begin
  500. { no error }
  501. doserror:=0;
  502. if not FindNextFile (F.FindHandle,F.W32FindData) then
  503. begin
  504. DosError:=Last2DosError(GetLastError);
  505. exit;
  506. end;
  507. { Find file with correct attribute }
  508. FindMatch(f);
  509. end;
  510. procedure swapvectors;
  511. begin
  512. end;
  513. Procedure FindClose(Var f: SearchRec);
  514. begin
  515. If longint(F.FindHandle)<>Invalid_Handle_value then
  516. FindCloseFile(F.FindHandle);
  517. end;
  518. {******************************************************************************
  519. --- File ---
  520. ******************************************************************************}
  521. function GetFileTime(h : longint;creation,lastaccess,lastwrite : PFileTime) : longbool;
  522. external 'kernel32' name 'GetFileTime';
  523. function SetFileTime(h : longint;creation,lastaccess,lastwrite : PFileTime) : longbool;
  524. external 'kernel32' name 'SetFileTime';
  525. function SetFileAttributes(lpFileName : pchar;dwFileAttributes : longint) : longbool;
  526. external 'kernel32' name 'SetFileAttributesA';
  527. function GetFileAttributes(lpFileName : pchar) : longint;
  528. external 'kernel32' name 'GetFileAttributesA';
  529. procedure fsplit(path : pathstr;var dir : dirstr;var name : namestr;var ext : extstr);
  530. var
  531. dotpos,p1,i : longint;
  532. begin
  533. { allow slash as backslash }
  534. for i:=1 to length(path) do
  535. if path[i]='/' then path[i]:='\';
  536. { get drive name }
  537. p1:=pos(':',path);
  538. if p1>0 then
  539. begin
  540. dir:=path[1]+':';
  541. delete(path,1,p1);
  542. end
  543. else
  544. dir:='';
  545. { split the path and the name, there are no more path informtions }
  546. { if path contains no backslashes }
  547. while true do
  548. begin
  549. p1:=pos('\',path);
  550. if p1=0 then
  551. break;
  552. dir:=dir+copy(path,1,p1);
  553. delete(path,1,p1);
  554. end;
  555. { try to find out a extension }
  556. Ext:='';
  557. i:=Length(Path);
  558. DotPos:=256;
  559. While (i>0) Do
  560. Begin
  561. If (Path[i]='.') Then
  562. begin
  563. DotPos:=i;
  564. break;
  565. end;
  566. Dec(i);
  567. end;
  568. Ext:=Copy(Path,DotPos,255);
  569. Name:=Copy(Path,1,DotPos - 1);
  570. end;
  571. { <immobilizer> }
  572. function GetFullPathName(lpFileName: PChar; nBufferLength: Longint; lpBuffer: PChar; var lpFilePart : PChar):DWORD;
  573. external 'kernel32' name 'GetFullPathNameA';
  574. function GetShortPathName(lpszLongPath:pchar; lpszShortPath:pchar; cchBuffer:DWORD):DWORD;
  575. external 'kernel32' name 'GetShortPathNameA';
  576. function FExpand(const path : pathstr) : pathstr;
  577. var value : Array[0..255] of char;
  578. tmp : PChar;
  579. p : string;
  580. i : Longint;
  581. begin
  582. { if path is empty then return the current dir }
  583. if path<>'' then
  584. p:=path
  585. else
  586. p:='.';
  587. { allow slash as backslash }
  588. for i:=1 to length(p) do
  589. if p[i]='/' then
  590. p[i]:='\';
  591. StringToPchar(p);
  592. tmp:=nil;
  593. fillchar(value,sizeof(value),0);
  594. GetFullPathName(@p, 255, value, tmp);
  595. FExpand := strpas(value);
  596. end;
  597. function SearchPath(lpPath : PChar; lpFileName : PChar; lpExtension : PChar; nBufferLength : Longint; lpBuffer : PChar;
  598. var lpFilePart : PChar) : Longint; external 'kernel32' name 'SearchPathA';
  599. Function FSearch(path: pathstr; dirlist: string): pathstr;
  600. var temp : PChar;
  601. value : Array [0..255] of char;
  602. i : Longint;
  603. dir,dir2 : dirstr;
  604. lastchar : char;
  605. name : namestr;
  606. ext : extstr;
  607. begin
  608. fsearch:='';
  609. for i:=1 to length(path) do
  610. if path[i]='/' then
  611. path[i]:='\';
  612. fsplit(path,dir,name,ext);
  613. for i:=1 to length(dirlist) do
  614. if dirlist[i]='/' then
  615. dirlist[i]:='\';
  616. { allow slash as backslash }
  617. StringToPchar(name);
  618. StringToPchar(ext);
  619. StringToPchar(dir);
  620. if SearchPath(@dir, @name, @ext, 255, @value, temp)>0 then
  621. begin
  622. fsearch := strpas(value);
  623. exit;
  624. end;
  625. PCharToString(dir);
  626. repeat
  627. i:=pos(';',dirlist);
  628. while i=1 do
  629. begin
  630. delete(dirlist,1,1);
  631. i:=pos(';',dirlist);
  632. end;
  633. if i=0 then
  634. begin
  635. dir2:=dirlist;
  636. dirlist:='';
  637. end
  638. else
  639. begin
  640. dir2:=Copy(dirlist,1,i-1);
  641. dirlist:=Copy(dirlist,i+1,255);
  642. end;
  643. { don't add anything if dir2 is empty string }
  644. if dir2<>'' then
  645. lastchar:=dir2[length(dir2)]
  646. else
  647. lastchar:='\';
  648. if (lastchar<>'\') and (lastchar<>':') then
  649. dir2:=dir2+'\'+dir
  650. else
  651. dir2:=dir2+dir;
  652. StringToPchar(dir2);
  653. if SearchPath(@dir2, @name, @ext, 255, @value, temp)>0 then
  654. begin
  655. fsearch := strpas(value);
  656. exit;
  657. end;
  658. until dirlist='';
  659. end;
  660. { </immobilizer> }
  661. procedure getftime(var f;var time : longint);
  662. var
  663. ft : TFileTime;
  664. begin
  665. if GetFileTime(filerec(f).Handle,nil,nil,@ft) and
  666. WinToDosTime(ft,time) then
  667. exit
  668. else
  669. time:=0;
  670. end;
  671. procedure setftime(var f;time : longint);
  672. var
  673. ft : TFileTime;
  674. begin
  675. if DosToWinTime(time,ft) then
  676. SetFileTime(filerec(f).Handle,nil,nil,@ft);
  677. end;
  678. procedure getfattr(var f;var attr : word);
  679. var
  680. l : longint;
  681. begin
  682. doserror:=0;
  683. l:=GetFileAttributes(filerec(f).name);
  684. if l=$ffffffff then
  685. begin
  686. doserror:=getlasterror;
  687. attr:=0;
  688. end
  689. else
  690. attr:=l and $ffff;
  691. end;
  692. procedure setfattr(var f;attr : word);
  693. begin
  694. doserror:=0;
  695. if not(SetFileAttributes(filerec(f).name,attr)) then
  696. doserror:=getlasterror;
  697. end;
  698. { change to short filename if successful win32 call PM }
  699. function GetShortName(var p : String) : boolean;
  700. var
  701. buffer : array[0..255] of char;
  702. ret : longint;
  703. begin
  704. {we can't mess with p, because we have to return it if call is
  705. unsuccesfully.}
  706. if Length(p)>0 then {copy p to array of char}
  707. move(p[1],buffer[0],length(p));
  708. buffer[length(p)]:=chr(0);
  709. {Should return value load loaddoserror?}
  710. ret:=GetShortPathName(@buffer,@buffer,255);
  711. if ret=0 then
  712. p:=strpas(buffer);
  713. GetShortName:=ret<>0;
  714. end;
  715. { change to long filename if successful DOS call PM }
  716. function GetLongName(var p : String) : boolean;
  717. var
  718. lfn,sfn : array[0..255] of char;
  719. filename : pchar;
  720. ret : longint;
  721. begin
  722. {contrary to shortname, SDK does not mention input buffer can be equal
  723. to output.}
  724. if Length(p)>0 then {copy p to array of char}
  725. move(p[1],sfn[0],length(p));
  726. sfn[length(p)]:=chr(0);
  727. fillchar(lfn,sizeof(lfn),#0);
  728. filename:=nil;
  729. {Should return value load loaddoserror?}
  730. ret:=GetFullPathName(@sfn,255,@lfn,filename);
  731. if ret=0 then
  732. p:=strpas(lfn); {lfn here returns full path, filename only fn}
  733. GetLongName:=ret<>0;
  734. end;
  735. {******************************************************************************
  736. --- Environment ---
  737. ******************************************************************************}
  738. {
  739. The environment is a block of zero terminated strings
  740. terminated by a #0
  741. }
  742. function GetEnvironmentStrings : pchar;
  743. external 'kernel32' name 'GetEnvironmentStringsA';
  744. function FreeEnvironmentStrings(p : pchar) : longbool;
  745. external 'kernel32' name 'FreeEnvironmentStringsA';
  746. function envcount : longint;
  747. var
  748. hp,p : pchar;
  749. count : longint;
  750. begin
  751. p:=GetEnvironmentStrings;
  752. hp:=p;
  753. count:=0;
  754. while hp^<>#0 do
  755. begin
  756. { next string entry}
  757. hp:=hp+strlen(hp)+1;
  758. inc(count);
  759. end;
  760. FreeEnvironmentStrings(p);
  761. envcount:=count;
  762. end;
  763. Function EnvStr(index: integer): string;
  764. var
  765. hp,p : pchar;
  766. count,i : longint;
  767. begin
  768. { envcount takes some time in win32 }
  769. count:=envcount;
  770. { range checking }
  771. if (index<=0) or (index>count) then
  772. begin
  773. envstr:='';
  774. exit;
  775. end;
  776. p:=GetEnvironmentStrings;
  777. hp:=p;
  778. { retrive the string with the given index }
  779. for i:=2 to index do
  780. hp:=hp+strlen(hp)+1;
  781. envstr:=strpas(hp);
  782. FreeEnvironmentStrings(p);
  783. end;
  784. Function GetEnv(envvar: string): string;
  785. var
  786. s : string;
  787. i : longint;
  788. hp,p : pchar;
  789. begin
  790. getenv:='';
  791. p:=GetEnvironmentStrings;
  792. hp:=p;
  793. while hp^<>#0 do
  794. begin
  795. s:=strpas(hp);
  796. i:=pos('=',s);
  797. if upcase(copy(s,1,i-1))=upcase(envvar) then
  798. begin
  799. getenv:=copy(s,i+1,length(s)-i);
  800. break;
  801. end;
  802. { next string entry}
  803. hp:=hp+strlen(hp)+1;
  804. end;
  805. FreeEnvironmentStrings(p);
  806. end;
  807. {******************************************************************************
  808. --- Not Supported ---
  809. ******************************************************************************}
  810. Procedure keep(exitcode : word);
  811. Begin
  812. End;
  813. Procedure getintvec(intno : byte;var vector : pointer);
  814. Begin
  815. End;
  816. Procedure setintvec(intno : byte;vector : pointer);
  817. Begin
  818. End;
  819. function FreeLibrary(hLibModule : THANDLE) : longbool;
  820. external 'kernel32' name 'FreeLibrary';
  821. function GetVersionEx(var VersionInformation:OSVERSIONINFO) : longbool;
  822. external 'kernel32' name 'GetVersionExA';
  823. function LoadLibrary(lpLibFileName : pchar):THandle;
  824. external 'kernel32' name 'LoadLibraryA';
  825. function GetProcAddress(hModule : THandle;lpProcName : pchar) : pointer;
  826. external 'kernel32' name 'GetProcAddress';
  827. var
  828. oldexitproc : pointer;
  829. procedure dosexitproc;
  830. begin
  831. exitproc:=oldexitproc;
  832. if kernel32dll<>0 then
  833. FreeLibrary(kernel32dll);
  834. end;
  835. begin
  836. oldexitproc:=exitproc;
  837. exitproc:=@dosexitproc;
  838. versioninfo.dwOSVersionInfoSize:=sizeof(versioninfo);
  839. GetVersionEx(versioninfo);
  840. kernel32dll:=0;
  841. GetDiskFreeSpaceEx:=nil;
  842. if ((versioninfo.dwPlatformId=VER_PLATFORM_WIN32_WINDOWS) and
  843. (versioninfo.dwBuildNUmber>=1000)) or
  844. (versioninfo.dwPlatformId=VER_PLATFORM_WIN32_NT) then
  845. begin
  846. kernel32dll:=LoadLibrary('kernel32');
  847. if kernel32dll<>0 then
  848. GetDiskFreeSpaceEx:=TGetDiskFreeSpaceEx(GetProcAddress(kernel32dll,'GetDiskFreeSpaceExA'));
  849. end;
  850. end.
  851. {
  852. $Log$
  853. Revision 1.1 2000-07-13 06:31:19 michael
  854. + Initial import
  855. Revision 1.37 2000/05/26 12:03:13 marco
  856. * added getlongname and getshortname
  857. Revision 1.36 2000/05/19 13:20:37 pierre
  858. * avoid some Range Check errors
  859. Revision 1.35 2000/04/17 20:43:27 pierre
  860. fix bug 902 for win32 and linux
  861. Revision 1.34 2000/02/26 13:24:26 peter
  862. * fixed fexpand with empty argument to return current dir
  863. Revision 1.33 2000/02/09 16:59:34 peter
  864. * truncated log
  865. Revision 1.32 2000/02/02 17:32:59 pierre
  866. * use int64 typecast in diskfree and disksize
  867. Revision 1.31 2000/01/24 21:57:56 florian
  868. * disksize/diskfree return now a int64
  869. Revision 1.30 2000/01/11 13:45:19 pierre
  870. * fsearch was still worng for multiple pathes
  871. Revision 1.29 2000/01/11 12:49:26 pierre
  872. * fsearch bugs and fexpand memory leak fixed
  873. Revision 1.28 2000/01/07 16:41:52 daniel
  874. * copyright 2000
  875. Revision 1.27 2000/01/07 16:32:34 daniel
  876. * copyright 2000 added
  877. Revision 1.26 1999/11/18 15:28:47 michael
  878. * Better and faster Fexpand, SearchPath fromPiotr Sawicki
  879. Revision 1.25 1999/10/14 08:57:51 peter
  880. * getfattr resets doserror
  881. Revision 1.24 1999/10/12 08:56:48 pierre
  882. * fix form bug660
  883. Revision 1.23 1999/09/22 12:34:05 pierre
  884. ExecInheritsHandles reset to false by default
  885. Revision 1.22 1999/09/21 13:24:32 pierre
  886. * typo error
  887. Revision 1.21 1999/09/21 12:37:09 pierre
  888. * Child inherits now file handles from parent in Exec by default
  889. Revision 1.20 1999/09/21 11:34:40 pierre
  890. + ExecInheritedHandles boolean
  891. Revision 1.19 1999/08/25 13:57:55 michael
  892. + Patched FSearch from Frank McCormick
  893. Revision 1.18 1999/08/12 09:24:14 michael
  894. Fixed win32finddata size; searchrec.excludeattr was overwritten.
  895. }