Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

TAPI Experiments


  • Please log in to reply
5 replies to this topic
DeadLock
  • Members
  • 86 posts
  • Last active:
  • Joined: 10 Jul 2013

I'm currently experimenting with the TAPI (theTelephony Application Programming Interfaces).

There are two major versions:

  • 2.x a C-programming language based API
  • 3.x a COM-based API

Most of the examples i found, are for TAPI 3.x, and most of the 2.x examples utilize some additional (wrapper-)libraries. So it's complicated for me, to even graps the basics.

 

Right now, i have (probably) managed to correctly initialize the TAPI 2.x .

#NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.
#Warn  ; Recommended for catching common errors.
SendMode Input  ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir%  ; Ensures a consistent starting directory.
#Persistent

; Declaring Constants
NULL =
LINEINITIALIZEEXOPTION_USEHIDDENWINDOW := 0x1
; End-Declaring Constants

;Init TAPI - TAPI32\lineInitializeEx

; Preparing Vars for In/Out communication with DllCalled Function


; a location that is filled with the application's usage handle for TAPI.
VarSetCapacity(lphLineApp, 4)

; Address of a callback function that is invoked to determine status and events on the line device
callback := RegisterCallback("lineCallback",, 6)

; this location is filled with the number of line devices available to the application.
VarSetCapacity(lpdwNumDevs, 4)

;The application must initialize this DWORD, before calling this function, to the highest API version it is designed to support
;on completion of this request, this location is filled with the highest API version supported by TAPI
lpdwAPIVersion := 0x00020002

; a structure of type LINEINITIALIZEEXPARAMS containing additional parameters
;  Creating structure
VarSetCapacity(LINEINITIZALIZEEXPARAMS, 24, 0)
; typedef struct lineinitializeexparams_tag {
    NumPut(24, LINEINITIZALIZEEXPARAMS, 0, "UInt")
    NumPut(24, LINEINITIZALIZEEXPARAMS, 4, "UInt")
    NumPut(24, LINEINITIZALIZEEXPARAMS, 8, "UInt")
	; Before calling lineInitializeEx the application is expected to set this member(dwOptions) to one of the LINEINITIALIZEEXOPTION_ constants.
    NumPut(LINEINITIALIZEEXOPTION_USEHIDDENWINDOW, LINEINITIZALIZEEXPARAMS, 12, "UInt")
    ; union {
        NumPut(0, LINEINITIZALIZEEXPARAMS, 16, "UInt")
        NumPut(0, LINEINITIZALIZEEXPARAMS, 16, "UInt")
    ; }
    NumPut(0, LINEINITIZALIZEEXPARAMS, 20, "UInt")
; }
;  End-Creating structure

;Load the TAPI Library into Memory
hModule := DllCall("LoadLibrary", "Str", "TAPI32.dll", "Ptr")

;Init TAPI
initTAPI := DllCall("TAPI32\lineInitializeEx", "UInt", &lphLineApp, "UInt", NULL, "UInt", callback, "UInt", NULL, "UInt", &lpdwNumDevs, "UInt", &lpdwAPIVersion, "UInt", &LINEINITIZALIZEEXPARAMS)
;End-Init TAPI - TAPI32\lineInitializeEx

Lines := NumGet(lpdwNumDevs,,"UInt") 
ListVars
MsgBox

lineCallback(dwDeviceID,  dwMessage,  dwInstance,  dwParam1,  dwParam2,  dwParam3)
{
	ListVars
}

Comments, Tips, Ideas, Codes are all very welcome.

Cheers Dead.Lock



DeadLock
  • Members
  • 86 posts
  • Last active:
  • Joined: 10 Jul 2013

Some useful resources

 

The TAPI 2.2 reference:

http://msdn.microsof...9(v=vs.85).aspx

 

MS-Guidelines for TAPI Applications:

http://msdn.microsof...3(v=vs.85).aspx

 

A nice explanation about initializing the TAPI via lineInitializeEx:

https://web.archive....i/initTapi.html

 

A TAPI Overview, explaining the basic concepts:

http://www.gtro.com/delphi/tapi_e.php



DeadLock
  • Members
  • 86 posts
  • Last active:
  • Joined: 10 Jul 2013

The Next Step: Enumerating the usable Line-Devices

#NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.
#Warn  ; Recommended for catching common errors.
SendMode Input  ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir%  ; Ensures a consistent starting directory.
#Persistent

; Declaring Constants
NULL =
LINEINITIALIZEEXOPTION_USEHIDDENWINDOW := 0x1
; End-Declaring Constants

;Init TAPI - TAPI32\lineInitializeEx

; Preparing Vars for In/Out communication with DllCalled Function


; a location that is filled with the application's usage handle for TAPI.
VarSetCapacity(lphLineApp, 4)

; Address of a callback function that is invoked to determine status and events on the line device
callback := RegisterCallback("lineCallback",, 6)

; this location is filled with the number of line devices available to the application.
VarSetCapacity(lpdwNumDevs, 4)

;The application must initialize this DWORD, before calling this function, to the highest API version it is designed to support
;on completion of this request, this location is filled with the highest API version supported by TAPI
; TAPI 2.2 is 0x00020002
VarSetCapacity(lpdwAPIVersion, 4)
NumPut(0x20002, lpdwAPIVersion, 0, "UInt")

; a structure of type LINEINITIALIZEEXPARAMS containing additional parameters
;  Creating structure
VarSetCapacity(LINEINITIZALIZEEXPARAMS, 24, 0)
; typedef struct lineinitializeexparams_tag {
    NumPut(24, LINEINITIZALIZEEXPARAMS, 0, "UInt")
    NumPut(24, LINEINITIZALIZEEXPARAMS, 4, "UInt")
    NumPut(24, LINEINITIZALIZEEXPARAMS, 8, "UInt")
	; Before calling lineInitializeEx the application is expected to set this member(dwOptions) to one of the LINEINITIALIZEEXOPTION_ constants.
    NumPut(LINEINITIALIZEEXOPTION_USEHIDDENWINDOW, LINEINITIZALIZEEXPARAMS, 12, "UInt")
    ; union {
        NumPut(0, LINEINITIZALIZEEXPARAMS, 16, "UInt")
        NumPut(0, LINEINITIZALIZEEXPARAMS, 16, "UInt")
    ; }
    NumPut(0, LINEINITIZALIZEEXPARAMS, 20, "UInt")
; }
;  End-Creating structure

;Load the TAPI Library into Memory
hModule := DllCall("LoadLibrary", "Str", "TAPI32.dll", "Ptr")

;Init TAPI
initTAPI := DllCall("TAPI32\lineInitializeEx", "UInt", &lphLineApp, "UInt", NULL, "UInt", callback, "UInt", NULL, "UInt", &lpdwNumDevs, "UInt", &lpdwAPIVersion, "UInt", &LINEINITIZALIZEEXPARAMS)
;End-Init TAPI - TAPI32\lineInitializeEx

; Show some Vars
Lines := NumGet(lpdwNumDevs,,"UInt")
MaxTAPIVersion := NumGet(lpdwAPIVersion,,"UInt")
Handle2LineApp := NumGet(lphLineApp,,"UInt")

; Convert a decimal integer to hexadecimal:
SetFormat, IntegerFast, hex
MaxTAPIVersion += 0  
MaxTAPIVersion .= ""  ; Necessary due to the "fast" mode.
SetFormat, IntegerFast, d
ListVars
MsgBox , Handle: %Handle2LineApp% - MaxTAPIVers.: %MaxTAPIVersion% - Lines: %Lines%

Loop , %Lines%
{
; Query TAPI-Lines
CurrLine := A_Index - 1 ; the queried Line Device
; Negotiating TAPI Versions per Line-Device
; Preparing Vars for In/Out communication with DllCalled Function
; the application's usage handle for TAPI. already retrieved as Handle2LineApp
; dwDeviceID : a number between 0 and the number of Lines - 1
dwDeviceID := CurrLine ; 0 is the first line
; dwAPILowVersion and dwAPIHighVersion , the min. and max. TAPI version supported. here 2.0 and 2.2
dwAPILowVersion := 0x20000
dwAPIHighVersion := 0x20002
; dwAPIVersion will be filled with the negotiated API version for this line
VarSetCapacity(dwAPIVersion, 4, 0)
; ExtensionID : a structure not used here, just create and ignore
VarSetCapacity(ExtensionID, 16, 0)
; call lineNegotiateAPIVersion
nRes := DllCall("TAPI32\lineNegotiateAPIVersion", "UInt", Handle2LineApp, "UInt", dwDeviceID, "UInt", dwAPILowVersion, "UInt", dwAPIHighVersion, "UInt", &dwAPIVersion, "UInt", &ExtensionID)
; End - Negotiating TAPI Versions per Line-Device

; Show some Vars
;Transform Error-Message to match SKAN's diction. see Error values below
VarSetCapacity(swapRes, 4, 0)
NumPut(nRes, swapRes, 0, "Int")
gnRes := NumGet(swapRes,,"UInt")
LineAPIVer := NumGet(dwAPIVersion,,"UInt")
; End - Tranform Error-Messages

SetFormat, IntegerFast, hex
nRes += 0  
nRes .= ""  ; Necessary due to the "fast" mode.
gnRes += 0  
gnRes .= ""  ; Necessary due to the "fast" mode.
LineAPIVer += 0  
LineAPIVer .= ""  ; Necessary due to the "fast" mode.
SetFormat, IntegerFast, d

ListVars 
if (nRes != 0)
    continue

; lineGetDevCaps
; prepare LINEDEVCAPS structure
VarSetCapacity(LINEDEVCAPS, 292, 0)
NumPut(292, LINEDEVCAPS, 0, "UInt")

Loop
{
    DevRes := DllCall("TAPI32\lineGetDevCaps", "UInt", Handle2LineApp, "UInt", dwDeviceID, "UInt", LineAPIVer, "UInt", 0, "UInt", &LINEDEVCAPS)
    LINEDEVCAPS_dwTotalSize := NumGet(LINEDEVCAPS, 0, "UInt")
    LINEDEVCAPS_dwNeededSize := NumGet(LINEDEVCAPS, 4, "UInt")
    if (LINEDEVCAPS_dwTotalSize >= LINEDEVCAPS_dwNeededSize)
        break
    VarSetCapacity(LINEDEVCAPS, LINEDEVCAPS_dwNeededSize, 0)
    NumPut(LINEDEVCAPS_dwNeededSize, LINEDEVCAPS, 0, "UInt")
}
 LINEDEVCAPS_LineNameSize := NumGet(LINEDEVCAPS, 32, "UInt")
 LINEDEVCAPS_LineNameOffset := NumGet(LINEDEVCAPS, 36, "UInt")
 LineName =
 loop, %LINEDEVCAPS_LineNameSize%
{
    MyByte := NumGet(LINEDEVCAPS, LINEDEVCAPS_LineNameOffset + A_Index - 1, "UChar")
    LineName .= Chr(MyByte)
}
 
;Transform Error-Message to match SKAN's diction. see Error values below
VarSetCapacity(swapRes, 4, 0)
NumPut(DevRes, swapRes, 0, "Int")
gDevRes := NumGet(swapRes,,"UInt")
SetFormat, IntegerFast, hex
gDevRes += 0  
gDevRes .= ""  ; Necessary due to the "fast" mode.
SetFormat, IntegerFast, d
ListVars
MsgBox , Line: %CurrLine% - API Ver: %LineAPIVer% - LineName: %LineName%

; nag Buster
if (A_Index > 10)
    break
}

return
lineCallback(dwDeviceID,  dwMessage,  dwInstance,  dwParam1,  dwParam2,  dwParam3)
{
	ListVars
}

/* ; Error Constants
 * LINEERR_BADDEVICEID := 0x80000002
 * LINEERR_NODRIVER := 0x80000043
 * LINEERR_INCOMPATIBLEAPIVERSION := 0x8000000C
 * LINEERR_OPERATIONFAILED := 0x80000048
 * LINEERR_INVALAPPHANDLE := 0x80000014
 * LINEERR_RESOURCEUNAVAIL := 0x8000004B
 * LINEERR_INVALPOINTER := 0x80000035
 * LINEERR_UNINITIALIZED := 0x80000050
 * LINEERR_NOMEM := 0x80000044
 * LINEERR_OPERATIONUNAVAIL := 0x80000049
 * LINEERR_NODEVICE := 0x80000042
 * LINEERR_STRUCTURETOOSMALL := 0x8000004D
 */



DeadLock
  • Members
  • 86 posts
  • Last active:
  • Joined: 10 Jul 2013

Another Step: Receiving Status-Messages for all compatible Lines

#NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.
#Warn  ; Recommended for catching common errors.
SendMode Input  ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir%  ; Ensures a consistent starting directory.
#Persistent

; Declaring Constants
NULL =
LINEINITIALIZEEXOPTION_USEHIDDENWINDOW := 0x1
LineLog =
; End-Declaring Constants

;Init TAPI - TAPI32\lineInitializeEx

; Preparing Vars for In/Out communication with DllCalled Function


; a location that is filled with the application's usage handle for TAPI.
VarSetCapacity(lphLineApp, 4)

; Address of a callback function that is invoked to determine status and events on the line device
callback := RegisterCallback("lineCallback",, 6)

; this location is filled with the number of line devices available to the application.
VarSetCapacity(lpdwNumDevs, 4)

;The application must initialize this DWORD, before calling this function, to the highest API version it is designed to support
;on completion of this request, this location is filled with the highest API version supported by TAPI
; TAPI 2.2 is 0x00020002
VarSetCapacity(lpdwAPIVersion, 4)
NumPut(0x20002, lpdwAPIVersion, 0, "UInt")

; a structure of type LINEINITIALIZEEXPARAMS containing additional parameters
;  Creating structure
VarSetCapacity(LINEINITIZALIZEEXPARAMS, 24, 0)
; typedef struct lineinitializeexparams_tag {
    NumPut(24, LINEINITIZALIZEEXPARAMS, 0, "UInt")
    NumPut(24, LINEINITIZALIZEEXPARAMS, 4, "UInt")
    NumPut(24, LINEINITIZALIZEEXPARAMS, 8, "UInt")
	; Before calling lineInitializeEx the application is expected to set this member(dwOptions) to one of the LINEINITIALIZEEXOPTION_ constants.
    NumPut(LINEINITIALIZEEXOPTION_USEHIDDENWINDOW, LINEINITIZALIZEEXPARAMS, 12, "UInt")
    ; union {
        NumPut(0, LINEINITIZALIZEEXPARAMS, 16, "UInt")
        NumPut(0, LINEINITIZALIZEEXPARAMS, 16, "UInt")
    ; }
    NumPut(0, LINEINITIZALIZEEXPARAMS, 20, "UInt")
; }
;  End-Creating structure

;Load the TAPI Library into Memory
hModule := DllCall("LoadLibrary", "Str", "TAPI32.dll", "Ptr")

;Init TAPI
initTAPI := DllCall("TAPI32\lineInitializeEx", "UInt", &lphLineApp, "UInt", NULL, "UInt", callback, "UInt", NULL, "UInt", &lpdwNumDevs, "UInt", &lpdwAPIVersion, "UInt", &LINEINITIZALIZEEXPARAMS)
;End-Init TAPI - TAPI32\lineInitializeEx

; Show some Vars
Lines := NumGet(lpdwNumDevs,,"UInt")
MaxTAPIVersion := NumGet(lpdwAPIVersion,,"UInt")
Handle2LineApp := NumGet(lphLineApp,,"UInt")

; Convert a decimal integer to hexadecimal:
SetFormat, IntegerFast, hex
MaxTAPIVersion += 0  
MaxTAPIVersion .= ""  ; Necessary due to the "fast" mode.
SetFormat, IntegerFast, d
ListVars
MsgBox , Handle: %Handle2LineApp% - MaxTAPIVers.: %MaxTAPIVersion% - Lines: %Lines%

Loop , %Lines%
{
; Query TAPI-Lines
CurrLine := A_Index - 1 ; the queried Line Device
; Negotiating TAPI Versions per Line-Device
; Preparing Vars for In/Out communication with DllCalled Function
; the application's usage handle for TAPI. already retrieved as Handle2LineApp
; dwDeviceID : a number between 0 and the number of Lines - 1
dwDeviceID := CurrLine ; 0 is the first line
; dwAPILowVersion and dwAPIHighVersion , the min. and max. TAPI version supported. here 2.0 and 2.2
dwAPILowVersion := 0x20000
dwAPIHighVersion := 0x20002
; dwAPIVersion will be filled with the negotiated API version for this line
VarSetCapacity(dwAPIVersion, 4, 0)
; ExtensionID : a structure not used here, just create and ignore
VarSetCapacity(ExtensionID, 16, 0)
; call lineNegotiateAPIVersion
nRes := DllCall("TAPI32\lineNegotiateAPIVersion", "UInt", Handle2LineApp, "UInt", dwDeviceID, "UInt", dwAPILowVersion, "UInt", dwAPIHighVersion, "UInt", &dwAPIVersion, "UInt", &ExtensionID)
; End - Negotiating TAPI Versions per Line-Device

; Show some Vars
;Transform Error-Message to match SKAN's diction. see Error values below
VarSetCapacity(swapRes, 4, 0)
NumPut(nRes, swapRes, 0, "Int")
gnRes := NumGet(swapRes,,"UInt")
LineAPIVer := NumGet(dwAPIVersion,,"UInt")
; End - Tranform Error-Messages

SetFormat, IntegerFast, hex
nRes += 0  
nRes .= ""  ; Necessary due to the "fast" mode.
gnRes += 0  
gnRes .= ""  ; Necessary due to the "fast" mode.
LineAPIVer += 0  
LineAPIVer .= ""  ; Necessary due to the "fast" mode.
SetFormat, IntegerFast, d

ListVars 
if (nRes != 0)
    continue

; lineGetDevCaps
; prepare LINEDEVCAPS structure
VarSetCapacity(LINEDEVCAPS, 292, 0)
NumPut(292, LINEDEVCAPS, 0, "UInt")

Loop
{
    DevRes := DllCall("TAPI32\lineGetDevCaps", "UInt", Handle2LineApp, "UInt", dwDeviceID, "UInt", LineAPIVer, "UInt", 0, "UInt", &LINEDEVCAPS)
    LINEDEVCAPS_dwTotalSize := NumGet(LINEDEVCAPS, 0, "UInt")
    LINEDEVCAPS_dwNeededSize := NumGet(LINEDEVCAPS, 4, "UInt")
    if (LINEDEVCAPS_dwTotalSize >= LINEDEVCAPS_dwNeededSize)
        break
    VarSetCapacity(LINEDEVCAPS, LINEDEVCAPS_dwNeededSize, 0)
    NumPut(LINEDEVCAPS_dwNeededSize, LINEDEVCAPS, 0, "UInt")
}
 LINEDEVCAPS_LineNameSize := NumGet(LINEDEVCAPS, 32, "UInt")
 LINEDEVCAPS_LineNameOffset := NumGet(LINEDEVCAPS, 36, "UInt")
 LineName =
 loop, %LINEDEVCAPS_LineNameSize%
{
    MyByte := NumGet(LINEDEVCAPS, LINEDEVCAPS_LineNameOffset + A_Index - 1, "UChar")
    LineName .= Chr(MyByte)
}
 
;Transform Error-Message to match SKAN's diction. see Error values below
VarSetCapacity(swapRes, 4, 0)
NumPut(DevRes, swapRes, 0, "Int")
gDevRes := NumGet(swapRes,,"UInt")
SetFormat, IntegerFast, hex
gDevRes += 0  
gDevRes .= ""  ; Necessary due to the "fast" mode.
SetFormat, IntegerFast, d



; Open TAPI Lines for monitoring
; prepare some vars
VarSetCapacity(lphLine, 4, 0)
LineCallbackData := "Line " . dwDeviceID
LINECALLPRIVILEGE_MONITOR := 0x2
; lineOpen : open line for monitoring
nRes := DllCall("TAPI32\lineOpen", "UInt", Handle2LineApp, "UInt", dwDeviceID, "UInt", &lphLine, "UInt", LineAPIVer, "UInt", 0, "UInt", &LineCallbackData, "UInt", LINECALLPRIVILEGE_MONITOR, "UInt", 0, "UInt", 0)

;Transform Error-Message to match SKAN's diction. see Error values below
VarSetCapacity(swapRes, 4, 0)
NumPut(nRes, swapRes, 0, "Int")
gnRes := NumGet(swapRes,,"UInt")
SetFormat, IntegerFast, hex
gnRes += 0  
gnRes .= ""  ; Necessary due to the "fast" mode.
SetFormat, IntegerFast, d

LineHandle := NumGet(lphLine,,"UInt")
LineLog .= "Line:" . CurrLine . " - API Ver: " . LineAPIVer . " - LineName: " . LineName . " - LineHandle: " . LineHandle . " - SuccessOpen: " . gnRes . "`n"
ListVars
}
MsgBox , %LineLog%
Gui, Add, Edit, r10 w800 vMessageContent
Gui, Show
MessageOut =
return

lineCallback(dwDeviceID,  dwMessage,  dwInstance,  dwParam1,  dwParam2,  dwParam3)
{
	global MessageOut
    NextLine := "DeviceID: " . dwDeviceID . " - Message: " . dwMessage . " - Instance: " . dwInstance . " - Param1: " . dwParam1 . " - Param2: " . dwParam2 . " - Param3: " . dwParam3 . "`n"
    MessageOut .= NextLine
    GuiControl, , MessageContent , %MessageOut% 
}



DeadLock
  • Members
  • 86 posts
  • Last active:
  • Joined: 10 Jul 2013

Another Step: Gathering the CallerID for all Calls

#NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.
#Warn  ; Recommended for catching common errors.
SendMode Input  ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir%  ; Ensures a consistent starting directory.
#Persistent

; Declaring Constants
NULL =
LINEINITIALIZEEXOPTION_USEHIDDENWINDOW := 0x1
LineLog =
; End-Declaring Constants

;Init TAPI - TAPI32\lineInitializeEx

; Preparing Vars for In/Out communication with DllCalled Function


; a location that is filled with the application's usage handle for TAPI.
VarSetCapacity(lphLineApp, 4)

; Address of a callback function that is invoked to determine status and events on the line device
callback := RegisterCallback("lineCallback",, 6)

; this location is filled with the number of line devices available to the application.
VarSetCapacity(lpdwNumDevs, 4)

;The application must initialize this DWORD, before calling this function, to the highest API version it is designed to support
;on completion of this request, this location is filled with the highest API version supported by TAPI
; TAPI 2.2 is 0x00020002
VarSetCapacity(lpdwAPIVersion, 4)
NumPut(0x20002, lpdwAPIVersion, 0, "UInt")

; a structure of type LINEINITIALIZEEXPARAMS containing additional parameters
;  Creating structure
VarSetCapacity(LINEINITIZALIZEEXPARAMS, 24, 0)
; typedef struct lineinitializeexparams_tag {
    NumPut(24, LINEINITIZALIZEEXPARAMS, 0, "UInt")
    NumPut(24, LINEINITIZALIZEEXPARAMS, 4, "UInt")
    NumPut(24, LINEINITIZALIZEEXPARAMS, 8, "UInt")
	; Before calling lineInitializeEx the application is expected to set this member(dwOptions) to one of the LINEINITIALIZEEXOPTION_ constants.
    NumPut(LINEINITIALIZEEXOPTION_USEHIDDENWINDOW, LINEINITIZALIZEEXPARAMS, 12, "UInt")
    ; union {
        NumPut(0, LINEINITIZALIZEEXPARAMS, 16, "UInt")
        NumPut(0, LINEINITIZALIZEEXPARAMS, 16, "UInt")
    ; }
    NumPut(0, LINEINITIZALIZEEXPARAMS, 20, "UInt")
; }
;  End-Creating structure

;Load the TAPI Library into Memory
hModule := DllCall("LoadLibrary", "Str", "TAPI32.dll", "Ptr")

;Init TAPI
initTAPI := DllCall("TAPI32\lineInitializeEx", "UInt", &lphLineApp, "UInt", NULL, "UInt", callback, "UInt", NULL, "UInt", &lpdwNumDevs, "UInt", &lpdwAPIVersion, "UInt", &LINEINITIZALIZEEXPARAMS)
;End-Init TAPI - TAPI32\lineInitializeEx

; Show some Vars
Lines := NumGet(lpdwNumDevs,,"UInt")
MaxTAPIVersion := NumGet(lpdwAPIVersion,,"UInt")
Handle2LineApp := NumGet(lphLineApp,,"UInt")

; Convert a decimal integer to hexadecimal:
SetFormat, IntegerFast, hex
MaxTAPIVersion += 0  
MaxTAPIVersion .= ""  ; Necessary due to the "fast" mode.
SetFormat, IntegerFast, d
ListVars
MsgBox , Handle: %Handle2LineApp% - MaxTAPIVers.: %MaxTAPIVersion% - Lines: %Lines%

Loop , %Lines%
{
; Query TAPI-Lines
CurrLine := A_Index - 1 ; the queried Line Device
; Negotiating TAPI Versions per Line-Device
; Preparing Vars for In/Out communication with DllCalled Function
; the application's usage handle for TAPI. already retrieved as Handle2LineApp
; dwDeviceID : a number between 0 and the number of Lines - 1
dwDeviceID := CurrLine ; 0 is the first line
; dwAPILowVersion and dwAPIHighVersion , the min. and max. TAPI version supported. here 2.0 and 2.2
dwAPILowVersion := 0x20000
dwAPIHighVersion := 0x20002
; dwAPIVersion will be filled with the negotiated API version for this line
VarSetCapacity(dwAPIVersion, 4, 0)
; ExtensionID : a structure not used here, just create and ignore
VarSetCapacity(ExtensionID, 16, 0)
; call lineNegotiateAPIVersion
nRes := DllCall("TAPI32\lineNegotiateAPIVersion", "UInt", Handle2LineApp, "UInt", dwDeviceID, "UInt", dwAPILowVersion, "UInt", dwAPIHighVersion, "UInt", &dwAPIVersion, "UInt", &ExtensionID)
; End - Negotiating TAPI Versions per Line-Device

; Show some Vars
;Transform Error-Message to match SKAN's diction. see Error values below
VarSetCapacity(swapRes, 4, 0)
NumPut(nRes, swapRes, 0, "Int")
gnRes := NumGet(swapRes,,"UInt")
LineAPIVer := NumGet(dwAPIVersion,,"UInt")
; End - Tranform Error-Messages

SetFormat, IntegerFast, hex
nRes += 0  
nRes .= ""  ; Necessary due to the "fast" mode.
gnRes += 0  
gnRes .= ""  ; Necessary due to the "fast" mode.
LineAPIVer += 0  
LineAPIVer .= ""  ; Necessary due to the "fast" mode.
SetFormat, IntegerFast, d

ListVars 
if (nRes != 0)
    continue

; lineGetDevCaps
; prepare LINEDEVCAPS structure
VarSetCapacity(LINEDEVCAPS, 292, 0)
NumPut(292, LINEDEVCAPS, 0, "UInt")

Loop
{
    DevRes := DllCall("TAPI32\lineGetDevCaps", "UInt", Handle2LineApp, "UInt", dwDeviceID, "UInt", LineAPIVer, "UInt", 0, "UInt", &LINEDEVCAPS)
    LINEDEVCAPS_dwTotalSize := NumGet(LINEDEVCAPS, 0, "UInt")
    LINEDEVCAPS_dwNeededSize := NumGet(LINEDEVCAPS, 4, "UInt")
    if (LINEDEVCAPS_dwTotalSize >= LINEDEVCAPS_dwNeededSize)
        break
    VarSetCapacity(LINEDEVCAPS, LINEDEVCAPS_dwNeededSize, 0)
    NumPut(LINEDEVCAPS_dwNeededSize, LINEDEVCAPS, 0, "UInt")
}
 LINEDEVCAPS_LineNameSize := NumGet(LINEDEVCAPS, 32, "UInt")
 LINEDEVCAPS_LineNameOffset := NumGet(LINEDEVCAPS, 36, "UInt")
 LineName =
 loop, %LINEDEVCAPS_LineNameSize%
{
    MyByte := NumGet(LINEDEVCAPS, LINEDEVCAPS_LineNameOffset + A_Index - 1, "UChar")
    LineName .= Chr(MyByte)
}
 
;Transform Error-Message to match SKAN's diction. see Error values below
VarSetCapacity(swapRes, 4, 0)
NumPut(DevRes, swapRes, 0, "Int")
gDevRes := NumGet(swapRes,,"UInt")
SetFormat, IntegerFast, hex
gDevRes += 0  
gDevRes .= ""  ; Necessary due to the "fast" mode.
SetFormat, IntegerFast, d



; Open TAPI Lines for monitoring
; prepare some vars
VarSetCapacity(lphLine, 4, 0)
LineCallbackData := "Line " . dwDeviceID
; LINECALLPRIVILEGE_MONITOR : get notifications for the line, don't owns it
LINECALLPRIVILEGE_MONITOR := 0x2
; lineOpen : open line for monitoring
nRes := DllCall("TAPI32\lineOpen", "UInt", Handle2LineApp, "UInt", dwDeviceID, "UInt", &lphLine, "UInt", LineAPIVer, "UInt", 0, "UInt", &LineCallbackData, "UInt", LINECALLPRIVILEGE_MONITOR, "UInt", 0, "UInt", 0)

;Transform Error-Message to match SKAN's diction. see Error values below
VarSetCapacity(swapRes, 4, 0)
NumPut(nRes, swapRes, 0, "Int")
gnRes := NumGet(swapRes,,"UInt")
SetFormat, IntegerFast, hex
gnRes += 0  
gnRes .= ""  ; Necessary due to the "fast" mode.
SetFormat, IntegerFast, d

LineHandle := NumGet(lphLine,,"UInt")
LineLog .= "Line:" . CurrLine . " - API Ver: " . LineAPIVer . " - LineName: " . LineName . " - LineHandle: " . LineHandle . " - SuccessOpen: " . gnRes . "`n"
ListVars
}
MsgBox , %LineLog%
Gui, Add, Edit, r10 w800 vMessageContent
Gui, Add, Edit, r10 w800 vMessageContentRaw
Gui, Show
MessageOut =
MessageOutRaw =
NewCalls =
MonitoredCalls := Object()

return

; the callback function will return all messages from the opened lines
; referenced in lineInitializeEx
lineCallback(dwDeviceID,  dwMessage,  dwInstance,  dwParam1,  dwParam2,  dwParam3)
{
	global NewCalls, MessageOutRaw
    LINE_CALLINFO := 1
    LINE_CALLSTATE := 2
    LINECALLINFOSTATE_CALLERID := 0x8000
    
    if ((dwMessage = LINE_CALLINFO) && (dwParam1 & LINECALLINFOSTATE_CALLERID = LINECALLINFOSTATE_CALLERID))
    {
        ; lineGetCallInfo
        ; prepare LINECALLINFO structure
        VarSetCapacity(LINECALLINFO, 344, 0)
        NumPut(344, LINECALLINFO, 0, "UInt")
        loop
        {
        lgiRes := DllCall("TAPI32\lineGetCallInfo", "UInt", dwDeviceID, "UInt", &LINECALLINFO)
        LINECALLINFO_dwTotalSize := NumGet(LINECALLINFO, 0, "UInt")
        LINECALLINFO_dwNeededSize := NumGet(LINECALLINFO, 4, "UInt")
        if (LINECALLINFO_dwTotalSize >= LINECALLINFO_dwNeededSize)
            break
        VarSetCapacity(LINECALLINFO, LINECALLINFO_dwNeededSize, 0)
        NumPut(LINECALLINFO_dwNeededSize, LINECALLINFO, 0, "UInt")
        }
        LINECALLINFO_dwOrigin := NumGet(LINECALLINFO, 80, "UInt")
        LINECALLINFO_dwCallerIDFlags := NumGet(LINECALLINFO, 108, "UInt")
        LINECALLINFO_dwCallerIDSize := NumGet(LINECALLINFO, 112, "UInt")
        LINECALLINFO_dwCallerIDOffset := NumGet(LINECALLINFO, 116, "UInt")
         CallerID =
        loop, %LINECALLINFO_dwCallerIDSize%
        {
            CIDMyByte := NumGet(LINECALLINFO, LINECALLINFO_dwCallerIDOffset + A_Index - 1, "UChar")
            CallerID .= Chr(CIDMyByte)
        }
        NextCall := "Handle: " . dwDeviceID . A_Tab . "Origin: " . LINECALLINFO_dwOrigin . A_Tab . "Flags: " . LINECALLINFO_dwCallerIDFlags . A_Tab . "CallerID: " . CallerID . "`n"
        NewCalls .= NextCall
        GuiControl, , MessageContent , %NewCalls%
        ListVars
    }
    
    NextLine := "DeviceID: " . dwDeviceID . A_Tab . "- Message: " . dwMessage . A_Tab . "- Instance: " . dwInstance . A_Tab . "- Param1: " . dwParam1 . A_Tab . "- Param2: " . dwParam2 . A_Tab . "- Param3: " . dwParam3 . "`n"
    MessageOutRaw .= NextLine
    GuiControl, , MessageContentRaw , %MessageOutRaw% 
}



DeadLock
  • Members
  • 86 posts
  • Last active:
  • Joined: 10 Jul 2013

The Final Step: a working CallerID Monitor

#NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.
#Warn  ; Recommended for catching common errors.
SendMode Input  ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir%  ; Ensures a consistent starting directory.
#Persistent

; Declaring Constants
NULL =
LINEINITIALIZEEXOPTION_USEHIDDENWINDOW := 0x1
LineLog =
UsedLine =
; End-Declaring Constants

;Init TAPI - TAPI32\lineInitializeEx

; Preparing Vars for In/Out communication with DllCalled Function


; a location that is filled with the application's usage handle for TAPI.
VarSetCapacity(lphLineApp, 4)

; Address of a callback function that is invoked to determine status and events on the line device
callback := RegisterCallback("lineCallback",, 6)

; this location is filled with the number of line devices available to the application.
VarSetCapacity(lpdwNumDevs, 4)

;The application must initialize this DWORD, before calling this function, to the highest API version it is designed to support
;on completion of this request, this location is filled with the highest API version supported by TAPI
; TAPI 2.2 is 0x00020002
VarSetCapacity(lpdwAPIVersion, 4)
NumPut(0x20002, lpdwAPIVersion, 0, "UInt")

; a structure of type LINEINITIALIZEEXPARAMS containing additional parameters
;  Creating structure
VarSetCapacity(LINEINITIZALIZEEXPARAMS, 24, 0)
; typedef struct lineinitializeexparams_tag {
    NumPut(24, LINEINITIZALIZEEXPARAMS, 0, "UInt")
    NumPut(24, LINEINITIZALIZEEXPARAMS, 4, "UInt")
    NumPut(24, LINEINITIZALIZEEXPARAMS, 8, "UInt")
	; Before calling lineInitializeEx the application is expected to set this member(dwOptions) to one of the LINEINITIALIZEEXOPTION_ constants.
    NumPut(LINEINITIALIZEEXOPTION_USEHIDDENWINDOW, LINEINITIZALIZEEXPARAMS, 12, "UInt")
    ; union {
        NumPut(0, LINEINITIZALIZEEXPARAMS, 16, "UInt")
        NumPut(0, LINEINITIZALIZEEXPARAMS, 16, "UInt")
    ; }
    NumPut(0, LINEINITIZALIZEEXPARAMS, 20, "UInt")
; }
;  End-Creating structure

;Load the TAPI Library into Memory
hModule := DllCall("LoadLibrary", "Str", "TAPI32.dll", "Ptr")

;Init TAPI
initTAPI := DllCall("TAPI32\lineInitializeEx", "UInt", &lphLineApp, "UInt", NULL, "UInt", callback, "UInt", NULL, "UInt", &lpdwNumDevs, "UInt", &lpdwAPIVersion, "UInt", &LINEINITIZALIZEEXPARAMS)
;End-Init TAPI - TAPI32\lineInitializeEx

; Show some Vars
Lines := NumGet(lpdwNumDevs,,"UInt")
MaxTAPIVersion := NumGet(lpdwAPIVersion,,"UInt")
Handle2LineApp := NumGet(lphLineApp,,"UInt")

if (initTAPI != 0)
{
    MsgBox % "Can't init TAPI. Error: " . initTAPI
    ExitApp
}
OnExit , ExitSub

Loop , %Lines%
{
; Query TAPI-Lines
CurrLine := A_Index - 1 ; the queried Line Device
; Negotiating TAPI Versions per Line-Device
; Preparing Vars for In/Out communication with DllCalled Function
; the application's usage handle for TAPI. already retrieved as Handle2LineApp
; dwDeviceID : a number between 0 and the number of Lines - 1
dwDeviceID := CurrLine ; 0 is the first line
; dwAPILowVersion and dwAPIHighVersion , the min. and max. TAPI version supported. here 2.0 and 2.2
dwAPILowVersion := 0x20000
dwAPIHighVersion := 0x20002
; dwAPIVersion will be filled with the negotiated API version for this line
VarSetCapacity(dwAPIVersion, 4, 0)
; ExtensionID : a structure not used here, just create and ignore
VarSetCapacity(ExtensionID, 16, 0)
; call lineNegotiateAPIVersion
nRes := DllCall("TAPI32\lineNegotiateAPIVersion", "UInt", Handle2LineApp, "UInt", dwDeviceID, "UInt", dwAPILowVersion, "UInt", dwAPIHighVersion, "UInt", &dwAPIVersion, "UInt", &ExtensionID)
; End - Negotiating TAPI Versions per Line-Device

LineAPIVer := NumGet(dwAPIVersion,,"UInt")

if (nRes != 0)
    continue

; lineGetDevCaps
; prepare LINEDEVCAPS structure
VarSetCapacity(LINEDEVCAPS, 292, 0)
NumPut(292, LINEDEVCAPS, 0, "UInt")

Loop
{
    DevRes := DllCall("TAPI32\lineGetDevCaps", "UInt", Handle2LineApp, "UInt", dwDeviceID, "UInt", LineAPIVer, "UInt", 0, "UInt", &LINEDEVCAPS)
    LINEDEVCAPS_dwTotalSize := NumGet(LINEDEVCAPS, 0, "UInt")
    LINEDEVCAPS_dwNeededSize := NumGet(LINEDEVCAPS, 4, "UInt")
    if (LINEDEVCAPS_dwTotalSize >= LINEDEVCAPS_dwNeededSize)
        break
    VarSetCapacity(LINEDEVCAPS, LINEDEVCAPS_dwNeededSize, 0)
    NumPut(LINEDEVCAPS_dwNeededSize, LINEDEVCAPS, 0, "UInt")
}
 LINEDEVCAPS_LineNameSize := NumGet(LINEDEVCAPS, 32, "UInt")
 LINEDEVCAPS_LineNameOffset := NumGet(LINEDEVCAPS, 36, "UInt")
 LineName =
 loop, %LINEDEVCAPS_LineNameSize%
{
    MyByte := NumGet(LINEDEVCAPS, LINEDEVCAPS_LineNameOffset + A_Index - 1, "UChar")
    LineName .= Chr(MyByte)
}
 
; Open TAPI Lines for monitoring
; prepare some vars
VarSetCapacity(lphLine, 4, 0)
LineCallbackData := "Line " . dwDeviceID
; LINECALLPRIVILEGE_MONITOR : get notifications for the line, don't owns it
LINECALLPRIVILEGE_MONITOR := 0x2
; lineOpen : open line for monitoring
nRes := DllCall("TAPI32\lineOpen", "UInt", Handle2LineApp, "UInt", dwDeviceID, "UInt", &lphLine, "UInt", LineAPIVer, "UInt", 0, "UInt", &LineCallbackData, "UInt", LINECALLPRIVILEGE_MONITOR, "UInt", 0, "UInt", 0)

if (nRes != 0)
    continue

LineHandle := NumGet(lphLine,,"UInt")
TAPI_Line_%CurrLine% := LineName
UsedLine .= CurrLine . ","

}
StringTrimRight, UsedLine, UsedLine, 1

Gui, Add, Edit, r12 w500 vMessageContent
Gui, Show, , CallerId Monitor

MessageOutRaw =
NewCalls =

return


; the callback function will return all messages from the opened lines
; referenced in lineInitializeEx
lineCallback(dwDeviceID,  dwMessage,  dwInstance,  dwParam1,  dwParam2,  dwParam3)
{
	global NewCalls, MessageOutRaw
    LINE_CALLINFO := 1
    LINE_CALLSTATE := 2
    LINECALLINFOSTATE_CALLERID := 0x8000
    LINECALLSTATE_DISCONNECTED := 0x4000
    LINECALLORIGIN_INTERNAL := 0x2
    LINECALLORIGIN_INBOUND := 0x80
    LINECALLORIGIN_EXTERNAL := 0x4

; check for LINE_CALLINFO messages indicating CallerID is availiable   
    if ((dwMessage = LINE_CALLINFO) && (dwParam1 & LINECALLINFOSTATE_CALLERID = LINECALLINFOSTATE_CALLERID))
    {
        ; lineGetCallInfo
        ; prepare LINECALLINFO structure
        VarSetCapacity(LINECALLINFO, 344, 0)
        NumPut(344, LINECALLINFO, 0, "UInt")
        ; call lineGetCallInfo, adjust Struct-size, call again
        loop
        {
        lgiRes := DllCall("TAPI32\lineGetCallInfo", "UInt", dwDeviceID, "UInt", &LINECALLINFO)
        LINECALLINFO_dwTotalSize := NumGet(LINECALLINFO, 0, "UInt")
        LINECALLINFO_dwNeededSize := NumGet(LINECALLINFO, 4, "UInt")
        if (LINECALLINFO_dwTotalSize >= LINECALLINFO_dwNeededSize)
            break
        VarSetCapacity(LINECALLINFO, LINECALLINFO_dwNeededSize, 0)
        NumPut(LINECALLINFO_dwNeededSize, LINECALLINFO, 0, "UInt")
        }
        LINECALLINFO_dwLineDeviceID := NumGet(LINECALLINFO, 16, "UInt")
        LINECALLINFO_dwOrigin := NumGet(LINECALLINFO, 80, "UInt")
        LINECALLINFO_dwCallerIDFlags := NumGet(LINECALLINFO, 108, "UInt")
        LINECALLINFO_dwCallerIDSize := NumGet(LINECALLINFO, 112, "UInt")
        LINECALLINFO_dwCallerIDOffset := NumGet(LINECALLINFO, 116, "UInt")
         CallerID =
         ; retrieve the CallerID
        loop, %LINECALLINFO_dwCallerIDSize%
        {
            CIDMyByte := NumGet(LINECALLINFO, LINECALLINFO_dwCallerIDOffset + A_Index - 1, "UChar")
            CallerID .= Chr(CIDMyByte)
        }
        if ((LINECALLINFO_dwOrigin = LINECALLORIGIN_INTERNAL) || (LINECALLINFO_dwOrigin = LINECALLORIGIN_INBOUND) || (LINECALLINFO_dwOrigin = LINECALLORIGIN_EXTERNAL))
        {
            MyLineName := TAPI_Line_%LINECALLINFO_dwLineDeviceID%
            InboundMode = Incoming
            if (LINECALLINFO_dwOrigin = LINECALLORIGIN_INTERNAL)
                InboundMode = Internal
            if (LINECALLINFO_dwOrigin = LINECALLORIGIN_EXTERNAL)
                InboundMode = External
            NextCall := A_Hour . ":" . A_Min . ":" . A_Sec . A_Tab . "Line" . LINECALLINFO_dwLineDeviceID . ": " . MyLineName . A_Tab . A_Tab . InboundMode . A_Tab . "CallerID: " . CallerID . "`n"
            NewCalls .= NextCall
            GuiControl, , MessageContent , %NewCalls%
        }
    }
    if ((dwMessage = LINE_CALLSTATE) && (dwParam1 = LINECALLSTATE_DISCONNECTED))
    {
        dcRes := DllCall("TAPI32\lineDeallocateCall", "UInt", dwDeviceID)
    }
    
}

GuiClose:
ExitApp
return
ExitSub:
Loop, parse, UsedLine, `,
{
   nRes := DllCall("TAPI32\lineClose", "UInt", A_LoopField) 
}
nRes := DllCall("TAPI32\lineShutdown", "UInt", Handle2LineApp)
ExitApp

that's all, folks.