dos.pp 24 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060
  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. Uses
  15. Watcom;
  16. Const
  17. {Bitmasks for CPU Flags}
  18. fcarry = $0001;
  19. fparity = $0004;
  20. fauxiliary = $0010;
  21. fzero = $0040;
  22. fsign = $0080;
  23. foverflow = $0800;
  24. {Bitmasks for file attribute}
  25. readonly = $01;
  26. hidden = $02;
  27. sysfile = $04;
  28. volumeid = $08;
  29. directory = $10;
  30. archive = $20;
  31. anyfile = $3F;
  32. {File Status}
  33. fmclosed = $D7B0;
  34. fminput = $D7B1;
  35. fmoutput = $D7B2;
  36. fminout = $D7B3;
  37. Type
  38. { Needed for LFN Support }
  39. ComStr = String[255];
  40. PathStr = String[255];
  41. DirStr = String[255];
  42. NameStr = String[255];
  43. ExtStr = String[255];
  44. {
  45. filerec.inc contains the definition of the filerec.
  46. textrec.inc contains the definition of the textrec.
  47. It is in a separate file to make it available in other units without
  48. having to use the DOS unit for it.
  49. }
  50. {$i filerec.inc}
  51. {$i textrec.inc}
  52. DateTime = packed record
  53. Year,
  54. Month,
  55. Day,
  56. Hour,
  57. Min,
  58. Sec : word;
  59. End;
  60. searchrec = packed record
  61. fill : array[1..21] of byte;
  62. attr : byte;
  63. time : longint;
  64. { reserved : word; not in DJGPP V2 }
  65. size : longint;
  66. name : string[255]; { LFN Name, DJGPP uses only [12] but more can't hurt (PFV) }
  67. end;
  68. Registers = Watcom.Registers;
  69. Var
  70. DosError : integer;
  71. {Interrupt}
  72. Procedure Intr(intno: byte; var regs: registers);
  73. Procedure MSDos(var regs: registers);
  74. {Info/Date/Time}
  75. Function DosVersion: Word;
  76. Procedure GetDate(var year, month, mday, wday: word);
  77. Procedure GetTime(var hour, minute, second, sec100: word);
  78. procedure SetDate(year,month,day: word);
  79. Procedure SetTime(hour,minute,second,sec100: word);
  80. Procedure UnpackTime(p: longint; var t: datetime);
  81. Procedure PackTime(var t: datetime; var p: longint);
  82. {Exec}
  83. Procedure Exec(const path: pathstr; const comline: comstr);
  84. Function DosExitCode: word;
  85. {Disk}
  86. Function DiskFree(drive: byte) : int64;
  87. Function DiskSize(drive: byte) : int64;
  88. Procedure FindFirst(const path: pathstr; attr: word; var f: searchRec);
  89. Procedure FindNext(var f: searchRec);
  90. Procedure FindClose(Var f: SearchRec);
  91. {File}
  92. Procedure GetFAttr(var f; var attr: word);
  93. Procedure GetFTime(var f; var time: longint);
  94. Function FSearch(path: pathstr; dirlist: string): pathstr;
  95. Function FExpand(const path: pathstr): pathstr;
  96. Procedure FSplit(path: pathstr; var dir: dirstr; var name: namestr; var ext: extstr);
  97. function GetShortName(var p : String) : boolean;
  98. function GetLongName(var p : String) : boolean;
  99. {Environment}
  100. Function EnvCount: longint;
  101. Function EnvStr(index: integer): string;
  102. Function GetEnv(envvar: string): string;
  103. {Misc}
  104. Procedure SetFAttr(var f; attr: word);
  105. Procedure SetFTime(var f; time: longint);
  106. Procedure GetCBreak(var breakvalue: boolean);
  107. Procedure SetCBreak(breakvalue: boolean);
  108. Procedure GetVerify(var verify: boolean);
  109. Procedure SetVerify(verify: boolean);
  110. {Do Nothing Functions}
  111. Procedure SwapVectors;
  112. Procedure GetIntVec(intno: byte; var vector: pointer);
  113. Procedure SetIntVec(intno: byte; vector: pointer);
  114. Procedure Keep(exitcode: word);
  115. implementation
  116. uses
  117. strings;
  118. {******************************************************************************
  119. --- Dos Interrupt ---
  120. ******************************************************************************}
  121. var
  122. dosregs : registers;
  123. procedure LoadDosError;
  124. var
  125. r : registers;
  126. SimpleDosError : word;
  127. begin
  128. if (dosregs.flags and fcarry) <> 0 then
  129. begin
  130. { I got a extended error = 0
  131. while CarryFlag was set from Exec function }
  132. SimpleDosError:=dosregs.ax;
  133. r.eax:=$5900;
  134. r.ebx:=$0;
  135. realintr($21,r);
  136. { conversion from word to integer !!
  137. gave a Bound check error if ax is $FFFF !! PM }
  138. doserror:=integer(r.ax);
  139. case doserror of
  140. 0 : DosError:=integer(SimpleDosError);
  141. 19 : DosError:=150;
  142. 21 : DosError:=152;
  143. end;
  144. end
  145. else
  146. doserror:=0;
  147. end;
  148. procedure intr(intno : byte;var regs : registers);
  149. begin
  150. realintr(intno,regs);
  151. end;
  152. procedure msdos(var regs : registers);
  153. begin
  154. intr($21,regs);
  155. end;
  156. {******************************************************************************
  157. --- Info / Date / Time ---
  158. ******************************************************************************}
  159. function dosversion : word;
  160. begin
  161. dosregs.ax:=$3000;
  162. msdos(dosregs);
  163. dosversion:=dosregs.ax;
  164. end;
  165. procedure getdate(var year,month,mday,wday : word);
  166. begin
  167. dosregs.ax:=$2a00;
  168. msdos(dosregs);
  169. wday:=dosregs.al;
  170. year:=dosregs.cx;
  171. month:=dosregs.dh;
  172. mday:=dosregs.dl;
  173. end;
  174. procedure setdate(year,month,day : word);
  175. begin
  176. dosregs.cx:=year;
  177. dosregs.dh:=month;
  178. dosregs.dl:=day;
  179. dosregs.ah:=$2b;
  180. msdos(dosregs);
  181. end;
  182. procedure gettime(var hour,minute,second,sec100 : word);
  183. begin
  184. dosregs.ah:=$2c;
  185. msdos(dosregs);
  186. hour:=dosregs.ch;
  187. minute:=dosregs.cl;
  188. second:=dosregs.dh;
  189. sec100:=dosregs.dl;
  190. end;
  191. procedure settime(hour,minute,second,sec100 : word);
  192. begin
  193. dosregs.ch:=hour;
  194. dosregs.cl:=minute;
  195. dosregs.dh:=second;
  196. dosregs.dl:=sec100;
  197. dosregs.ah:=$2d;
  198. msdos(dosregs);
  199. end;
  200. Procedure packtime(var t : datetime;var p : longint);
  201. Begin
  202. 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);
  203. End;
  204. Procedure unpacktime(p : longint;var t : datetime);
  205. Begin
  206. with t do
  207. begin
  208. sec:=(p and 31) shl 1;
  209. min:=(p shr 5) and 63;
  210. hour:=(p shr 11) and 31;
  211. day:=(p shr 16) and 31;
  212. month:=(p shr 21) and 15;
  213. year:=(p shr 25)+1980;
  214. end;
  215. End;
  216. {******************************************************************************
  217. --- Exec ---
  218. ******************************************************************************}
  219. var
  220. lastdosexitcode : word;
  221. procedure exec(const path : pathstr;const comline : comstr);
  222. type
  223. realptr = packed record
  224. ofs,seg : word;
  225. end;
  226. texecblock = packed record
  227. envseg : word;
  228. comtail : realptr;
  229. firstFCB : realptr;
  230. secondFCB : realptr;
  231. iniStack : realptr;
  232. iniCSIP : realptr;
  233. end;
  234. var
  235. current_dos_buffer_pos,
  236. arg_ofs,
  237. i,la_env,
  238. la_p,la_c,la_e,
  239. fcb1_la,fcb2_la : longint;
  240. execblock : texecblock;
  241. c,p : string;
  242. function paste_to_dos(src : string) : boolean;
  243. var
  244. c : array[0..255] of char;
  245. begin
  246. paste_to_dos:=false;
  247. if current_dos_buffer_pos+length(src)+1>transfer_buffer+tb_size then
  248. RunError(217);
  249. move(src[1],c[0],length(src));
  250. c[length(src)]:=#0;
  251. seg_move(get_ds,longint(@c),dosmemselector,current_dos_buffer_pos,length(src)+1);
  252. current_dos_buffer_pos:=current_dos_buffer_pos+length(src)+1;
  253. paste_to_dos:=true;
  254. end;
  255. begin
  256. { create command line }
  257. move(comline[0],c[1],length(comline)+1);
  258. c[length(comline)+2]:=#13;
  259. c[0]:=char(length(comline)+2);
  260. { create path }
  261. p:=path;
  262. for i:=1 to length(p) do
  263. if p[i]='/' then
  264. p[i]:='\';
  265. if LFNSupport then
  266. GetShortName(p);
  267. { create buffer }
  268. la_env:=transfer_buffer;
  269. while (la_env and 15)<>0 do
  270. inc(la_env);
  271. current_dos_buffer_pos:=la_env;
  272. { copy environment }
  273. for i:=1 to envcount do
  274. paste_to_dos(envstr(i));
  275. paste_to_dos(''); { adds a double zero at the end }
  276. { allow slash as backslash }
  277. la_p:=current_dos_buffer_pos;
  278. paste_to_dos(p);
  279. la_c:=current_dos_buffer_pos;
  280. paste_to_dos(c);
  281. la_e:=current_dos_buffer_pos;
  282. fcb1_la:=la_e;
  283. la_e:=la_e+16;
  284. fcb2_la:=la_e;
  285. la_e:=la_e+16;
  286. { allocate FCB see dosexec code }
  287. arg_ofs:=1;
  288. while (c[arg_ofs] in [' ',#9]) do
  289. inc(arg_ofs);
  290. dosregs.ax:=$2901;
  291. dosregs.ds:=(la_c+arg_ofs) shr 4;
  292. dosregs.esi:=(la_c+arg_ofs) and 15;
  293. dosregs.es:=fcb1_la shr 4;
  294. dosregs.edi:=fcb1_la and 15;
  295. msdos(dosregs);
  296. { allocate second FCB see dosexec code }
  297. repeat
  298. inc(arg_ofs);
  299. until (c[arg_ofs] in [' ',#9,#13]);
  300. if c[arg_ofs]<>#13 then
  301. begin
  302. repeat
  303. inc(arg_ofs);
  304. until not (c[arg_ofs] in [' ',#9]);
  305. end;
  306. dosregs.ax:=$2901;
  307. dosregs.ds:=(la_c+arg_ofs) shr 4;
  308. dosregs.si:=(la_c+arg_ofs) and 15;
  309. dosregs.es:=fcb2_la shr 4;
  310. dosregs.di:=fcb2_la and 15;
  311. msdos(dosregs);
  312. with execblock do
  313. begin
  314. envseg:=la_env shr 4;
  315. comtail.seg:=la_c shr 4;
  316. comtail.ofs:=la_c and 15;
  317. firstFCB.seg:=fcb1_la shr 4;
  318. firstFCB.ofs:=fcb1_la and 15;
  319. secondFCB.seg:=fcb2_la shr 4;
  320. secondFCB.ofs:=fcb2_la and 15;
  321. end;
  322. seg_move(get_ds,longint(@execblock),dosmemselector,la_e,sizeof(texecblock));
  323. dosregs.edx:=la_p and 15;
  324. dosregs.ds:=la_p shr 4;
  325. dosregs.ebx:=la_e and 15;
  326. dosregs.es:=la_e shr 4;
  327. dosregs.ax:=$4b00;
  328. msdos(dosregs);
  329. LoadDosError;
  330. if DosError=0 then
  331. begin
  332. dosregs.ax:=$4d00;
  333. msdos(dosregs);
  334. LastDosExitCode:=DosRegs.al
  335. end
  336. else
  337. LastDosExitCode:=0;
  338. end;
  339. function dosexitcode : word;
  340. begin
  341. dosexitcode:=lastdosexitcode;
  342. end;
  343. procedure getcbreak(var breakvalue : boolean);
  344. begin
  345. dosregs.ax:=$3300;
  346. msdos(dosregs);
  347. breakvalue:=dosregs.dl<>0;
  348. end;
  349. procedure setcbreak(breakvalue : boolean);
  350. begin
  351. dosregs.ax:=$3301;
  352. dosregs.dl:=ord(breakvalue);
  353. msdos(dosregs);
  354. end;
  355. procedure getverify(var verify : boolean);
  356. begin
  357. dosregs.ah:=$54;
  358. msdos(dosregs);
  359. verify:=dosregs.al<>0;
  360. end;
  361. procedure setverify(verify : boolean);
  362. begin
  363. dosregs.ah:=$2e;
  364. dosregs.al:=ord(verify);
  365. msdos(dosregs);
  366. end;
  367. {******************************************************************************
  368. --- Disk ---
  369. ******************************************************************************}
  370. TYPE ExtendedFat32FreeSpaceRec=packed Record
  371. RetSize : WORD; { (ret) size of returned structure}
  372. Strucversion : WORD; {(call) structure version (0000h)
  373. (ret) actual structure version (0000h)}
  374. SecPerClus, {number of sectors per cluster}
  375. BytePerSec, {number of bytes per sector}
  376. AvailClusters, {number of available clusters}
  377. TotalClusters, {total number of clusters on the drive}
  378. AvailPhysSect, {physical sectors available on the drive}
  379. TotalPhysSect, {total physical sectors on the drive}
  380. AvailAllocUnits, {Available allocation units}
  381. TotalAllocUnits : DWORD; {Total allocation units}
  382. Dummy,Dummy2 : DWORD; {8 bytes reserved}
  383. END;
  384. function do_diskdata(drive : byte; Free : BOOLEAN) : Int64;
  385. VAR
  386. S : String;
  387. Rec : ExtendedFat32FreeSpaceRec;
  388. BEGIN
  389. if (swap(dosversion)>=$070A) AND LFNSupport then
  390. begin
  391. S:='C:\'#0;
  392. if Drive=0 then
  393. begin
  394. GetDir(Drive,S);
  395. Setlength(S,4);
  396. S[4]:=#0;
  397. end
  398. else
  399. S[1]:=chr(Drive+64);
  400. Rec.Strucversion:=0;
  401. dosmemput(tb_segment,tb_offset,Rec,SIZEOF(ExtendedFat32FreeSpaceRec));
  402. dosmemput(tb_segment,tb_offset+Sizeof(ExtendedFat32FreeSpaceRec)+1,S[1],4);
  403. dosregs.dx:=tb_offset+Sizeof(ExtendedFat32FreeSpaceRec)+1;
  404. dosregs.ds:=tb_segment;
  405. dosregs.di:=tb_offset;
  406. dosregs.es:=tb_segment;
  407. dosregs.cx:=Sizeof(ExtendedFat32FreeSpaceRec);
  408. dosregs.ax:=$7303;
  409. msdos(dosregs);
  410. if (dosregs.flags and fcarry) = 0 then {No error clausule in int except cf}
  411. begin
  412. copyfromdos(rec,Sizeof(ExtendedFat32FreeSpaceRec));
  413. if Free then
  414. Do_DiskData:=int64(rec.AvailAllocUnits)*rec.SecPerClus*rec.BytePerSec
  415. else
  416. Do_DiskData:=int64(rec.TotalAllocUnits)*rec.SecPerClus*rec.BytePerSec;
  417. end
  418. else
  419. Do_DiskData:=-1;
  420. end
  421. else
  422. begin
  423. dosregs.dl:=drive;
  424. dosregs.ah:=$36;
  425. msdos(dosregs);
  426. if dosregs.ax<>$FFFF then
  427. begin
  428. if Free then
  429. Do_DiskData:=int64(dosregs.ax)*dosregs.bx*dosregs.cx
  430. else
  431. Do_DiskData:=int64(dosregs.ax)*dosregs.cx*dosregs.dx;
  432. end
  433. else
  434. do_diskdata:=-1;
  435. end;
  436. end;
  437. function diskfree(drive : byte) : int64;
  438. begin
  439. diskfree:=Do_DiskData(drive,TRUE);
  440. end;
  441. function disksize(drive : byte) : int64;
  442. begin
  443. disksize:=Do_DiskData(drive,false);
  444. end;
  445. {******************************************************************************
  446. --- LFNFindfirst LFNFindNext ---
  447. ******************************************************************************}
  448. type
  449. LFNSearchRec=packed record
  450. attr,
  451. crtime,
  452. crtimehi,
  453. actime,
  454. actimehi,
  455. lmtime,
  456. lmtimehi,
  457. sizehi,
  458. size : longint;
  459. reserved : array[0..7] of byte;
  460. name : array[0..259] of byte;
  461. shortname : array[0..13] of byte;
  462. end;
  463. procedure LFNSearchRec2Dos(const w:LFNSearchRec;hdl:longint;var d:Searchrec;from_findfirst : boolean);
  464. var
  465. Len : longint;
  466. begin
  467. With w do
  468. begin
  469. FillChar(d,sizeof(SearchRec),0);
  470. if DosError=0 then
  471. len:=StrLen(@Name)
  472. else
  473. len:=0;
  474. d.Name[0]:=chr(len);
  475. Move(Name[0],d.Name[1],Len);
  476. d.Time:=lmTime;
  477. d.Size:=Size;
  478. d.Attr:=Attr and $FF;
  479. if (DosError<>0) and from_findfirst then
  480. hdl:=-1;
  481. Move(hdl,d.Fill,4);
  482. end;
  483. end;
  484. procedure LFNFindFirst(path:pchar;attr:longint;var s:searchrec);
  485. var
  486. i : longint;
  487. w : LFNSearchRec;
  488. begin
  489. { allow slash as backslash }
  490. for i:=0 to strlen(path) do
  491. if path[i]='/' then path[i]:='\';
  492. dosregs.si:=1; { use ms-dos time }
  493. { don't include the label if not asked for it, needed for network drives }
  494. if attr=$8 then
  495. dosregs.ecx:=8
  496. else
  497. dosregs.ecx:=attr and (not 8);
  498. dosregs.edx:=tb_offset+Sizeof(LFNSearchrec)+1;
  499. dosmemput(tb_segment,tb_offset+Sizeof(LFNSearchrec)+1,path^,strlen(path)+1);
  500. dosregs.ds:=tb_segment;
  501. dosregs.edi:=tb_offset;
  502. dosregs.es:=tb_segment;
  503. dosregs.ax:=$714e;
  504. msdos(dosregs);
  505. LoadDosError;
  506. copyfromdos(w,sizeof(LFNSearchRec));
  507. LFNSearchRec2Dos(w,dosregs.ax,s,true);
  508. end;
  509. procedure LFNFindNext(var s:searchrec);
  510. var
  511. hdl : longint;
  512. w : LFNSearchRec;
  513. begin
  514. Move(s.Fill,hdl,4);
  515. dosregs.si:=1; { use ms-dos time }
  516. dosregs.edi:=tb_offset;
  517. dosregs.es:=tb_segment;
  518. dosregs.ebx:=hdl;
  519. dosregs.ax:=$714f;
  520. msdos(dosregs);
  521. LoadDosError;
  522. copyfromdos(w,sizeof(LFNSearchRec));
  523. LFNSearchRec2Dos(w,hdl,s,false);
  524. end;
  525. procedure LFNFindClose(var s:searchrec);
  526. var
  527. hdl : longint;
  528. begin
  529. Move(s.Fill,hdl,4);
  530. { Do not call MsDos if FindFirst returned with an error }
  531. if hdl=-1 then
  532. begin
  533. DosError:=0;
  534. exit;
  535. end;
  536. dosregs.ebx:=hdl;
  537. dosregs.ax:=$71a1;
  538. msdos(dosregs);
  539. LoadDosError;
  540. end;
  541. {******************************************************************************
  542. --- DosFindfirst DosFindNext ---
  543. ******************************************************************************}
  544. procedure dossearchrec2searchrec(var f : searchrec);
  545. var
  546. len : longint;
  547. begin
  548. { Check is necessary!! OS/2's VDM doesn't clear the name with #0 if the }
  549. { file doesn't exist! (JM) }
  550. if dosError = 0 then
  551. len:=StrLen(@f.Name)
  552. else len := 0;
  553. Move(f.Name[0],f.Name[1],Len);
  554. f.Name[0]:=chr(len);
  555. end;
  556. procedure DosFindfirst(path : pchar;attr : word;var f : searchrec);
  557. var
  558. i : longint;
  559. begin
  560. { allow slash as backslash }
  561. for i:=0 to strlen(path) do
  562. if path[i]='/' then path[i]:='\';
  563. copytodos(f,sizeof(searchrec));
  564. dosregs.edx:=tb_offset;
  565. dosregs.ds:=tb_segment;
  566. dosregs.ah:=$1a;
  567. msdos(dosregs);
  568. dosregs.ecx:=attr;
  569. dosregs.edx:=tb_offset+Sizeof(searchrec)+1;
  570. dosmemput(tb_segment,tb_offset+Sizeof(searchrec)+1,path^,strlen(path)+1);
  571. dosregs.ds:=tb_segment;
  572. dosregs.ah:=$4e;
  573. msdos(dosregs);
  574. copyfromdos(f,sizeof(searchrec));
  575. LoadDosError;
  576. dossearchrec2searchrec(f);
  577. end;
  578. procedure Dosfindnext(var f : searchrec);
  579. begin
  580. copytodos(f,sizeof(searchrec));
  581. dosregs.edx:=tb_offset;
  582. dosregs.ds:=tb_segment;
  583. dosregs.ah:=$1a;
  584. msdos(dosregs);
  585. dosregs.ah:=$4f;
  586. msdos(dosregs);
  587. copyfromdos(f,sizeof(searchrec));
  588. LoadDosError;
  589. dossearchrec2searchrec(f);
  590. end;
  591. {******************************************************************************
  592. --- Findfirst FindNext ---
  593. ******************************************************************************}
  594. procedure findfirst(const path : pathstr;attr : word;var f : searchRec);
  595. var
  596. path0 : array[0..256] of char;
  597. begin
  598. doserror:=0;
  599. strpcopy(path0,path);
  600. if LFNSupport then
  601. LFNFindFirst(path0,attr,f)
  602. else
  603. Dosfindfirst(path0,attr,f);
  604. end;
  605. procedure findnext(var f : searchRec);
  606. begin
  607. doserror:=0;
  608. if LFNSupport then
  609. LFNFindnext(f)
  610. else
  611. Dosfindnext(f);
  612. end;
  613. Procedure FindClose(Var f: SearchRec);
  614. begin
  615. DosError:=0;
  616. if LFNSupport then
  617. LFNFindClose(f);
  618. end;
  619. type swap_proc = procedure;
  620. //var
  621. // _swap_in : swap_proc;external name '_swap_in';
  622. // _swap_out : swap_proc;external name '_swap_out';
  623. // _exception_exit : pointer;external name '_exception_exit';
  624. // _v2prt0_exceptions_on : longbool;external name '_v2prt0_exceptions_on';
  625. procedure swapvectors;
  626. begin
  627. (* if _exception_exit<>nil then
  628. if _v2prt0_exceptions_on then
  629. _swap_out()
  630. else
  631. _swap_in();*)
  632. end;
  633. {******************************************************************************
  634. --- File ---
  635. ******************************************************************************}
  636. procedure fsplit(path : pathstr;var dir : dirstr;var name : namestr;var ext : extstr);
  637. var
  638. dotpos,p1,i : longint;
  639. begin
  640. { allow slash as backslash }
  641. for i:=1 to length(path) do
  642. if path[i]='/' then path[i]:='\';
  643. { get drive name }
  644. p1:=pos(':',path);
  645. if p1>0 then
  646. begin
  647. dir:=path[1]+':';
  648. delete(path,1,p1);
  649. end
  650. else
  651. dir:='';
  652. { split the path and the name, there are no more path informtions }
  653. { if path contains no backslashes }
  654. while true do
  655. begin
  656. p1:=pos('\',path);
  657. if p1=0 then
  658. break;
  659. dir:=dir+copy(path,1,p1);
  660. delete(path,1,p1);
  661. end;
  662. { try to find out a extension }
  663. if LFNSupport then
  664. begin
  665. Ext:='';
  666. i:=Length(Path);
  667. DotPos:=256;
  668. While (i>0) Do
  669. Begin
  670. If (Path[i]='.') Then
  671. begin
  672. DotPos:=i;
  673. break;
  674. end;
  675. Dec(i);
  676. end;
  677. Ext:=Copy(Path,DotPos,255);
  678. Name:=Copy(Path,1,DotPos - 1);
  679. end
  680. else
  681. begin
  682. p1:=pos('.',path);
  683. if p1>0 then
  684. begin
  685. ext:=copy(path,p1,4);
  686. delete(path,p1,length(path)-p1+1);
  687. end
  688. else
  689. ext:='';
  690. name:=path;
  691. end;
  692. end;
  693. (*
  694. function FExpand (const Path: PathStr): PathStr;
  695. - declared in fexpand.inc
  696. *)
  697. {$DEFINE FPC_FEXPAND_UNC} (* UNC paths are supported *)
  698. {$DEFINE FPC_FEXPAND_DRIVES} (* Full paths begin with drive specification *)
  699. {$I fexpand.inc}
  700. {$UNDEF FPC_FEXPAND_DRIVES}
  701. {$UNDEF FPC_FEXPAND_UNC}
  702. Function FSearch(path: pathstr; dirlist: string): pathstr;
  703. var
  704. i,p1 : longint;
  705. s : searchrec;
  706. newdir : pathstr;
  707. begin
  708. { check if the file specified exists }
  709. findfirst(path,anyfile,s);
  710. if doserror=0 then
  711. begin
  712. findclose(s);
  713. fsearch:=path;
  714. exit;
  715. end;
  716. { No wildcards allowed in these things }
  717. if (pos('?',path)<>0) or (pos('*',path)<>0) then
  718. fsearch:=''
  719. else
  720. begin
  721. { allow slash as backslash }
  722. for i:=1 to length(dirlist) do
  723. if dirlist[i]='/' then dirlist[i]:='\';
  724. repeat
  725. p1:=pos(';',dirlist);
  726. if p1<>0 then
  727. begin
  728. newdir:=copy(dirlist,1,p1-1);
  729. delete(dirlist,1,p1);
  730. end
  731. else
  732. begin
  733. newdir:=dirlist;
  734. dirlist:='';
  735. end;
  736. if (newdir<>'') and (not (newdir[length(newdir)] in ['\',':'])) then
  737. newdir:=newdir+'\';
  738. findfirst(newdir+path,anyfile,s);
  739. if doserror=0 then
  740. newdir:=newdir+path
  741. else
  742. newdir:='';
  743. until (dirlist='') or (newdir<>'');
  744. fsearch:=newdir;
  745. end;
  746. findclose(s);
  747. end;
  748. { change to short filename if successful DOS call PM }
  749. function GetShortName(var p : String) : boolean;
  750. var
  751. c : array[0..255] of char;
  752. begin
  753. move(p[1],c[0],length(p));
  754. c[length(p)]:=#0;
  755. copytodos(c,length(p)+1);
  756. dosregs.ax:=$7160;
  757. dosregs.cx:=1;
  758. dosregs.ds:=tb_segment;
  759. dosregs.si:=tb_offset;
  760. dosregs.es:=tb_segment;
  761. dosregs.di:=tb_offset;
  762. msdos(dosregs);
  763. LoadDosError;
  764. if DosError=0 then
  765. begin
  766. copyfromdos(c,255);
  767. move(c[0],p[1],strlen(c));
  768. p[0]:=char(strlen(c));
  769. GetShortName:=true;
  770. end
  771. else
  772. GetShortName:=false;
  773. end;
  774. { change to long filename if successful DOS call PM }
  775. function GetLongName(var p : String) : boolean;
  776. var
  777. c : array[0..255] of char;
  778. begin
  779. move(p[1],c[0],length(p));
  780. c[length(p)]:=#0;
  781. copytodos(c,length(p)+1);
  782. dosregs.ax:=$7160;
  783. dosregs.cx:=2;
  784. dosregs.ds:=tb_segment;
  785. dosregs.si:=tb_offset;
  786. dosregs.es:=tb_segment;
  787. dosregs.di:=tb_offset;
  788. msdos(dosregs);
  789. LoadDosError;
  790. if DosError=0 then
  791. begin
  792. copyfromdos(c,255);
  793. move(c[0],p[1],strlen(c));
  794. p[0]:=char(strlen(c));
  795. GetLongName:=true;
  796. end
  797. else
  798. GetLongName:=false;
  799. end;
  800. {******************************************************************************
  801. --- Get/Set File Time,Attr ---
  802. ******************************************************************************}
  803. procedure getftime(var f;var time : longint);
  804. begin
  805. dosregs.bx:=textrec(f).handle;
  806. dosregs.ax:=$5700;
  807. msdos(dosregs);
  808. loaddoserror;
  809. time:=(dosregs.dx shl 16)+dosregs.cx;
  810. end;
  811. procedure setftime(var f;time : longint);
  812. begin
  813. dosregs.bx:=textrec(f).handle;
  814. dosregs.cx:=time and $ffff;
  815. dosregs.dx:=time shr 16;
  816. dosregs.ax:=$5701;
  817. msdos(dosregs);
  818. loaddoserror;
  819. end;
  820. procedure getfattr(var f;var attr : word);
  821. begin
  822. copytodos(filerec(f).name,strlen(filerec(f).name)+1);
  823. dosregs.edx:=tb_offset;
  824. dosregs.ds:=tb_segment;
  825. if LFNSupport then
  826. begin
  827. dosregs.ax:=$7143;
  828. dosregs.bx:=0;
  829. end
  830. else
  831. dosregs.ax:=$4300;
  832. msdos(dosregs);
  833. LoadDosError;
  834. Attr:=dosregs.cx;
  835. end;
  836. procedure setfattr(var f;attr : word);
  837. begin
  838. copytodos(filerec(f).name,strlen(filerec(f).name)+1);
  839. dosregs.edx:=tb_offset;
  840. dosregs.ds:=tb_segment;
  841. if LFNSupport then
  842. begin
  843. dosregs.ax:=$7143;
  844. dosregs.bx:=1;
  845. end
  846. else
  847. dosregs.ax:=$4301;
  848. dosregs.cx:=attr;
  849. msdos(dosregs);
  850. LoadDosError;
  851. end;
  852. {******************************************************************************
  853. --- Environment ---
  854. ******************************************************************************}
  855. function envcount : longint;
  856. var
  857. hp : ppchar;
  858. begin
  859. hp:=envp;
  860. envcount:=0;
  861. while assigned(hp^) do
  862. begin
  863. inc(envcount);
  864. inc(hp);
  865. end;
  866. end;
  867. function envstr(index : integer) : string;
  868. begin
  869. if (index<=0) or (index>envcount) then
  870. begin
  871. envstr:='';
  872. exit;
  873. end;
  874. envstr:=strpas(ppchar(pointer(envp)+4*(index-1))^);
  875. end;
  876. Function GetEnv(envvar: string): string;
  877. var
  878. hp : ppchar;
  879. hs : string;
  880. eqpos : longint;
  881. begin
  882. envvar:=upcase(envvar);
  883. hp:=envp;
  884. getenv:='';
  885. while assigned(hp^) do
  886. begin
  887. hs:=strpas(hp^);
  888. eqpos:=pos('=',hs);
  889. if upcase(copy(hs,1,eqpos-1))=envvar then
  890. begin
  891. getenv:=copy(hs,eqpos+1,255);
  892. exit;
  893. end;
  894. inc(hp);
  895. end;
  896. end;
  897. {******************************************************************************
  898. --- Not Supported ---
  899. ******************************************************************************}
  900. Procedure keep(exitcode : word);
  901. Begin
  902. End;
  903. Procedure getintvec(intno : byte;var vector : pointer);
  904. Begin
  905. End;
  906. Procedure setintvec(intno : byte;vector : pointer);
  907. Begin
  908. End;
  909. end.
  910. {
  911. $Log$
  912. Revision 1.3 2003-10-03 21:59:28 peter
  913. * stdcall fixes
  914. Revision 1.2 2003/09/07 22:29:26 hajny
  915. * syswat renamed to system, CVS log added
  916. Revision 1.1 2003/09/05 18:09:35 florian
  917. * added initial watcom extender files; they need to be cleaned up
  918. }