dos.pp 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849
  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. DoDirSeparators(p);
  170. if LFNSupport then
  171. GetShortName(p);
  172. { create buffer }
  173. la_env:=tb;
  174. while (la_env and 15)<>0 do
  175. inc(la_env);
  176. current_dos_buffer_pos:=la_env;
  177. { copy environment }
  178. for i:=1 to envcount do
  179. paste_to_dos(envstr(i));
  180. paste_to_dos(''); { adds a double zero at the end }
  181. { allow slash as backslash }
  182. la_p:=current_dos_buffer_pos;
  183. paste_to_dos(p);
  184. la_c:=current_dos_buffer_pos;
  185. paste_to_dos(c);
  186. la_e:=current_dos_buffer_pos;
  187. fcb1_la:=la_e;
  188. la_e:=la_e+16;
  189. fcb2_la:=la_e;
  190. la_e:=la_e+16;
  191. { allocate FCB see dosexec code }
  192. arg_ofs:=1;
  193. while (arg_ofs < Length (C)) and (c[arg_ofs] in [' ',#9]) do
  194. inc(arg_ofs);
  195. dosregs.ax:=$2901;
  196. dosregs.ds:=(la_c+arg_ofs) shr 4;
  197. dosregs.esi:=(la_c+arg_ofs) and 15;
  198. dosregs.es:=fcb1_la shr 4;
  199. dosregs.edi:=fcb1_la and 15;
  200. msdos(dosregs);
  201. { allocate second FCB see dosexec code }
  202. repeat
  203. inc(arg_ofs);
  204. until (Arg_Ofs >= Length (C)) or (c[arg_ofs] in [' ',#9,#13]);
  205. if (c[arg_ofs]<>#13) and (Arg_Ofs < Length (C)) then
  206. begin
  207. repeat
  208. inc(arg_ofs);
  209. until (Arg_Ofs > Length (C)) or not (c[arg_ofs] in [' ',#9]);
  210. end;
  211. dosregs.ax:=$2901;
  212. dosregs.ds:=(la_c+arg_ofs) shr 4;
  213. dosregs.si:=(la_c+arg_ofs) and 15;
  214. dosregs.es:=fcb2_la shr 4;
  215. dosregs.di:=fcb2_la and 15;
  216. msdos(dosregs);
  217. with execblock do
  218. begin
  219. envseg:=la_env shr 4;
  220. comtail.seg:=la_c shr 4;
  221. comtail.ofs:=la_c and 15;
  222. firstFCB.seg:=fcb1_la shr 4;
  223. firstFCB.ofs:=fcb1_la and 15;
  224. secondFCB.seg:=fcb2_la shr 4;
  225. secondFCB.ofs:=fcb2_la and 15;
  226. end;
  227. seg_move(get_ds,longint(@execblock),dosmemselector,la_e,sizeof(texecblock));
  228. dosregs.edx:=la_p and 15;
  229. dosregs.ds:=la_p shr 4;
  230. dosregs.ebx:=la_e and 15;
  231. dosregs.es:=la_e shr 4;
  232. dosregs.ax:=$4b00;
  233. msdos(dosregs);
  234. LoadDosError;
  235. if DosError=0 then
  236. begin
  237. dosregs.ax:=$4d00;
  238. msdos(dosregs);
  239. LastDosExitCode:=DosRegs.al
  240. end
  241. else
  242. LastDosExitCode:=0;
  243. end;
  244. procedure getcbreak(var breakvalue : boolean);
  245. begin
  246. dosregs.ax:=$3300;
  247. msdos(dosregs);
  248. breakvalue:=dosregs.dl<>0;
  249. end;
  250. procedure setcbreak(breakvalue : boolean);
  251. begin
  252. dosregs.ax:=$3301;
  253. dosregs.dl:=ord(breakvalue);
  254. msdos(dosregs);
  255. end;
  256. procedure getverify(var verify : boolean);
  257. begin
  258. dosregs.ah:=$54;
  259. msdos(dosregs);
  260. verify:=dosregs.al<>0;
  261. end;
  262. procedure setverify(verify : boolean);
  263. begin
  264. dosregs.ah:=$2e;
  265. dosregs.al:=ord(verify);
  266. msdos(dosregs);
  267. end;
  268. {******************************************************************************
  269. --- Disk ---
  270. ******************************************************************************}
  271. TYPE ExtendedFat32FreeSpaceRec=packed Record
  272. RetSize : WORD; { (ret) size of returned structure}
  273. Strucversion : WORD; {(call) structure version (0000h)
  274. (ret) actual structure version (0000h)}
  275. SecPerClus, {number of sectors per cluster}
  276. BytePerSec, {number of bytes per sector}
  277. AvailClusters, {number of available clusters}
  278. TotalClusters, {total number of clusters on the drive}
  279. AvailPhysSect, {physical sectors available on the drive}
  280. TotalPhysSect, {total physical sectors on the drive}
  281. AvailAllocUnits, {Available allocation units}
  282. TotalAllocUnits : DWORD; {Total allocation units}
  283. Dummy,Dummy2 : DWORD; {8 bytes reserved}
  284. END;
  285. function do_diskdata(drive : byte; Free : BOOLEAN) : Int64;
  286. VAR
  287. S : String;
  288. Rec : ExtendedFat32FreeSpaceRec;
  289. procedure OldDosDiskData; inline;
  290. begin
  291. dosregs.dl:=drive;
  292. dosregs.ah:=$36;
  293. msdos(dosregs);
  294. if dosregs.ax<>$FFFF then
  295. begin
  296. if Free then
  297. Do_DiskData:=int64(dosregs.ax)*dosregs.bx*dosregs.cx
  298. else
  299. Do_DiskData:=int64(dosregs.ax)*dosregs.cx*dosregs.dx;
  300. end
  301. else
  302. do_diskdata:=-1;
  303. end;
  304. BEGIN
  305. if LFNSupport then
  306. begin
  307. S:='C:\'#0;
  308. if Drive=0 then
  309. begin
  310. GetDir(Drive,S);
  311. Setlength(S,4);
  312. S[4]:=#0;
  313. end
  314. else
  315. S[1]:=chr(Drive+64);
  316. Rec.Strucversion:=0;
  317. Rec.RetSize := 0;
  318. dosmemput(tb_segment,tb_offset,Rec,SIZEOF(ExtendedFat32FreeSpaceRec));
  319. dosmemput(tb_segment,tb_offset+Sizeof(ExtendedFat32FreeSpaceRec)+1,S[1],4);
  320. dosregs.dx:=tb_offset+Sizeof(ExtendedFat32FreeSpaceRec)+1;
  321. dosregs.ds:=tb_segment;
  322. dosregs.di:=tb_offset;
  323. dosregs.es:=tb_segment;
  324. dosregs.cx:=Sizeof(ExtendedFat32FreeSpaceRec);
  325. dosregs.ax:=$7303;
  326. msdos(dosregs);
  327. if (dosregs.flags and fcarry) = 0 then {No error clausule in int except cf}
  328. begin
  329. copyfromdos(rec,Sizeof(ExtendedFat32FreeSpaceRec));
  330. if Rec.RetSize = 0 then (* Error - "FAT32" function not supported! *)
  331. OldDosDiskData
  332. else
  333. if Free then
  334. Do_DiskData:=int64(rec.AvailAllocUnits)*rec.SecPerClus*rec.BytePerSec
  335. else
  336. Do_DiskData:=int64(rec.TotalAllocUnits)*rec.SecPerClus*rec.BytePerSec;
  337. end
  338. else
  339. Do_DiskData:=-1;
  340. end
  341. else
  342. OldDosDiskData;
  343. end;
  344. function diskfree(drive : byte) : int64;
  345. begin
  346. diskfree:=Do_DiskData(drive,TRUE);
  347. end;
  348. function disksize(drive : byte) : int64;
  349. begin
  350. disksize:=Do_DiskData(drive,false);
  351. end;
  352. {******************************************************************************
  353. --- LFNFindfirst LFNFindNext ---
  354. ******************************************************************************}
  355. type
  356. LFNSearchRec=packed record
  357. attr,
  358. crtime,
  359. crtimehi,
  360. actime,
  361. actimehi,
  362. lmtime,
  363. lmtimehi,
  364. sizehi,
  365. size : longint;
  366. reserved : array[0..7] of byte;
  367. name : array[0..259] of byte;
  368. shortname : array[0..13] of byte;
  369. end;
  370. procedure LFNSearchRec2Dos(const w:LFNSearchRec;hdl:longint;var d:Searchrec;from_findfirst : boolean);
  371. var
  372. Len : longint;
  373. begin
  374. With w do
  375. begin
  376. FillChar(d,sizeof(SearchRec),0);
  377. if DosError=0 then
  378. len:=StrLen(@Name)
  379. else
  380. len:=0;
  381. d.Name[0]:=chr(len);
  382. Move(Name[0],d.Name[1],Len);
  383. d.Time:=lmTime;
  384. d.Size:=Size;
  385. d.Attr:=Attr and $FF;
  386. if (DosError<>0) and from_findfirst then
  387. hdl:=-1;
  388. Move(hdl,d.Fill,4);
  389. end;
  390. end;
  391. procedure LFNFindFirst(path:pchar;attr:longint;var s:searchrec);
  392. var
  393. i : longint;
  394. w : LFNSearchRec;
  395. begin
  396. { allow slash as backslash }
  397. DoDirSeparators(path);
  398. dosregs.si:=1; { use ms-dos time }
  399. { don't include the label if not asked for it, needed for network drives }
  400. if attr=$8 then
  401. dosregs.ecx:=8
  402. else
  403. dosregs.ecx:=attr and (not 8) and $FF; { No required attributes }
  404. dosregs.edx:=tb_offset+Sizeof(LFNSearchrec)+1;
  405. dosmemput(tb_segment,tb_offset+Sizeof(LFNSearchrec)+1,path^,strlen(path)+1);
  406. dosregs.ds:=tb_segment;
  407. dosregs.edi:=tb_offset;
  408. dosregs.es:=tb_segment;
  409. dosregs.ax:=$714e;
  410. msdos(dosregs);
  411. LoadDosError;
  412. copyfromdos(w,sizeof(LFNSearchRec));
  413. LFNSearchRec2Dos(w,dosregs.ax,s,true);
  414. end;
  415. procedure LFNFindNext(var s:searchrec);
  416. var
  417. hdl : longint;
  418. w : LFNSearchRec;
  419. begin
  420. Move(s.Fill,hdl,4);
  421. dosregs.si:=1; { use ms-dos time }
  422. dosregs.edi:=tb_offset;
  423. dosregs.es:=tb_segment;
  424. dosregs.ebx:=hdl;
  425. dosregs.ax:=$714f;
  426. msdos(dosregs);
  427. LoadDosError;
  428. copyfromdos(w,sizeof(LFNSearchRec));
  429. LFNSearchRec2Dos(w,hdl,s,false);
  430. end;
  431. procedure LFNFindClose(var s:searchrec);
  432. var
  433. hdl : longint;
  434. begin
  435. Move(s.Fill,hdl,4);
  436. { Do not call MsDos if FindFirst returned with an error }
  437. if hdl=-1 then
  438. begin
  439. DosError:=0;
  440. exit;
  441. end;
  442. dosregs.ebx:=hdl;
  443. dosregs.ax:=$71a1;
  444. msdos(dosregs);
  445. LoadDosError;
  446. end;
  447. {******************************************************************************
  448. --- DosFindfirst DosFindNext ---
  449. ******************************************************************************}
  450. procedure dossearchrec2searchrec(var f : searchrec);
  451. var
  452. len : longint;
  453. begin
  454. { Check is necessary!! OS/2's VDM doesn't clear the name with #0 if the }
  455. { file doesn't exist! (JM) }
  456. if dosError = 0 then
  457. len:=StrLen(@f.Name)
  458. else len := 0;
  459. Move(f.Name[0],f.Name[1],Len);
  460. f.Name[0]:=chr(len);
  461. end;
  462. procedure DosFindfirst(path : pchar;attr : word;var f : searchrec);
  463. var
  464. i : longint;
  465. begin
  466. { allow slash as backslash }
  467. DoDirSeparators(path);
  468. copytodos(f,sizeof(searchrec));
  469. dosregs.edx:=tb_offset;
  470. dosregs.ds:=tb_segment;
  471. dosregs.ah:=$1a;
  472. msdos(dosregs);
  473. dosregs.ecx:=attr;
  474. dosregs.edx:=tb_offset+Sizeof(searchrec)+1;
  475. dosmemput(tb_segment,tb_offset+Sizeof(searchrec)+1,path^,strlen(path)+1);
  476. dosregs.ds:=tb_segment;
  477. dosregs.ah:=$4e;
  478. msdos(dosregs);
  479. copyfromdos(f,sizeof(searchrec));
  480. LoadDosError;
  481. dossearchrec2searchrec(f);
  482. end;
  483. procedure Dosfindnext(var f : searchrec);
  484. begin
  485. copytodos(f,sizeof(searchrec));
  486. dosregs.edx:=tb_offset;
  487. dosregs.ds:=tb_segment;
  488. dosregs.ah:=$1a;
  489. msdos(dosregs);
  490. dosregs.ah:=$4f;
  491. msdos(dosregs);
  492. copyfromdos(f,sizeof(searchrec));
  493. LoadDosError;
  494. dossearchrec2searchrec(f);
  495. end;
  496. {******************************************************************************
  497. --- Findfirst FindNext ---
  498. ******************************************************************************}
  499. procedure findfirst(const path : pathstr;attr : word;var f : searchRec);
  500. var
  501. path0 : array[0..256] of char;
  502. begin
  503. doserror:=0;
  504. strpcopy(path0,path);
  505. if LFNSupport then
  506. LFNFindFirst(path0,attr,f)
  507. else
  508. Dosfindfirst(path0,attr,f);
  509. end;
  510. procedure findnext(var f : searchRec);
  511. begin
  512. doserror:=0;
  513. if LFNSupport then
  514. LFNFindnext(f)
  515. else
  516. Dosfindnext(f);
  517. end;
  518. Procedure FindClose(Var f: SearchRec);
  519. begin
  520. DosError:=0;
  521. if LFNSupport then
  522. LFNFindClose(f);
  523. end;
  524. //type swap_proc = procedure;
  525. //var
  526. // _swap_in : swap_proc;external name '_swap_in';
  527. // _swap_out : swap_proc;external name '_swap_out';
  528. // _exception_exit : pointer;external name '_exception_exit';
  529. // _v2prt0_exceptions_on : longbool;external name '_v2prt0_exceptions_on';
  530. (*
  531. procedure swapvectors;
  532. begin
  533. if _exception_exit<>nil then
  534. if _v2prt0_exceptions_on then
  535. _swap_out()
  536. else
  537. _swap_in();
  538. end;
  539. *)
  540. {******************************************************************************
  541. --- File ---
  542. ******************************************************************************}
  543. Function FSearch(path: pathstr; dirlist: string): pathstr;
  544. var
  545. p1 : longint;
  546. s : searchrec;
  547. newdir : pathstr;
  548. begin
  549. { No wildcards allowed in these things }
  550. if (pos('?',path)<>0) or (pos('*',path)<>0) then
  551. begin
  552. fsearch:='';
  553. exit;
  554. end;
  555. { check if the file specified exists }
  556. findfirst(path,anyfile and not(directory),s);
  557. if doserror=0 then
  558. begin
  559. findclose(s);
  560. fsearch:=path;
  561. exit;
  562. end;
  563. findclose(s);
  564. { allow slash as backslash }
  565. DoDirSeparators(dirlist);
  566. repeat
  567. p1:=pos(';',dirlist);
  568. if p1<>0 then
  569. begin
  570. newdir:=copy(dirlist,1,p1-1);
  571. delete(dirlist,1,p1);
  572. end
  573. else
  574. begin
  575. newdir:=dirlist;
  576. dirlist:='';
  577. end;
  578. if (newdir<>'') and (not (newdir[length(newdir)] in [DirectorySeparator,DriveSeparator])) then
  579. newdir:=newdir+DirectorySeparator;
  580. findfirst(newdir+path,anyfile and not(directory),s);
  581. if doserror=0 then
  582. newdir:=newdir+path
  583. else
  584. newdir:='';
  585. findclose(s);
  586. until (dirlist='') or (newdir<>'');
  587. fsearch:=newdir;
  588. end;
  589. { change to short filename if successful DOS call PM }
  590. function GetShortName(var p : String) : boolean;
  591. var
  592. c : array[0..255] of char;
  593. begin
  594. move(p[1],c[0],length(p));
  595. c[length(p)]:=#0;
  596. copytodos(c,length(p)+1);
  597. dosregs.ax:=$7160;
  598. dosregs.cx:=1;
  599. dosregs.ds:=tb_segment;
  600. dosregs.si:=tb_offset;
  601. dosregs.es:=tb_segment;
  602. dosregs.di:=tb_offset;
  603. msdos(dosregs);
  604. LoadDosError;
  605. if DosError=0 then
  606. begin
  607. copyfromdos(c,255);
  608. move(c[0],p[1],strlen(c));
  609. p[0]:=char(strlen(c));
  610. GetShortName:=true;
  611. end
  612. else
  613. GetShortName:=false;
  614. end;
  615. { change to long filename if successful DOS call PM }
  616. function GetLongName(var p : String) : boolean;
  617. var
  618. c : array[0..255] of char;
  619. begin
  620. move(p[1],c[0],length(p));
  621. c[length(p)]:=#0;
  622. copytodos(c,length(p)+1);
  623. dosregs.ax:=$7160;
  624. dosregs.cx:=2;
  625. dosregs.ds:=tb_segment;
  626. dosregs.si:=tb_offset;
  627. dosregs.es:=tb_segment;
  628. dosregs.di:=tb_offset;
  629. msdos(dosregs);
  630. LoadDosError;
  631. if DosError=0 then
  632. begin
  633. copyfromdos(c,255);
  634. move(c[0],p[1],strlen(c));
  635. p[0]:=char(strlen(c));
  636. GetLongName:=true;
  637. end
  638. else
  639. GetLongName:=false;
  640. end;
  641. {******************************************************************************
  642. --- Get/Set File Time,Attr ---
  643. ******************************************************************************}
  644. procedure getftime(var f;var time : longint);
  645. begin
  646. dosregs.bx:=textrec(f).handle;
  647. dosregs.ax:=$5700;
  648. msdos(dosregs);
  649. loaddoserror;
  650. time:=(dosregs.dx shl 16)+dosregs.cx;
  651. end;
  652. procedure setftime(var f;time : longint);
  653. begin
  654. dosregs.bx:=textrec(f).handle;
  655. dosregs.cx:=time and $ffff;
  656. dosregs.dx:=time shr 16;
  657. dosregs.ax:=$5701;
  658. msdos(dosregs);
  659. loaddoserror;
  660. end;
  661. procedure getfattr(var f;var attr : word);
  662. begin
  663. copytodos(filerec(f).name,strlen(filerec(f).name)+1);
  664. dosregs.edx:=tb_offset;
  665. dosregs.ds:=tb_segment;
  666. if LFNSupport then
  667. begin
  668. dosregs.ax:=$7143;
  669. dosregs.bx:=0;
  670. end
  671. else
  672. dosregs.ax:=$4300;
  673. msdos(dosregs);
  674. LoadDosError;
  675. Attr:=dosregs.cx;
  676. end;
  677. procedure setfattr(var f;attr : word);
  678. begin
  679. copytodos(filerec(f).name,strlen(filerec(f).name)+1);
  680. dosregs.edx:=tb_offset;
  681. dosregs.ds:=tb_segment;
  682. if LFNSupport then
  683. begin
  684. dosregs.ax:=$7143;
  685. dosregs.bx:=1;
  686. end
  687. else
  688. dosregs.ax:=$4301;
  689. dosregs.cx:=attr;
  690. msdos(dosregs);
  691. LoadDosError;
  692. end;
  693. {******************************************************************************
  694. --- Environment ---
  695. ******************************************************************************}
  696. function envcount : longint;
  697. var
  698. hp : ppchar;
  699. begin
  700. hp:=envp;
  701. envcount:=0;
  702. while assigned(hp^) do
  703. begin
  704. inc(envcount);
  705. inc(hp);
  706. end;
  707. end;
  708. function EnvStr (Index: longint): string;
  709. begin
  710. if (index<=0) or (index>envcount) then
  711. begin
  712. envstr:='';
  713. exit;
  714. end;
  715. envstr:=strpas(ppchar(pointer(envp)+4*(index-1))^);
  716. end;
  717. Function GetEnv(envvar: string): string;
  718. var
  719. hp : ppchar;
  720. hs : string;
  721. eqpos : longint;
  722. begin
  723. envvar:=upcase(envvar);
  724. hp:=envp;
  725. getenv:='';
  726. while assigned(hp^) do
  727. begin
  728. hs:=strpas(hp^);
  729. eqpos:=pos('=',hs);
  730. if upcase(copy(hs,1,eqpos-1))=envvar then
  731. begin
  732. getenv:=copy(hs,eqpos+1,255);
  733. exit;
  734. end;
  735. inc(hp);
  736. end;
  737. end;
  738. end.