2
0

sysutils.pp 29 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066
  1. {
  2. $Id$
  3. This file is part of the Free Pascal run time library.
  4. Copyright (c) 1999-2000 by Florian Klaempfl
  5. member of the Free Pascal development team
  6. Sysutils unit for OS/2
  7. See the file COPYING.FPC, included in this distribution,
  8. for details about the copyright.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  12. **********************************************************************}
  13. unit sysutils;
  14. interface
  15. {$MODE objfpc}
  16. { force ansistrings }
  17. {$H+}
  18. uses
  19. Dos;
  20. type
  21. THandle = type Longint;
  22. { Include platform independent interface part }
  23. {$i sysutilh.inc}
  24. implementation
  25. { Include platform independent implementation part }
  26. {$i sysutils.inc}
  27. {****************************************************************************
  28. System (imported) calls
  29. ****************************************************************************}
  30. (* "uses DosCalls" could not be used here due to type *)
  31. (* conflicts, so needed parts had to be redefined here). *)
  32. type
  33. TFileStatus = object
  34. end;
  35. PFileStatus = ^TFileStatus;
  36. TFileStatus0 = object (TFileStatus)
  37. DateCreation, {Date of file creation.}
  38. TimeCreation, {Time of file creation.}
  39. DateLastAccess, {Date of last access to file.}
  40. TimeLastAccess, {Time of last access to file.}
  41. DateLastWrite, {Date of last modification of file.}
  42. TimeLastWrite: word; {Time of last modification of file.}
  43. FileSize, {Size of file.}
  44. FileAlloc: longint; {Amount of space the file really
  45. occupies on disk.}
  46. end;
  47. PFileStatus0 = ^TFileStatus0;
  48. TFileStatus3 = object (TFileStatus)
  49. NextEntryOffset: longint; {Offset of next entry}
  50. DateCreation, {Date of file creation.}
  51. TimeCreation, {Time of file creation.}
  52. DateLastAccess, {Date of last access to file.}
  53. TimeLastAccess, {Time of last access to file.}
  54. DateLastWrite, {Date of last modification of file.}
  55. TimeLastWrite: word; {Time of last modification of file.}
  56. FileSize, {Size of file.}
  57. FileAlloc: longint; {Amount of space the file really
  58. occupies on disk.}
  59. AttrFile: longint; {Attributes of file.}
  60. end;
  61. PFileStatus3 = ^TFileStatus3;
  62. TFileFindBuf3 = object (TFileStatus3)
  63. Name: ShortString; {Also possible to use as ASCIIZ.
  64. The byte following the last string
  65. character is always zero.}
  66. end;
  67. PFileFindBuf3 = ^TFileFindBuf3;
  68. TFSInfo = record
  69. case word of
  70. 1:
  71. (File_Sys_ID,
  72. Sectors_Per_Cluster,
  73. Total_Clusters,
  74. Free_Clusters: longint;
  75. Bytes_Per_Sector: word);
  76. 2: {For date/time description,
  77. see file searching realted
  78. routines.}
  79. (Label_Date, {Date when volume label was created.}
  80. Label_Time: word; {Time when volume label was created.}
  81. VolumeLabel: ShortString); {Volume label. Can also be used
  82. as ASCIIZ, because the byte
  83. following the last character of
  84. the string is always zero.}
  85. end;
  86. PFSInfo = ^TFSInfo;
  87. TCountryCode=record
  88. Country, {Country to query info about (0=current).}
  89. CodePage: longint; {Code page to query info about (0=current).}
  90. end;
  91. PCountryCode=^TCountryCode;
  92. TTimeFmt = (Clock12, Clock24);
  93. TCountryInfo=record
  94. Country, CodePage: longint; {Country and codepage requested.}
  95. case byte of
  96. 0:
  97. (DateFormat: longint; {1=ddmmyy 2=yymmdd 3=mmddyy}
  98. CurrencyUnit: array [0..4] of char;
  99. ThousandSeparator: char; {Thousands separator.}
  100. Zero1: byte; {Always zero.}
  101. DecimalSeparator: char; {Decimals separator,}
  102. Zero2: byte;
  103. DateSeparator: char; {Date separator.}
  104. Zero3: byte;
  105. TimeSeparator: char; {Time separator.}
  106. Zero4: byte;
  107. CurrencyFormat, {Bit field:
  108. Bit 0: 0=indicator before value
  109. 1=indicator after value
  110. Bit 1: 1=insert space after
  111. indicator.
  112. Bit 2: 1=Ignore bit 0&1, replace
  113. decimal separator with
  114. indicator.}
  115. DecimalPlace: byte; {Number of decimal places used in
  116. currency indication.}
  117. TimeFormat: TTimeFmt; {12/24 hour.}
  118. Reserve1: array [0..1] of word;
  119. DataSeparator: char; {Data list separator}
  120. Zero5: byte;
  121. Reserve2: array [0..4] of word);
  122. 1:
  123. (fsDateFmt: longint; {1=ddmmyy 2=yymmdd 3=mmddyy}
  124. szCurrency: array [0..4] of char;
  125. {null terminated currency symbol}
  126. szThousandsSeparator: array [0..1] of char;
  127. {Thousands separator + #0}
  128. szDecimal: array [0..1] of char;
  129. {Decimals separator + #0}
  130. szDateSeparator: array [0..1] of char;
  131. {Date separator + #0}
  132. szTimeSeparator: array [0..1] of char;
  133. {Time separator + #0}
  134. fsCurrencyFmt, {Bit field:
  135. Bit 0: 0=indicator before value
  136. 1=indicator after value
  137. Bit 1: 1=insert space after
  138. indicator.
  139. Bit 2: 1=Ignore bit 0&1, replace
  140. decimal separator with
  141. indicator}
  142. cDecimalPlace: byte; {Number of decimal places used in
  143. currency indication}
  144. fsTimeFmt: byte; {0=12,1=24 hours}
  145. abReserved1: array [0..1] of word;
  146. szDataSeparator: array [0..1] of char;
  147. {Data list separator + #0}
  148. abReserved2: array [0..4] of word);
  149. end;
  150. PCountryInfo=^TCountryInfo;
  151. const
  152. ilStandard = 1;
  153. ilQueryEAsize = 2;
  154. ilQueryEAs = 3;
  155. ilQueryFullName = 5;
  156. {This is the correct way to call external assembler procedures.}
  157. procedure syscall;external name '___SYSCALL';
  158. function DosSetFileInfo (Handle, InfoLevel: longint; AFileStatus: PFileStatus;
  159. FileStatusLen: longint): longint; cdecl; external 'DOSCALLS' index 218;
  160. function DosQueryFSInfo (DiskNum, InfoLevel: longint; var Buffer: TFSInfo;
  161. BufLen: longint): longint; cdecl; external 'DOSCALLS' index 278;
  162. function DosQueryFileInfo (Handle, InfoLevel: longint;
  163. AFileStatus: PFileStatus; FileStatusLen: longint): longint; cdecl;
  164. external 'DOSCALLS' index 279;
  165. function DosScanEnv (Name: PChar; var Value: PChar): longint; cdecl;
  166. external 'DOSCALLS' index 227;
  167. function DosFindFirst (FileMask: PChar; var Handle: longint; Attrib: longint;
  168. AFileStatus: PFileStatus; FileStatusLen: cardinal;
  169. var Count: cardinal; InfoLevel: cardinal): longint; cdecl;
  170. external 'DOSCALLS' index 264;
  171. function DosFindNext (Handle: longint; AFileStatus: PFileStatus;
  172. FileStatusLen: cardinal; var Count: cardinal): longint; cdecl;
  173. external 'DOSCALLS' index 265;
  174. function DosFindClose (Handle: longint): longint; cdecl;
  175. external 'DOSCALLS' index 263;
  176. function DosQueryCtryInfo (Size: longint; var Country: TCountryCode;
  177. var Res: TCountryInfo; var ActualSize: longint): longint; cdecl;
  178. external 'NLS' index 5;
  179. function DosMapCase (Size: longint; var Country: TCountryCode;
  180. AString: PChar): longint; cdecl; external 'NLS' index 7;
  181. {****************************************************************************
  182. File Functions
  183. ****************************************************************************}
  184. const
  185. ofRead = $0000; {Open for reading}
  186. ofWrite = $0001; {Open for writing}
  187. ofReadWrite = $0002; {Open for reading/writing}
  188. doDenyRW = $0010; {DenyAll (no sharing)}
  189. faCreateNew = $00010000; {Create if file does not exist}
  190. faOpenReplace = $00040000; {Truncate if file exists}
  191. faCreate = $00050000; {Create if file does not exist, truncate otherwise}
  192. FindResvdMask = $00003737; {Allowed bits in attribute
  193. specification for DosFindFirst call.}
  194. {$ASMMODE INTEL}
  195. function FileOpen (const FileName: string; Mode: integer): longint;
  196. {$IFOPT H+}
  197. assembler;
  198. {$ELSE}
  199. var FN: string;
  200. begin
  201. FN := FileName + #0;
  202. {$ENDIF}
  203. asm
  204. mov eax, Mode
  205. (* DenyAll if sharing not specified. *)
  206. test eax, 112
  207. jnz @FOpen1
  208. or eax, 16
  209. @FOpen1:
  210. mov ecx, eax
  211. mov eax, 7F2Bh
  212. {$IFOPT H+}
  213. mov edx, FileName
  214. {$ELSE}
  215. lea edx, FN
  216. inc edx
  217. {$ENDIF}
  218. call syscall
  219. {$IFOPT H-}
  220. mov Result, eax
  221. {$ENDIF}
  222. end ['eax', 'ebx', 'ecx', 'edx'];
  223. {$IFOPT H-}
  224. end;
  225. {$ENDIF}
  226. function FileCreate (const FileName: string): longint;
  227. {$IFOPT H+}
  228. assembler;
  229. {$ELSE}
  230. var FN: string;
  231. begin
  232. FN := FileName + #0;
  233. {$ENDIF}
  234. asm
  235. mov eax, 7F2Bh
  236. mov ecx, ofReadWrite or faCreate or doDenyRW (* Sharing to DenyAll *)
  237. {$IFOPT H+}
  238. mov edx, FileName
  239. {$ELSE}
  240. lea edx, FN
  241. inc edx
  242. {$ENDIF}
  243. call syscall
  244. {$IFOPT H-}
  245. mov Result, eax
  246. {$ENDIF}
  247. end ['eax', 'ebx', 'ecx', 'edx'];
  248. {$IFOPT H-}
  249. end;
  250. {$ENDIF}
  251. Function FileCreate (Const FileName : String; Mode:longint) : Longint;
  252. begin
  253. FileCreate:=FileCreate(FileName);
  254. end;
  255. function FileRead (Handle: longint; var Buffer; Count: longint): longint;
  256. assembler;
  257. asm
  258. mov eax, 3F00h
  259. mov ebx, Handle
  260. mov ecx, Count
  261. mov edx, Buffer
  262. call syscall
  263. jnc @FReadEnd
  264. mov eax, -1
  265. @FReadEnd:
  266. end ['eax', 'ebx', 'ecx', 'edx'];
  267. function FileWrite (Handle: longint; const Buffer; Count: longint): longint;
  268. assembler;
  269. asm
  270. mov eax, 4000h
  271. mov ebx, Handle
  272. mov ecx, Count
  273. mov edx, Buffer
  274. call syscall
  275. jnc @FWriteEnd
  276. mov eax, -1
  277. @FWriteEnd:
  278. end ['eax', 'ebx', 'ecx', 'edx'];
  279. function FileSeek (Handle, FOffset, Origin: longint): longint; assembler;
  280. asm
  281. mov eax, Origin
  282. mov ah, 42h
  283. mov ebx, Handle
  284. mov edx, FOffset
  285. call syscall
  286. jnc @FSeekEnd
  287. mov eax, -1
  288. @FSeekEnd:
  289. end ['eax', 'ebx', 'edx'];
  290. Function FileSeek (Handle : Longint; FOffset,Origin : Int64) : Int64;
  291. begin
  292. {$warning need to add 64bit call }
  293. Result:=FileSeek(Handle,Longint(Foffset),Longint(Origin));
  294. end;
  295. procedure FileClose (Handle: longint);
  296. begin
  297. if (Handle > 4) or ((os_mode = osOS2) and (Handle > 2)) then
  298. asm
  299. push ebx
  300. mov eax, 3E00h
  301. mov ebx, Handle
  302. call syscall
  303. pop ebx
  304. end ['eax'];
  305. end;
  306. function FileTruncate (Handle, Size: longint): boolean; assembler;
  307. asm
  308. mov eax, 7F25h
  309. mov ebx, Handle
  310. mov edx, Size
  311. call syscall
  312. jc @FTruncEnd
  313. mov eax, 4202h
  314. mov ebx, Handle
  315. mov edx, 0
  316. call syscall
  317. mov eax, 0
  318. jnc @FTruncEnd
  319. dec eax
  320. @FTruncEnd:
  321. end ['eax', 'ebx', 'ecx', 'edx'];
  322. function FileAge (const FileName: string): longint;
  323. var Handle: longint;
  324. begin
  325. Handle := FileOpen (FileName, 0);
  326. if Handle <> -1 then
  327. begin
  328. Result := FileGetDate (Handle);
  329. FileClose (Handle);
  330. end
  331. else
  332. Result := -1;
  333. end;
  334. function FileExists (const FileName: string): boolean;
  335. {$IFOPT H+}
  336. assembler;
  337. {$ELSE}
  338. var FN: string;
  339. begin
  340. FN := FileName + #0;
  341. {$ENDIF}
  342. asm
  343. mov ax, 4300h
  344. {$IFOPT H+}
  345. mov edx, FileName
  346. {$ELSE}
  347. lea edx, FN
  348. inc edx
  349. {$ENDIF}
  350. call syscall
  351. mov eax, 0
  352. jc @FExistsEnd
  353. test cx, 18h
  354. jnz @FExistsEnd
  355. inc eax
  356. @FExistsEnd:
  357. {$IFOPT H-}
  358. mov Result, eax
  359. {$ENDIF}
  360. end ['eax', 'ecx', 'edx'];
  361. {$IFOPT H-}
  362. end;
  363. {$ENDIF}
  364. type TRec = record
  365. T, D: word;
  366. end;
  367. PSearchRec = ^SearchRec;
  368. function FindFirst (const Path: string; Attr: longint; var Rslt: TSearchRec): longint;
  369. var SR: PSearchRec;
  370. FStat: PFileFindBuf3;
  371. Count: cardinal;
  372. Err: longint;
  373. begin
  374. if os_mode = osOS2 then
  375. begin
  376. New (FStat);
  377. Rslt.FindHandle := $FFFFFFFF;
  378. Count := 1;
  379. Err := DosFindFirst (PChar (Path), Rslt.FindHandle,
  380. Attr and FindResvdMask, FStat, SizeOf (FStat^), Count,
  381. ilStandard);
  382. if (Err = 0) and (Count = 0) then Err := 18;
  383. FindFirst := -Err;
  384. if Err = 0 then
  385. begin
  386. Rslt.Name := FStat^.Name;
  387. Rslt.Size := FStat^.FileSize;
  388. Rslt.Attr := FStat^.AttrFile;
  389. Rslt.ExcludeAttr := 0;
  390. TRec (Rslt.Time).T := FStat^.TimeLastWrite;
  391. TRec (Rslt.Time).D := FStat^.DateLastWrite;
  392. end;
  393. Dispose (FStat);
  394. end
  395. else
  396. begin
  397. Err := DOS.DosError;
  398. GetMem (SR, SizeOf (SearchRec));
  399. Rslt.FindHandle := longint(SR);
  400. DOS.FindFirst (Path, Attr, SR^);
  401. FindFirst := -DOS.DosError;
  402. if DosError = 0 then
  403. begin
  404. Rslt.Time := SR^.Time;
  405. Rslt.Size := SR^.Size;
  406. Rslt.Attr := SR^.Attr;
  407. Rslt.ExcludeAttr := 0;
  408. Rslt.Name := SR^.Name;
  409. end;
  410. DOS.DosError := Err;
  411. end;
  412. end;
  413. function FindNext (var Rslt: TSearchRec): longint;
  414. var SR: PSearchRec;
  415. FStat: PFileFindBuf3;
  416. Count: cardinal;
  417. Err: longint;
  418. begin
  419. if os_mode = osOS2 then
  420. begin
  421. New (FStat);
  422. Count := 1;
  423. Err := DosFindNext (Rslt.FindHandle, FStat, SizeOf (FStat^),
  424. Count);
  425. if (Err = 0) and (Count = 0) then Err := 18;
  426. FindNext := -Err;
  427. if Err = 0 then
  428. begin
  429. Rslt.Name := FStat^.Name;
  430. Rslt.Size := FStat^.FileSize;
  431. Rslt.Attr := FStat^.AttrFile;
  432. Rslt.ExcludeAttr := 0;
  433. TRec (Rslt.Time).T := FStat^.TimeLastWrite;
  434. TRec (Rslt.Time).D := FStat^.DateLastWrite;
  435. end;
  436. Dispose (FStat);
  437. end
  438. else
  439. begin
  440. SR := PSearchRec (Rslt.FindHandle);
  441. if SR <> nil then
  442. begin
  443. DOS.FindNext (SR^);
  444. FindNext := -DosError;
  445. if DosError = 0 then
  446. begin
  447. Rslt.Time := SR^.Time;
  448. Rslt.Size := SR^.Size;
  449. Rslt.Attr := SR^.Attr;
  450. Rslt.ExcludeAttr := 0;
  451. Rslt.Name := SR^.Name;
  452. end;
  453. end;
  454. end;
  455. end;
  456. procedure FindClose (var F: TSearchrec);
  457. var SR: PSearchRec;
  458. begin
  459. if os_mode = osOS2 then
  460. begin
  461. DosFindClose (F.FindHandle);
  462. end
  463. else
  464. begin
  465. SR := PSearchRec (F.FindHandle);
  466. DOS.FindClose (SR^);
  467. FreeMem (SR, SizeOf (SearchRec));
  468. end;
  469. F.FindHandle := 0;
  470. end;
  471. function FileGetDate (Handle: longint): longint; assembler;
  472. asm
  473. mov ax, 5700h
  474. mov ebx, Handle
  475. call syscall
  476. mov eax, -1
  477. jc @FGetDateEnd
  478. mov ax, dx
  479. shld eax, ecx, 16
  480. @FGetDateEnd:
  481. end ['eax', 'ebx', 'ecx', 'edx'];
  482. function FileSetDate (Handle, Age: longint): longint;
  483. var FStat: PFileStatus0;
  484. RC: longint;
  485. begin
  486. if os_mode = osOS2 then
  487. begin
  488. New (FStat);
  489. RC := DosQueryFileInfo (Handle, ilStandard, FStat,
  490. SizeOf (FStat^));
  491. if RC <> 0 then
  492. FileSetDate := -1
  493. else
  494. begin
  495. FStat^.DateLastAccess := Hi (Age);
  496. FStat^.DateLastWrite := Hi (Age);
  497. FStat^.TimeLastAccess := Lo (Age);
  498. FStat^.TimeLastWrite := Lo (Age);
  499. RC := DosSetFileInfo (Handle, ilStandard, FStat,
  500. SizeOf (FStat^));
  501. if RC <> 0 then
  502. FileSetDate := -1
  503. else
  504. FileSetDate := 0;
  505. end;
  506. Dispose (FStat);
  507. end
  508. else
  509. asm
  510. push ebx
  511. mov ax, 5701h
  512. mov ebx, Handle
  513. mov cx, word ptr [Age]
  514. mov dx, word ptr [Age + 2]
  515. call syscall
  516. jnc @FSetDateEnd
  517. mov eax, -1
  518. @FSetDateEnd:
  519. mov Result, eax
  520. pop ebx
  521. end ['eax', 'ecx', 'edx'];
  522. end;
  523. function FileGetAttr (const FileName: string): longint;
  524. {$IFOPT H+}
  525. assembler;
  526. {$ELSE}
  527. var FN: string;
  528. begin
  529. FN := FileName + #0;
  530. {$ENDIF}
  531. asm
  532. mov ax, 4300h
  533. {$IFOPT H+}
  534. mov edx, FileName
  535. {$ELSE}
  536. lea edx, FN
  537. inc edx
  538. {$ENDIF}
  539. call syscall
  540. jnc @FGetAttrEnd
  541. mov eax, -1
  542. @FGetAttrEnd:
  543. {$IFOPT H-}
  544. mov Result, eax
  545. {$ENDIF}
  546. end ['eax', 'edx'];
  547. {$IFOPT H-}
  548. end;
  549. {$ENDIF}
  550. function FileSetAttr (const Filename: string; Attr: longint): longint;
  551. {$IFOPT H+}
  552. assembler;
  553. {$ELSE}
  554. var FN: string;
  555. begin
  556. FN := FileName + #0;
  557. {$ENDIF}
  558. asm
  559. mov ax, 4301h
  560. mov ecx, Attr
  561. {$IFOPT H+}
  562. mov edx, FileName
  563. {$ELSE}
  564. lea edx, FN
  565. inc edx
  566. {$ENDIF}
  567. call syscall
  568. mov eax, 0
  569. jnc @FSetAttrEnd
  570. mov eax, -1
  571. @FSetAttrEnd:
  572. {$IFOPT H-}
  573. mov Result, eax
  574. {$ENDIF}
  575. end ['eax', 'ecx', 'edx'];
  576. {$IFOPT H-}
  577. end;
  578. {$ENDIF}
  579. function DeleteFile (const FileName: string): boolean;
  580. {$IFOPT H+}
  581. assembler;
  582. {$ELSE}
  583. var FN: string;
  584. begin
  585. FN := FileName + #0;
  586. {$ENDIF}
  587. asm
  588. mov ax, 4100h
  589. {$IFOPT H+}
  590. mov edx, FileName
  591. {$ELSE}
  592. lea edx, FN
  593. inc edx
  594. {$ENDIF}
  595. call syscall
  596. mov eax, 0
  597. jc @FDeleteEnd
  598. inc eax
  599. @FDeleteEnd:
  600. {$IFOPT H-}
  601. mov Result, eax
  602. {$ENDIF}
  603. end ['eax', 'edx'];
  604. {$IFOPT H-}
  605. end;
  606. {$ENDIF}
  607. function RenameFile (const OldName, NewName: string): boolean;
  608. {$IFOPT H+}
  609. assembler;
  610. {$ELSE}
  611. var FN1, FN2: string;
  612. begin
  613. FN1 := OldName + #0;
  614. FN2 := NewName + #0;
  615. {$ENDIF}
  616. asm
  617. mov ax, 5600h
  618. {$IFOPT H+}
  619. mov edx, OldName
  620. mov edi, NewName
  621. {$ELSE}
  622. lea edx, FN1
  623. inc edx
  624. lea edi, FN2
  625. inc edi
  626. {$ENDIF}
  627. call syscall
  628. mov eax, 0
  629. jc @FRenameEnd
  630. inc eax
  631. @FRenameEnd:
  632. {$IFOPT H-}
  633. mov Result, eax
  634. {$ENDIF}
  635. end ['eax', 'edx', 'edi'];
  636. {$IFOPT H-}
  637. end;
  638. {$ENDIF}
  639. {****************************************************************************
  640. Disk Functions
  641. ****************************************************************************}
  642. {$ASMMODE ATT}
  643. function DiskFree (Drive: byte): int64;
  644. var FI: TFSinfo;
  645. RC: longint;
  646. begin
  647. if (os_mode = osDOS) or (os_mode = osDPMI) then
  648. {Function 36 is not supported in OS/2.}
  649. asm
  650. pushl %ebx
  651. movb Drive,%dl
  652. movb $0x36,%ah
  653. call syscall
  654. cmpw $-1,%ax
  655. je .LDISKFREE1
  656. mulw %cx
  657. mulw %bx
  658. shll $16,%edx
  659. movw %ax,%dx
  660. movl $0,%eax
  661. xchgl %edx,%eax
  662. jmp .LDISKFREE2
  663. .LDISKFREE1:
  664. cltd
  665. .LDISKFREE2:
  666. popl %ebx
  667. leave
  668. ret
  669. end
  670. else
  671. {In OS/2, we use the filesystem information.}
  672. begin
  673. RC := DosQueryFSInfo (Drive, 1, FI, SizeOf (FI));
  674. if RC = 0 then
  675. DiskFree := int64 (FI.Free_Clusters) *
  676. int64 (FI.Sectors_Per_Cluster) * int64 (FI.Bytes_Per_Sector)
  677. else
  678. DiskFree := -1;
  679. end;
  680. end;
  681. function DiskSize (Drive: byte): int64;
  682. var FI: TFSinfo;
  683. RC: longint;
  684. begin
  685. if (os_mode = osDOS) or (os_mode = osDPMI) then
  686. {Function 36 is not supported in OS/2.}
  687. asm
  688. pushl %ebx
  689. movb Drive,%dl
  690. movb $0x36,%ah
  691. call syscall
  692. movw %dx,%bx
  693. cmpw $-1,%ax
  694. je .LDISKSIZE1
  695. mulw %cx
  696. mulw %bx
  697. shll $16,%edx
  698. movw %ax,%dx
  699. movl $0,%eax
  700. xchgl %edx,%eax
  701. jmp .LDISKSIZE2
  702. .LDISKSIZE1:
  703. cltd
  704. .LDISKSIZE2:
  705. popl %ebx
  706. leave
  707. ret
  708. end
  709. else
  710. {In OS/2, we use the filesystem information.}
  711. begin
  712. RC := DosQueryFSinfo (Drive, 1, FI, SizeOf (FI));
  713. if RC = 0 then
  714. DiskSize := int64 (FI.Total_Clusters) *
  715. int64 (FI.Sectors_Per_Cluster) * int64 (FI.Bytes_Per_Sector)
  716. else
  717. DiskSize := -1;
  718. end;
  719. end;
  720. function GetCurrentDir: string;
  721. begin
  722. GetDir (0, Result);
  723. end;
  724. function SetCurrentDir (const NewDir: string): boolean;
  725. begin
  726. {$I-}
  727. ChDir (NewDir);
  728. Result := (IOResult = 0);
  729. {$I+}
  730. end;
  731. function CreateDir (const NewDir: string): boolean;
  732. begin
  733. {$I-}
  734. MkDir (NewDir);
  735. Result := (IOResult = 0);
  736. {$I+}
  737. end;
  738. function RemoveDir (const Dir: string): boolean;
  739. begin
  740. {$I-}
  741. RmDir (Dir);
  742. Result := (IOResult = 0);
  743. {$I+}
  744. end;
  745. {$ASMMODE INTEL}
  746. function DirectoryExists (const Directory: string): boolean;
  747. {$IFOPT H+}
  748. assembler;
  749. {$ELSE}
  750. var FN: string;
  751. begin
  752. FN := Directory + #0;
  753. {$ENDIF}
  754. asm
  755. mov ax, 4300h
  756. {$IFOPT H+}
  757. mov edx, Directory
  758. {$ELSE}
  759. lea edx, FN
  760. inc edx
  761. {$ENDIF}
  762. call syscall
  763. mov eax, 0
  764. jc @FExistsEnd
  765. test cx, 10h
  766. jz @FExistsEnd
  767. inc eax
  768. @FExistsEnd:
  769. {$IFOPT H-}
  770. mov Result, eax
  771. {$ENDIF}
  772. end ['eax', 'ecx', 'edx'];
  773. {$IFOPT H-}
  774. end;
  775. {$ENDIF}
  776. {****************************************************************************
  777. Time Functions
  778. ****************************************************************************}
  779. procedure GetLocalTime (var SystemTime: TSystemTime); assembler;
  780. asm
  781. (* Expects the default record alignment (word)!!! *)
  782. mov ah, 2Ah
  783. call syscall
  784. mov edi, SystemTime
  785. mov ax, cx
  786. stosw
  787. xor eax, eax
  788. mov al, 10
  789. mul dl
  790. shl eax, 16
  791. mov al, dh
  792. stosd
  793. push edi
  794. mov ah, 2Ch
  795. call syscall
  796. pop edi
  797. xor eax, eax
  798. mov al, cl
  799. shl eax, 16
  800. mov al, ch
  801. stosd
  802. mov al, dl
  803. shl eax, 16
  804. mov al, dh
  805. stosd
  806. end ['eax', 'ecx', 'edx', 'edi'];
  807. {$asmmode default}
  808. {****************************************************************************
  809. Misc Functions
  810. ****************************************************************************}
  811. procedure Beep;
  812. begin
  813. end;
  814. {****************************************************************************
  815. Locale Functions
  816. ****************************************************************************}
  817. procedure InitAnsi;
  818. var I: byte;
  819. Country: TCountryCode;
  820. begin
  821. for I := 0 to 255 do
  822. UpperCaseTable [I] := Chr (I);
  823. Move (UpperCaseTable, LowerCaseTable, SizeOf (UpperCaseTable));
  824. if os_mode = osOS2 then
  825. begin
  826. FillChar (Country, SizeOf (Country), 0);
  827. DosMapCase (SizeOf (UpperCaseTable), Country, @UpperCaseTable);
  828. end
  829. else
  830. begin
  831. (* !!! TODO: DOS/DPMI mode support!!! *)
  832. end;
  833. for I := 0 to 255 do
  834. if UpperCaseTable [I] <> Chr (I) then
  835. LowerCaseTable [Ord (UpperCaseTable [I])] := Chr (I);
  836. end;
  837. procedure InitInternational;
  838. var Country: TCountryCode;
  839. CtryInfo: TCountryInfo;
  840. Size: longint;
  841. RC: longint;
  842. begin
  843. Size := 0;
  844. FillChar (Country, SizeOf (Country), 0);
  845. FillChar (CtryInfo, SizeOf (CtryInfo), 0);
  846. RC := DosQueryCtryInfo (SizeOf (CtryInfo), Country, CtryInfo, Size);
  847. if RC = 0 then
  848. begin
  849. DateSeparator := CtryInfo.DateSeparator;
  850. case CtryInfo.DateFormat of
  851. 1: begin
  852. ShortDateFormat := 'd/m/y';
  853. LongDateFormat := 'dd" "mmmm" "yyyy';
  854. end;
  855. 2: begin
  856. ShortDateFormat := 'y/m/d';
  857. LongDateFormat := 'yyyy" "mmmm" "dd';
  858. end;
  859. 3: begin
  860. ShortDateFormat := 'm/d/y';
  861. LongDateFormat := 'mmmm" "dd" "yyyy';
  862. end;
  863. end;
  864. TimeSeparator := CtryInfo.TimeSeparator;
  865. DecimalSeparator := CtryInfo.DecimalSeparator;
  866. ThousandSeparator := CtryInfo.ThousandSeparator;
  867. CurrencyFormat := CtryInfo.CurrencyFormat;
  868. CurrencyString := PChar (CtryInfo.CurrencyUnit);
  869. end;
  870. InitAnsi;
  871. end;
  872. function SysErrorMessage(ErrorCode: Integer): String;
  873. begin
  874. Result:=Format(SUnknownErrorCode,[ErrorCode]);
  875. end;
  876. {****************************************************************************
  877. OS Utils
  878. ****************************************************************************}
  879. Function GetEnvironmentVariable(Const EnvVar : String) : String;
  880. begin
  881. GetEnvironmentVariable := StrPas (GetEnvPChar (EnvVar));
  882. end;
  883. {****************************************************************************
  884. Initialization code
  885. ****************************************************************************}
  886. Initialization
  887. InitExceptions; { Initialize exceptions. OS independent }
  888. InitInternational; { Initialize internationalization settings }
  889. Finalization
  890. DoneExceptions;
  891. end.
  892. {
  893. $Log$
  894. Revision 1.31 2003-10-07 21:26:34 hajny
  895. * stdcall fixes and asm routines cleanup
  896. Revision 1.30 2003/10/03 21:46:41 peter
  897. * stdcall fixes
  898. Revision 1.29 2003/06/06 23:34:40 hajny
  899. * better fix for bug 2518
  900. Revision 1.28 2003/06/06 23:31:17 hajny
  901. * fix for bug 2518 applied to OS/2 as well
  902. Revision 1.27 2003/04/01 15:57:41 peter
  903. * made THandle platform dependent and unique type
  904. Revision 1.26 2003/03/31 02:18:39 yuri
  905. FileClose bug fixed (again ;))
  906. Revision 1.25 2003/03/29 19:14:16 yuri
  907. * Directoryexists function header changed back.
  908. Revision 1.24 2003/03/29 18:53:10 yuri
  909. * Fixed DirectoryExists function header
  910. Revision 1.23 2003/03/29 15:01:20 hajny
  911. + DirectoryExists added for main branch OS/2 too
  912. Revision 1.22 2003/03/01 21:19:14 hajny
  913. * FileClose bug fixed
  914. Revision 1.21 2003/01/04 16:25:08 hajny
  915. * modified to make use of the common GetEnv code
  916. Revision 1.20 2003/01/03 20:41:04 peter
  917. * FileCreate(string,mode) overload added
  918. Revision 1.19 2002/11/18 19:51:00 hajny
  919. * another bunch of type corrections
  920. Revision 1.18 2002/09/23 17:42:37 hajny
  921. * AnsiString to PChar typecast
  922. Revision 1.17 2002/09/07 16:01:25 peter
  923. * old logs removed and tabs fixed
  924. Revision 1.16 2002/07/11 16:00:05 hajny
  925. * FindFirst fix (invalid attribute bits masked out)
  926. Revision 1.15 2002/01/25 16:23:03 peter
  927. * merged filesearch() fix
  928. }