sysutils.pp 34 KB

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