{*******************************************************}
{                                                       }
{       nrCommLib Communication Library for Delphi      }
{       WinFax service header                           }
{       Copyright (c) 1997-2011 Roman Novgorodov        }
{       v9.27                                           }
{       last update: 25 Apr 2006                        }
{                                                       }
{       e-mail:noro@deepsoftware.com                    }
{       DeepSoftware                                    }
{       http://www.deepsoftware.com/                    }
{                                                       }
{*******************************************************}
{$I nrcommlib.inc}
{$MINENUMSIZE 4}
unit nrfaxw32;
interface
uses windows;

Const

  FEI_DIALING                 =$00000001;
  FEI_SENDING                 =$00000002;
  FEI_RECEIVING               =$00000003;
  FEI_COMPLETED               =$00000004;
  FEI_BUSY                    =$00000005;
  FEI_NO_ANSWER               =$00000006;
  FEI_BAD_ADDRESS             =$00000007;
  FEI_NO_DIAL_TONE            =$00000008;
  FEI_DISCONNECTED            =$00000009;
  FEI_FATAL_ERROR             =$0000000a;
  FEI_NOT_FAX_CALL            =$0000000b;
  FEI_CALL_DELAYED            =$0000000c;
  FEI_CALL_BLACKLISTED        =$0000000d;
  FEI_RINGING                 =$0000000e;
  FEI_ABORTING                =$0000000f;
  FEI_ROUTING                 =$00000010;
  FEI_MODEM_POWERED_ON        =$00000011;
  FEI_MODEM_POWERED_OFF       =$00000012;
  FEI_IDLE                    =$00000013;
  FEI_FAXSVC_ENDED            =$00000014;
  FEI_ANSWERED                =$00000015;
  FEI_JOB_QUEUED              =$00000016;
  FEI_DELETED                 =$00000017;
  FEI_INITIALIZING            =$00000018;
  FEI_LINE_UNAVAILABLE        =$00000019;
  FEI_HANDLED                 =$0000001a;
  FEI_FAXSVC_STARTED          =$0000001b;
  FEI_NEVENTS                 =FEI_FAXSVC_STARTED;

  JT_UNKNOWN                  =0;
  JT_SEND                     =1;
  JT_RECEIVE                  =2;
  JT_ROUTING                  =3;
  JT_FAIL_RECEIVE             =4;

  JS_PENDING                  =$00000000;
  JS_INPROGRESS               =$00000001;
  JS_DELETING                 =$00000002;
  JS_FAILED                   =$00000004;
  JS_PAUSED                   =$00000008;
  JS_NOLINE                   =$00000010;
  JS_RETRYING                 =$00000020;
  JS_RETRIES_EXCEEDED         =$00000040;



Type
  FAX_PORT_INFO = packed record
    SizeOfStruct      :DWORD;       // size of this structure
    DeviceId          :DWORD;       // Device ID
    State             :DWORD;       // State of the device
    Flags             :DWORD;       // Device specific flags
    Rings             :DWORD;       // Number of rings before answer
    Priority          :DWORD;       // Device priority
    DeviceName        :PChar;       // Device name
    Tsid              :PChar;       // Device Tsid
    Csid              :PChar;       // Device Csid
  end;
  PFAX_PORT_INFO = ^FAX_PORT_INFO;


  FAX_JOB_PARAM = packed record
    SizeOfStruct        :DWORD;               // size of this structure
    RecipientNumber     :PChar;            // recipient fax number
    RecipientName       :PChar;              // recipient name
    Tsid                :PChar;               // transmitter's id
    SenderName          :PChar;               // sender name
    SenderCompany       :PChar;               // sender company
    SenderDept          :PChar;               // sender department
    BillingCode         :PChar;               // billing code
    ScheduleAction      :DWORD;               // when to schedule the fax, see JSA defines
    ScheduleTime        :TSYSTEMTIME;               // time to send the fax when JSA_SPECIFIC_TIME is used (must be local time)
    DeliveryReportType   :DWORD;         // delivery report type, see DRT defines
    DeliveryReportAddress : PChar;      // email address for delivery report (ndr or dr) thru MAPI / SMTP
    DocumentName        :PChar;               // document name (optional)
    CallHandle          :DWORD;                 // optional call handle
    Reserved:array [0..2]of pointer;                // reserved for ms use only
  end;
  PFAX_JOB_PARAM =^FAX_JOB_PARAM;

  FAX_COVERPAGE_INFO = packed record
    SizeOfStruct        :dword;              // Size of this structure
    CoverPageName       :PChar;              // coverpage document name
    UseServerCoverPage  :BOOL;               // coverpage exists on the fax server
    //
    // Recipient information
    //
    RecName              :PChar;      //
    RecFaxNumber         :PChar;      //
    RecCompany           :PChar;      //
    RecStreetAddress     :PChar;      //
    RecCity              :PChar;      //
    RecState             :PChar;      //
    RecZip               :PChar;      //
    RecCountry           :PChar;      //
    RecTitle             :PChar;      //
    RecDepartment        :PChar;      //
    RecOfficeLocation    :PChar;      //
    RecHomePhone         :PChar;      //
    RecOfficePhone       :PChar;      //
    //
    // Sender information
    //
    SdrName              :PChar;      //
    SdrFaxNumber         :PChar;      //
    SdrCompany           :PChar;      //
    SdrAddress           :PChar;      //
    SdrTitle             :PChar;      //
    SdrDepartment        :PChar;      //
    SdrOfficeLocation    :PChar;      //
    SdrHomePhone         :PChar;      //
    SdrOfficePhone       :PChar;      //
    //
    // Misc information
    //
    Note                :PChar;                    //
    Subject             :PChar;                    //
    TimeSent            :TSYSTEMTIME;                   // Time the fax was sent
    PageCount           :DWORD;                  // Number of pages
  end;

  PFAX_COVERPAGE_INFO = ^FAX_COVERPAGE_INFO;


  FAX_EVENT = packed record
    SizeOfStruct :DWORD;
    TimeStamp    :TFILETIME;
    DeviceId     :DWORD;
    EventId      :DWORD;
    JobId        :DWORD;
  end;

  PFAX_EVENT = ^FAX_EVENT;

  function FaxConnectFaxServer(MachineName:PChar;var FaxHandle:THandle):BOOL;
  function FaxClose(FaxHandle:THandle):BOOL;
  procedure FaxFreeBuffer(Buffer:pointer);
  function FaxEnumPorts(FaxHandle:longint;var PortInfo:PFAX_PORT_INFO;
           var PortsReturned:integer):BOOL;
  function FaxCompleteJobParams(var JobParams:PFAX_JOB_PARAM;
           var CoverpageInfo:PFAX_COVERPAGE_INFO):BOOL;
  function FaxAbort(FaxHandle:DWORD;JobId:DWORD):BOOL;
  function FaxSendDocument(FaxHandle:dword; FileName:PChar;
           JobParams:FAX_JOB_PARAM; CoverpageInfo:FAX_COVERPAGE_INFO;
           var FaxJobId:dword):BOOL;

  function FaxInitializeEventQueue(FaxHandle,CompletionPort:dword;
           CompletionKey:dword; hWnd,MessageStart:dword):BOOL;


implementation

// ===============================
// CfgMgr32 API ...

Var
  hWinFaxDLL:THandle=0;

Const
  winfaxdll='winfax.dll';

function AllocWinFaxDLL:boolean;
begin
  if hWinFaxDLL=0
    then hWinFaxDLL:=LoadLibrary(winfaxdll);
  Result:=(hWinFaxDLL<>0);
end;

function FaxConnectFaxServer(MachineName:PChar;var FaxHandle:THandle):BOOL;
var p:function (
  MachineName:PChar;var FaxHandle:THandle): BOOL; stdcall;
begin
  Result:=False;
  if not AllocWinFaxDLL then exit;
  @p:=GetProcAddress(hWinFaxDLL,'FaxConnectFaxServerA');
  if @p=nil then exit;
  Result:=p(MachineName,FaxHandle);
end;

function FaxClose(FaxHandle:THandle):BOOL;
var p:function (var FaxHandle:THandle): BOOL; stdcall;
begin
  Result:=False;
  if not AllocWinFaxDLL then exit;
  @p:=GetProcAddress(hWinFaxDLL,'FaxClose');
  if @p=nil then exit;
  Result:=p(FaxHandle);
end;

procedure FaxFreeBuffer(Buffer:pointer);
var p:procedure (Buffer:pointer); stdcall;
begin
  if not AllocWinFaxDLL then exit;
  @p:=GetProcAddress(hWinFaxDLL,'FaxFreeBuffer');
  if @p=nil then exit;
  p(Buffer);
end;

function FaxEnumPorts(FaxHandle:longint;var PortInfo:PFAX_PORT_INFO;
           var PortsReturned:integer):BOOL;
var p:function (FaxHandle:longint;var PortInfo:PFAX_PORT_INFO;
           var PortsReturned:integer): BOOL; stdcall;
begin
  Result:=False;
  if not AllocWinFaxDLL then exit;
  @p:=GetProcAddress(hWinFaxDLL,'FaxEnumPortsA');
  if @p=nil then exit;
  Result:=p(FaxHandle,PortInfo,PortsReturned);
end;

function FaxCompleteJobParams(var JobParams:PFAX_JOB_PARAM;
           var CoverpageInfo:PFAX_COVERPAGE_INFO):BOOL;
var p:function (var JobParams:PFAX_JOB_PARAM;
           var CoverpageInfo:PFAX_COVERPAGE_INFO): BOOL; stdcall;
begin
  Result:=False;
  if not AllocWinFaxDLL then exit;
  @p:=GetProcAddress(hWinFaxDLL,'FaxCompleteJobParamsA');
  if @p=nil then exit;
  Result:=p(JobParams,CoverpageInfo);
end;

function FaxAbort(FaxHandle:dword;JobId:DWORD):BOOL;
var p:function (FaxHandle:dword;JobId:DWORD): BOOL; stdcall;
begin
  Result:=False;
  if not AllocWinFaxDLL then exit;
  @p:=GetProcAddress(hWinFaxDLL,'FaxAbort');
  if @p=nil then exit;
  Result:=p(FaxHandle,JobId);
end;

function FaxSendDocument(FaxHandle:dword; FileName:PChar;
           JobParams:FAX_JOB_PARAM; CoverpageInfo:FAX_COVERPAGE_INFO;
           var FaxJobId:dword):BOOL;
var p:function (FaxHandle:dword; FileName:PChar;
           JobParams:FAX_JOB_PARAM; CoverpageInfo:FAX_COVERPAGE_INFO;
           var FaxJobId:dword): BOOL; stdcall;
begin
  Result:=False;
  if not AllocWinFaxDLL then exit;
  @p:=GetProcAddress(hWinFaxDLL,'FaxSendDocumentA');
  if @p=nil then exit;
  Result:=p(FaxHandle,FileName,JobParams,CoverpageInfo,FaxJobId);
end;

function FaxInitializeEventQueue(FaxHandle,CompletionPort:dword;
           CompletionKey:dword; hWnd,MessageStart:dword):BOOL;
var p:function (FaxHandle,CompletionPort:dword;
           CompletionKey:dword; hWnd,MessageStart:dword): BOOL; stdcall;
begin
  Result:=False;
  if not AllocWinFaxDLL then exit;
  @p:=GetProcAddress(hWinFaxDLL,'FaxInitializeEventQueue');
  if @p=nil then exit;
  Result:=p(FaxHandle,CompletionPort,CompletionKey,hWnd,MessageStart);
end;


initialization

finalization
  if hWinFaxDLL<>0 then FreeLibrary(hWinFaxDLL);

end.
