XPWinBase.pas
上传用户:yjb1804
上传日期:2021-01-30
资源大小:3105k
文件大小:13k
源码类别:

Email服务器

开发平台:

Delphi

  1. unit XPWinBase;
  2. {
  3.  $Source: /cvsroot/dunit/dunit/Contrib/DUnitWizard/Source/Common/XPWinBase.pas,v $
  4.  $Revision: 1.1 $
  5.  $Date: 2004/05/03 15:07:15 $
  6.  Last amended by $Author: pvspain $
  7.  $State: Exp $
  8.  XPWinBase:
  9.  Interfaces and implementing classes which provide a base
  10.  for Win32 Kernel objects.
  11.  Copyright (c) 2001 by The Excellent Programming Company Pty Ltd
  12.  (Australia) (ABN 27 005 394 918).
  13.  Contact Paul Spain via email: paul@xpro.com.au
  14.  This unit is free software; you can redistribute it and/or
  15.  modify it under the terms of the GNU Lesser General Public
  16.  License as published by the Free Software Foundation; either
  17.  version 2.1 of the License, or (at your option) any later version.
  18.  This unit is distributed in the hope that it will be useful,
  19.  but WITHOUT ANY WARRANTY; without even the implied warranty of
  20.  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  21.  Lesser General Public License for more details.
  22.  You should have received a copy of the GNU Lesser General Public
  23.  License along with this unit; if not, the license can be viewed at:
  24.  http://www.gnu.org/copyleft/lesser.html
  25.  or write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
  26.  Boston, MA  02111-1307  USA
  27.  }
  28. interface
  29. uses
  30.   Windows,    // THandle,  CreateXXX(), OpenXXX
  31.   SysUtils;   // Exception, Trim(), FmtStr(), AnsiPos(),
  32.               // AnsiLowerCase()
  33. {$IFDEF XPW32E}
  34. type
  35.   EXPWin32 = class (Exception) end;
  36.     EXPWin32Handle = class (EXPWin32) end;
  37. {$ENDIF}
  38. //////////////////////////////////////////////////////////////////////////////
  39. ///   IXPWinError
  40. //////////////////////////////////////////////////////////////////////////////
  41. type
  42.   IXPWinError = interface
  43.     ['{B53D5BE1-3BC8-11D5-A2BB-00608CF441D9}']
  44.     function HasErred: boolean;
  45.     function GetLastError: cardinal;
  46.     function GetLastErrorText: string;
  47.     function GetLastContext: string;
  48.     procedure Reset;
  49.     end;
  50. {$IFDEF XPW32E}
  51.   TTEXPWin32 = class of EXPWin32;
  52. {$ENDIF}
  53.   TXPWinError = class(TInterfacedObject, IXPWinError)
  54.     private
  55.     FLastError: cardinal;
  56.     FLastContext: string;
  57. {$IFDEF XPW32E}
  58.     FException: TTEXPWin32;
  59. {$ENDIF}
  60.     protected
  61. {$IFDEF XPW32E}
  62.     procedure SetException(const AException: TTEXPWin32);
  63. {$ENDIF}
  64.     procedure Error(const Context: string);
  65.     procedure SetLastError(const Value: cardinal = 0);
  66.     procedure SetLastContext(const Context: string);
  67.     //
  68.     // IXPWinError implementation
  69.     //
  70.     function HasErred: boolean;
  71.     procedure Reset;
  72.     function GetLastError: cardinal;
  73.     function GetLastErrorText: string;
  74.     function GetLastContext: string;
  75.     public
  76. {$IFDEF XPW32E}
  77.     constructor Create(AException: TTEXPWin32);
  78. {$ELSE}
  79.     constructor Create;
  80. {$ENDIF}
  81.     end;
  82. //////////////////////////////////////////////////////////////////////////////
  83. ///   IXPWinHandle
  84. //////////////////////////////////////////////////////////////////////////////
  85. type
  86.   { Reference to a Windows handle which looks after its own closure.
  87.     Used by kernel objects which can return multiple handles. }
  88.   IXPWinHandle = interface(IXPWinError)
  89.     ['{EC93EF02-1092-11D5-A266-00608CF441D9}']
  90.     function IsSignaled: boolean;
  91.     function GetHandle: THandle;
  92.     function Wait: boolean;
  93.     function WaitFor(const Millisecs: cardinal): boolean;
  94.     property Handle: THandle read GetHandle;
  95.     end;
  96.   TXPWinHandle = class(TXPWinError, IXPWinHandle)
  97.     private
  98.     FHandle: THandle;
  99.     //
  100.     // IXPWinHandle implementation
  101.     //
  102.     function GetHandle: THandle;
  103.     protected
  104.     function IsSignaled: boolean; virtual;
  105.     function Wait: boolean; virtual;
  106.     function WaitFor(const Millisecs: cardinal): boolean; virtual;
  107.     public
  108.     constructor Create(AHandle: THandle);
  109.     destructor Destroy; override;
  110.     end;
  111. //////////////////////////////////////////////////////////////////////////////
  112. ///   IXPWinNamedKernelObject
  113. //////////////////////////////////////////////////////////////////////////////
  114. type
  115.   TXPKOInstance = (koUnknown, koCreated, koOpened);
  116.   IXPWinNamedKernelObject = interface(IXPWinHandle)
  117.     ['{0BCC42D3-1528-11D5-A26D-00608CF441D9}']
  118.     function GetName: string;
  119.     function GetInstance: TXPKOInstance;
  120.     property Name: string read GetName;
  121.     property Instance: TXPKOInstance read GetInstance;
  122.     end;
  123.   TXPWinKernelObject = class(TXPWinError)
  124.     protected
  125.     FSecurityAttributes: TSecurityAttributes;
  126.     public
  127.     constructor Create(const Inheritable: boolean;
  128.       const SecurityDescriptor: Pointer);
  129.     end;
  130.   TXPWinNamedKernelObject = class(TXPWinKernelObject, IXPWinHandle,
  131.     IXPWinNamedKernelObject)
  132.     private
  133.     function CustomWait(const Timeout: cardinal): boolean;
  134.     protected
  135.     FName: string;
  136.     FHandle: THandle;
  137.     FInstance: TXPKOInstance;
  138.     //
  139.     // IXPWinHandle implementation
  140.     //
  141.     function IsSignaled: boolean; virtual;
  142.     function GetHandle: THandle;
  143.     function Wait: boolean; virtual;
  144.     function WaitFor(const Millisecs: cardinal): boolean; virtual;
  145.     //
  146.     // IXPWinNamedKernelObject implementation
  147.     //
  148.     function GetName: string;
  149.     function GetInstance: TXPKOInstance;
  150.     public
  151.     constructor Create(const AName: string; const Inheritable: boolean;
  152.       const SecurityDescriptor: Pointer);
  153.     destructor Destroy; override;
  154.     class function UniqueName: string;
  155.     end;
  156. //////////////////////////////////////////////////////////////////////////////
  157. ///   Creator functions: unit entry points
  158. //////////////////////////////////////////////////////////////////////////////
  159. function CreateHandle(const AHandle: THandle): IXPWinHandle;
  160. //////////////////////////////////////////////////////////////////////////////
  161. ///   Global utility functions 
  162. //////////////////////////////////////////////////////////////////////////////
  163. function CreateGUIDAsString: string;
  164. function Win32ErrorText(const ErrorCode: cardinal): string;
  165. implementation
  166. uses
  167.   ActiveX;    // CoCreateGUID
  168. const CVSID: string = '$Header: /cvsroot/dunit/dunit/Contrib/DUnitWizard/Source/Common/XPWinBase.pas,v 1.1 2004/05/03 15:07:15 pvspain Exp $';
  169. //////////////////////////////////////////////////////////////////////////////
  170. ///   IXPWinError implementation
  171. //////////////////////////////////////////////////////////////////////////////
  172. const
  173.   XPWinNoError = ERROR_SUCCESS;
  174. {$IFDEF XPW32E}
  175. constructor TXPWinError.Create(AException: TTEXPWin32);
  176.   begin
  177.   inherited Create;
  178.   FLastError := XPWinNoError;
  179.   SetException(AException);
  180.   end;
  181. procedure TXPWinError.SetException(const AException: TTEXPWin32);
  182.   begin
  183.   FException := AException;
  184.   end;
  185. {$ELSE}
  186. constructor TXPWinError.Create;
  187.   begin
  188.   inherited Create;
  189.   FLastError := XPWinNoError;
  190.   end;
  191. {$ENDIF}
  192. procedure TXPWinError.Error(const Context: string);
  193.   begin
  194.   SetLastError;
  195.   SetLastContext(Context);
  196. {$IFDEF XPW32E}
  197.   raise FException.CreateFmt(GetLastContext + ': Win32 Error %d: %s',
  198.     [GetLastError, GetLastErrorText]);
  199. {$ENDIF}
  200.   end;
  201. function TXPWinError.GetLastError: cardinal;
  202.   begin
  203.   Result := FLastError;
  204.   end;
  205. function TXPWinError.GetLastErrorText: string;
  206.   begin
  207.   Result := Win32ErrorText(FLastError);
  208.   end;
  209. function TXPWinError.GetLastContext: string;
  210.   begin
  211.   Result := FLastContext;
  212.   end;
  213. function TXPWinError.HasErred: boolean;
  214.   begin
  215.   Result := FLastError <> XPWinNoError;
  216.   end;
  217. procedure TXPWinError.Reset;
  218.   begin
  219.   FLastError := XPWinNoError;
  220.   System.SetLength(FLastContext, 0);
  221.   end;
  222. procedure TXPWinError.SetLastError(const Value: cardinal);
  223.   begin
  224.   if Value = 0 then
  225.     FLastError := Windows.GetLastError
  226.   else
  227.     FLastError := Value;
  228.   end;
  229. procedure TXPWinError.SetLastContext(const Context: string);
  230.   begin
  231.   FLastContext := Context;
  232.   end;
  233. ///////////////////////////////////////////////////////////////////////////////
  234. ///     IXPWinHandle implementation
  235. ///////////////////////////////////////////////////////////////////////////////
  236. constructor TXPWinHandle.Create(AHandle: THandle);
  237.   begin
  238. {$IFDEF XPW32E}
  239.   inherited Create(EXPWin32Handle);
  240. {$ELSE}
  241.   inherited Create;
  242. {$ENDIF}
  243.   FHandle := AHandle;
  244.   end;
  245. destructor TXPWinHandle.Destroy;
  246.   begin
  247.   Windows.CloseHandle(FHandle);
  248.   inherited Destroy;
  249.   end;
  250. function TXPWinHandle.IsSignaled: boolean;
  251.   begin
  252.   Result := false;
  253.   end;
  254. function TXPWinHandle.Wait: boolean;
  255.   begin
  256.   Result := true;
  257.   end;
  258. function TXPWinHandle.WaitFor(const Millisecs: cardinal): boolean;
  259.   begin
  260.   Result := true;
  261.   end;
  262. function TXPWinHandle.GetHandle: THandle;
  263.   begin
  264.   Result := FHandle;
  265.   end;
  266. ///////////////////////////////////////////////////////////////////////////////
  267. ///     TXPWinKernelObject implementation
  268. ///////////////////////////////////////////////////////////////////////////////
  269. constructor TXPWinKernelObject.Create(const Inheritable: boolean;
  270.   const SecurityDescriptor: Pointer);
  271.   begin
  272. {$IFDEF XPW32E}
  273.   inherited Create(EXPWin32);
  274. {$ELSE}
  275.   inherited Create;
  276. {$ENDIF}
  277.   with FSecurityAttributes do
  278.     begin
  279.     nLength := SizeOf(FSecurityAttributes);
  280.     lpSecurityDescriptor := SecurityDescriptor;
  281.     bInheritHandle := Inheritable;
  282.     end;
  283.   end;
  284. ///////////////////////////////////////////////////////////////////////////////
  285. ///     TXPWinNamedKernelObject implementation
  286. ///////////////////////////////////////////////////////////////////////////////
  287. constructor TXPWinNamedKernelObject.Create(const AName: string;
  288.   const Inheritable: boolean; const SecurityDescriptor: Pointer);
  289.   begin
  290.   inherited Create(Inheritable, SecurityDescriptor);
  291.   { Create a "unique"  name if none is passed. }
  292.   if System.Length(SysUtils.Trim(AName)) = 0 then
  293.     FName := UniqueName
  294.   else
  295.     FName := AName;
  296.   FHandle := INVALID_HANDLE_VALUE;
  297.   FInstance := koUnknown;
  298.   end;
  299. function TXPWinNamedKernelObject.GetInstance: TXPKOInstance;
  300.   begin
  301.   Result := FInstance;
  302.   end;
  303. destructor TXPWinNamedKernelObject.Destroy;
  304.   begin
  305.   if FHandle <> INVALID_HANDLE_VALUE then
  306.     Windows.CloseHandle(FHandle);
  307.   inherited Destroy;
  308.   end;
  309. class function TXPWinNamedKernelObject.UniqueName: string;
  310.   var
  311.   Count: int64;
  312.   begin
  313.   if Windows.QueryPerformanceCounter(Count) then
  314.     // Create a number which (hopefully) uniquely identifies the calling context
  315.     // in machine-space (current thread ID) and time (high res counter value).
  316.     SysUtils.FmtStr(Result, '%d.%d', [Windows.GetCurrentThreadID, Count])
  317.   else
  318.     // High-res counter not available, create a GUID
  319.     Result := CreateGUIDAsString;
  320.   end;
  321. function TXPWinNamedKernelObject.GetHandle: THandle;
  322.   begin
  323.   Result  := FHandle;
  324.   end;
  325. function TXPWinNamedKernelObject.GetName: string;
  326.   begin
  327.   Result := FName;
  328.   end;
  329. function TXPWinNamedKernelObject.CustomWait(const Timeout: cardinal): boolean;
  330.   var
  331.   WaitResult: cardinal;
  332.   begin
  333.   WaitResult := Windows.WaitForSingleObject(FHandle, Timeout);
  334.   case WaitResult of
  335.     WAIT_FAILED:
  336.       begin
  337.       Error('TXPWinNamedKernelObject: Windows.WaitForSingleObject failure');
  338.       Result := false;
  339.       end;
  340.     WAIT_TIMEOUT:
  341.       Result := false;
  342.     WAIT_OBJECT_0, WAIT_ABANDONED:
  343.       Result := true;
  344.     else
  345.       Result := false;
  346.     end;
  347.   end;
  348. function TXPWinNamedKernelObject.IsSignaled: boolean;
  349.   begin
  350.   Result := CustomWait(0);
  351.   end;
  352. function TXPWinNamedKernelObject.Wait: boolean;
  353.   begin
  354.   Result := CustomWait(INFINITE);
  355.   end;
  356. function TXPWinNamedKernelObject.WaitFor(const Millisecs: cardinal): boolean;
  357.   begin
  358.   Result := CustomWait(Millisecs);
  359.   end;
  360. ///////////////////////////////////////////////////////////////////////////////
  361. ///    Global functions
  362. ///////////////////////////////////////////////////////////////////////////////
  363. function CreateHandle(const AHandle: THandle): IXPWinHandle;
  364.   begin
  365.   Result := TXPWinHandle.Create(AHandle);
  366.   end;
  367. function CreateGUIDAsString: string;
  368.   var
  369.   AGUID: TGUID;
  370.   AGUIDString: widestring;
  371.   begin
  372.   ActiveX.CoCreateGUID(AGUID);
  373.   System.SetLength(AGUIDString, 39);
  374.   ActiveX.StringFromGUID2(AGUID, PWideChar(AGUIDString), 39);
  375.   Result := string(PWideChar(AGUIDString));
  376.   end;
  377. function Win32ErrorText(const ErrorCode: cardinal): string;
  378.   const
  379.   LangID = 0;
  380.   MessageSource = nil;
  381.   Inserts = nil;
  382.   begin
  383.   System.SetLength(Result, 255);
  384.   Windows.FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, MessageSource, ErrorCode,
  385.     LangID, PAnsiChar(Result), 255, Inserts);
  386.   Result := string(PAnsiChar(Result));
  387.   end;
  388. end.