(*
 * Author  : Michael Puff - http://www.michael-puff.de
 * Date    : 2006-04-05
 *)

(*======================================================================*
 |                                                                      |
 |                        COPYRIGHT NOTICE                              |
 |                                                                      |
 | Copyright (c) 2001-2006, Michael Puff ["copyright holder(s)"]        |
 | All rights reserved.                                                 |
 |                                                                      |
 | Redistribution and use in source and binary forms, with or without   |
 | modification, are permitted provided that the following conditions   |
 | are met:                                                             |
 |                                                                      |
 | 1. Redistributions of source code must retain the above copyright    |
 |    notice, this list of conditions and the following disclaimer.     |
 | 2. Redistributions in binary form must reproduce the above copyright |
 |    notice, this list of conditions and the following disclaimer in   |
 |    the documentation and/or other materials provided with the        |
 |    distribution.                                                     |
 | 3. The name(s) of the copyright holder(s) may not be used to endorse |
 |    or promote products derived from this software without specific   |
 |    prior written permission.                                         |
 |                                                                      |
 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS  |
 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT    |
 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS    |
 | FORA PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE        |
 | REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,          |
 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
 | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;     |
 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER     |
 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT   |
 | LIABILITY, OR TORT INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY |
 | WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE          |
 | POSSIBILITY OF SUCH DAMAGE.                                          |
 |                                                                      |
 *======================================================================*)


unit MpuConnectionCls;

interface

uses
  Windows,
  SysUtils,
  Classes,
  Dialogs;

type
  TOnConnect = procedure(Sender: TObject) of object;
  TOnDisconnect = procedure(Sender: TObject) of object;
  TOnOnError = procedure(Sender: TObject; ErrorCode: DWORD; const ErrorMsg: string) of object;
  TConnection = class(TObject)
  private
    FUNCPath: string;
    FLogin: string;
    FPassword: string;
    FConnected: Boolean;
    FOnConnect: TOnConnect;
    FOnDisconnect: TOnDisconnect;
    FOnError: TOnOnError;
  public
    constructor Create(const AUNCPath, ALogin, APassword: string);
    destructor Destroy; override;
    function Connect: DWORD;
    function Disconnect: DWORD;
    function CheckConnetion: Boolean;
    property Connected: Boolean read FConnected;
    property OnConnect: TOnConnect read FOnConnect write FOnConnect;
    property OnDisconnect: TOnDisconnect read FOnDisconnect write FOnDisconnect;
    property OnError: TOnOnError read FOnError write FOnError;
  end;

  TCheckConnection = class(TThread)

  end;

implementation

{ TConnection }


function GetLastNetErrorMsg(var NetErrorCode: DWORD): string;
var
  NetError          : PChar;
  ProviderName      : PChar;
begin
  NetError := StrAlloc(1024);
  ProviderName := StrAlloc(100);
  WNetGetLastError(NetErrorCode, NetError, sizeof(NetError), ProviderName, 100);
  result := Format('Extended NetError [%d]: %s', [NetErrorCode, NetError]);
  StrDispose(NetError);
  StrDispose(ProviderName);
end;

function TConnection.CheckConnetion: Boolean;
var LRes: TNetResource; 
    LInfo: TNetConnectInfoStruct; 
begin 
  ZeroMemory(@LRes, SizeOf(LRes)); 
  LRes.lpLocalName := nil; 
  LRes.lpRemoteName := PChar(FUNCPath); 
  LInfo.cbStructure := SizeOf(LInfo);
  result := MultinetGetConnectionPerformance(@LRes, @LInfo) = NOERROR;
  FConnected := result;
end;

function TConnection.Connect: DWORD;
var
  NetResource       : TNetResource;
  dwFlags           : DWORD;
  err               : DWORD;
begin
  ZeroMemory(@NetResource, sizeof(TNetResource));
  with NetResource do
  begin
    dwType := RESOURCETYPE_DISK;
    lpLocalName := nil;
    lpRemoteName := PChar(FUNCPath);
    lpProvider := nil;
  end;

  dwFlags := CONNECT_UPDATE_PROFILE;

  err := WNetAddConnection2(NetResource, PChar(FPassword), PChar(FLogin), dwFlags);
  if err <> NO_ERROR then
  begin
    if Assigned(OnError) then
      FOnError(self, err, SysErrorMessage(err));
  end
  else
  begin
    FConnected := True;
    if Assigned(OnConnect) then
      FOnConnect(self);
  end;
  result := err;
end;

constructor TConnection.Create(const AUNCPath, ALogin, APassword: string);
begin
  inherited create;
  FUNCPath := AUNCPath;
  FLogin := ALogin;
  FPassword := APassword;
  FConnected := False;
end;

destructor TConnection.Destroy;
var
  err               : DWORD;
begin
  if FConnected then
  begin
    err := Disconnect;
    FConnected := err = 0;
  end;
  inherited;
end;

function TConnection.Disconnect: DWORD;
var
  err               : DWORD;
begin
  err := WNetCancelConnection2(PChar(FUNCPath), CONNECT_UPDATE_PROFILE, True);
  if err <> NO_ERROR then
  begin
    if Assigned(OnError) then
      FOnError(self, err, SysErrorMessage(err));
  end
  else
  begin
    FConnected := False;
    if Assigned(OnDisconnect) then
      FOnDisconnect(self);
  end;
  result := err;
end;

end.


