dos.pp 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872
  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. 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 := 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. BEGIN
  292. if (swap(dosversion)>=$070A) AND LFNSupport then
  293. begin
  294. S:='C:\'#0;
  295. if Drive=0 then
  296. begin
  297. GetDir(Drive,S);
  298. Setlength(S,4);
  299. S[4]:=#0;
  300. end
  301. else
  302. S[1]:=chr(Drive+64);
  303. Rec.Strucversion:=0;
  304. dosmemput(tb_segment,tb_offset,Rec,SIZEOF(ExtendedFat32FreeSpaceRec));
  305. dosmemput(tb_segment,tb_offset+Sizeof(ExtendedFat32FreeSpaceRec)+1,S[1],4);
  306. dosregs.dx:=tb_offset+Sizeof(ExtendedFat32FreeSpaceRec)+1;
  307. dosregs.ds:=tb_segment;
  308. dosregs.di:=tb_offset;
  309. dosregs.es:=tb_segment;
  310. dosregs.cx:=Sizeof(ExtendedFat32FreeSpaceRec);
  311. dosregs.ax:=$7303;
  312. msdos(dosregs);
  313. if (dosregs.flags and fcarry) = 0 then {No error clausule in int except cf}
  314. begin
  315. copyfromdos(rec,Sizeof(ExtendedFat32FreeSpaceRec));
  316. if Free then
  317. Do_DiskData:=int64(rec.AvailAllocUnits)*rec.SecPerClus*rec.BytePerSec
  318. else
  319. Do_DiskData:=int64(rec.TotalAllocUnits)*rec.SecPerClus*rec.BytePerSec;
  320. end
  321. else
  322. Do_DiskData:=-1;
  323. end
  324. else
  325. begin
  326. dosregs.dl:=drive;
  327. dosregs.ah:=$36;
  328. msdos(dosregs);
  329. if dosregs.ax<>$FFFF then
  330. begin
  331. if Free then
  332. Do_DiskData:=int64(dosregs.ax)*dosregs.bx*dosregs.cx
  333. else
  334. Do_DiskData:=int64(dosregs.ax)*dosregs.cx*dosregs.dx;
  335. end
  336. else
  337. do_diskdata:=-1;
  338. end;
  339. end;
  340. function diskfree(drive : byte) : int64;
  341. begin
  342. diskfree:=Do_DiskData(drive,TRUE);
  343. end;
  344. function disksize(drive : byte) : int64;
  345. begin
  346. disksize:=Do_DiskData(drive,false);
  347. end;
  348. {******************************************************************************
  349. --- LFNFindfirst LFNFindNext ---
  350. ******************************************************************************}
  351. type
  352. LFNSearchRec=packed record
  353. attr,
  354. crtime,
  355. crtimehi,
  356. actime,
  357. actimehi,
  358. lmtime,
  359. lmtimehi,
  360. sizehi,
  361. size : longint;
  362. reserved : array[0..7] of byte;
  363. name : array[0..259] of byte;
  364. shortname : array[0..13] of byte;
  365. end;
  366. procedure LFNSearchRec2Dos(const w:LFNSearchRec;hdl:longint;var d:Searchrec;from_findfirst : boolean);
  367. var
  368. Len : longint;
  369. begin
  370. With w do
  371. begin
  372. FillChar(d,sizeof(SearchRec),0);
  373. if DosError=0 then
  374. len:=StrLen(@Name)
  375. else
  376. len:=0;
  377. d.Name[0]:=chr(len);
  378. Move(Name[0],d.Name[1],Len);
  379. d.Time:=lmTime;
  380. d.Size:=Size;
  381. d.Attr:=Attr and $FF;
  382. if (DosError<>0) and from_findfirst then
  383. hdl:=-1;
  384. Move(hdl,d.Fill,4);
  385. end;
  386. end;
  387. procedure LFNFindFirst(path:pchar;attr:longint;var s:searchrec);
  388. var
  389. i : longint;
  390. w : LFNSearchRec;
  391. begin
  392. { allow slash as backslash }
  393. for i:=0 to strlen(path) do
  394. if path[i]='/' then path[i]:='\';
  395. dosregs.si:=1; { use ms-dos time }
  396. { don't include the label if not asked for it, needed for network drives }
  397. if attr=$8 then
  398. dosregs.ecx:=8
  399. else
  400. dosregs.ecx:=attr and (not 8);
  401. dosregs.edx:=tb_offset+Sizeof(LFNSearchrec)+1;
  402. dosmemput(tb_segment,tb_offset+Sizeof(LFNSearchrec)+1,path^,strlen(path)+1);
  403. dosregs.ds:=tb_segment;
  404. dosregs.edi:=tb_offset;
  405. dosregs.es:=tb_segment;
  406. dosregs.ax:=$714e;
  407. msdos(dosregs);
  408. LoadDosError;
  409. copyfromdos(w,sizeof(LFNSearchRec));
  410. LFNSearchRec2Dos(w,dosregs.ax,s,true);
  411. end;
  412. procedure LFNFindNext(var s:searchrec);
  413. var
  414. hdl : longint;
  415. w : LFNSearchRec;
  416. begin
  417. Move(s.Fill,hdl,4);
  418. dosregs.si:=1; { use ms-dos time }
  419. dosregs.edi:=tb_offset;
  420. dosregs.es:=tb_segment;
  421. dosregs.ebx:=hdl;
  422. dosregs.ax:=$714f;
  423. msdos(dosregs);
  424. LoadDosError;
  425. copyfromdos(w,sizeof(LFNSearchRec));
  426. LFNSearchRec2Dos(w,hdl,s,false);
  427. end;
  428. procedure LFNFindClose(var s:searchrec);
  429. var
  430. hdl : longint;
  431. begin
  432. Move(s.Fill,hdl,4);
  433. { Do not call MsDos if FindFirst returned with an error }
  434. if hdl=-1 then
  435. begin
  436. DosError:=0;
  437. exit;
  438. end;
  439. dosregs.ebx:=hdl;
  440. dosregs.ax:=$71a1;
  441. msdos(dosregs);
  442. LoadDosError;
  443. end;
  444. {******************************************************************************
  445. --- DosFindfirst DosFindNext ---
  446. ******************************************************************************}
  447. procedure dossearchrec2searchrec(var f : searchrec);
  448. var
  449. len : longint;
  450. begin
  451. { Check is necessary!! OS/2's VDM doesn't clear the name with #0 if the }
  452. { file doesn't exist! (JM) }
  453. if dosError = 0 then
  454. len:=StrLen(@f.Name)
  455. else len := 0;
  456. Move(f.Name[0],f.Name[1],Len);
  457. f.Name[0]:=chr(len);
  458. end;
  459. procedure DosFindfirst(path : pchar;attr : word;var f : searchrec);
  460. var
  461. i : longint;
  462. begin
  463. { allow slash as backslash }
  464. for i:=0 to strlen(path) do
  465. if path[i]='/' then path[i]:='\';
  466. copytodos(f,sizeof(searchrec));
  467. dosregs.edx:=tb_offset;
  468. dosregs.ds:=tb_segment;
  469. dosregs.ah:=$1a;
  470. msdos(dosregs);
  471. dosregs.ecx:=attr;
  472. dosregs.edx:=tb_offset+Sizeof(searchrec)+1;
  473. dosmemput(tb_segment,tb_offset+Sizeof(searchrec)+1,path^,strlen(path)+1);
  474. dosregs.ds:=tb_segment;
  475. dosregs.ah:=$4e;
  476. msdos(dosregs);
  477. copyfromdos(f,sizeof(searchrec));
  478. LoadDosError;
  479. dossearchrec2searchrec(f);
  480. end;
  481. procedure Dosfindnext(var f : searchrec);
  482. begin
  483. copytodos(f,sizeof(searchrec));
  484. dosregs.edx:=tb_offset;
  485. dosregs.ds:=tb_segment;
  486. dosregs.ah:=$1a;
  487. msdos(dosregs);
  488. dosregs.ah:=$4f;
  489. msdos(dosregs);
  490. copyfromdos(f,sizeof(searchrec));
  491. LoadDosError;
  492. dossearchrec2searchrec(f);
  493. end;
  494. {******************************************************************************
  495. --- Findfirst FindNext ---
  496. ******************************************************************************}
  497. procedure findfirst(const path : pathstr;attr : word;var f : searchRec);
  498. var
  499. path0 : array[0..256] of char;
  500. begin
  501. doserror:=0;
  502. strpcopy(path0,path);
  503. if LFNSupport then
  504. LFNFindFirst(path0,attr,f)
  505. else
  506. Dosfindfirst(path0,attr,f);
  507. end;
  508. procedure findnext(var f : searchRec);
  509. begin
  510. doserror:=0;
  511. if LFNSupport then
  512. LFNFindnext(f)
  513. else
  514. Dosfindnext(f);
  515. end;
  516. Procedure FindClose(Var f: SearchRec);
  517. begin
  518. DosError:=0;
  519. if LFNSupport then
  520. LFNFindClose(f);
  521. end;
  522. //type swap_proc = procedure;
  523. //var
  524. // _swap_in : swap_proc;external name '_swap_in';
  525. // _swap_out : swap_proc;external name '_swap_out';
  526. // _exception_exit : pointer;external name '_exception_exit';
  527. // _v2prt0_exceptions_on : longbool;external name '_v2prt0_exceptions_on';
  528. (*
  529. procedure swapvectors;
  530. begin
  531. if _exception_exit<>nil then
  532. if _v2prt0_exceptions_on then
  533. _swap_out()
  534. else
  535. _swap_in();
  536. end;
  537. *)
  538. {******************************************************************************
  539. --- File ---
  540. ******************************************************************************}
  541. Function FSearch(path: pathstr; dirlist: string): pathstr;
  542. var
  543. i,p1 : longint;
  544. s : searchrec;
  545. newdir : pathstr;
  546. begin
  547. { check if the file specified exists }
  548. findfirst(path,anyfile,s);
  549. if doserror=0 then
  550. begin
  551. findclose(s);
  552. fsearch:=path;
  553. exit;
  554. end;
  555. { No wildcards allowed in these things }
  556. if (pos('?',path)<>0) or (pos('*',path)<>0) then
  557. fsearch:=''
  558. else
  559. begin
  560. { allow slash as backslash }
  561. for i:=1 to length(dirlist) do
  562. if dirlist[i]='/' then dirlist[i]:='\';
  563. repeat
  564. p1:=pos(';',dirlist);
  565. if p1<>0 then
  566. begin
  567. newdir:=copy(dirlist,1,p1-1);
  568. delete(dirlist,1,p1);
  569. end
  570. else
  571. begin
  572. newdir:=dirlist;
  573. dirlist:='';
  574. end;
  575. if (newdir<>'') and (not (newdir[length(newdir)] in ['\',':'])) then
  576. newdir:=newdir+'\';
  577. findfirst(newdir+path,anyfile,s);
  578. if doserror=0 then
  579. newdir:=newdir+path
  580. else
  581. newdir:='';
  582. until (dirlist='') or (newdir<>'');
  583. fsearch:=newdir;
  584. end;
  585. findclose(s);
  586. end;
  587. { change to short filename if successful DOS call PM }
  588. function GetShortName(var p : String) : boolean;
  589. var
  590. c : array[0..255] of char;
  591. begin
  592. move(p[1],c[0],length(p));
  593. c[length(p)]:=#0;
  594. copytodos(c,length(p)+1);
  595. dosregs.ax:=$7160;
  596. dosregs.cx:=1;
  597. dosregs.ds:=tb_segment;
  598. dosregs.si:=tb_offset;
  599. dosregs.es:=tb_segment;
  600. dosregs.di:=tb_offset;
  601. msdos(dosregs);
  602. LoadDosError;
  603. if DosError=0 then
  604. begin
  605. copyfromdos(c,255);
  606. move(c[0],p[1],strlen(c));
  607. p[0]:=char(strlen(c));
  608. GetShortName:=true;
  609. end
  610. else
  611. GetShortName:=false;
  612. end;
  613. { change to long filename if successful DOS call PM }
  614. function GetLongName(var p : String) : boolean;
  615. var
  616. c : array[0..255] of char;
  617. begin
  618. move(p[1],c[0],length(p));
  619. c[length(p)]:=#0;
  620. copytodos(c,length(p)+1);
  621. dosregs.ax:=$7160;
  622. dosregs.cx:=2;
  623. dosregs.ds:=tb_segment;
  624. dosregs.si:=tb_offset;
  625. dosregs.es:=tb_segment;
  626. dosregs.di:=tb_offset;
  627. msdos(dosregs);
  628. LoadDosError;
  629. if DosError=0 then
  630. begin
  631. copyfromdos(c,255);
  632. move(c[0],p[1],strlen(c));
  633. p[0]:=char(strlen(c));
  634. GetLongName:=true;
  635. end
  636. else
  637. GetLongName:=false;
  638. end;
  639. {******************************************************************************
  640. --- Get/Set File Time,Attr ---
  641. ******************************************************************************}
  642. procedure getftime(var f;var time : longint);
  643. begin
  644. dosregs.bx:=textrec(f).handle;
  645. dosregs.ax:=$5700;
  646. msdos(dosregs);
  647. loaddoserror;
  648. time:=(dosregs.dx shl 16)+dosregs.cx;
  649. end;
  650. procedure setftime(var f;time : longint);
  651. begin
  652. dosregs.bx:=textrec(f).handle;
  653. dosregs.cx:=time and $ffff;
  654. dosregs.dx:=time shr 16;
  655. dosregs.ax:=$5701;
  656. msdos(dosregs);
  657. loaddoserror;
  658. end;
  659. procedure getfattr(var f;var attr : word);
  660. begin
  661. copytodos(filerec(f).name,strlen(filerec(f).name)+1);
  662. dosregs.edx:=tb_offset;
  663. dosregs.ds:=tb_segment;
  664. if LFNSupport then
  665. begin
  666. dosregs.ax:=$7143;
  667. dosregs.bx:=0;
  668. end
  669. else
  670. dosregs.ax:=$4300;
  671. msdos(dosregs);
  672. LoadDosError;
  673. Attr:=dosregs.cx;
  674. end;
  675. procedure setfattr(var f;attr : word);
  676. begin
  677. copytodos(filerec(f).name,strlen(filerec(f).name)+1);
  678. dosregs.edx:=tb_offset;
  679. dosregs.ds:=tb_segment;
  680. if LFNSupport then
  681. begin
  682. dosregs.ax:=$7143;
  683. dosregs.bx:=1;
  684. end
  685. else
  686. dosregs.ax:=$4301;
  687. dosregs.cx:=attr;
  688. msdos(dosregs);
  689. LoadDosError;
  690. end;
  691. {******************************************************************************
  692. --- Environment ---
  693. ******************************************************************************}
  694. function envcount : longint;
  695. var
  696. hp : ppchar;
  697. begin
  698. hp:=envp;
  699. envcount:=0;
  700. while assigned(hp^) do
  701. begin
  702. inc(envcount);
  703. inc(hp);
  704. end;
  705. end;
  706. function EnvStr (Index: longint): string;
  707. begin
  708. if (index<=0) or (index>envcount) then
  709. begin
  710. envstr:='';
  711. exit;
  712. end;
  713. envstr:=strpas(ppchar(pointer(envp)+4*(index-1))^);
  714. end;
  715. Function GetEnv(envvar: string): string;
  716. var
  717. hp : ppchar;
  718. hs : string;
  719. eqpos : longint;
  720. begin
  721. envvar:=upcase(envvar);
  722. hp:=envp;
  723. getenv:='';
  724. while assigned(hp^) do
  725. begin
  726. hs:=strpas(hp^);
  727. eqpos:=pos('=',hs);
  728. if upcase(copy(hs,1,eqpos-1))=envvar then
  729. begin
  730. getenv:=copy(hs,eqpos+1,255);
  731. exit;
  732. end;
  733. inc(hp);
  734. end;
  735. end;
  736. end.
  737. {
  738. $Log$
  739. Revision 1.9 2004-12-05 16:44:43 hajny
  740. * GetMsCount added, platform independent routines moved to single include file
  741. Revision 1.8 2004/02/17 17:37:26 daniel
  742. * Enable threadvars again
  743. Revision 1.7 2004/02/16 22:18:44 hajny
  744. * LastDosExitCode changed back from threadvar temporarily
  745. Revision 1.6 2004/02/15 21:36:10 hajny
  746. * overloaded ExecuteProcess added, EnvStr param changed to longint
  747. Revision 1.5 2004/02/09 12:03:16 michael
  748. + Switched to single interface in dosh.inc
  749. Revision 1.4 2003/10/18 09:18:29 hajny
  750. * Wiktor Sywula: transfer_buffer changed to tb
  751. Revision 1.3 2003/10/03 21:59:28 peter
  752. * stdcall fixes
  753. Revision 1.2 2003/09/07 22:29:26 hajny
  754. * syswat renamed to system, CVS log added
  755. Revision 1.1 2003/09/05 18:09:35 florian
  756. * added initial watcom extender files; they need to be cleaned up
  757. }