sysutils.pp 37 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120
  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:shortstring; {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:shortstring; {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. TResultCodes=record
  218. TerminateReason, {0 = Normal termionation.
  219. 1 = Critical error.
  220. 2 = Trapped. (GPE, etc.)
  221. 3 = Killed by DosKillProcess.}
  222. ExitCode:cardinal; {Exit code of child.}
  223. end;
  224. const
  225. ilStandard = 1;
  226. ilQueryEAsize = 2;
  227. ilQueryEAs = 3;
  228. ilQueryFullName = 5;
  229. quFIFO = 0;
  230. quLIFO = 1;
  231. quPriority = 2;
  232. quNoConvert_Address = 0;
  233. quConvert_Address = 4;
  234. {Start the new session independent or as a child.}
  235. ssf_Related_Independent = 0; {Start new session independent
  236. of the calling session.}
  237. ssf_Related_Child = 1; {Start new session as a child
  238. session to the calling session.}
  239. {Start the new session in the foreground or in the background.}
  240. ssf_FgBg_Fore = 0; {Start new session in foreground.}
  241. ssf_FgBg_Back = 1; {Start new session in background.}
  242. {Should the program started in the new session
  243. be executed under conditions for tracing?}
  244. ssf_TraceOpt_None = 0; {No trace.}
  245. ssf_TraceOpt_Trace = 1; {Trace with no notification
  246. of descendants.}
  247. ssf_TraceOpt_TraceAll = 2; {Trace all descendant sessions.
  248. A termination queue must be
  249. supplied and Related must be
  250. ssf_Related_Child (=1).}
  251. {Will the new session inherit open file handles
  252. and environment from the calling process.}
  253. ssf_InhertOpt_Shell = 0; {Inherit from the shell.}
  254. ssf_InhertOpt_Parent = 1; {Inherit from the calling process.}
  255. {Specifies the type of session to start.}
  256. ssf_Type_Default = 0; {Use program's type.}
  257. ssf_Type_FullScreen = 1; {OS/2 full screen.}
  258. ssf_Type_WindowableVIO = 2; {OS/2 window.}
  259. ssf_Type_PM = 3; {Presentation Manager.}
  260. ssf_Type_VDM = 4; {DOS full screen.}
  261. ssf_Type_WindowedVDM = 7; {DOS window.}
  262. {Additional values for Windows programs}
  263. Prog_31_StdSeamlessVDM = 15; {Windows 3.1 program in its
  264. own windowed session.}
  265. Prog_31_StdSeamlessCommon = 16; {Windows 3.1 program in a
  266. common windowed session.}
  267. Prog_31_EnhSeamlessVDM = 17; {Windows 3.1 program in enhanced
  268. compatibility mode in its own
  269. windowed session.}
  270. Prog_31_EnhSeamlessCommon = 18; {Windows 3.1 program in enhanced
  271. compatibility mode in a common
  272. windowed session.}
  273. Prog_31_Enh = 19; {Windows 3.1 program in enhanced
  274. compatibility mode in a full
  275. screen session.}
  276. Prog_31_Std = 20; {Windows 3.1 program in a full
  277. screen session.}
  278. {Specifies the initial attributes for a OS/2 window or DOS window session.}
  279. ssf_Control_Visible = 0; {Window is visible.}
  280. ssf_Control_Invisible = 1; {Window is invisible.}
  281. ssf_Control_Maximize = 2; {Window is maximized.}
  282. ssf_Control_Minimize = 4; {Window is minimized.}
  283. ssf_Control_NoAutoClose = 8; {Window will not close after
  284. the program has ended.}
  285. ssf_Control_SetPos = 32768; {Use InitXPos, InitYPos,
  286. InitXSize, and InitYSize for
  287. the size and placement.}
  288. function DosSetFileInfo (Handle: THandle; InfoLevel: cardinal; AFileStatus: PFileStatus;
  289. FileStatusLen: cardinal): cardinal; cdecl; external 'DOSCALLS' index 218;
  290. function DosQueryFSInfo (DiskNum, InfoLevel: cardinal; var Buffer: TFSInfo;
  291. BufLen: cardinal): cardinal; cdecl; external 'DOSCALLS' index 278;
  292. function DosQueryFileInfo (Handle: THandle; InfoLevel: cardinal;
  293. AFileStatus: PFileStatus; FileStatusLen: cardinal): cardinal; cdecl;
  294. external 'DOSCALLS' index 279;
  295. function DosScanEnv (Name: PChar; var Value: PChar): cardinal; cdecl;
  296. external 'DOSCALLS' index 227;
  297. function DosFindFirst (FileMask: PChar; var Handle: THandle; Attrib: cardinal;
  298. AFileStatus: PFileStatus; FileStatusLen: cardinal;
  299. var Count: cardinal; InfoLevel: cardinal): cardinal; cdecl;
  300. external 'DOSCALLS' index 264;
  301. function DosFindNext (Handle: THandle; AFileStatus: PFileStatus;
  302. FileStatusLen: cardinal; var Count: cardinal): cardinal; cdecl;
  303. external 'DOSCALLS' index 265;
  304. function DosFindClose (Handle: THandle): cardinal; cdecl;
  305. external 'DOSCALLS' index 263;
  306. function DosQueryCtryInfo (Size: cardinal; var Country: TCountryCode;
  307. var Res: TCountryInfo; var ActualSize: cardinal): cardinal; cdecl;
  308. external 'NLS' index 5;
  309. function DosMapCase (Size: cardinal; var Country: TCountryCode;
  310. AString: PChar): cardinal; cdecl; external 'NLS' index 7;
  311. function DosDelete(FileName:PChar): cardinal; cdecl;
  312. external 'DOSCALLS' index 259;
  313. function DosMove(OldFile, NewFile:PChar): cardinal; cdecl;
  314. external 'DOSCALLS' index 271;
  315. function DosQueryPathInfo(FileName:PChar;InfoLevel:cardinal;
  316. AFileStatus:PFileStatus;FileStatusLen:cardinal): cardinal; cdecl;
  317. external 'DOSCALLS' index 223;
  318. function DosSetPathInfo(FileName:PChar;InfoLevel:cardinal;
  319. AFileStatus:PFileStatus;FileStatusLen,
  320. Options:cardinal):cardinal; cdecl;
  321. external 'DOSCALLS' index 219;
  322. function DosOpen(FileName:PChar;var Handle: THandle; var Action: cardinal;
  323. InitSize,Attrib,OpenFlags,FileMode:cardinal;
  324. EA:Pointer):cardinal; cdecl;
  325. external 'DOSCALLS' index 273;
  326. function DosClose(Handle: THandle): cardinal; cdecl;
  327. external 'DOSCALLS' index 257;
  328. function DosRead(Handle:THandle; var Buffer; Count: cardinal;
  329. var ActCount: cardinal): cardinal; cdecl;
  330. external 'DOSCALLS' index 281;
  331. function DosWrite(Handle: THandle; Buffer: pointer; Count: cardinal;
  332. var ActCount: cardinal): cardinal; cdecl;
  333. external 'DOSCALLS' index 282;
  334. function DosSetFilePtr(Handle: THandle; Pos: longint; Method: cardinal;
  335. var PosActual: cardinal): cardinal; cdecl;
  336. external 'DOSCALLS' index 256;
  337. function DosSetFileSize (Handle: THandle; Size: cardinal): cardinal; cdecl;
  338. external 'DOSCALLS' index 272;
  339. procedure DosSleep (MSec: cardinal); cdecl; external 'DOSCALLS' index 229;
  340. function DosCreateQueue (var Handle: THandle; Priority:longint;
  341. Name: PChar): cardinal; cdecl;
  342. external 'QUECALLS' index 16;
  343. function DosReadQueue (Handle: THandle; var ReqBuffer: TRequestData;
  344. var DataLen: cardinal; var DataPtr: pointer;
  345. Element, Wait: cardinal; var Priority: byte;
  346. ASem: THandle): cardinal; cdecl;
  347. external 'QUECALLS' index 9;
  348. function DosCloseQueue (Handle: THandle): cardinal; cdecl;
  349. external 'QUECALLS' index 11;
  350. function DosStartSession (var AStartData: TStartData;
  351. var SesID, PID: cardinal): cardinal; cdecl;
  352. external 'SESMGR' index 37;
  353. function DosFreeMem(P:pointer):cardinal; cdecl; external 'DOSCALLS' index 304;
  354. function DosExecPgm (ObjName: PChar; ObjLen: longint; ExecFlag: cardinal;
  355. Args, Env: PByteArray; var Res: TResultCodes;
  356. FileName:PChar): cardinal; cdecl;
  357. external 'DOSCALLS' index 283;
  358. type
  359. TDT=packed record
  360. Hour,
  361. Minute,
  362. Second,
  363. Sec100,
  364. Day,
  365. Month: byte;
  366. Year: word;
  367. TimeZone: smallint;
  368. WeekDay: byte;
  369. end;
  370. function DosGetDateTime(var Buf: TDT): cardinal; cdecl;
  371. external 'DOSCALLS' index 230;
  372. {****************************************************************************
  373. File Functions
  374. ****************************************************************************}
  375. const
  376. ofRead = $0000; {Open for reading}
  377. ofWrite = $0001; {Open for writing}
  378. ofReadWrite = $0002; {Open for reading/writing}
  379. doDenyRW = $0010; {DenyAll (no sharing)}
  380. faCreateNew = $00010000; {Create if file does not exist}
  381. faOpenReplace = $00040000; {Truncate if file exists}
  382. faCreate = $00050000; {Create if file does not exist, truncate otherwise}
  383. FindResvdMask = $00003737; {Allowed bits in attribute
  384. specification for DosFindFirst call.}
  385. function FileOpen (const FileName: string; Mode: integer): longint;
  386. Var
  387. Handle: THandle;
  388. Rc, Action: cardinal;
  389. begin
  390. (* DenyNone if sharing not specified. *)
  391. if Mode and 112 = 0 then Mode:=Mode or 64;
  392. Rc:=DosOpen(PChar (FileName), Handle, Action, 0, 0, 1, Mode, nil);
  393. If Rc=0 then
  394. FileOpen:=Handle
  395. else
  396. FileOpen:=-RC;
  397. end;
  398. function FileCreate (const FileName: string): longint;
  399. Const
  400. Mode = ofReadWrite or faCreate or doDenyRW; (* Sharing to DenyAll *)
  401. Var
  402. Handle: THandle;
  403. RC, Action: cardinal;
  404. Begin
  405. RC:=DosOpen(PChar (FileName), Handle, Action, 0, 0, $12, Mode, Nil);
  406. If RC=0 then
  407. FileCreate:=Handle
  408. else
  409. FileCreate:=-RC;
  410. End;
  411. function FileCreate (const FileName: string; Mode: integer): longint;
  412. begin
  413. FileCreate := FileCreate(FileName);
  414. end;
  415. function FileRead (Handle: longint; var Buffer; Count: longint): longint;
  416. Var
  417. T: cardinal;
  418. begin
  419. DosRead(Handle, Buffer, Count, T);
  420. FileRead := longint (T);
  421. end;
  422. function FileWrite (Handle: longint; const Buffer; Count: longint): longint;
  423. Var
  424. T: cardinal;
  425. begin
  426. DosWrite (Handle, @Buffer, Count, T);
  427. FileWrite := longint (T);
  428. end;
  429. function FileSeek (Handle, FOffset, Origin: longint): longint;
  430. var
  431. npos: cardinal;
  432. begin
  433. if DosSetFilePtr (Handle, FOffset, Origin, npos) = 0 Then
  434. FileSeek:= longint (npos)
  435. else
  436. FileSeek:=-1;
  437. end;
  438. function FileSeek (Handle: longint; FOffset, Origin: Int64): Int64;
  439. begin
  440. {$warning need to add 64bit call }
  441. Result:=FileSeek(Handle,Longint(Foffset),Longint(Origin));
  442. end;
  443. procedure FileClose (Handle: longint);
  444. begin
  445. DosClose(Handle);
  446. end;
  447. function FileTruncate (Handle, Size: longint): boolean;
  448. begin
  449. FileTruncate:=DosSetFileSize(Handle, Size)=0;
  450. FileSeek(Handle, 0, 2);
  451. end;
  452. function FileAge (const FileName: string): longint;
  453. var Handle: longint;
  454. begin
  455. Handle := FileOpen (FileName, 0);
  456. if Handle <> -1 then
  457. begin
  458. Result := FileGetDate (Handle);
  459. FileClose (Handle);
  460. end
  461. else
  462. Result := -1;
  463. end;
  464. function FileExists (const FileName: string): boolean;
  465. var
  466. SR: TSearchRec;
  467. RC: longint;
  468. begin
  469. FileExists:=False;
  470. if FindFirst (FileName, faAnyFile, SR)=0 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; var 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 := $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, faDirectory, SR)=0;
  658. FindClose(SR);
  659. end;
  660. {****************************************************************************
  661. Time Functions
  662. ****************************************************************************}
  663. procedure GetLocalTime (var SystemTime: TSystemTime);
  664. var
  665. DT: TDT;
  666. begin
  667. DosGetDateTime(DT);
  668. with SystemTime do
  669. begin
  670. Year:=DT.Year;
  671. Month:=DT.Month;
  672. Day:=DT.Day;
  673. Hour:=DT.Hour;
  674. Minute:=DT.Minute;
  675. Second:=DT.Second;
  676. MilliSecond:=DT.Sec100;
  677. end;
  678. end;
  679. {****************************************************************************
  680. Misc Functions
  681. ****************************************************************************}
  682. procedure Beep;
  683. begin
  684. end;
  685. {****************************************************************************
  686. Locale Functions
  687. ****************************************************************************}
  688. procedure InitAnsi;
  689. var I: byte;
  690. Country: TCountryCode;
  691. begin
  692. for I := 0 to 255 do
  693. UpperCaseTable [I] := Chr (I);
  694. Move (UpperCaseTable, LowerCaseTable, SizeOf (UpperCaseTable));
  695. FillChar (Country, SizeOf (Country), 0);
  696. DosMapCase (SizeOf (UpperCaseTable), Country, @UpperCaseTable);
  697. for I := 0 to 255 do
  698. if UpperCaseTable [I] <> Chr (I) then
  699. LowerCaseTable [Ord (UpperCaseTable [I])] := Chr (I);
  700. end;
  701. procedure InitInternational;
  702. var Country: TCountryCode;
  703. CtryInfo: TCountryInfo;
  704. Size: cardinal;
  705. RC: cardinal;
  706. begin
  707. Size := 0;
  708. FillChar (Country, SizeOf (Country), 0);
  709. FillChar (CtryInfo, SizeOf (CtryInfo), 0);
  710. RC := DosQueryCtryInfo (SizeOf (CtryInfo), Country, CtryInfo, Size);
  711. if RC = 0 then
  712. begin
  713. DateSeparator := CtryInfo.DateSeparator;
  714. case CtryInfo.DateFormat of
  715. 1: begin
  716. ShortDateFormat := 'd/m/y';
  717. LongDateFormat := 'dd" "mmmm" "yyyy';
  718. end;
  719. 2: begin
  720. ShortDateFormat := 'y/m/d';
  721. LongDateFormat := 'yyyy" "mmmm" "dd';
  722. end;
  723. 3: begin
  724. ShortDateFormat := 'm/d/y';
  725. LongDateFormat := 'mmmm" "dd" "yyyy';
  726. end;
  727. end;
  728. TimeSeparator := CtryInfo.TimeSeparator;
  729. DecimalSeparator := CtryInfo.DecimalSeparator;
  730. ThousandSeparator := CtryInfo.ThousandSeparator;
  731. CurrencyFormat := CtryInfo.CurrencyFormat;
  732. CurrencyString := PChar (CtryInfo.CurrencyUnit);
  733. end;
  734. InitAnsi;
  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. procedure Sleep (Milliseconds: cardinal);
  748. begin
  749. DosSleep (Milliseconds);
  750. end;
  751. function ExecuteProcess (const Path: AnsiString; const ComLine: AnsiString):
  752. integer;
  753. var
  754. HQ: THandle;
  755. SPID, STID, QName: shortstring;
  756. SD: TStartData;
  757. SID, PID: cardinal;
  758. RD: TRequestData;
  759. PCI: PChildInfo;
  760. CISize: cardinal;
  761. Prio: byte;
  762. E: EOSError;
  763. CommandLine: ansistring;
  764. Args: PByteArray;
  765. ObjNameBuf: PChar;
  766. ArgSize: word;
  767. Res: TResultCodes;
  768. ObjName: shortstring;
  769. const
  770. MaxArgsSize = 2048; (* Amount of memory reserved for arguments in bytes. *)
  771. ObjBufSize = 512;
  772. begin
  773. ObjName := '';
  774. GetMem (ObjNameBuf, ObjBufSize);
  775. FillChar (ObjNameBuf^, ObjBufSize, 0);
  776. if ComLine = '' then
  777. Args := nil
  778. else
  779. begin
  780. GetMem (Args, MaxArgsSize);
  781. ArgSize := 0;
  782. Move (Path [1], Args^ [ArgSize], Length (Path));
  783. Inc (ArgSize, Length (Path));
  784. Args^ [ArgSize] := 0;
  785. Inc (ArgSize);
  786. {Now do the real arguments.}
  787. Move (ComLine [1], Args^ [ArgSize], Length (ComLine));
  788. Inc (ArgSize, Length (ComLine));
  789. Args^ [ArgSize] := 0;
  790. Inc (ArgSize);
  791. Args^ [ArgSize] := 0;
  792. end;
  793. Result := DosExecPgm (ObjNameBuf, ObjBufSize, 0, Args, nil, Res, PChar (Path));
  794. if Args <> nil then
  795. FreeMem (Args, MaxArgsSize);
  796. if Result = 0 then
  797. begin
  798. Result := Res.ExitCode;
  799. FreeMem (ObjNameBuf, ObjBufSize);
  800. end
  801. else
  802. begin
  803. if (Result = 190) or (Result = 191) then
  804. begin
  805. FillChar (SD, SizeOf (SD), 0);
  806. SD.Length := 24;
  807. SD.Related := ssf_Related_Child;
  808. CommandLine := FExpand (Path); (* Needed for other session types... *)
  809. SD.PgmName := PChar (CommandLine);
  810. if ComLine <> '' then
  811. SD.PgmInputs := PChar (ComLine);
  812. SD.InheritOpt := ssf_InhertOpt_Parent;
  813. Str (GetProcessID, SPID);
  814. Str (ThreadID, STID);
  815. QName := '\QUEUES\FPC_ExecuteProcess_p' + SPID + 't' + STID + '.QUE'#0;
  816. SD.TermQ := @QName [1];
  817. Result := DosCreateQueue (HQ, quFIFO or quConvert_Address, @QName [1]);
  818. if Result = 0 then
  819. begin
  820. Result := DosStartSession (SD, SID, PID);
  821. if (Result = 0) or (Result = 457) then
  822. begin
  823. Result := DosReadQueue (HQ, RD, CISize, PCI, 0, 0, Prio, 0);
  824. if Result = 0 then
  825. begin
  826. Result := PCI^.Return;
  827. DosCloseQueue (HQ);
  828. DosFreeMem (PCI);
  829. Exit;
  830. end;
  831. end;
  832. DosCloseQueue (HQ);
  833. end;
  834. end
  835. else
  836. ObjName := StrPas (ObjNameBuf);
  837. FreeMem (ObjNameBuf, ObjBufSize);
  838. if ComLine = '' then
  839. CommandLine := Path
  840. else
  841. CommandLine := Path + ' ' + ComLine;
  842. if ObjName = '' then
  843. E := EOSError.CreateFmt (SExecuteProcessFailed, [CommandLine, Result])
  844. else
  845. E := EOSError.CreateFmt (SExecuteProcessFailed + '(' + ObjName + ')', [CommandLine, Result]);
  846. E.ErrorCode := Result;
  847. raise E;
  848. end;
  849. end;
  850. function ExecuteProcess (const Path: AnsiString;
  851. const ComLine: array of AnsiString): integer;
  852. var
  853. CommandLine: AnsiString;
  854. I: integer;
  855. begin
  856. Commandline := '';
  857. for I := 0 to High (ComLine) do
  858. if Pos (' ', ComLine [I]) <> 0 then
  859. CommandLine := CommandLine + ' ' + '"' + ComLine [I] + '"'
  860. else
  861. CommandLine := CommandLine + ' ' + Comline [I];
  862. ExecuteProcess := ExecuteProcess (Path, CommandLine);
  863. end;
  864. {****************************************************************************
  865. Initialization code
  866. ****************************************************************************}
  867. Initialization
  868. InitExceptions; { Initialize exceptions. OS independent }
  869. InitInternational; { Initialize internationalization settings }
  870. Finalization
  871. DoneExceptions;
  872. end.
  873. {
  874. $Log$
  875. Revision 1.46 2004-12-06 22:11:47 hajny
  876. * one more fix for ExecuteProcess
  877. Revision 1.45 2004/12/06 18:50:21 hajny
  878. * fix for ExecuteProcess
  879. Revision 1.44 2004/12/05 19:33:08 hajny
  880. * ExecuteProcess update - run VIO apps in the same window
  881. Revision 1.43 2004/02/22 15:01:49 hajny
  882. * lots of fixes (regcall, THandle, string operations in sysutils, longint2cardinal according to OS/2 docs, dosh.inc, ...)
  883. Revision 1.42 2004/02/15 21:36:10 hajny
  884. * overloaded ExecuteProcess added, EnvStr param changed to longint
  885. Revision 1.41 2004/02/15 08:02:44 yuri
  886. * fixes for dosh.inc
  887. * Executeprocess iverloaded function
  888. * updated todo
  889. Revision 1.40 2004/01/20 23:11:20 hajny
  890. * ExecuteProcess fixes, ProcessID and ThreadID added
  891. Revision 1.39 2003/11/26 20:00:19 florian
  892. * error handling for Variants improved
  893. Revision 1.38 2003/11/23 15:50:07 yuri
  894. * Now native
  895. Revision 1.37 2003/11/05 09:14:00 yuri
  896. * exec fix
  897. * unused units removed
  898. Revision 1.36 2003/10/27 12:19:20 yuri
  899. * GetLocatTime now also native
  900. Revision 1.35 2003/10/27 11:43:40 yuri
  901. * New set of native functions
  902. Revision 1.34 2003/10/18 16:58:39 hajny
  903. * stdcall fixes again
  904. Revision 1.33 2003/10/13 21:17:31 hajny
  905. * longint to cardinal corrections
  906. Revision 1.32 2003/10/08 05:22:47 yuri
  907. * Some emx code removed
  908. Revision 1.31 2003/10/07 21:26:34 hajny
  909. * stdcall fixes and asm routines cleanup
  910. Revision 1.30 2003/10/03 21:46:41 peter
  911. * stdcall fixes
  912. Revision 1.29 2003/06/06 23:34:40 hajny
  913. * better fix for bug 2518
  914. Revision 1.28 2003/06/06 23:31:17 hajny
  915. * fix for bug 2518 applied to OS/2 as well
  916. Revision 1.27 2003/04/01 15:57:41 peter
  917. * made THandle platform dependent and unique type
  918. Revision 1.26 2003/03/31 02:18:39 yuri
  919. FileClose bug fixed (again ;))
  920. Revision 1.25 2003/03/29 19:14:16 yuri
  921. * Directoryexists function header changed back.
  922. Revision 1.24 2003/03/29 18:53:10 yuri
  923. * Fixed DirectoryExists function header
  924. Revision 1.23 2003/03/29 15:01:20 hajny
  925. + DirectoryExists added for main branch OS/2 too
  926. Revision 1.22 2003/03/01 21:19:14 hajny
  927. * FileClose bug fixed
  928. Revision 1.21 2003/01/04 16:25:08 hajny
  929. * modified to make use of the common GetEnv code
  930. Revision 1.20 2003/01/03 20:41:04 peter
  931. * FileCreate(string,mode) overload added
  932. Revision 1.19 2002/11/18 19:51:00 hajny
  933. * another bunch of type corrections
  934. Revision 1.18 2002/09/23 17:42:37 hajny
  935. * AnsiString to PChar typecast
  936. Revision 1.17 2002/09/07 16:01:25 peter
  937. * old logs removed and tabs fixed
  938. Revision 1.16 2002/07/11 16:00:05 hajny
  939. * FindFirst fix (invalid attribute bits masked out)
  940. Revision 1.15 2002/01/25 16:23:03 peter
  941. * merged filesearch() fix
  942. }