sysutils.inc 18 KB

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