sysutils.pp 34 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040
  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, SR)=0 then FileExists:=True;
  470. FindClose(SR);
  471. end;
  472. type TRec = record
  473. T, D: word;
  474. end;
  475. PSearchRec = ^SearchRec;
  476. function FindFirst (const Path: string; Attr: longint; out Rslt: TSearchRec): longint;
  477. var SR: PSearchRec;
  478. FStat: PFileFindBuf3;
  479. Count: cardinal;
  480. Err: cardinal;
  481. I: cardinal;
  482. begin
  483. New (FStat);
  484. Rslt.FindHandle := THandle ($FFFFFFFF);
  485. Count := 1;
  486. Err := DosFindFirst (PChar (Path), Rslt.FindHandle,
  487. Attr and FindResvdMask, FStat, SizeOf (FStat^), Count, ilStandard);
  488. if (Err = 0) and (Count = 0) then Err := 18;
  489. FindFirst := -Err;
  490. if Err = 0 then
  491. begin
  492. Rslt.Name := FStat^.Name;
  493. Rslt.Size := FStat^.FileSize;
  494. Rslt.Attr := FStat^.AttrFile;
  495. Rslt.ExcludeAttr := 0;
  496. TRec (Rslt.Time).T := FStat^.TimeLastWrite;
  497. TRec (Rslt.Time).D := FStat^.DateLastWrite;
  498. end;
  499. Dispose (FStat);
  500. end;
  501. function FindNext (var Rslt: TSearchRec): longint;
  502. var
  503. SR: PSearchRec;
  504. FStat: PFileFindBuf3;
  505. Count: cardinal;
  506. Err: cardinal;
  507. begin
  508. New (FStat);
  509. Count := 1;
  510. Err := DosFindNext (Rslt.FindHandle, FStat, SizeOf (FStat^),
  511. Count);
  512. if (Err = 0) and (Count = 0) then Err := 18;
  513. FindNext := -Err;
  514. if Err = 0 then
  515. begin
  516. Rslt.Name := FStat^.Name;
  517. Rslt.Size := FStat^.FileSize;
  518. Rslt.Attr := FStat^.AttrFile;
  519. Rslt.ExcludeAttr := 0;
  520. TRec (Rslt.Time).T := FStat^.TimeLastWrite;
  521. TRec (Rslt.Time).D := FStat^.DateLastWrite;
  522. end;
  523. Dispose (FStat);
  524. end;
  525. procedure FindClose (var F: TSearchrec);
  526. var
  527. SR: PSearchRec;
  528. begin
  529. DosFindClose (F.FindHandle);
  530. F.FindHandle := 0;
  531. end;
  532. function FileGetDate (Handle: longint): longint;
  533. var
  534. FStat: TFileStatus3;
  535. Time: Longint;
  536. begin
  537. DosError := DosQueryFileInfo(Handle, ilStandard, @FStat, SizeOf(FStat));
  538. if DosError=0 then
  539. begin
  540. Time := FStat.TimeLastWrite + longint (FStat.DateLastWrite) shl 16;
  541. if Time = 0 then
  542. Time := FStat.TimeCreation + longint (FStat.DateCreation) shl 16;
  543. end else
  544. Time:=0;
  545. FileGetDate:=Time;
  546. end;
  547. function FileSetDate (Handle, Age: longint): longint;
  548. var
  549. FStat: PFileStatus3;
  550. RC: cardinal;
  551. begin
  552. New (FStat);
  553. RC := DosQueryFileInfo (Handle, ilStandard, FStat, SizeOf (FStat^));
  554. if RC <> 0 then
  555. FileSetDate := -1
  556. else
  557. begin
  558. FStat^.DateLastAccess := Hi (Age);
  559. FStat^.DateLastWrite := Hi (Age);
  560. FStat^.TimeLastAccess := Lo (Age);
  561. FStat^.TimeLastWrite := Lo (Age);
  562. RC := DosSetFileInfo (Handle, ilStandard, FStat, SizeOf (FStat^));
  563. if RC <> 0 then
  564. FileSetDate := -1
  565. else
  566. FileSetDate := 0;
  567. end;
  568. Dispose (FStat);
  569. end;
  570. function FileGetAttr (const FileName: string): longint;
  571. var
  572. FS: PFileStatus3;
  573. begin
  574. New(FS);
  575. Result:=-DosQueryPathInfo(PChar (FileName), ilStandard, FS, SizeOf(FS^));
  576. If Result=0 Then Result:=FS^.attrFile;
  577. Dispose(FS);
  578. end;
  579. function FileSetAttr (const Filename: string; Attr: longint): longint;
  580. Var
  581. FS: PFileStatus3;
  582. Begin
  583. New(FS);
  584. FillChar(FS, SizeOf(FS^), 0);
  585. FS^.AttrFile:=Attr;
  586. Result:=-DosSetPathInfo(PChar (FileName), ilStandard, FS, SizeOf(FS^), 0);
  587. Dispose(FS);
  588. end;
  589. function DeleteFile (const FileName: string): boolean;
  590. Begin
  591. Result:=(DosDelete(PChar (FileName))=0);
  592. End;
  593. function RenameFile (const OldName, NewName: string): boolean;
  594. Begin
  595. Result:=(DosMove(PChar (OldName), PChar (NewName))=0);
  596. End;
  597. {****************************************************************************
  598. Disk Functions
  599. ****************************************************************************}
  600. function DiskFree (Drive: byte): int64;
  601. var FI: TFSinfo;
  602. RC: cardinal;
  603. begin
  604. {In OS/2, we use the filesystem information.}
  605. RC := DosQueryFSInfo (Drive, 1, FI, SizeOf (FI));
  606. if RC = 0 then
  607. DiskFree := int64 (FI.Free_Clusters) *
  608. int64 (FI.Sectors_Per_Cluster) * int64 (FI.Bytes_Per_Sector)
  609. else
  610. DiskFree := -1;
  611. end;
  612. function DiskSize (Drive: byte): int64;
  613. var FI: TFSinfo;
  614. RC: cardinal;
  615. begin
  616. {In OS/2, we use the filesystem information.}
  617. RC := DosQueryFSinfo (Drive, 1, FI, SizeOf (FI));
  618. if RC = 0 then
  619. DiskSize := int64 (FI.Total_Clusters) *
  620. int64 (FI.Sectors_Per_Cluster) * int64 (FI.Bytes_Per_Sector)
  621. else
  622. DiskSize := -1;
  623. end;
  624. function GetCurrentDir: string;
  625. begin
  626. GetDir (0, Result);
  627. end;
  628. function SetCurrentDir (const NewDir: string): boolean;
  629. begin
  630. {$I-}
  631. {$WARNING Should be rewritten to avoid unit dos dependancy!}
  632. ChDir (NewDir);
  633. Result := (IOResult = 0);
  634. {$I+}
  635. end;
  636. function CreateDir (const NewDir: string): boolean;
  637. begin
  638. {$I-}
  639. {$WARNING Should be rewritten to avoid unit dos dependancy!}
  640. MkDir (NewDir);
  641. Result := (IOResult = 0);
  642. {$I+}
  643. end;
  644. function RemoveDir (const Dir: string): boolean;
  645. begin
  646. {$I-}
  647. {$WARNING Should be rewritten to avoid unit dos dependancy!}
  648. RmDir (Dir);
  649. Result := (IOResult = 0);
  650. {$I+}
  651. end;
  652. function DirectoryExists (const Directory: string): boolean;
  653. var
  654. SR: TSearchRec;
  655. begin
  656. DirectoryExists:=FindFirst(Directory, faDirectory, SR)=0;
  657. FindClose(SR);
  658. end;
  659. {****************************************************************************
  660. Time Functions
  661. ****************************************************************************}
  662. procedure GetLocalTime (var SystemTime: TSystemTime);
  663. var
  664. DT: TDT;
  665. begin
  666. DosGetDateTime(DT);
  667. with SystemTime do
  668. begin
  669. Year:=DT.Year;
  670. Month:=DT.Month;
  671. Day:=DT.Day;
  672. Hour:=DT.Hour;
  673. Minute:=DT.Minute;
  674. Second:=DT.Second;
  675. MilliSecond:=DT.Sec100;
  676. end;
  677. end;
  678. {****************************************************************************
  679. Misc Functions
  680. ****************************************************************************}
  681. procedure Beep;
  682. begin
  683. end;
  684. {****************************************************************************
  685. Locale Functions
  686. ****************************************************************************}
  687. procedure InitAnsi;
  688. var I: byte;
  689. Country: TCountryCode;
  690. begin
  691. for I := 0 to 255 do
  692. UpperCaseTable [I] := Chr (I);
  693. Move (UpperCaseTable, LowerCaseTable, SizeOf (UpperCaseTable));
  694. FillChar (Country, SizeOf (Country), 0);
  695. DosMapCase (SizeOf (UpperCaseTable), Country, @UpperCaseTable);
  696. for I := 0 to 255 do
  697. if UpperCaseTable [I] <> Chr (I) then
  698. LowerCaseTable [Ord (UpperCaseTable [I])] := Chr (I);
  699. end;
  700. procedure InitInternational;
  701. var Country: TCountryCode;
  702. CtryInfo: TCountryInfo;
  703. Size: cardinal;
  704. RC: cardinal;
  705. begin
  706. Size := 0;
  707. FillChar (Country, SizeOf (Country), 0);
  708. FillChar (CtryInfo, SizeOf (CtryInfo), 0);
  709. RC := DosQueryCtryInfo (SizeOf (CtryInfo), Country, CtryInfo, Size);
  710. if RC = 0 then
  711. begin
  712. DateSeparator := CtryInfo.DateSeparator;
  713. case CtryInfo.DateFormat of
  714. 1: begin
  715. ShortDateFormat := 'd/m/y';
  716. LongDateFormat := 'dd" "mmmm" "yyyy';
  717. end;
  718. 2: begin
  719. ShortDateFormat := 'y/m/d';
  720. LongDateFormat := 'yyyy" "mmmm" "dd';
  721. end;
  722. 3: begin
  723. ShortDateFormat := 'm/d/y';
  724. LongDateFormat := 'mmmm" "dd" "yyyy';
  725. end;
  726. end;
  727. TimeSeparator := CtryInfo.TimeSeparator;
  728. DecimalSeparator := CtryInfo.DecimalSeparator;
  729. ThousandSeparator := CtryInfo.ThousandSeparator;
  730. CurrencyFormat := CtryInfo.CurrencyFormat;
  731. CurrencyString := PChar (CtryInfo.CurrencyUnit);
  732. end;
  733. InitAnsi;
  734. InitInternationalGeneric;
  735. end;
  736. function SysErrorMessage(ErrorCode: Integer): String;
  737. begin
  738. Result:=Format(SUnknownErrorCode,[ErrorCode]);
  739. end;
  740. {****************************************************************************
  741. OS Utils
  742. ****************************************************************************}
  743. Function GetEnvironmentVariable(Const EnvVar : String) : String;
  744. begin
  745. GetEnvironmentVariable := StrPas (GetEnvPChar (EnvVar));
  746. end;
  747. Function GetEnvironmentVariableCount : Integer;
  748. begin
  749. (* Result:=FPCCountEnvVar(EnvP); - the amount is already known... *)
  750. GetEnvironmentVariableCount := EnvC;
  751. end;
  752. Function GetEnvironmentString(Index : Integer) : String;
  753. begin
  754. Result:=FPCGetEnvStrFromP (EnvP, Index);
  755. end;
  756. procedure Sleep (Milliseconds: cardinal);
  757. begin
  758. DosSleep (Milliseconds);
  759. end;
  760. function ExecuteProcess (const Path: AnsiString; const ComLine: AnsiString):
  761. integer;
  762. var
  763. HQ: THandle;
  764. SPID, STID, QName: shortstring;
  765. SD: TStartData;
  766. SID, PID: cardinal;
  767. RD: TRequestData;
  768. PCI: PChildInfo;
  769. CISize: cardinal;
  770. Prio: byte;
  771. E: EOSError;
  772. CommandLine: ansistring;
  773. Args0, Args: PByteArray;
  774. ObjNameBuf: PChar;
  775. ArgSize: word;
  776. Res: TResultCodes;
  777. ObjName: shortstring;
  778. const
  779. MaxArgsSize = 3072; (* Amount of memory reserved for arguments in bytes. *)
  780. ObjBufSize = 512;
  781. begin
  782. ObjName := '';
  783. GetMem (ObjNameBuf, ObjBufSize);
  784. FillChar (ObjNameBuf^, ObjBufSize, 0);
  785. if ComLine = '' then
  786. begin
  787. Args0 := nil;
  788. Args := nil;
  789. end
  790. else
  791. begin
  792. GetMem (Args0, MaxArgsSize);
  793. Args := Args0;
  794. (* Work around a bug in OS/2 - argument to DosExecPgm *)
  795. (* should not cross 64K boundary. *)
  796. if ((PtrUInt (Args) + 1024) and $FFFF) < 1024 then
  797. Inc (Args, 1024);
  798. ArgSize := 0;
  799. Move (Path [1], Args^ [ArgSize], Length (Path));
  800. Inc (ArgSize, Length (Path));
  801. Args^ [ArgSize] := 0;
  802. Inc (ArgSize);
  803. {Now do the real arguments.}
  804. Move (ComLine [1], Args^ [ArgSize], Length (ComLine));
  805. Inc (ArgSize, Length (ComLine));
  806. Args^ [ArgSize] := 0;
  807. Inc (ArgSize);
  808. Args^ [ArgSize] := 0;
  809. end;
  810. Result := DosExecPgm (ObjNameBuf, ObjBufSize, 0, Args, nil, Res, PChar (Path));
  811. if Args0 <> nil then
  812. FreeMem (Args0, MaxArgsSize);
  813. if Result = 0 then
  814. begin
  815. Result := Res.ExitCode;
  816. FreeMem (ObjNameBuf, ObjBufSize);
  817. end
  818. else
  819. begin
  820. if (Result = 190) or (Result = 191) then
  821. begin
  822. FillChar (SD, SizeOf (SD), 0);
  823. SD.Length := 24;
  824. SD.Related := ssf_Related_Child;
  825. CommandLine := FExpand (Path); (* Needed for other session types... *)
  826. SD.PgmName := PChar (CommandLine);
  827. if ComLine <> '' then
  828. SD.PgmInputs := PChar (ComLine);
  829. SD.InheritOpt := ssf_InhertOpt_Parent;
  830. Str (GetProcessID, SPID);
  831. Str (ThreadID, STID);
  832. QName := '\QUEUES\FPC_ExecuteProcess_p' + SPID + 't' + STID + '.QUE'#0;
  833. SD.TermQ := @QName [1];
  834. Result := DosCreateQueue (HQ, quFIFO or quConvert_Address, @QName [1]);
  835. if Result = 0 then
  836. begin
  837. Result := DosStartSession (SD, SID, PID);
  838. if (Result = 0) or (Result = 457) then
  839. begin
  840. Result := DosReadQueue (HQ, RD, CISize, PCI, 0, 0, Prio, 0);
  841. if Result = 0 then
  842. begin
  843. Result := PCI^.Return;
  844. DosCloseQueue (HQ);
  845. DosFreeMem (PCI);
  846. Exit;
  847. end;
  848. end;
  849. DosCloseQueue (HQ);
  850. end;
  851. end
  852. else
  853. ObjName := StrPas (ObjNameBuf);
  854. FreeMem (ObjNameBuf, ObjBufSize);
  855. if ComLine = '' then
  856. CommandLine := Path
  857. else
  858. CommandLine := Path + ' ' + ComLine;
  859. if ObjName = '' then
  860. E := EOSError.CreateFmt (SExecuteProcessFailed, [CommandLine, Result])
  861. else
  862. E := EOSError.CreateFmt (SExecuteProcessFailed + '(' + ObjName + ')', [CommandLine, Result]);
  863. E.ErrorCode := Result;
  864. raise E;
  865. end;
  866. end;
  867. function ExecuteProcess (const Path: AnsiString;
  868. const ComLine: array of AnsiString): integer;
  869. var
  870. CommandLine: AnsiString;
  871. I: integer;
  872. begin
  873. Commandline := '';
  874. for I := 0 to High (ComLine) do
  875. if Pos (' ', ComLine [I]) <> 0 then
  876. CommandLine := CommandLine + ' ' + '"' + ComLine [I] + '"'
  877. else
  878. CommandLine := CommandLine + ' ' + Comline [I];
  879. ExecuteProcess := ExecuteProcess (Path, CommandLine);
  880. end;
  881. {****************************************************************************
  882. Initialization code
  883. ****************************************************************************}
  884. Initialization
  885. InitExceptions; { Initialize exceptions. OS independent }
  886. InitInternational; { Initialize internationalization settings }
  887. Finalization
  888. DoneExceptions;
  889. end.