dos.pp 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853
  1. {
  2. This file is part of the Free Pascal run time library.
  3. Copyright (c) 1999-2000 by the Free Pascal development team.
  4. Dos unit for BP7 compatible RTL
  5. See the file COPYING.FPC, included in this distribution,
  6. for details about the copyright.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10. **********************************************************************}
  11. {$inline on}
  12. unit dos;
  13. interface
  14. Uses
  15. Watcom;
  16. Type
  17. searchrec = packed record
  18. fill : array[1..21] of byte;
  19. attr : byte;
  20. time : longint;
  21. { reserved : word; not in DJGPP V2 }
  22. size : longint;
  23. name : string[255]; { LFN Name, DJGPP uses only [12] but more can't hurt (PFV) }
  24. end;
  25. {$DEFINE HAS_REGISTERS}
  26. Registers = Watcom.Registers;
  27. {$i dosh.inc}
  28. implementation
  29. uses
  30. strings;
  31. {$DEFINE HAS_GETMSCOUNT}
  32. {$DEFINE HAS_INTR}
  33. {$DEFINE HAS_GETCBREAK}
  34. {$DEFINE HAS_SETCBREAK}
  35. {$DEFINE HAS_GETVERIFY}
  36. {$DEFINE HAS_SETVERIFY}
  37. {$DEFINE HAS_GETSHORTNAME}
  38. {$DEFINE HAS_GETLONGNAME}
  39. {$DEFINE HAS_GETMSCOUNT}
  40. {$DEFINE FPC_FEXPAND_UNC} (* UNC paths are supported *)
  41. {$DEFINE FPC_FEXPAND_DRIVES} (* Full paths begin with drive specification *)
  42. {$I dos.inc}
  43. {******************************************************************************
  44. --- Dos Interrupt ---
  45. ******************************************************************************}
  46. var
  47. dosregs : registers;
  48. procedure LoadDosError;
  49. var
  50. r : registers;
  51. SimpleDosError : word;
  52. begin
  53. if (dosregs.flags and fcarry) <> 0 then
  54. begin
  55. { I got a extended error = 0
  56. while CarryFlag was set from Exec function }
  57. SimpleDosError:=dosregs.ax;
  58. r.eax:=$5900;
  59. r.ebx:=$0;
  60. realintr($21,r);
  61. { conversion from word to integer !!
  62. gave a Bound check error if ax is $FFFF !! PM }
  63. doserror:=integer(r.ax);
  64. case doserror of
  65. 0 : DosError:=integer(SimpleDosError);
  66. 19 : DosError:=150;
  67. 21 : DosError:=152;
  68. end;
  69. end
  70. else
  71. doserror:=0;
  72. end;
  73. procedure intr(intno : byte;var regs : registers);
  74. begin
  75. realintr(intno,regs);
  76. end;
  77. {******************************************************************************
  78. --- Info / Date / Time ---
  79. ******************************************************************************}
  80. function dosversion : word;
  81. begin
  82. dosregs.ax:=$3000;
  83. msdos(dosregs);
  84. dosversion:=dosregs.ax;
  85. end;
  86. procedure getdate(var year,month,mday,wday : word);
  87. begin
  88. dosregs.ax:=$2a00;
  89. msdos(dosregs);
  90. wday:=dosregs.al;
  91. year:=dosregs.cx;
  92. month:=dosregs.dh;
  93. mday:=dosregs.dl;
  94. end;
  95. procedure setdate(year,month,day : word);
  96. begin
  97. dosregs.cx:=year;
  98. dosregs.dh:=month;
  99. dosregs.dl:=day;
  100. dosregs.ah:=$2b;
  101. msdos(dosregs);
  102. end;
  103. procedure gettime(var hour,minute,second,sec100 : word);
  104. begin
  105. dosregs.ah:=$2c;
  106. msdos(dosregs);
  107. hour:=dosregs.ch;
  108. minute:=dosregs.cl;
  109. second:=dosregs.dh;
  110. sec100:=dosregs.dl;
  111. end;
  112. procedure settime(hour,minute,second,sec100 : word);
  113. begin
  114. dosregs.ch:=hour;
  115. dosregs.cl:=minute;
  116. dosregs.dh:=second;
  117. dosregs.dl:=sec100;
  118. dosregs.ah:=$2d;
  119. msdos(dosregs);
  120. end;
  121. function GetMsCount: int64;
  122. begin
  123. GetMsCount := int64 (MemL [$40:$6c]) * 55;
  124. end;
  125. {******************************************************************************
  126. --- Exec ---
  127. ******************************************************************************}
  128. procedure exec(const path : pathstr;const comline : comstr);
  129. type
  130. realptr = packed record
  131. ofs,seg : word;
  132. end;
  133. texecblock = packed record
  134. envseg : word;
  135. comtail : realptr;
  136. firstFCB : realptr;
  137. secondFCB : realptr;
  138. iniStack : realptr;
  139. iniCSIP : realptr;
  140. end;
  141. var
  142. current_dos_buffer_pos,
  143. arg_ofs,
  144. i,la_env,
  145. la_p,la_c,la_e,
  146. fcb1_la,fcb2_la : longint;
  147. execblock : texecblock;
  148. c,p : string;
  149. function paste_to_dos(src : string) : boolean;
  150. var
  151. c : array[0..255] of char;
  152. begin
  153. paste_to_dos:=false;
  154. if current_dos_buffer_pos+length(src)+1>tb+tb_size then
  155. RunError(217);
  156. move(src[1],c[0],length(src));
  157. c[length(src)]:=#0;
  158. seg_move(get_ds,longint(@c),dosmemselector,current_dos_buffer_pos,length(src)+1);
  159. current_dos_buffer_pos:=current_dos_buffer_pos+length(src)+1;
  160. paste_to_dos:=true;
  161. end;
  162. begin
  163. { create command line }
  164. move(comline[0],c[1],length(comline)+1);
  165. c[length(comline)+2]:=#13;
  166. c[0]:=char(length(comline)+2);
  167. { create path }
  168. p:=path;
  169. for i:=1 to length(p) do
  170. if p[i]='/' then
  171. p[i]:='\';
  172. if LFNSupport then
  173. GetShortName(p);
  174. { create buffer }
  175. la_env:=tb;
  176. while (la_env and 15)<>0 do
  177. inc(la_env);
  178. current_dos_buffer_pos:=la_env;
  179. { copy environment }
  180. for i:=1 to envcount do
  181. paste_to_dos(envstr(i));
  182. paste_to_dos(''); { adds a double zero at the end }
  183. { allow slash as backslash }
  184. la_p:=current_dos_buffer_pos;
  185. paste_to_dos(p);
  186. la_c:=current_dos_buffer_pos;
  187. paste_to_dos(c);
  188. la_e:=current_dos_buffer_pos;
  189. fcb1_la:=la_e;
  190. la_e:=la_e+16;
  191. fcb2_la:=la_e;
  192. la_e:=la_e+16;
  193. { allocate FCB see dosexec code }
  194. arg_ofs:=1;
  195. while (c[arg_ofs] in [' ',#9]) do
  196. inc(arg_ofs);
  197. dosregs.ax:=$2901;
  198. dosregs.ds:=(la_c+arg_ofs) shr 4;
  199. dosregs.esi:=(la_c+arg_ofs) and 15;
  200. dosregs.es:=fcb1_la shr 4;
  201. dosregs.edi:=fcb1_la and 15;
  202. msdos(dosregs);
  203. { allocate second FCB see dosexec code }
  204. repeat
  205. inc(arg_ofs);
  206. until (c[arg_ofs] in [' ',#9,#13]);
  207. if c[arg_ofs]<>#13 then
  208. begin
  209. repeat
  210. inc(arg_ofs);
  211. until not (c[arg_ofs] in [' ',#9]);
  212. end;
  213. dosregs.ax:=$2901;
  214. dosregs.ds:=(la_c+arg_ofs) shr 4;
  215. dosregs.si:=(la_c+arg_ofs) and 15;
  216. dosregs.es:=fcb2_la shr 4;
  217. dosregs.di:=fcb2_la and 15;
  218. msdos(dosregs);
  219. with execblock do
  220. begin
  221. envseg:=la_env shr 4;
  222. comtail.seg:=la_c shr 4;
  223. comtail.ofs:=la_c and 15;
  224. firstFCB.seg:=fcb1_la shr 4;
  225. firstFCB.ofs:=fcb1_la and 15;
  226. secondFCB.seg:=fcb2_la shr 4;
  227. secondFCB.ofs:=fcb2_la and 15;
  228. end;
  229. seg_move(get_ds,longint(@execblock),dosmemselector,la_e,sizeof(texecblock));
  230. dosregs.edx:=la_p and 15;
  231. dosregs.ds:=la_p shr 4;
  232. dosregs.ebx:=la_e and 15;
  233. dosregs.es:=la_e shr 4;
  234. dosregs.ax:=$4b00;
  235. msdos(dosregs);
  236. LoadDosError;
  237. if DosError=0 then
  238. begin
  239. dosregs.ax:=$4d00;
  240. msdos(dosregs);
  241. LastDosExitCode:=DosRegs.al
  242. end
  243. else
  244. LastDosExitCode:=0;
  245. end;
  246. procedure getcbreak(var breakvalue : boolean);
  247. begin
  248. dosregs.ax:=$3300;
  249. msdos(dosregs);
  250. breakvalue:=dosregs.dl<>0;
  251. end;
  252. procedure setcbreak(breakvalue : boolean);
  253. begin
  254. dosregs.ax:=$3301;
  255. dosregs.dl:=ord(breakvalue);
  256. msdos(dosregs);
  257. end;
  258. procedure getverify(var verify : boolean);
  259. begin
  260. dosregs.ah:=$54;
  261. msdos(dosregs);
  262. verify:=dosregs.al<>0;
  263. end;
  264. procedure setverify(verify : boolean);
  265. begin
  266. dosregs.ah:=$2e;
  267. dosregs.al:=ord(verify);
  268. msdos(dosregs);
  269. end;
  270. {******************************************************************************
  271. --- Disk ---
  272. ******************************************************************************}
  273. TYPE ExtendedFat32FreeSpaceRec=packed Record
  274. RetSize : WORD; { (ret) size of returned structure}
  275. Strucversion : WORD; {(call) structure version (0000h)
  276. (ret) actual structure version (0000h)}
  277. SecPerClus, {number of sectors per cluster}
  278. BytePerSec, {number of bytes per sector}
  279. AvailClusters, {number of available clusters}
  280. TotalClusters, {total number of clusters on the drive}
  281. AvailPhysSect, {physical sectors available on the drive}
  282. TotalPhysSect, {total physical sectors on the drive}
  283. AvailAllocUnits, {Available allocation units}
  284. TotalAllocUnits : DWORD; {Total allocation units}
  285. Dummy,Dummy2 : DWORD; {8 bytes reserved}
  286. END;
  287. function do_diskdata(drive : byte; Free : BOOLEAN) : Int64;
  288. VAR
  289. S : String;
  290. Rec : ExtendedFat32FreeSpaceRec;
  291. procedure OldDosDiskData; inline;
  292. begin
  293. dosregs.dl:=drive;
  294. dosregs.ah:=$36;
  295. msdos(dosregs);
  296. if dosregs.ax<>$FFFF then
  297. begin
  298. if Free then
  299. Do_DiskData:=int64(dosregs.ax)*dosregs.bx*dosregs.cx
  300. else
  301. Do_DiskData:=int64(dosregs.ax)*dosregs.cx*dosregs.dx;
  302. end
  303. else
  304. do_diskdata:=-1;
  305. end;
  306. BEGIN
  307. if LFNSupport then
  308. begin
  309. S:='C:\'#0;
  310. if Drive=0 then
  311. begin
  312. GetDir(Drive,S);
  313. Setlength(S,4);
  314. S[4]:=#0;
  315. end
  316. else
  317. S[1]:=chr(Drive+64);
  318. Rec.Strucversion:=0;
  319. Rec.RetSize := 0;
  320. dosmemput(tb_segment,tb_offset,Rec,SIZEOF(ExtendedFat32FreeSpaceRec));
  321. dosmemput(tb_segment,tb_offset+Sizeof(ExtendedFat32FreeSpaceRec)+1,S[1],4);
  322. dosregs.dx:=tb_offset+Sizeof(ExtendedFat32FreeSpaceRec)+1;
  323. dosregs.ds:=tb_segment;
  324. dosregs.di:=tb_offset;
  325. dosregs.es:=tb_segment;
  326. dosregs.cx:=Sizeof(ExtendedFat32FreeSpaceRec);
  327. dosregs.ax:=$7303;
  328. msdos(dosregs);
  329. if (dosregs.flags and fcarry) = 0 then {No error clausule in int except cf}
  330. begin
  331. copyfromdos(rec,Sizeof(ExtendedFat32FreeSpaceRec));
  332. if Rec.RetSize = 0 then (* Error - "FAT32" function not supported! *)
  333. OldDosDiskData
  334. else
  335. if Free then
  336. Do_DiskData:=int64(rec.AvailAllocUnits)*rec.SecPerClus*rec.BytePerSec
  337. else
  338. Do_DiskData:=int64(rec.TotalAllocUnits)*rec.SecPerClus*rec.BytePerSec;
  339. end
  340. else
  341. Do_DiskData:=-1;
  342. end
  343. else
  344. OldDosDiskData;
  345. end;
  346. function diskfree(drive : byte) : int64;
  347. begin
  348. diskfree:=Do_DiskData(drive,TRUE);
  349. end;
  350. function disksize(drive : byte) : int64;
  351. begin
  352. disksize:=Do_DiskData(drive,false);
  353. end;
  354. {******************************************************************************
  355. --- LFNFindfirst LFNFindNext ---
  356. ******************************************************************************}
  357. type
  358. LFNSearchRec=packed record
  359. attr,
  360. crtime,
  361. crtimehi,
  362. actime,
  363. actimehi,
  364. lmtime,
  365. lmtimehi,
  366. sizehi,
  367. size : longint;
  368. reserved : array[0..7] of byte;
  369. name : array[0..259] of byte;
  370. shortname : array[0..13] of byte;
  371. end;
  372. procedure LFNSearchRec2Dos(const w:LFNSearchRec;hdl:longint;var d:Searchrec;from_findfirst : boolean);
  373. var
  374. Len : longint;
  375. begin
  376. With w do
  377. begin
  378. FillChar(d,sizeof(SearchRec),0);
  379. if DosError=0 then
  380. len:=StrLen(@Name)
  381. else
  382. len:=0;
  383. d.Name[0]:=chr(len);
  384. Move(Name[0],d.Name[1],Len);
  385. d.Time:=lmTime;
  386. d.Size:=Size;
  387. d.Attr:=Attr and $FF;
  388. if (DosError<>0) and from_findfirst then
  389. hdl:=-1;
  390. Move(hdl,d.Fill,4);
  391. end;
  392. end;
  393. procedure LFNFindFirst(path:pchar;attr:longint;var s:searchrec);
  394. var
  395. i : longint;
  396. w : LFNSearchRec;
  397. begin
  398. { allow slash as backslash }
  399. for i:=0 to strlen(path) do
  400. if path[i]='/' then path[i]:='\';
  401. dosregs.si:=1; { use ms-dos time }
  402. { don't include the label if not asked for it, needed for network drives }
  403. if attr=$8 then
  404. dosregs.ecx:=8
  405. else
  406. dosregs.ecx:=attr and (not 8);
  407. dosregs.edx:=tb_offset+Sizeof(LFNSearchrec)+1;
  408. dosmemput(tb_segment,tb_offset+Sizeof(LFNSearchrec)+1,path^,strlen(path)+1);
  409. dosregs.ds:=tb_segment;
  410. dosregs.edi:=tb_offset;
  411. dosregs.es:=tb_segment;
  412. dosregs.ax:=$714e;
  413. msdos(dosregs);
  414. LoadDosError;
  415. copyfromdos(w,sizeof(LFNSearchRec));
  416. LFNSearchRec2Dos(w,dosregs.ax,s,true);
  417. end;
  418. procedure LFNFindNext(var s:searchrec);
  419. var
  420. hdl : longint;
  421. w : LFNSearchRec;
  422. begin
  423. Move(s.Fill,hdl,4);
  424. dosregs.si:=1; { use ms-dos time }
  425. dosregs.edi:=tb_offset;
  426. dosregs.es:=tb_segment;
  427. dosregs.ebx:=hdl;
  428. dosregs.ax:=$714f;
  429. msdos(dosregs);
  430. LoadDosError;
  431. copyfromdos(w,sizeof(LFNSearchRec));
  432. LFNSearchRec2Dos(w,hdl,s,false);
  433. end;
  434. procedure LFNFindClose(var s:searchrec);
  435. var
  436. hdl : longint;
  437. begin
  438. Move(s.Fill,hdl,4);
  439. { Do not call MsDos if FindFirst returned with an error }
  440. if hdl=-1 then
  441. begin
  442. DosError:=0;
  443. exit;
  444. end;
  445. dosregs.ebx:=hdl;
  446. dosregs.ax:=$71a1;
  447. msdos(dosregs);
  448. LoadDosError;
  449. end;
  450. {******************************************************************************
  451. --- DosFindfirst DosFindNext ---
  452. ******************************************************************************}
  453. procedure dossearchrec2searchrec(var f : searchrec);
  454. var
  455. len : longint;
  456. begin
  457. { Check is necessary!! OS/2's VDM doesn't clear the name with #0 if the }
  458. { file doesn't exist! (JM) }
  459. if dosError = 0 then
  460. len:=StrLen(@f.Name)
  461. else len := 0;
  462. Move(f.Name[0],f.Name[1],Len);
  463. f.Name[0]:=chr(len);
  464. end;
  465. procedure DosFindfirst(path : pchar;attr : word;var f : searchrec);
  466. var
  467. i : longint;
  468. begin
  469. { allow slash as backslash }
  470. for i:=0 to strlen(path) do
  471. if path[i]='/' then path[i]:='\';
  472. copytodos(f,sizeof(searchrec));
  473. dosregs.edx:=tb_offset;
  474. dosregs.ds:=tb_segment;
  475. dosregs.ah:=$1a;
  476. msdos(dosregs);
  477. dosregs.ecx:=attr;
  478. dosregs.edx:=tb_offset+Sizeof(searchrec)+1;
  479. dosmemput(tb_segment,tb_offset+Sizeof(searchrec)+1,path^,strlen(path)+1);
  480. dosregs.ds:=tb_segment;
  481. dosregs.ah:=$4e;
  482. msdos(dosregs);
  483. copyfromdos(f,sizeof(searchrec));
  484. LoadDosError;
  485. dossearchrec2searchrec(f);
  486. end;
  487. procedure Dosfindnext(var f : searchrec);
  488. begin
  489. copytodos(f,sizeof(searchrec));
  490. dosregs.edx:=tb_offset;
  491. dosregs.ds:=tb_segment;
  492. dosregs.ah:=$1a;
  493. msdos(dosregs);
  494. dosregs.ah:=$4f;
  495. msdos(dosregs);
  496. copyfromdos(f,sizeof(searchrec));
  497. LoadDosError;
  498. dossearchrec2searchrec(f);
  499. end;
  500. {******************************************************************************
  501. --- Findfirst FindNext ---
  502. ******************************************************************************}
  503. procedure findfirst(const path : pathstr;attr : word;var f : searchRec);
  504. var
  505. path0 : array[0..256] of char;
  506. begin
  507. doserror:=0;
  508. strpcopy(path0,path);
  509. if LFNSupport then
  510. LFNFindFirst(path0,attr,f)
  511. else
  512. Dosfindfirst(path0,attr,f);
  513. end;
  514. procedure findnext(var f : searchRec);
  515. begin
  516. doserror:=0;
  517. if LFNSupport then
  518. LFNFindnext(f)
  519. else
  520. Dosfindnext(f);
  521. end;
  522. Procedure FindClose(Var f: SearchRec);
  523. begin
  524. DosError:=0;
  525. if LFNSupport then
  526. LFNFindClose(f);
  527. end;
  528. //type swap_proc = procedure;
  529. //var
  530. // _swap_in : swap_proc;external name '_swap_in';
  531. // _swap_out : swap_proc;external name '_swap_out';
  532. // _exception_exit : pointer;external name '_exception_exit';
  533. // _v2prt0_exceptions_on : longbool;external name '_v2prt0_exceptions_on';
  534. (*
  535. procedure swapvectors;
  536. begin
  537. if _exception_exit<>nil then
  538. if _v2prt0_exceptions_on then
  539. _swap_out()
  540. else
  541. _swap_in();
  542. end;
  543. *)
  544. {******************************************************************************
  545. --- File ---
  546. ******************************************************************************}
  547. Function FSearch(path: pathstr; dirlist: string): pathstr;
  548. var
  549. i,p1 : longint;
  550. s : searchrec;
  551. newdir : pathstr;
  552. begin
  553. { check if the file specified exists }
  554. findfirst(path,anyfile,s);
  555. if doserror=0 then
  556. begin
  557. findclose(s);
  558. fsearch:=path;
  559. exit;
  560. end;
  561. { No wildcards allowed in these things }
  562. if (pos('?',path)<>0) or (pos('*',path)<>0) then
  563. fsearch:=''
  564. else
  565. begin
  566. { allow slash as backslash }
  567. for i:=1 to length(dirlist) do
  568. if dirlist[i]='/' then dirlist[i]:='\';
  569. repeat
  570. p1:=pos(';',dirlist);
  571. if p1<>0 then
  572. begin
  573. newdir:=copy(dirlist,1,p1-1);
  574. delete(dirlist,1,p1);
  575. end
  576. else
  577. begin
  578. newdir:=dirlist;
  579. dirlist:='';
  580. end;
  581. if (newdir<>'') and (not (newdir[length(newdir)] in ['\',':'])) then
  582. newdir:=newdir+'\';
  583. findfirst(newdir+path,anyfile,s);
  584. if doserror=0 then
  585. newdir:=newdir+path
  586. else
  587. newdir:='';
  588. until (dirlist='') or (newdir<>'');
  589. fsearch:=newdir;
  590. end;
  591. findclose(s);
  592. end;
  593. { change to short filename if successful DOS call PM }
  594. function GetShortName(var p : String) : boolean;
  595. var
  596. c : array[0..255] of char;
  597. begin
  598. move(p[1],c[0],length(p));
  599. c[length(p)]:=#0;
  600. copytodos(c,length(p)+1);
  601. dosregs.ax:=$7160;
  602. dosregs.cx:=1;
  603. dosregs.ds:=tb_segment;
  604. dosregs.si:=tb_offset;
  605. dosregs.es:=tb_segment;
  606. dosregs.di:=tb_offset;
  607. msdos(dosregs);
  608. LoadDosError;
  609. if DosError=0 then
  610. begin
  611. copyfromdos(c,255);
  612. move(c[0],p[1],strlen(c));
  613. p[0]:=char(strlen(c));
  614. GetShortName:=true;
  615. end
  616. else
  617. GetShortName:=false;
  618. end;
  619. { change to long filename if successful DOS call PM }
  620. function GetLongName(var p : String) : boolean;
  621. var
  622. c : array[0..255] of char;
  623. begin
  624. move(p[1],c[0],length(p));
  625. c[length(p)]:=#0;
  626. copytodos(c,length(p)+1);
  627. dosregs.ax:=$7160;
  628. dosregs.cx:=2;
  629. dosregs.ds:=tb_segment;
  630. dosregs.si:=tb_offset;
  631. dosregs.es:=tb_segment;
  632. dosregs.di:=tb_offset;
  633. msdos(dosregs);
  634. LoadDosError;
  635. if DosError=0 then
  636. begin
  637. copyfromdos(c,255);
  638. move(c[0],p[1],strlen(c));
  639. p[0]:=char(strlen(c));
  640. GetLongName:=true;
  641. end
  642. else
  643. GetLongName:=false;
  644. end;
  645. {******************************************************************************
  646. --- Get/Set File Time,Attr ---
  647. ******************************************************************************}
  648. procedure getftime(var f;var time : longint);
  649. begin
  650. dosregs.bx:=textrec(f).handle;
  651. dosregs.ax:=$5700;
  652. msdos(dosregs);
  653. loaddoserror;
  654. time:=(dosregs.dx shl 16)+dosregs.cx;
  655. end;
  656. procedure setftime(var f;time : longint);
  657. begin
  658. dosregs.bx:=textrec(f).handle;
  659. dosregs.cx:=time and $ffff;
  660. dosregs.dx:=time shr 16;
  661. dosregs.ax:=$5701;
  662. msdos(dosregs);
  663. loaddoserror;
  664. end;
  665. procedure getfattr(var f;var attr : word);
  666. begin
  667. copytodos(filerec(f).name,strlen(filerec(f).name)+1);
  668. dosregs.edx:=tb_offset;
  669. dosregs.ds:=tb_segment;
  670. if LFNSupport then
  671. begin
  672. dosregs.ax:=$7143;
  673. dosregs.bx:=0;
  674. end
  675. else
  676. dosregs.ax:=$4300;
  677. msdos(dosregs);
  678. LoadDosError;
  679. Attr:=dosregs.cx;
  680. end;
  681. procedure setfattr(var f;attr : word);
  682. begin
  683. copytodos(filerec(f).name,strlen(filerec(f).name)+1);
  684. dosregs.edx:=tb_offset;
  685. dosregs.ds:=tb_segment;
  686. if LFNSupport then
  687. begin
  688. dosregs.ax:=$7143;
  689. dosregs.bx:=1;
  690. end
  691. else
  692. dosregs.ax:=$4301;
  693. dosregs.cx:=attr;
  694. msdos(dosregs);
  695. LoadDosError;
  696. end;
  697. {******************************************************************************
  698. --- Environment ---
  699. ******************************************************************************}
  700. function envcount : longint;
  701. var
  702. hp : ppchar;
  703. begin
  704. hp:=envp;
  705. envcount:=0;
  706. while assigned(hp^) do
  707. begin
  708. inc(envcount);
  709. inc(hp);
  710. end;
  711. end;
  712. function EnvStr (Index: longint): string;
  713. begin
  714. if (index<=0) or (index>envcount) then
  715. begin
  716. envstr:='';
  717. exit;
  718. end;
  719. envstr:=strpas(ppchar(pointer(envp)+4*(index-1))^);
  720. end;
  721. Function GetEnv(envvar: string): string;
  722. var
  723. hp : ppchar;
  724. hs : string;
  725. eqpos : longint;
  726. begin
  727. envvar:=upcase(envvar);
  728. hp:=envp;
  729. getenv:='';
  730. while assigned(hp^) do
  731. begin
  732. hs:=strpas(hp^);
  733. eqpos:=pos('=',hs);
  734. if upcase(copy(hs,1,eqpos-1))=envvar then
  735. begin
  736. getenv:=copy(hs,eqpos+1,255);
  737. exit;
  738. end;
  739. inc(hp);
  740. end;
  741. end;
  742. end.