sysutils.inc 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749
  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. See the file COPYING.FPC, included in this distribution,
  6. for details about the copyright.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10. **********************************************************************}
  11. { MCBS functions }
  12. {$i sysansi.inc}
  13. {$i syscodepages.inc}
  14. {$macro on}
  15. {$define PathStr:=UnicodeString}
  16. {$define PathPChar:=PWideChar}
  17. { Read filename handling functions implementation }
  18. {$i fina.inc}
  19. { Read disk function implementations }
  20. {$i disk.inc}
  21. {$define PathStr:=AnsiString}
  22. {$define PathPChar:=PAnsiChar}
  23. { Read filename handling functions implementation }
  24. {$i fina.inc}
  25. { Read disk function implementations }
  26. {$i disk.inc}
  27. {$undef PathStr}
  28. {$undef PathPChar}
  29. { Read file utility functions implementation }
  30. {$i filutil.inc}
  31. { variant error codes }
  32. {$i varerror.inc}
  33. {$ifndef OS_FILEISREADONLY}
  34. Function FileIsReadOnly(const FileName: RawByteString): Boolean;
  35. begin
  36. Result := (FileGetAttr(FileName) and faReadOnly) <> 0;
  37. end;
  38. Function FileIsReadOnly(const FileName: UnicodeString): Boolean;
  39. begin
  40. Result := (FileGetAttr(FileName) and faReadOnly) <> 0;
  41. end;
  42. {$endif OS_FILEISREADONLY}
  43. {$ifndef OS_FILESETDATEBYNAME}
  44. Function FileSetDate (Const FileName : RawByteString;Age : Longint) : Longint;
  45. Var
  46. fd : THandle;
  47. begin
  48. { at least windows requires fmOpenWrite here }
  49. fd:=FileOpen(FileName,fmOpenWrite);
  50. If (Fd<>feInvalidHandle) then
  51. try
  52. Result:=FileSetDate(fd,Age);
  53. finally
  54. FileClose(fd);
  55. end
  56. else
  57. {$ifdef HAS_OSERROR}
  58. Result:=GetLastOSError;
  59. {$else}
  60. Result:=-1;
  61. {$endif}
  62. end;
  63. Function FileSetDate (Const FileName : UnicodeString;Age : Longint) : Longint;
  64. Var
  65. fd : THandle;
  66. begin
  67. { at least windows requires fmOpenWrite here }
  68. fd:=FileOpen(FileName,fmOpenWrite);
  69. If (Fd<>feInvalidHandle) then
  70. try
  71. Result:=FileSetDate(fd,Age);
  72. finally
  73. FileClose(fd);
  74. end
  75. else
  76. {$ifdef HAS_OSERROR}
  77. Result:=GetLastOSError;
  78. {$else}
  79. Result:=-1;
  80. {$endif}
  81. end;
  82. {$endif}
  83. { Read String Handling functions implementation }
  84. {$i sysstr.inc}
  85. { Read date & Time function implementations }
  86. {$ifndef FPUNONE}
  87. {$i dati.inc}
  88. {$endif}
  89. {$IFNDEF HAS_GETTICKCOUNT}
  90. function GetTickCount: LongWord;
  91. begin
  92. Result := LongWord(GetTickCount64);
  93. end;
  94. {$ENDIF}
  95. {$IFNDEF HAS_GETTICKCOUNT64}
  96. function GetTickCount64: QWord;
  97. begin
  98. {$IFDEF FPU_NONE}
  99. {$IFDEF HAS_SYSTIMERTICK}
  100. Result := SysTimerTick;
  101. {$ELSE}
  102. Result := 0;
  103. {$ENDIF}
  104. {$ELSE}
  105. Result := Trunc(Now * 24 * 60 * 60 * 1000);
  106. {$ENDIF}
  107. end;
  108. {$ENDIF}
  109. { Read pchar handling functions implementation }
  110. {$i syspch.inc}
  111. { generic internationalisation code }
  112. {$i sysint.inc}
  113. { wide string functions }
  114. {$i syswide.inc}
  115. {$ifdef FPC_HAS_UNICODESTRING}
  116. { unicode string functions }
  117. {$i sysuni.inc}
  118. {$i sysencoding.inc}
  119. {$endif FPC_HAS_UNICODESTRING}
  120. { threading stuff }
  121. {$i sysuthrd.inc}
  122. { OS utility code }
  123. {$i osutil.inc}
  124. procedure FreeAndNil(var obj);
  125. var
  126. temp: tobject;
  127. begin
  128. temp:=tobject(obj);
  129. pointer(obj):=nil;
  130. temp.free;
  131. end;
  132. function FileAge(const FileName: string; out FileDateTime: TDateTime; FollowLink: Boolean = True): Boolean;
  133. Var
  134. Info : TSearchRec;
  135. A : Integer;
  136. begin
  137. for A:=1 to Length(FileName) do
  138. If (FileName[A] in ['?','*']) then
  139. Exit(False);
  140. A:=0;
  141. if Not FollowLink then
  142. A:=A or faSymLink;
  143. Result:=FindFirst(FileName,A,Info)=0;
  144. If Result then
  145. FileDateTime:=FileDatetoDateTime (Info.Time);
  146. FindClose(Info);
  147. end;
  148. { Interfaces support }
  149. {$i sysuintf.inc}
  150. constructor Exception.Create(const msg : string);
  151. begin
  152. inherited create;
  153. fmessage:=msg;
  154. end;
  155. constructor Exception.CreateFmt(const msg : string; const args : array of const);
  156. begin
  157. inherited create;
  158. fmessage:=Format(msg,args);
  159. end;
  160. constructor Exception.CreateRes(ResString: PString);
  161. begin
  162. inherited create;
  163. fmessage:=ResString^;
  164. end;
  165. constructor Exception.CreateResFmt(ResString: PString; const Args: array of const);
  166. begin
  167. inherited create;
  168. fmessage:=Format(ResString^,args);
  169. end;
  170. constructor Exception.CreateHelp(const Msg: string; AHelpContext: Integer);
  171. begin
  172. inherited create;
  173. fmessage:=Msg;
  174. fhelpcontext:=AHelpContext;
  175. end;
  176. constructor Exception.CreateFmtHelp(const Msg: string; const Args: array of const;
  177. AHelpContext: Integer);
  178. begin
  179. inherited create;
  180. fmessage:=Format(Msg,args);
  181. fhelpcontext:=AHelpContext;
  182. end;
  183. constructor Exception.CreateResHelp(ResString: PString; AHelpContext: Integer);
  184. begin
  185. inherited create;
  186. fmessage:=ResString^;
  187. fhelpcontext:=AHelpContext;
  188. end;
  189. constructor Exception.CreateResFmtHelp(ResString: PString; const Args: array of const;
  190. AHelpContext: Integer);
  191. begin
  192. inherited create;
  193. fmessage:=Format(ResString^,args);
  194. fhelpcontext:=AHelpContext;
  195. end;
  196. procedure EHeapMemoryError.FreeInstance;
  197. begin
  198. if AllowFree then
  199. inherited FreeInstance;
  200. end;
  201. Constructor EVariantError.CreateCode (Code : longint);
  202. begin
  203. case Code of
  204. VAR_OK:
  205. Create(SNoError);
  206. VAR_PARAMNOTFOUND:
  207. Create(SVarParamNotFound);
  208. VAR_TYPEMISMATCH:
  209. Create(SInvalidVarCast);
  210. VAR_BADVARTYPE:
  211. Create(SVarBadType);
  212. VAR_OVERFLOW:
  213. Create(SVarOverflow);
  214. VAR_BADINDEX:
  215. Create(SVarArrayBounds);
  216. VAR_ARRAYISLOCKED:
  217. Create(SVarArrayLocked);
  218. VAR_NOTIMPL:
  219. Create(SVarNotImplemented);
  220. VAR_OUTOFMEMORY:
  221. Create(SVarOutOfMemory);
  222. VAR_INVALIDARG:
  223. Create(SVarInvalid);
  224. VAR_UNEXPECTED,
  225. VAR_EXCEPTION:
  226. Create(SVarUnexpected);
  227. else
  228. CreateFmt(SUnknownErrorCode,[Code]);
  229. end;
  230. ErrCode:=Code;
  231. end;
  232. {$ifdef windows}
  233. function EExternal.GetExceptionRecord: PExceptionRecord;
  234. begin
  235. result:=@FExceptionRecord;
  236. end;
  237. {$endif windows}
  238. {$push}
  239. {$S-}
  240. Procedure CatchUnhandledException (Obj : TObject; Addr: Pointer; FrameCount: Longint; Frames: PPointer);[public,alias:'FPC_BREAK_UNHANDLED_EXCEPTION'];
  241. Var
  242. i : longint;
  243. hstdout : ^text;
  244. begin
  245. hstdout:=@stdout;
  246. Writeln(hstdout^,'An unhandled exception occurred at $',HexStr(Addr),':');
  247. if Obj is exception then
  248. Writeln(hstdout^,Obj.ClassName,': ',Exception(Obj).Message)
  249. else
  250. Writeln(hstdout^,'Exception object ',Obj.ClassName,' is not of class Exception.');
  251. Writeln(hstdout^,BackTraceStrFunc(Addr));
  252. if (FrameCount>0) then
  253. begin
  254. for i:=0 to FrameCount-1 do
  255. Writeln(hstdout^,BackTraceStrFunc(Frames[i]));
  256. end;
  257. Writeln(hstdout^,'');
  258. end;
  259. type
  260. PExceptMapEntry=^TExceptMapEntry;
  261. TExceptMapEntry=record
  262. code: byte;
  263. cls: ExceptClass;
  264. {$IFDEF FPC_HAS_FEATURE_RESOURCES} // This is necessary for 2.4.4, which does not have reasources as a separate feature
  265. msg: PResStringRec;
  266. {$else FPC_HAS_FEATURE_RESOURCES}
  267. msg: PString;
  268. {$endif FPC_HAS_FEATURE_RESOURCES}
  269. end;
  270. const
  271. exceptmap: array[0..28] of TExceptMapEntry = (
  272. (code: 200; cls: EDivByZero; msg: @SDivByZero),
  273. (code: 201; cls: ERangeError; msg: @SRangeError),
  274. (code: 202; cls: EStackOverflow; msg: @SStackOverflow),
  275. (code: 205; cls: EOverflow; msg: @SOverflow),
  276. (code: 206; cls: EUnderflow; msg: @SUnderflow),
  277. (code: 207; cls: EInvalidOp; msg: @SInvalidOp),
  278. { Delphi distinguishes reDivByZero from reZeroDivide, but maps both to code 200. }
  279. (code: 208; cls: EZeroDivide; msg: @SZeroDivide),
  280. (code: 210; cls: EObjectCheck; msg: @SObjectCheckError),
  281. (code: 211; cls: EAbstractError; msg: @SAbstractError),
  282. (code: 212; cls: EExternalException; msg: @SExternalException),
  283. (code: 214; cls: EBusError; msg: @SBusError),
  284. (code: 215; cls: EIntOverflow; msg: @SIntOverflow),
  285. (code: 216; cls: EAccessViolation; msg: @SAccessViolation),
  286. (code: 217; cls: EControlC; msg: @SControlC),
  287. (code: 218; cls: EPrivilege; msg: @SPrivilege),
  288. (code: 219; cls: EInvalidCast; msg: @SInvalidCast),
  289. (code: 220; cls: EVariantError; msg: @SInvalidVarCast),
  290. (code: 221; cls: EVariantError; msg: @SInvalidVarOp),
  291. (code: 222; cls: EVariantError; msg: @SDispatchError),
  292. (code: 223; cls: EVariantError; msg: @SVarArrayCreate),
  293. (code: 224; cls: EVariantError; msg: @SVarNotArray),
  294. (code: 225; cls: EVariantError; msg: @SVarArrayBounds),
  295. (code: 227; cls: EAssertionFailed; msg: @SAssertionFailed),
  296. (code: 228; cls: EIntfCastError; msg: @SIntfCastError),
  297. (code: 229; cls: ESafecallException; msg: @SSafecallException),
  298. (code: 231; cls: EConvertError; msg: @SiconvError),
  299. (code: 232; cls: ENoThreadSupport; msg: @SNoThreadSupport),
  300. (code: 233; cls: ENoWideStringSupport; msg: @SSigQuit),
  301. (code: 234; cls: ENoWideStringSupport; msg: @SMissingWStringManager)
  302. );
  303. function FindExceptMapEntry(err: longint): PExceptMapEntry;
  304. var
  305. i: longint;
  306. begin
  307. for i:=low(exceptmap) to high(exceptmap) do
  308. if err=exceptmap[i].code then
  309. begin
  310. result:=@exceptmap[i];
  311. exit;
  312. end;
  313. result:=nil;
  314. end;
  315. Var OutOfMemory : EOutOfMemory;
  316. InValidPointer : EInvalidPointer;
  317. Procedure RunErrorToExcept (ErrNo : Longint; Address,Frame : Pointer);
  318. var
  319. E: Exception;
  320. HS: PString;
  321. Entry: PExceptMapEntry;
  322. begin
  323. Case Errno of
  324. 1,203 : E:=OutOfMemory;
  325. 204 : E:=InvalidPointer;
  326. else
  327. Entry:=FindExceptMapEntry(ErrNo);
  328. if Assigned(Entry) then
  329. E:=Entry^.cls.CreateRes(Entry^.msg)
  330. else
  331. begin
  332. HS:=nil;
  333. Case Errno of
  334. 2 : HS:=@SFileNotFound;
  335. 3 : HS:=@SInvalidFileName;
  336. 4 : HS:=@STooManyOpenFiles;
  337. 5 : HS:=@SAccessDenied;
  338. 6 : HS:=@SInvalidFileHandle;
  339. 15 : HS:=@SInvalidDrive;
  340. 100 : HS:=@SEndOfFile;
  341. 101 : HS:=@SDiskFull;
  342. 102 : HS:=@SFileNotAssigned;
  343. 103 : HS:=@SFileNotOpen;
  344. 104 : HS:=@SFileNotOpenForInput;
  345. 105 : HS:=@SFileNotOpenForOutput;
  346. 106 : HS:=@SInvalidInput;
  347. end;
  348. if Assigned(HS) then
  349. E:=EInOutError.CreateRes(HS)
  350. else
  351. E:=EInOutError.CreateResFmt(@SUnknownRunTimeError,[errno]);
  352. // this routine can be called from FPC_IOCHECK,
  353. // which clears inoutres and then passes its
  354. // original value to HandleErrorFrame() (which calls
  355. // us). So use errno rather than IOResult, and clear
  356. // InOutRes explicitly in case we can also be called
  357. // from a place that does not clear InOutRes explicitly
  358. EInoutError(E).ErrorCode:=errno;
  359. inoutres:=0;
  360. end;
  361. end;
  362. Raise E at Address,Frame;
  363. end;
  364. {$IFDEF HAS_OSERROR}
  365. Procedure RaiseLastOSError;overload;
  366. begin
  367. RaiseLastOSError(GetLastOSError);
  368. end;
  369. Procedure RaiseLastOSError(LastError: Integer);overload;
  370. var
  371. E : EOSError;
  372. begin
  373. If (LastError<>0) then
  374. E:=EOSError.CreateFmt(SOSError, [LastError, SysErrorMessage(LastError)])
  375. else
  376. E:=EOSError.Create(SUnkOSError);
  377. E.ErrorCode:=LastError;
  378. Raise E;
  379. end;
  380. {$else}
  381. Procedure RaiseLastOSError;overload;
  382. begin
  383. Raise Exception.Create('RaiseLastOSError not implemented on this platform.');
  384. end;
  385. Procedure RaiseLastOSError(LastError: Integer);overload;
  386. begin
  387. RaiseLastOSError;
  388. end;
  389. {$endif}
  390. Procedure AssertErrorHandler (Const Msg,FN : ShortString;LineNo:longint; TheAddr : pointer);
  391. Var
  392. S : String;
  393. begin
  394. If Msg='' then
  395. S:=SAssertionFailed
  396. else
  397. S:=Msg;
  398. Raise EAssertionFailed.Createfmt(SAssertError,[S,Fn,LineNo]) at get_caller_addr(theAddr), get_caller_frame(theAddr);
  399. end;
  400. {$pop} //{$S-} for Error handling functions
  401. Procedure InitExceptions;
  402. {
  403. Must install uncaught exception handler (ExceptProc)
  404. and install exceptions for system exceptions or signals.
  405. (e.g: SIGSEGV -> ESegFault or so.)
  406. }
  407. begin
  408. ExceptionClass := Exception;
  409. ExceptProc:=@CatchUnhandledException;
  410. // Create objects that may have problems when there is no memory.
  411. OutOfMemory:=EOutOfMemory.Create(SOutOfMemory);
  412. OutOfMemory.AllowFree:=false;
  413. InvalidPointer:=EInvalidPointer.Create(SInvalidPointer);
  414. InvalidPointer.AllowFree:=false;
  415. AssertErrorProc:=@AssertErrorHandler;
  416. ErrorProc:=@RunErrorToExcept;
  417. OnShowException:=Nil;
  418. end;
  419. Procedure DoneExceptions;
  420. begin
  421. OutOfMemory.AllowFree:=true;
  422. OutOfMemory.Free;
  423. InValidPointer.AllowFree:=true;
  424. InValidPointer.Free;
  425. end;
  426. { Exception handling routines }
  427. function ExceptObject: TObject;
  428. begin
  429. If RaiseList=Nil then
  430. Result:=Nil
  431. else
  432. Result:=RaiseList^.FObject;
  433. end;
  434. function ExceptAddr: Pointer;
  435. begin
  436. If RaiseList=Nil then
  437. Result:=Nil
  438. else
  439. Result:=RaiseList^.Addr;
  440. end;
  441. function ExceptFrameCount: Longint;
  442. begin
  443. If RaiseList=Nil then
  444. Result:=0
  445. else
  446. Result:=RaiseList^.Framecount;
  447. end;
  448. function ExceptFrames: PPointer;
  449. begin
  450. If RaiseList=Nil then
  451. Result:=Nil
  452. else
  453. Result:=RaiseList^.Frames;
  454. end;
  455. function ExceptionErrorMessage(ExceptObject: TObject; ExceptAddr: Pointer;
  456. Buffer: PChar; Size: Integer): Integer;
  457. Var
  458. S : AnsiString;
  459. Len : Integer;
  460. begin
  461. S:=Format(SExceptionErrorMessage,[ExceptAddr,ExceptObject.ClassName]);
  462. If ExceptObject is Exception then
  463. S:=Format('%s:'#10'%s',[S,Exception(ExceptObject).Message]);
  464. Len:=Length(S);
  465. If S[Len]<>'.' then
  466. begin
  467. S:=S+'.';
  468. Inc(len);
  469. end;
  470. If Len>Size then
  471. Len:=Size;
  472. if Len > 0 then
  473. Move(S[1],Buffer^,Len);
  474. Result:=Len;
  475. end;
  476. procedure ShowException(ExceptObject: TObject; ExceptAddr: Pointer);
  477. // use shortstring. On exception, the heap may be corrupt.
  478. Var
  479. Buf : ShortString;
  480. begin
  481. SetLength(Buf,ExceptionErrorMessage(ExceptObject,ExceptAddr,@Buf[1],255));
  482. If IsConsole Then
  483. writeln(Buf)
  484. else
  485. If Assigned(OnShowException) Then
  486. OnShowException (Buf);
  487. end;
  488. procedure Abort;
  489. begin
  490. Raise EAbort.Create(SAbortError) at Pointer(Get_Caller_addr(Get_Frame));
  491. end;
  492. procedure OutOfMemoryError;
  493. begin
  494. Raise OutOfMemory;
  495. end;
  496. { ---------------------------------------------------------------------
  497. Initialization/Finalization/exit code
  498. ---------------------------------------------------------------------}
  499. Type
  500. PPRecord = ^TPRecord;
  501. TPRecord = Record
  502. Func : TTerminateProc;
  503. NextFunc : PPRecord;
  504. end;
  505. Const
  506. TPList : PPRecord = Nil;
  507. procedure AddTerminateProc(TermProc: TTerminateProc);
  508. Var
  509. TPR : PPRecord;
  510. begin
  511. New(TPR);
  512. With TPR^ do
  513. begin
  514. NextFunc:=TPList;
  515. Func:=TermProc;
  516. end;
  517. TPList:=TPR;
  518. end;
  519. function CallTerminateProcs: Boolean;
  520. Var
  521. TPR : PPRecord;
  522. begin
  523. Result:=True;
  524. TPR:=TPList;
  525. While Result and (TPR<>Nil) do
  526. begin
  527. Result:=TPR^.Func();
  528. TPR:=TPR^.NextFunc;
  529. end;
  530. end;
  531. { ---------------------------------------------------------------------
  532. Diskh functions, OS independent.
  533. ---------------------------------------------------------------------}
  534. Function GetCurrentDir: {$ifdef FPC_UNICODE_RTL}UnicodeString{$else}AnsiString{$endif};
  535. begin
  536. GetDir(0,Result);
  537. end;
  538. { ---------------------------------------------------------------------
  539. Other functions, OS independent.
  540. ---------------------------------------------------------------------}
  541. Var
  542. GUIDCalledRandomize : Boolean = False;
  543. Procedure GetRandomBytes(Var Buf; NBytes : Integer);
  544. Var
  545. I : Integer;
  546. P : PByte;
  547. begin
  548. P:=@Buf;
  549. If Not GUIDCalledRandomize then
  550. begin
  551. Randomize;
  552. GUIDCalledRandomize:=True;
  553. end;
  554. For I:=0 to NBytes-1 do
  555. P[i]:=Random(256);
  556. end;
  557. {$IFDEF HASCREATEGUID}
  558. Function SysCreateGUID(out GUID : TGUID) : Integer; forward;
  559. {$ENDIF}
  560. Function CreateGUID(out GUID : TGUID) : Integer;
  561. begin
  562. If Assigned(OnCreateGUID) then
  563. Result:=OnCreateGUID(GUID)
  564. else
  565. begin
  566. {$IFDEF HASCREATEGUID}
  567. Result:=SysCreateGUID(GUID);
  568. {$ELSE}
  569. GetRandomBytes(GUID,SizeOf(Guid));
  570. guid.clock_seq_hi_and_reserved:=(guid.clock_seq_hi_and_reserved and $3F) + 64;
  571. guid.time_hi_and_version :=(guid.time_hi_and_version and $0FFF)+ $4000;
  572. Result:=0;
  573. {$ENDIF}
  574. end;
  575. end;
  576. function SafeLoadLibrary(const FileName: AnsiString;
  577. ErrorMode: DWord = {$ifdef windows}SEM_NOOPENFILEERRORBOX{$else windows}0{$endif windows}): HMODULE;
  578. {$if defined(cpui386) or defined(cpux86_64)}
  579. var
  580. mode : DWord;
  581. fpucw : Word;
  582. ssecw : DWord;
  583. {$endif}
  584. begin
  585. {$if defined(win64) or defined(win32)}
  586. mode:=SetErrorMode(ErrorMode);
  587. {$endif}
  588. try
  589. {$if defined(cpui386) or defined(cpux86_64)}
  590. fpucw:=Get8087CW;
  591. {$ifdef cpui386}
  592. if has_sse_support then
  593. {$endif cpui386}
  594. ssecw:=GetSSECSR;
  595. {$endif}
  596. {$if defined(windows) or defined(win32)}
  597. Result:=LoadLibraryA(PChar(Filename));
  598. {$else}
  599. Result:=0;
  600. {$endif}
  601. finally
  602. {$if defined(cpui386) or defined(cpux86_64)}
  603. Set8087CW(fpucw);
  604. {$ifdef cpui386}
  605. if has_sse_support then
  606. {$endif cpui386}
  607. SetSSECSR(ssecw);
  608. {$endif}
  609. {$if defined(win64) or defined(win32)}
  610. SetErrorMode(mode);
  611. {$endif}
  612. end;
  613. end;
  614. function GetModuleName(Module: HMODULE): string;
  615. begin
  616. {$ifdef MSWINDOWS}
  617. SetLength(Result,MAX_PATH);
  618. SetLength(Result,GetModuleFileName(Module, Pchar(Result),Length(Result)));
  619. {$ELSE}
  620. Result:='';
  621. {$ENDIF}
  622. end;
  623. { Beep support }
  624. procedure Beep;
  625. begin
  626. If Assigned(OnBeep) then
  627. OnBeep;
  628. end;