sysutils.inc 18 KB

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