sysutils.pp 34 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042
  1. {
  2. This file is part of the Free Pascal run time library.
  3. Copyright (c) 1999-2000 by Florian Klaempfl
  4. member of the Free Pascal development team
  5. Sysutils unit for OS/2
  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 sysutils;
  13. interface
  14. {$MODE objfpc}
  15. { force ansistrings }
  16. {$H+}
  17. uses
  18. Dos;
  19. {$DEFINE HAS_SLEEP}
  20. { Include platform independent interface part }
  21. {$i sysutilh.inc}
  22. implementation
  23. uses
  24. sysconst;
  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. TFileStatus3 = 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:cardinal; {Amount of space the file really
  45. occupies on disk.}
  46. AttrFile:cardinal; {Attributes of file.}
  47. end;
  48. PFileStatus3=^TFileStatus3;
  49. TFileStatus4=object(TFileStatus3)
  50. cbList:cardinal; {Length of entire EA set.}
  51. end;
  52. PFileStatus4=^TFileStatus4;
  53. TFileFindBuf3=object(TFileStatus)
  54. NextEntryOffset: cardinal; {Offset of next entry}
  55. DateCreation, {Date of file creation.}
  56. TimeCreation, {Time of file creation.}
  57. DateLastAccess, {Date of last access to file.}
  58. TimeLastAccess, {Time of last access to file.}
  59. DateLastWrite, {Date of last modification of file.}
  60. TimeLastWrite:word; {Time of last modification of file.}
  61. FileSize, {Size of file.}
  62. FileAlloc:cardinal; {Amount of space the file really
  63. occupies on disk.}
  64. AttrFile:cardinal; {Attributes of file.}
  65. Name:shortstring; {Also possible to use as ASCIIZ.
  66. The byte following the last string
  67. character is always zero.}
  68. end;
  69. PFileFindBuf3=^TFileFindBuf3;
  70. TFileFindBuf4=object(TFileStatus)
  71. NextEntryOffset: cardinal; {Offset of next entry}
  72. DateCreation, {Date of file creation.}
  73. TimeCreation, {Time of file creation.}
  74. DateLastAccess, {Date of last access to file.}
  75. TimeLastAccess, {Time of last access to file.}
  76. DateLastWrite, {Date of last modification of file.}
  77. TimeLastWrite:word; {Time of last modification of file.}
  78. FileSize, {Size of file.}
  79. FileAlloc:cardinal; {Amount of space the file really
  80. occupies on disk.}
  81. AttrFile:cardinal; {Attributes of file.}
  82. cbList:longint; {Size of the file's extended attributes.}
  83. Name:shortstring; {Also possible to use as ASCIIZ.
  84. The byte following the last string
  85. character is always zero.}
  86. end;
  87. PFileFindBuf4=^TFileFindBuf4;
  88. TFSInfo = record
  89. case word of
  90. 1:
  91. (File_Sys_ID,
  92. Sectors_Per_Cluster,
  93. Total_Clusters,
  94. Free_Clusters: cardinal;
  95. Bytes_Per_Sector: word);
  96. 2: {For date/time description,
  97. see file searching realted
  98. routines.}
  99. (Label_Date, {Date when volume label was created.}
  100. Label_Time: word; {Time when volume label was created.}
  101. VolumeLabel: ShortString); {Volume label. Can also be used
  102. as ASCIIZ, because the byte
  103. following the last character of
  104. the string is always zero.}
  105. end;
  106. PFSInfo = ^TFSInfo;
  107. TCountryCode=record
  108. Country, {Country to query info about (0=current).}
  109. CodePage: cardinal; {Code page to query info about (0=current).}
  110. end;
  111. PCountryCode=^TCountryCode;
  112. TTimeFmt = (Clock12, Clock24);
  113. TCountryInfo=record
  114. Country, CodePage: cardinal; {Country and codepage requested.}
  115. case byte of
  116. 0:
  117. (DateFormat: cardinal; {1=ddmmyy 2=yymmdd 3=mmddyy}
  118. CurrencyUnit: array [0..4] of char;
  119. ThousandSeparator: char; {Thousands separator.}
  120. Zero1: byte; {Always zero.}
  121. DecimalSeparator: char; {Decimals separator,}
  122. Zero2: byte;
  123. DateSeparator: char; {Date separator.}
  124. Zero3: byte;
  125. TimeSeparator: char; {Time separator.}
  126. Zero4: byte;
  127. CurrencyFormat, {Bit field:
  128. Bit 0: 0=indicator before value
  129. 1=indicator after value
  130. Bit 1: 1=insert space after
  131. indicator.
  132. Bit 2: 1=Ignore bit 0&1, replace
  133. decimal separator with
  134. indicator.}
  135. DecimalPlace: byte; {Number of decimal places used in
  136. currency indication.}
  137. TimeFormat: TTimeFmt; {12/24 hour.}
  138. Reserve1: array [0..1] of word;
  139. DataSeparator: char; {Data list separator}
  140. Zero5: byte;
  141. Reserve2: array [0..4] of word);
  142. 1:
  143. (fsDateFmt: cardinal; {1=ddmmyy 2=yymmdd 3=mmddyy}
  144. szCurrency: array [0..4] of char;
  145. {null terminated currency symbol}
  146. szThousandsSeparator: array [0..1] of char;
  147. {Thousands separator + #0}
  148. szDecimal: array [0..1] of char;
  149. {Decimals separator + #0}
  150. szDateSeparator: array [0..1] of char;
  151. {Date separator + #0}
  152. szTimeSeparator: array [0..1] of char;
  153. {Time separator + #0}
  154. fsCurrencyFmt, {Bit field:
  155. Bit 0: 0=indicator before value
  156. 1=indicator after value
  157. Bit 1: 1=insert space after
  158. indicator.
  159. Bit 2: 1=Ignore bit 0&1, replace
  160. decimal separator with
  161. indicator}
  162. cDecimalPlace: byte; {Number of decimal places used in
  163. currency indication}
  164. fsTimeFmt: byte; {0=12,1=24 hours}
  165. abReserved1: array [0..1] of word;
  166. szDataSeparator: array [0..1] of char;
  167. {Data list separator + #0}
  168. abReserved2: array [0..4] of word);
  169. end;
  170. PCountryInfo=^TCountryInfo;
  171. TRequestData=record
  172. PID, {ID of process that wrote element.}
  173. Data: cardinal; {Information from process writing the data.}
  174. end;
  175. PRequestData=^TRequestData;
  176. {Queue data structure for synchronously started sessions.}
  177. TChildInfo = record
  178. case boolean of
  179. false:
  180. (SessionID,
  181. Return: word); {Return code from the child process.}
  182. true:
  183. (usSessionID,
  184. usReturn: word); {Return code from the child process.}
  185. end;
  186. PChildInfo = ^TChildInfo;
  187. TStartData=record
  188. {Note: to omit some fields, use a length smaller than SizeOf(TStartData).}
  189. Length:word; {Length, in bytes, of datastructure
  190. (24/30/32/50/60).}
  191. Related:word; {Independent/child session (0/1).}
  192. FgBg:word; {Foreground/background (0/1).}
  193. TraceOpt:word; {No trace/trace this/trace all (0/1/2).}
  194. PgmTitle:PChar; {Program title.}
  195. PgmName:PChar; {Filename to program.}
  196. PgmInputs:PChar; {Command parameters (nil allowed).}
  197. TermQ:PChar; {System queue. (nil allowed).}
  198. Environment:PChar; {Environment to pass (nil allowed).}
  199. InheritOpt:word; {Inherit enviroment from shell/
  200. inherit environment from parent (0/1).}
  201. SessionType:word; {Auto/full screen/window/presentation
  202. manager/full screen Dos/windowed Dos
  203. (0/1/2/3/4/5/6/7).}
  204. Iconfile:PChar; {Icon file to use (nil allowed).}
  205. PgmHandle:cardinal; {0 or the program handle.}
  206. PgmControl:word; {Bitfield describing initial state
  207. of windowed sessions.}
  208. InitXPos,InitYPos:word; {Initial top coordinates.}
  209. InitXSize,InitYSize:word; {Initial size.}
  210. Reserved:word;
  211. ObjectBuffer:PChar; {If a module cannot be loaded, its
  212. name will be returned here.}
  213. ObjectBuffLen:cardinal; {Size of your buffer.}
  214. end;
  215. PStartData=^TStartData;
  216. TResultCodes=record
  217. TerminateReason, {0 = Normal termionation.
  218. 1 = Critical error.
  219. 2 = Trapped. (GPE, etc.)
  220. 3 = Killed by DosKillProcess.}
  221. ExitCode:cardinal; {Exit code of child.}
  222. end;
  223. const
  224. ilStandard = 1;
  225. ilQueryEAsize = 2;
  226. ilQueryEAs = 3;
  227. ilQueryFullName = 5;
  228. quFIFO = 0;
  229. quLIFO = 1;
  230. quPriority = 2;
  231. quNoConvert_Address = 0;
  232. quConvert_Address = 4;
  233. {Start the new session independent or as a child.}
  234. ssf_Related_Independent = 0; {Start new session independent
  235. of the calling session.}
  236. ssf_Related_Child = 1; {Start new session as a child
  237. session to the calling session.}
  238. {Start the new session in the foreground or in the background.}
  239. ssf_FgBg_Fore = 0; {Start new session in foreground.}
  240. ssf_FgBg_Back = 1; {Start new session in background.}
  241. {Should the program started in the new session
  242. be executed under conditions for tracing?}
  243. ssf_TraceOpt_None = 0; {No trace.}
  244. ssf_TraceOpt_Trace = 1; {Trace with no notification
  245. of descendants.}
  246. ssf_TraceOpt_TraceAll = 2; {Trace all descendant sessions.
  247. A termination queue must be
  248. supplied and Related must be
  249. ssf_Related_Child (=1).}
  250. {Will the new session inherit open file handles
  251. and environment from the calling process.}
  252. ssf_InhertOpt_Shell = 0; {Inherit from the shell.}
  253. ssf_InhertOpt_Parent = 1; {Inherit from the calling process.}
  254. {Specifies the type of session to start.}
  255. ssf_Type_Default = 0; {Use program's type.}
  256. ssf_Type_FullScreen = 1; {OS/2 full screen.}
  257. ssf_Type_WindowableVIO = 2; {OS/2 window.}
  258. ssf_Type_PM = 3; {Presentation Manager.}
  259. ssf_Type_VDM = 4; {DOS full screen.}
  260. ssf_Type_WindowedVDM = 7; {DOS window.}
  261. {Additional values for Windows programs}
  262. Prog_31_StdSeamlessVDM = 15; {Windows 3.1 program in its
  263. own windowed session.}
  264. Prog_31_StdSeamlessCommon = 16; {Windows 3.1 program in a
  265. common windowed session.}
  266. Prog_31_EnhSeamlessVDM = 17; {Windows 3.1 program in enhanced
  267. compatibility mode in its own
  268. windowed session.}
  269. Prog_31_EnhSeamlessCommon = 18; {Windows 3.1 program in enhanced
  270. compatibility mode in a common
  271. windowed session.}
  272. Prog_31_Enh = 19; {Windows 3.1 program in enhanced
  273. compatibility mode in a full
  274. screen session.}
  275. Prog_31_Std = 20; {Windows 3.1 program in a full
  276. screen session.}
  277. {Specifies the initial attributes for a OS/2 window or DOS window session.}
  278. ssf_Control_Visible = 0; {Window is visible.}
  279. ssf_Control_Invisible = 1; {Window is invisible.}
  280. ssf_Control_Maximize = 2; {Window is maximized.}
  281. ssf_Control_Minimize = 4; {Window is minimized.}
  282. ssf_Control_NoAutoClose = 8; {Window will not close after
  283. the program has ended.}
  284. ssf_Control_SetPos = 32768; {Use InitXPos, InitYPos,
  285. InitXSize, and InitYSize for
  286. the size and placement.}
  287. function DosSetFileInfo (Handle: THandle; InfoLevel: cardinal; AFileStatus: PFileStatus;
  288. FileStatusLen: cardinal): cardinal; cdecl; external 'DOSCALLS' index 218;
  289. function DosQueryFSInfo (DiskNum, InfoLevel: cardinal; var Buffer: TFSInfo;
  290. BufLen: cardinal): cardinal; cdecl; external 'DOSCALLS' index 278;
  291. function DosQueryFileInfo (Handle: THandle; InfoLevel: cardinal;
  292. AFileStatus: PFileStatus; FileStatusLen: cardinal): cardinal; cdecl;
  293. external 'DOSCALLS' index 279;
  294. function DosScanEnv (Name: PChar; var Value: PChar): cardinal; cdecl;
  295. external 'DOSCALLS' index 227;
  296. function DosFindFirst (FileMask: PChar; var Handle: THandle; Attrib: cardinal;
  297. AFileStatus: PFileStatus; FileStatusLen: cardinal;
  298. var Count: cardinal; InfoLevel: cardinal): cardinal; cdecl;
  299. external 'DOSCALLS' index 264;
  300. function DosFindNext (Handle: THandle; AFileStatus: PFileStatus;
  301. FileStatusLen: cardinal; var Count: cardinal): cardinal; cdecl;
  302. external 'DOSCALLS' index 265;
  303. function DosFindClose (Handle: THandle): cardinal; cdecl;
  304. external 'DOSCALLS' index 263;
  305. function DosQueryCtryInfo (Size: cardinal; var Country: TCountryCode;
  306. var Res: TCountryInfo; var ActualSize: cardinal): cardinal; cdecl;
  307. external 'NLS' index 5;
  308. function DosMapCase (Size: cardinal; var Country: TCountryCode;
  309. AString: PChar): cardinal; cdecl; external 'NLS' index 7;
  310. function DosDelete(FileName:PChar): cardinal; cdecl;
  311. external 'DOSCALLS' index 259;
  312. function DosMove(OldFile, NewFile:PChar): cardinal; cdecl;
  313. external 'DOSCALLS' index 271;
  314. function DosQueryPathInfo(FileName:PChar;InfoLevel:cardinal;
  315. AFileStatus:PFileStatus;FileStatusLen:cardinal): cardinal; cdecl;
  316. external 'DOSCALLS' index 223;
  317. function DosSetPathInfo(FileName:PChar;InfoLevel:cardinal;
  318. AFileStatus:PFileStatus;FileStatusLen,
  319. Options:cardinal):cardinal; cdecl;
  320. external 'DOSCALLS' index 219;
  321. function DosOpen(FileName:PChar;var Handle: THandle; var Action: cardinal;
  322. InitSize,Attrib,OpenFlags,FileMode:cardinal;
  323. EA:Pointer):cardinal; cdecl;
  324. external 'DOSCALLS' index 273;
  325. function DosClose(Handle: THandle): cardinal; cdecl;
  326. external 'DOSCALLS' index 257;
  327. function DosRead(Handle:THandle; var Buffer; Count: cardinal;
  328. var ActCount: cardinal): cardinal; cdecl;
  329. external 'DOSCALLS' index 281;
  330. function DosWrite(Handle: THandle; Buffer: pointer; Count: cardinal;
  331. var ActCount: cardinal): cardinal; cdecl;
  332. external 'DOSCALLS' index 282;
  333. function DosSetFilePtr(Handle: THandle; Pos: longint; Method: cardinal;
  334. var PosActual: cardinal): cardinal; cdecl;
  335. external 'DOSCALLS' index 256;
  336. function DosSetFileSize (Handle: THandle; Size: cardinal): cardinal; cdecl;
  337. external 'DOSCALLS' index 272;
  338. procedure DosSleep (MSec: cardinal); cdecl; external 'DOSCALLS' index 229;
  339. function DosCreateQueue (var Handle: THandle; Priority:longint;
  340. Name: PChar): cardinal; cdecl;
  341. external 'QUECALLS' index 16;
  342. function DosReadQueue (Handle: THandle; var ReqBuffer: TRequestData;
  343. var DataLen: cardinal; var DataPtr: pointer;
  344. Element, Wait: cardinal; var Priority: byte;
  345. ASem: THandle): cardinal; cdecl;
  346. external 'QUECALLS' index 9;
  347. function DosCloseQueue (Handle: THandle): cardinal; cdecl;
  348. external 'QUECALLS' index 11;
  349. function DosStartSession (var AStartData: TStartData;
  350. var SesID, PID: cardinal): cardinal; cdecl;
  351. external 'SESMGR' index 37;
  352. function DosFreeMem(P:pointer):cardinal; cdecl; external 'DOSCALLS' index 304;
  353. function DosExecPgm (ObjName: PChar; ObjLen: longint; ExecFlag: cardinal;
  354. Args, Env: PByteArray; var Res: TResultCodes;
  355. FileName:PChar): cardinal; cdecl;
  356. external 'DOSCALLS' index 283;
  357. type
  358. TDT=packed record
  359. Hour,
  360. Minute,
  361. Second,
  362. Sec100,
  363. Day,
  364. Month: byte;
  365. Year: word;
  366. TimeZone: smallint;
  367. WeekDay: byte;
  368. end;
  369. function DosGetDateTime(var Buf: TDT): cardinal; cdecl;
  370. external 'DOSCALLS' index 230;
  371. {****************************************************************************
  372. File Functions
  373. ****************************************************************************}
  374. const
  375. ofRead = $0000; {Open for reading}
  376. ofWrite = $0001; {Open for writing}
  377. ofReadWrite = $0002; {Open for reading/writing}
  378. doDenyRW = $0010; {DenyAll (no sharing)}
  379. faCreateNew = $00010000; {Create if file does not exist}
  380. faOpenReplace = $00040000; {Truncate if file exists}
  381. faCreate = $00050000; {Create if file does not exist, truncate otherwise}
  382. FindResvdMask = $00003737; {Allowed bits in attribute
  383. specification for DosFindFirst call.}
  384. function FileOpen (const FileName: string; Mode: integer): longint;
  385. Var
  386. Handle: THandle;
  387. Rc, Action: cardinal;
  388. begin
  389. (* DenyNone if sharing not specified. *)
  390. if Mode and 112 = 0 then Mode:=Mode or 64;
  391. Rc:=DosOpen(PChar (FileName), Handle, Action, 0, 0, 1, Mode, nil);
  392. If Rc=0 then
  393. FileOpen:=Handle
  394. else
  395. FileOpen:=-RC;
  396. end;
  397. function FileCreate (const FileName: string): longint;
  398. Const
  399. Mode = ofReadWrite or faCreate or doDenyRW; (* Sharing to DenyAll *)
  400. Var
  401. Handle: THandle;
  402. RC, Action: cardinal;
  403. Begin
  404. RC:=DosOpen(PChar (FileName), Handle, Action, 0, 0, $12, Mode, Nil);
  405. If RC=0 then
  406. FileCreate:=Handle
  407. else
  408. FileCreate:=-RC;
  409. End;
  410. function FileCreate (const FileName: string; Mode: integer): longint;
  411. begin
  412. FileCreate := FileCreate(FileName);
  413. end;
  414. function FileRead (Handle: longint; var Buffer; Count: longint): longint;
  415. Var
  416. T: cardinal;
  417. begin
  418. DosRead(Handle, Buffer, Count, T);
  419. FileRead := longint (T);
  420. end;
  421. function FileWrite (Handle: longint; const Buffer; Count: longint): longint;
  422. Var
  423. T: cardinal;
  424. begin
  425. DosWrite (Handle, @Buffer, Count, T);
  426. FileWrite := longint (T);
  427. end;
  428. function FileSeek (Handle, FOffset, Origin: longint): longint;
  429. var
  430. npos: cardinal;
  431. begin
  432. if DosSetFilePtr (Handle, FOffset, Origin, npos) = 0 Then
  433. FileSeek:= longint (npos)
  434. else
  435. FileSeek:=-1;
  436. end;
  437. function FileSeek (Handle: longint; FOffset, Origin: Int64): Int64;
  438. begin
  439. {$warning need to add 64bit call }
  440. Result:=FileSeek(Handle,Longint(Foffset),Longint(Origin));
  441. end;
  442. procedure FileClose (Handle: longint);
  443. begin
  444. DosClose(Handle);
  445. end;
  446. function FileTruncate (Handle, Size: longint): boolean;
  447. begin
  448. FileTruncate:=DosSetFileSize(Handle, Size)=0;
  449. FileSeek(Handle, 0, 2);
  450. end;
  451. function FileAge (const FileName: string): longint;
  452. var Handle: longint;
  453. begin
  454. Handle := FileOpen (FileName, 0);
  455. if Handle <> -1 then
  456. begin
  457. Result := FileGetDate (Handle);
  458. FileClose (Handle);
  459. end
  460. else
  461. Result := -1;
  462. end;
  463. function FileExists (const FileName: string): boolean;
  464. var
  465. SR: TSearchRec;
  466. RC: longint;
  467. begin
  468. FileExists:=False;
  469. if FindFirst (FileName, faAnyFile and not (faDirectory), SR) = 0
  470. then FileExists := True;
  471. FindClose(SR);
  472. end;
  473. type TRec = record
  474. T, D: word;
  475. end;
  476. PSearchRec = ^SearchRec;
  477. function FindFirst (const Path: string; Attr: longint; out Rslt: TSearchRec): longint;
  478. var SR: PSearchRec;
  479. FStat: PFileFindBuf3;
  480. Count: cardinal;
  481. Err: cardinal;
  482. I: cardinal;
  483. begin
  484. New (FStat);
  485. Rslt.FindHandle := THandle ($FFFFFFFF);
  486. Count := 1;
  487. Err := DosFindFirst (PChar (Path), Rslt.FindHandle,
  488. Attr and FindResvdMask, FStat, SizeOf (FStat^), Count, ilStandard);
  489. if (Err = 0) and (Count = 0) then Err := 18;
  490. FindFirst := -Err;
  491. if Err = 0 then
  492. begin
  493. Rslt.Name := FStat^.Name;
  494. Rslt.Size := FStat^.FileSize;
  495. Rslt.Attr := FStat^.AttrFile;
  496. Rslt.ExcludeAttr := 0;
  497. TRec (Rslt.Time).T := FStat^.TimeLastWrite;
  498. TRec (Rslt.Time).D := FStat^.DateLastWrite;
  499. end;
  500. Dispose (FStat);
  501. end;
  502. function FindNext (var Rslt: TSearchRec): longint;
  503. var
  504. SR: PSearchRec;
  505. FStat: PFileFindBuf3;
  506. Count: cardinal;
  507. Err: cardinal;
  508. begin
  509. New (FStat);
  510. Count := 1;
  511. Err := DosFindNext (Rslt.FindHandle, FStat, SizeOf (FStat^),
  512. Count);
  513. if (Err = 0) and (Count = 0) then Err := 18;
  514. FindNext := -Err;
  515. if Err = 0 then
  516. begin
  517. Rslt.Name := FStat^.Name;
  518. Rslt.Size := FStat^.FileSize;
  519. Rslt.Attr := FStat^.AttrFile;
  520. Rslt.ExcludeAttr := 0;
  521. TRec (Rslt.Time).T := FStat^.TimeLastWrite;
  522. TRec (Rslt.Time).D := FStat^.DateLastWrite;
  523. end;
  524. Dispose (FStat);
  525. end;
  526. procedure FindClose (var F: TSearchrec);
  527. var
  528. SR: PSearchRec;
  529. begin
  530. DosFindClose (F.FindHandle);
  531. F.FindHandle := 0;
  532. end;
  533. function FileGetDate (Handle: longint): longint;
  534. var
  535. FStat: TFileStatus3;
  536. Time: Longint;
  537. begin
  538. DosError := DosQueryFileInfo(Handle, ilStandard, @FStat, SizeOf(FStat));
  539. if DosError=0 then
  540. begin
  541. Time := FStat.TimeLastWrite + longint (FStat.DateLastWrite) shl 16;
  542. if Time = 0 then
  543. Time := FStat.TimeCreation + longint (FStat.DateCreation) shl 16;
  544. end else
  545. Time:=0;
  546. FileGetDate:=Time;
  547. end;
  548. function FileSetDate (Handle, Age: longint): longint;
  549. var
  550. FStat: PFileStatus3;
  551. RC: cardinal;
  552. begin
  553. New (FStat);
  554. RC := DosQueryFileInfo (Handle, ilStandard, FStat, SizeOf (FStat^));
  555. if RC <> 0 then
  556. FileSetDate := -1
  557. else
  558. begin
  559. FStat^.DateLastAccess := Hi (Age);
  560. FStat^.DateLastWrite := Hi (Age);
  561. FStat^.TimeLastAccess := Lo (Age);
  562. FStat^.TimeLastWrite := Lo (Age);
  563. RC := DosSetFileInfo (Handle, ilStandard, FStat, SizeOf (FStat^));
  564. if RC <> 0 then
  565. FileSetDate := -1
  566. else
  567. FileSetDate := 0;
  568. end;
  569. Dispose (FStat);
  570. end;
  571. function FileGetAttr (const FileName: string): longint;
  572. var
  573. FS: PFileStatus3;
  574. begin
  575. New(FS);
  576. Result:=-DosQueryPathInfo(PChar (FileName), ilStandard, FS, SizeOf(FS^));
  577. If Result=0 Then Result:=FS^.attrFile;
  578. Dispose(FS);
  579. end;
  580. function FileSetAttr (const Filename: string; Attr: longint): longint;
  581. Var
  582. FS: PFileStatus3;
  583. Begin
  584. New(FS);
  585. FillChar(FS, SizeOf(FS^), 0);
  586. FS^.AttrFile:=Attr;
  587. Result:=-DosSetPathInfo(PChar (FileName), ilStandard, FS, SizeOf(FS^), 0);
  588. Dispose(FS);
  589. end;
  590. function DeleteFile (const FileName: string): boolean;
  591. Begin
  592. Result:=(DosDelete(PChar (FileName))=0);
  593. End;
  594. function RenameFile (const OldName, NewName: string): boolean;
  595. Begin
  596. Result:=(DosMove(PChar (OldName), PChar (NewName))=0);
  597. End;
  598. {****************************************************************************
  599. Disk Functions
  600. ****************************************************************************}
  601. function DiskFree (Drive: byte): int64;
  602. var FI: TFSinfo;
  603. RC: cardinal;
  604. begin
  605. {In OS/2, we use the filesystem information.}
  606. RC := DosQueryFSInfo (Drive, 1, FI, SizeOf (FI));
  607. if RC = 0 then
  608. DiskFree := int64 (FI.Free_Clusters) *
  609. int64 (FI.Sectors_Per_Cluster) * int64 (FI.Bytes_Per_Sector)
  610. else
  611. DiskFree := -1;
  612. end;
  613. function DiskSize (Drive: byte): int64;
  614. var FI: TFSinfo;
  615. RC: cardinal;
  616. begin
  617. {In OS/2, we use the filesystem information.}
  618. RC := DosQueryFSinfo (Drive, 1, FI, SizeOf (FI));
  619. if RC = 0 then
  620. DiskSize := int64 (FI.Total_Clusters) *
  621. int64 (FI.Sectors_Per_Cluster) * int64 (FI.Bytes_Per_Sector)
  622. else
  623. DiskSize := -1;
  624. end;
  625. function GetCurrentDir: string;
  626. begin
  627. GetDir (0, Result);
  628. end;
  629. function SetCurrentDir (const NewDir: string): boolean;
  630. begin
  631. {$I-}
  632. {$WARNING Should be rewritten to avoid unit dos dependancy!}
  633. ChDir (NewDir);
  634. Result := (IOResult = 0);
  635. {$I+}
  636. end;
  637. function CreateDir (const NewDir: string): boolean;
  638. begin
  639. {$I-}
  640. {$WARNING Should be rewritten to avoid unit dos dependancy!}
  641. MkDir (NewDir);
  642. Result := (IOResult = 0);
  643. {$I+}
  644. end;
  645. function RemoveDir (const Dir: string): boolean;
  646. begin
  647. {$I-}
  648. {$WARNING Should be rewritten to avoid unit dos dependancy!}
  649. RmDir (Dir);
  650. Result := (IOResult = 0);
  651. {$I+}
  652. end;
  653. function DirectoryExists (const Directory: string): boolean;
  654. var
  655. SR: TSearchRec;
  656. begin
  657. DirectoryExists := (FindFirst (Directory, faAnyFile, SR) = 0) and
  658. (SR.Attr and faDirectory <> 0);
  659. FindClose(SR);
  660. end;
  661. {****************************************************************************
  662. Time Functions
  663. ****************************************************************************}
  664. procedure GetLocalTime (var SystemTime: TSystemTime);
  665. var
  666. DT: TDT;
  667. begin
  668. DosGetDateTime(DT);
  669. with SystemTime do
  670. begin
  671. Year:=DT.Year;
  672. Month:=DT.Month;
  673. Day:=DT.Day;
  674. Hour:=DT.Hour;
  675. Minute:=DT.Minute;
  676. Second:=DT.Second;
  677. MilliSecond:=DT.Sec100;
  678. end;
  679. end;
  680. {****************************************************************************
  681. Misc Functions
  682. ****************************************************************************}
  683. procedure Beep;
  684. begin
  685. end;
  686. {****************************************************************************
  687. Locale Functions
  688. ****************************************************************************}
  689. procedure InitAnsi;
  690. var I: byte;
  691. Country: TCountryCode;
  692. begin
  693. for I := 0 to 255 do
  694. UpperCaseTable [I] := Chr (I);
  695. Move (UpperCaseTable, LowerCaseTable, SizeOf (UpperCaseTable));
  696. FillChar (Country, SizeOf (Country), 0);
  697. DosMapCase (SizeOf (UpperCaseTable), Country, @UpperCaseTable);
  698. for I := 0 to 255 do
  699. if UpperCaseTable [I] <> Chr (I) then
  700. LowerCaseTable [Ord (UpperCaseTable [I])] := Chr (I);
  701. end;
  702. procedure InitInternational;
  703. var Country: TCountryCode;
  704. CtryInfo: TCountryInfo;
  705. Size: cardinal;
  706. RC: cardinal;
  707. begin
  708. Size := 0;
  709. FillChar (Country, SizeOf (Country), 0);
  710. FillChar (CtryInfo, SizeOf (CtryInfo), 0);
  711. RC := DosQueryCtryInfo (SizeOf (CtryInfo), Country, CtryInfo, Size);
  712. if RC = 0 then
  713. begin
  714. DateSeparator := CtryInfo.DateSeparator;
  715. case CtryInfo.DateFormat of
  716. 1: begin
  717. ShortDateFormat := 'd/m/y';
  718. LongDateFormat := 'dd" "mmmm" "yyyy';
  719. end;
  720. 2: begin
  721. ShortDateFormat := 'y/m/d';
  722. LongDateFormat := 'yyyy" "mmmm" "dd';
  723. end;
  724. 3: begin
  725. ShortDateFormat := 'm/d/y';
  726. LongDateFormat := 'mmmm" "dd" "yyyy';
  727. end;
  728. end;
  729. TimeSeparator := CtryInfo.TimeSeparator;
  730. DecimalSeparator := CtryInfo.DecimalSeparator;
  731. ThousandSeparator := CtryInfo.ThousandSeparator;
  732. CurrencyFormat := CtryInfo.CurrencyFormat;
  733. CurrencyString := PChar (CtryInfo.CurrencyUnit);
  734. end;
  735. InitAnsi;
  736. InitInternationalGeneric;
  737. end;
  738. function SysErrorMessage(ErrorCode: Integer): String;
  739. begin
  740. Result:=Format(SUnknownErrorCode,[ErrorCode]);
  741. end;
  742. {****************************************************************************
  743. OS Utils
  744. ****************************************************************************}
  745. Function GetEnvironmentVariable(Const EnvVar : String) : String;
  746. begin
  747. GetEnvironmentVariable := StrPas (GetEnvPChar (EnvVar));
  748. end;
  749. Function GetEnvironmentVariableCount : Integer;
  750. begin
  751. (* Result:=FPCCountEnvVar(EnvP); - the amount is already known... *)
  752. GetEnvironmentVariableCount := EnvC;
  753. end;
  754. Function GetEnvironmentString(Index : Integer) : String;
  755. begin
  756. Result:=FPCGetEnvStrFromP (EnvP, Index);
  757. end;
  758. procedure Sleep (Milliseconds: cardinal);
  759. begin
  760. DosSleep (Milliseconds);
  761. end;
  762. function ExecuteProcess (const Path: AnsiString; const ComLine: AnsiString):
  763. integer;
  764. var
  765. HQ: THandle;
  766. SPID, STID, QName: shortstring;
  767. SD: TStartData;
  768. SID, PID: cardinal;
  769. RD: TRequestData;
  770. PCI: PChildInfo;
  771. CISize: cardinal;
  772. Prio: byte;
  773. E: EOSError;
  774. CommandLine: ansistring;
  775. Args0, Args: PByteArray;
  776. ObjNameBuf: PChar;
  777. ArgSize: word;
  778. Res: TResultCodes;
  779. ObjName: shortstring;
  780. const
  781. MaxArgsSize = 3072; (* Amount of memory reserved for arguments in bytes. *)
  782. ObjBufSize = 512;
  783. begin
  784. ObjName := '';
  785. GetMem (ObjNameBuf, ObjBufSize);
  786. FillChar (ObjNameBuf^, ObjBufSize, 0);
  787. if ComLine = '' then
  788. begin
  789. Args0 := nil;
  790. Args := nil;
  791. end
  792. else
  793. begin
  794. GetMem (Args0, MaxArgsSize);
  795. Args := Args0;
  796. (* Work around a bug in OS/2 - argument to DosExecPgm *)
  797. (* should not cross 64K boundary. *)
  798. if ((PtrUInt (Args) + 1024) and $FFFF) < 1024 then
  799. Inc (Args, 1024);
  800. ArgSize := 0;
  801. Move (Path [1], Args^ [ArgSize], Length (Path));
  802. Inc (ArgSize, Length (Path));
  803. Args^ [ArgSize] := 0;
  804. Inc (ArgSize);
  805. {Now do the real arguments.}
  806. Move (ComLine [1], Args^ [ArgSize], Length (ComLine));
  807. Inc (ArgSize, Length (ComLine));
  808. Args^ [ArgSize] := 0;
  809. Inc (ArgSize);
  810. Args^ [ArgSize] := 0;
  811. end;
  812. Result := DosExecPgm (ObjNameBuf, ObjBufSize, 0, Args, nil, Res, PChar (Path));
  813. if Args0 <> nil then
  814. FreeMem (Args0, MaxArgsSize);
  815. if Result = 0 then
  816. begin
  817. Result := Res.ExitCode;
  818. FreeMem (ObjNameBuf, ObjBufSize);
  819. end
  820. else
  821. begin
  822. if (Result = 190) or (Result = 191) then
  823. begin
  824. FillChar (SD, SizeOf (SD), 0);
  825. SD.Length := 24;
  826. SD.Related := ssf_Related_Child;
  827. CommandLine := FExpand (Path); (* Needed for other session types... *)
  828. SD.PgmName := PChar (CommandLine);
  829. if ComLine <> '' then
  830. SD.PgmInputs := PChar (ComLine);
  831. SD.InheritOpt := ssf_InhertOpt_Parent;
  832. Str (GetProcessID, SPID);
  833. Str (ThreadID, STID);
  834. QName := '\QUEUES\FPC_ExecuteProcess_p' + SPID + 't' + STID + '.QUE'#0;
  835. SD.TermQ := @QName [1];
  836. Result := DosCreateQueue (HQ, quFIFO or quConvert_Address, @QName [1]);
  837. if Result = 0 then
  838. begin
  839. Result := DosStartSession (SD, SID, PID);
  840. if (Result = 0) or (Result = 457) then
  841. begin
  842. Result := DosReadQueue (HQ, RD, CISize, PCI, 0, 0, Prio, 0);
  843. if Result = 0 then
  844. begin
  845. Result := PCI^.Return;
  846. DosCloseQueue (HQ);
  847. DosFreeMem (PCI);
  848. Exit;
  849. end;
  850. end;
  851. DosCloseQueue (HQ);
  852. end;
  853. end
  854. else
  855. ObjName := StrPas (ObjNameBuf);
  856. FreeMem (ObjNameBuf, ObjBufSize);
  857. if ComLine = '' then
  858. CommandLine := Path
  859. else
  860. CommandLine := Path + ' ' + ComLine;
  861. if ObjName = '' then
  862. E := EOSError.CreateFmt (SExecuteProcessFailed, [CommandLine, Result])
  863. else
  864. E := EOSError.CreateFmt (SExecuteProcessFailed + '(' + ObjName + ')', [CommandLine, Result]);
  865. E.ErrorCode := Result;
  866. raise E;
  867. end;
  868. end;
  869. function ExecuteProcess (const Path: AnsiString;
  870. const ComLine: array of AnsiString): integer;
  871. var
  872. CommandLine: AnsiString;
  873. I: integer;
  874. begin
  875. Commandline := '';
  876. for I := 0 to High (ComLine) do
  877. if Pos (' ', ComLine [I]) <> 0 then
  878. CommandLine := CommandLine + ' ' + '"' + ComLine [I] + '"'
  879. else
  880. CommandLine := CommandLine + ' ' + Comline [I];
  881. ExecuteProcess := ExecuteProcess (Path, CommandLine);
  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.