/* C K N T A P -- Kermit Telephony interface for MS Win32 TAPI systems */ /* Author: Jeffrey E Altman (jaltman@secure-endpoints.com), Secure Endpoints Inc., New York City. Copyright (C) 1985, 2004, Trustees of Columbia University in the City of New York. */ /* * =============================#includes===================================== */ #include "ckcdeb.h" /* Typedefs, debug formats, etc */ #include "ckcker.h" /* Kermit definitions */ #include "ckucmd.h" #include "ckuusr.h" #include "ckowin.h" #include #include #define TAPI_CURRENT_VERSION 0x00010004 #include #include /* all functions in this module return TRUE to indicate success */ /* or FALSE to indicate failure */ #include "ckntap.h" /* Kermit Telephony */ #include "cknwin.h" #ifdef CK_TAPI _PROTOTYP( char * cktapiErrorString, (DWORD)); extern int tttapi ; /* is Line TAPI ? */ extern struct keytab * tapilinetab, * tapilocationtab ; extern int ntapiline, ntapilocation ; extern long speed; extern int parity, flow; #ifndef NODIAL extern int dialdpy; extern int dialidt, /* DIAL IGNORE-DIAL-TONE */ dialec, /* DIAL ERROR-CORRECTION */ dialdc, /* DIAL COMPRESSION */ dialfc, /* DIAL FLOW-CONTROL */ dialmth, /* DIAL METHOD */ dialmauto, /* DIAL METHOD AUTO */ mdmspd, /* SPEED-MATCHING */ mdmspk, /* SPEAKER ON/OFF */ mdmvol; /* SPEAKER VOLUME */ extern int waitct; /* DIAL TIMEOUT */ extern MDMINF *modemp[]; extern MDMINF GENERIC; #else /* NODIAL */ int dialdpy = 0; int waitct = 254; #endif /* NODIAL */ HINSTANCE hLib = NULL ; extern HINSTANCE hInstance ; extern HWND hwndConsole ; extern char * termessage ; #ifndef NODIAL /* Failure codes from ckudia.c */ extern int fail_code; #define F_TIME 1 /* timeout */ #define F_INT 2 /* interrupt */ #define F_MODEM 3 /* modem-detected failure */ #define F_MINIT 4 /* cannot initialize modem */ #endif /* NODIAL */ int tapiopen = 0; int tapipass = CK_ON ; /* TAPI Passthrough mode */ int tapiconv = CK_AUTO ; /* TAPI Conversion mode */ int tapilights = TRUE; int tapipreterm = FALSE; int tapipostterm = FALSE; int tapimanual = FALSE; int tapiinactivity = 0; int tapibong = 8; int tapiusecfg = CK_OFF; /* TAPI Location Information */ char tapiloc[257] = "" ; int tapilocid = -1 ; DWORD tapiCountryID = -1 ; char tapiAreaCode[65] = "" ; DWORD tapiPreferredCardID=MAXDWORD; DWORD tapiCountryCode=0; char tapiLocalAccessCode[65] = "" ; char tapiLongDistAccessCode[65] = ""; char tapiTollPrefixList[4097]=""; DWORD tapiOptions=0; char tapiCancelCallWaiting[65] = ""; char tapiCountryName[65] = ""; char tapiSameAreaRule[65] = ""; char tapiLongDistanceRule[65] = ""; char tapiInternationalRule[65] = ""; LONG (WINAPI *cklineInitialize)(LPHLINEAPP, HINSTANCE, LINECALLBACK, LPCSTR, LPDWORD ) = NULL ; LONG (WINAPI *cklineNegotiateAPIVersion)(HLINEAPP, DWORD, DWORD, DWORD, LPDWORD, LPLINEEXTENSIONID) = NULL ; LONG (WINAPI *cklineGetDevCaps)(HLINEAPP, DWORD, DWORD, DWORD, LPLINEDEVCAPS) = NULL ; LONG (WINAPI *cklineShutdown)(HLINEAPP) = NULL ; LONG (WINAPI *cklineOpen)(HLINEAPP, DWORD, LPHLINE, DWORD, DWORD, DWORD, DWORD, DWORD, LPLINECALLPARAMS) = NULL ; LONG (WINAPI *cklineMakeCall)(HLINE hLine, LPHCALL lphCall, LPCSTR lpszDestAddress, DWORD dwCountryCode, LPLINECALLPARAMS const lpCallParams) = NULL ; LONG (WINAPI *cklineDial)(HCALL hCall, LPCSTR lpszDestAddress, DWORD dwCountryCode) = NULL ; LONG (WINAPI *cklineDrop)(HCALL hCall, LPCSTR lpsUserUserInfo, DWORD dwSize) = NULL ; LONG (WINAPI *cklineAnswer)(HCALL hCall, LPCSTR lpsUserUserInfo, DWORD dwSize) = NULL ; LONG (WINAPI *cklineAccept)(HCALL hCall, LPCSTR lpsUserUserInfo, DWORD dwSize) = NULL ; LONG (WINAPI *cklineDeallocateCall)(HCALL hCall) = NULL ; LONG (WINAPI *cklineSetCallPrivilege)(HCALL,DWORD) = NULL ; LONG (WINAPI *cklineClose)(HLINE hLine) = NULL ; LONG (WINAPI *cklineHandoff)(HCALL,LPCSTR,DWORD) = NULL ; LONG (WINAPI *cklineGetID)(HLINE hLine, DWORD dwAddressID, HCALL hCall, DWORD dwSelect, LPVARSTRING lpDeviceID, LPCSTR lpszDeviceClass) = NULL ; LONG (WINAPI *cklineGetTranslateCaps)( HLINEAPP hLineApp, DWORD, LPLINETRANSLATECAPS lpLineTranslateCaps) = NULL ; LONG (WINAPI *cklineSetCurrentLocation)( HLINEAPP hLineApp, DWORD dwLocationID ) = NULL ; LONG (WINAPI *cklineSetStatusMessages)( HLINE hLine, DWORD dwLineStates, DWORD dwAddressStates ) = NULL ; LONG (WINAPI *cklineConfigDialog)( DWORD dwLine, HWND hwin, LPCSTR lpszTypes ) = NULL ; LONG (WINAPI *cklineTranslateDialog)( HLINEAPP hTAPI, DWORD dwLine, DWORD dwVersionToUse, HWND hwndOwner, LPCSTR lpszAddressIn ) = NULL ; LONG (WINAPI *cklineTranslateAddress)( HLINEAPP hTAPI, DWORD dwLine, DWORD dwVersionToUse, LPCSTR lpszAddressIn, DWORD dwCard, DWORD dwTranslateOptions, LPLINETRANSLATEOUTPUT lpTranslateOutput) = NULL ; LONG (WINAPI *cklineGetCountry)( DWORD, DWORD, LPLINECOUNTRYLIST ) = NULL; LONG (WINAPI *cklineGetDevConfig)(DWORD, LPVARSTRING, LPCSTR) = NULL; LONG (WINAPI *cklineGetLineDevStatus)(HLINE hLine,LPLINEDEVSTATUS lpLineDevStatus)=NULL; LONG (WINAPI *cklineSetDevConfig)(DWORD,LPVOID const,DWORD,LPCSTR)=NULL; LONG (WINAPI *cklineGetCallInfo)(HCALL, LPLINECALLINFO)=NULL; LONG (WINAPI *cklineMonitorMedia)(HCALL,DWORD)=NULL; LONG (WINAPI *cklineGetAppPriority)(LPCSTR,DWORD,LPLINEEXTENSIONID, DWORD,LPVARSTRING,LPDWORD)=NULL; LONG (WINAPI *cklineSetAppPriority)(LPCSTR,DWORD,LPLINEEXTENSIONID, DWORD,LPCSTR,DWORD)=NULL; LONG (WINAPI *cklineGetNumRings)(HLINE,DWORD,LPDWORD)=NULL; LONG (WINAPI *cklineSetNumRings)(HLINE,DWORD,DWORD)=NULL; LONG (WINAPI *cklineSetCallParams)(HCALL,DWORD,DWORD,DWORD,LPLINEDIALPARAMS)=NULL; int cktapiunload(void) { debug(F100,"Closing TAPI Semaphores","",0); CloseTAPIInitSem(); CloseTAPIConnectSem(); CloseTAPIAnswerSem(); debug(F100,"Freeing the TAPI Library","",0); FreeLibrary( hLib ) ; hLib = NULL ; cklineInitialize = NULL ; debug(F100,"TAPI unload complete","",0); return TRUE ; } int cktapiload(void) { DWORD rc = 0 ; hLib = LoadLibrary("tapi32") ; if ( !hLib ) { rc = GetLastError() ; debug(F111, "cktapiload LoadLibrary failed","tapi32",rc) ; return FALSE; } if (((FARPROC) cklineInitialize = GetProcAddress( hLib, "lineInitialize" )) == NULL ) { rc = GetLastError() ; debug(F111, "cktapiload LoadLibrary failed","tapi32",rc) ; return FALSE; } if (((FARPROC) cklineNegotiateAPIVersion = GetProcAddress( hLib, "lineNegotiateAPIVersion" )) == NULL ) { rc = GetLastError() ; debug(F111, "cktapiload LoadLibrary failed","tapi32",rc) ; return FALSE; } if (((FARPROC) cklineGetDevCaps = GetProcAddress( hLib, "lineGetDevCaps" )) == NULL ) { rc = GetLastError() ; debug(F111, "cktapiload LoadLibrary failed","tapi32",rc) ; return FALSE; } if (((FARPROC) cklineShutdown = GetProcAddress( hLib, "lineShutdown" )) == NULL ) { rc = GetLastError() ; debug(F111, "cktapiload LoadLibrary failed","tapi32",rc) ; return FALSE; } if (((FARPROC) cklineOpen = GetProcAddress( hLib, "lineOpen" )) == NULL ) { rc = GetLastError() ; debug(F111, "cktapiload LoadLibrary failed","tapi32",rc) ; return FALSE; } if (((FARPROC) cklineMakeCall = GetProcAddress( hLib, "lineMakeCall" )) == NULL ) { rc = GetLastError() ; debug(F111, "cktapiload LoadLibrary failed","tapi32",rc) ; return FALSE; } if (((FARPROC) cklineDial = GetProcAddress( hLib, "lineDial" )) == NULL ) { rc = GetLastError() ; debug(F111, "cktapiload LoadLibrary failed","tapi32",rc) ; return FALSE; } if (((FARPROC) cklineDrop = GetProcAddress( hLib, "lineDrop" )) == NULL ) { rc = GetLastError() ; debug(F111, "cktapiload LoadLibrary failed","tapi32",rc) ; return FALSE; } if (((FARPROC) cklineAnswer = GetProcAddress( hLib, "lineAnswer" )) == NULL ) { rc = GetLastError() ; debug(F111, "cktapiload LoadLibrary failed","tapi32",rc) ; return FALSE; } if (((FARPROC) cklineAccept = GetProcAddress( hLib, "lineAccept" )) == NULL ) { rc = GetLastError() ; debug(F111, "cktapiload LoadLibrary failed","tapi32",rc) ; return FALSE; } if (((FARPROC) cklineDeallocateCall = GetProcAddress( hLib, "lineDeallocateCall" )) == NULL ) { rc = GetLastError() ; debug(F111, "cktapiload LoadLibrary failed","tapi32",rc) ; return FALSE; } if (((FARPROC) cklineClose = GetProcAddress( hLib, "lineClose" )) == NULL ) { rc = GetLastError() ; debug(F111, "cktapiload LoadLibrary failed","tapi32",rc) ; return FALSE; } if (((FARPROC) cklineGetID = GetProcAddress( hLib, "lineGetID" )) == NULL ) { rc = GetLastError() ; debug(F111, "cktapiload LoadLibrary failed","tapi32",rc) ; return FALSE; } if (((FARPROC) cklineGetTranslateCaps = GetProcAddress( hLib, "lineGetTranslateCaps" )) == NULL ) { rc = GetLastError() ; debug(F111, "cktapiload LoadLibrary failed","tapi32",rc) ; return FALSE; } if (((FARPROC) cklineSetCurrentLocation = GetProcAddress( hLib, "lineSetCurrentLocation" )) == NULL ) { rc = GetLastError() ; debug(F111, "cktapiload LoadLibrary failed","tapi32",rc) ; return FALSE; } if (((FARPROC) cklineSetStatusMessages = GetProcAddress( hLib, "lineSetStatusMessages" )) == NULL ) { rc = GetLastError() ; debug(F111, "cktapiload LoadLibrary failed","tapi32",rc) ; return FALSE; } if (((FARPROC) cklineConfigDialog = GetProcAddress( hLib, "lineConfigDialog" )) == NULL ) { rc = GetLastError() ; debug(F111, "cktapiload LoadLibrary failed","tapi32",rc) ; return FALSE; } if (((FARPROC) cklineTranslateDialog = GetProcAddress( hLib, "lineTranslateDialog" )) == NULL ) { rc = GetLastError() ; debug(F111, "cktapiload LoadLibrary failed","tapi32",rc) ; return FALSE; } if (((FARPROC) cklineTranslateAddress = GetProcAddress( hLib, "lineTranslateAddress" )) == NULL ) { rc = GetLastError() ; debug(F111, "cktapiload LoadLibrary failed","tapi32",rc) ; return FALSE; } if (((FARPROC) cklineGetCountry = GetProcAddress( hLib, "lineGetCountry" )) == NULL ) { rc = GetLastError() ; debug(F111, "cktapiload LoadLibrary failed","tapi32",rc) ; return FALSE; } if (((FARPROC) cklineGetLineDevStatus = GetProcAddress( hLib, "lineGetLineDevStatus" )) == NULL ) { rc = GetLastError() ; debug(F111, "cktapiload LoadLibrary failed","tapi32",rc) ; return FALSE; } if (((FARPROC) cklineGetDevConfig = GetProcAddress( hLib, "lineGetDevConfig" )) == NULL ) { rc = GetLastError() ; debug(F111, "cktapiload LoadLibrary failed","tapi32",rc) ; return FALSE; } if (((FARPROC) cklineSetDevConfig = GetProcAddress( hLib, "lineSetDevConfig" )) == NULL ) { rc = GetLastError() ; debug(F111, "cktapiload LoadLibrary failed","tapi32",rc) ; return FALSE; } if (((FARPROC) cklineHandoff = GetProcAddress( hLib, "lineHandoff" )) == NULL ) { rc = GetLastError() ; debug(F111, "cktapiload LoadLibrary failed","tapi32",rc) ; return FALSE; } if (((FARPROC) cklineSetCallPrivilege = GetProcAddress( hLib, "lineSetCallPrivilege" )) == NULL ) { rc = GetLastError() ; debug(F111, "cktapiload LoadLibrary failed","tapi32",rc) ; return FALSE; } if (((FARPROC) cklineGetCallInfo = GetProcAddress( hLib, "lineGetCallInfo" )) == NULL ) { rc = GetLastError() ; debug(F111, "cktapiload LoadLibrary failed","tapi32",rc) ; return FALSE; } if (((FARPROC) cklineMonitorMedia = GetProcAddress( hLib, "lineMonitorMedia" )) == NULL ) { rc = GetLastError() ; debug(F111, "cktapiload LoadLibrary failed","tapi32",rc) ; return FALSE; } if (((FARPROC) cklineGetAppPriority = GetProcAddress( hLib, "lineGetAppPriority" )) == NULL ) { rc = GetLastError() ; debug(F111, "cktapiload LoadLibrary failed","tapi32",rc) ; return FALSE; } if (((FARPROC) cklineSetAppPriority = GetProcAddress( hLib, "lineSetAppPriority" )) == NULL ) { rc = GetLastError() ; debug(F111, "cktapiload LoadLibrary failed","tapi32",rc) ; return FALSE; } if (((FARPROC) cklineGetNumRings = GetProcAddress( hLib, "lineGetNumRings" )) == NULL ) { rc = GetLastError() ; debug(F111, "cktapiload LoadLibrary failed","tapi32",rc) ; return FALSE; } if (((FARPROC) cklineSetNumRings = GetProcAddress( hLib, "lineSetNumRings" )) == NULL ) { rc = GetLastError() ; debug(F111, "cktapiload LoadLibrary failed","tapi32",rc) ; return FALSE; } if (((FARPROC) cklineSetCallParams = GetProcAddress( hLib, "lineSetCallParams" )) == NULL ) { rc = GetLastError() ; debug(F111, "cktapiload LoadLibrary failed","tapi32",rc) ; return FALSE; } CreateTAPIInitSem( FALSE ); CreateTAPIConnectSem( FALSE ); CreateTAPIAnswerSem( FALSE ); return TRUE; } // Global TAPI variables. HWND g_hWndMainWindow = NULL; // Apps main window. HWND g_hDlgParentWindow = NULL; // This will be the parent of all dialogs. HLINEAPP g_hLineApp = (HLINEAPP) 0; DWORD g_dwNumDevs = -1; DWORD g_DataDevices = 0 ; #define MAXDEVS 64 LPLINEDEVCAPS g_lpLineDevCaps[64] ; extern HINSTANCE hInst ; // Global variable that holds the handle to a TAPI dialog // that needs to be dismissed if line conditions change. HWND g_hDialog = NULL; // Global flags to prevent re-entrancy problems. BOOL g_bShuttingDown = FALSE; BOOL g_bStoppingCall = FALSE; BOOL g_bInitializing = FALSE; // This sample only supports one call in progress at a time. BOOL g_bTapiInUse = FALSE; // Data needed per call. This sample only supports one call. HCALL g_hCall = (HCALL) 0; HLINE g_hLine = (HLINE) 0; extern int ttyfd ; /* this holds the HLINE hLine */ extern int mdmtyp ; static int mdmtyp_sav=0; CHAR szModemName[256] ; DWORD LineDeviceId = -1; DWORD LineDeviceAPIVersion = 0 ; DWORD LineAddressCount = 0 ; DWORD LineMediaModes = 0 ; DWORD g_dwAPIVersion = 0; DWORD g_dwCallState = 0; BOOL g_bConnected = FALSE; // Global variables to allow us to do various waits. BOOL g_bReplyReceived=FALSE; DWORD g_dwRequestedID=0; long g_lAsyncReply=SUCCESS; BOOL g_bCallStateReceived=FALSE; BOOL g_bAnswering = FALSE; BOOL g_bDialing = FALSE; BOOL g_bHangingUp = FALSE; BOOL g_bClosing = FALSE; int cktapiinit(void) { int i = 0 ; // This will be the parent of all dialogs. g_hWndMainWindow = g_hDlgParentWindow = hwndConsole; for ( i=0 ; i < MAXDEVS ; i++ ) g_lpLineDevCaps[i] = NULL ; if ( cktapiload() ) { if (cktapiopen()) { debug(F100,"TAPI open successful","",0); g_DataDevices = cktapidevenum() ; cktapiclose() ; return TRUE ; } else { debug(F100,"TAPI open failed","",0); } } return FALSE; } void OutputDebugLastError( DWORD x, char * string ) { char buf[1024]; sprintf(buf,"%s %s",string,cktapiErrorString(x)); debug(F111,"TAPI LastError",buf,x); #ifdef BETADEBUG printf("TAPI LastError %s=%x\n",string,x); #endif } void HandleNoMem( ) { debug(F100,"TAPI Out of Memory","",0); } // // FUNCTION: LPVOID CheckAndReAllocBuffer(LPVOID, size_t, LPCSTR) // // PURPOSE: Checks and ReAllocates a buffer if necessary. // // PARAMETERS: // lpBuffer - Pointer to buffer to be checked. Can be NULL. // sizeBufferMinimum - Minimum size that lpBuffer should be. // szApiPhrase - Phrase to print if an error occurs. // // RETURN VALUE: // Returns a pointer to a valid buffer that is guarenteed to be // at least sizeBufferMinimum size. // Returns NULL if an error occured. // // COMMENTS: // // This function is a helper function intended to make all of the // line API Wrapper Functions much simplier. It allocates (or // reallocates) a buffer of the requested size. // // The returned pointer has been allocated with LocalAlloc, // so LocalFree has to be called on it when you're finished with it, // or there will be a memory leak. // // Similarly, if a pointer is passed in, it *must* have been allocated // with LocalAlloc and it could potentially be LocalFree()d. // // If lpBuffer == NULL, then a new buffer is allocated. It is // normal to pass in NULL for this parameter the first time and only // pass in a pointer if the buffer needs to be reallocated. // // szApiPhrase is used only for debugging purposes. // // It is assumed that the buffer returned from this function will be used // to contain a variable sized structure. Thus, the dwTotalSize field // is always filled in before returning the pointer. // // LPVOID CheckAndReAllocBuffer(LPVOID lpBuffer, size_t sizeBufferMinimum, LPCSTR szApiPhrase) { size_t sizeBuffer; debug(F110,"CheckAndReAllocBuffer",szApiPhrase,0); debug(F111,"CheckAndReAllocBuffer","lpBuffer",lpBuffer); debug(F111,"CheckAndReAllocBuffer","sizeBufferMinimum",sizeBufferMinimum); if (lpBuffer == NULL) // Allocate the buffer if necessary. { sizeBuffer = sizeBufferMinimum; lpBuffer = (LPVOID) LocalAlloc(LPTR, sizeBuffer); if (lpBuffer == NULL) { HandleNoMem(); return NULL; } } else // If the structure already exists, make sure its good. { sizeBuffer = LocalSize((HLOCAL) lpBuffer); if (sizeBuffer == 0) // Bad pointer? { return NULL; } // Was the buffer big enough for the structure? if (sizeBuffer < sizeBufferMinimum) { LocalFree(lpBuffer); return CheckAndReAllocBuffer(NULL, sizeBufferMinimum, szApiPhrase); } // Lets zero the buffer out. memset(lpBuffer, 0, sizeBuffer); } ((LPVARSTRING) lpBuffer ) -> dwTotalSize = (DWORD) sizeBuffer; return lpBuffer; } char * cktapiErrorString(DWORD error) { char * estr = NULL; switch ( error ) { case 0: estr = "Success"; break; case LINEERR_ALLOCATED: estr = "Line already allocated"; break; case LINEERR_BADDEVICEID: estr = "Bad device ID"; break; case LINEERR_BEARERMODEUNAVAIL: estr = "Requested Bearer Mode Unavailable"; break; case LINEERR_CALLUNAVAIL: estr = "Unable to place call on current device"; break; case LINEERR_COMPLETIONOVERRUN : estr = "Completion Overrun"; break; case LINEERR_CONFERENCEFULL : estr = "Conference Full"; break; case LINEERR_DIALBILLING : estr = "Dial Billing error"; break; case LINEERR_DIALDIALTONE : estr = "Wait for Dial Tone not supported"; break; case LINEERR_DIALPROMPT : estr = "Wait for Dial Prompt not supported"; break; case LINEERR_DIALQUIET : estr = "Wait for Quiet not supported"; break; case LINEERR_INCOMPATIBLEAPIVERSION : estr = "Incompatible TAPI Version"; break; case LINEERR_INCOMPATIBLEEXTVERSION : estr = "Incompatible Extension Version"; break; case LINEERR_INIFILECORRUPT : estr = "TELEPHON.INI file corrupt"; break; case LINEERR_INUSE : estr = "Line in use"; break; case LINEERR_INVALADDRESS : estr = "Invalid Line Address"; break; case LINEERR_INVALADDRESSID : estr = "Invalid Line Address ID"; break; case LINEERR_INVALADDRESSMODE : estr = "Invalid Line Address Mode"; break; case LINEERR_INVALADDRESSSTATE : estr = "Invalid Line Address State"; break; case LINEERR_INVALAPPHANDLE : estr = "Invalid Application Handle"; break; case LINEERR_INVALAPPNAME : estr = "Invalid Application Name"; break; case LINEERR_INVALBEARERMODE : estr = "Invalid Bearer Mode"; break; case LINEERR_INVALCALLCOMPLMODE : estr = "Invalid Call Completion Mode"; break; case LINEERR_INVALCALLHANDLE : estr = "Invalid Call Handle"; break; case LINEERR_INVALCALLPARAMS : estr = "Invalid Call Parameters"; break; case LINEERR_INVALCALLPRIVILEGE : estr = "Invalid Call Privilege"; break; case LINEERR_INVALCALLSELECT : estr = "Invalid Call Selection"; break; case LINEERR_INVALCALLSTATE : estr = "Invalid Call State"; break; case LINEERR_INVALCALLSTATELIST : estr = "Invalid Call State List"; break; case LINEERR_INVALCARD : estr = "Invalid Card"; break; case LINEERR_INVALCOMPLETIONID : estr = "Invalid Completion ID"; break; case LINEERR_INVALCONFCALLHANDLE : estr = "Invalid Conference Call Handle"; break; case LINEERR_INVALCONSULTCALLHANDLE : estr = "Invalid Consulation Call Handle"; break; case LINEERR_INVALCOUNTRYCODE : estr = "Invalid Country Code"; break; case LINEERR_INVALDEVICECLASS : estr = "Invalid Device Class"; break; case LINEERR_INVALDEVICEHANDLE : estr = "Invalid Device Handle"; break; case LINEERR_INVALDIALPARAMS : estr = "Invalid Dial Parameters"; break; case LINEERR_INVALDIGITLIST : estr = "Invalid Digit List"; break; case LINEERR_INVALDIGITMODE : estr = "Invalid Digit Mode"; break; case LINEERR_INVALDIGITS : estr = "Invalid Digits"; break; case LINEERR_INVALEXTVERSION : estr = "Invalid Extension Version"; break; case LINEERR_INVALGROUPID : estr = "Invalid Group ID"; break; case LINEERR_INVALLINEHANDLE : estr = "Invalid Line Handle"; break; case LINEERR_INVALLINESTATE : estr = "Invalid Line State"; break; case LINEERR_INVALLOCATION : estr = "Invalid Location"; break; case LINEERR_INVALMEDIALIST : estr = "Invalid Media List"; break; case LINEERR_INVALMEDIAMODE : estr = "Invalid Media Mode"; break; case LINEERR_INVALMESSAGEID : estr = "Invalid Message ID"; break; case LINEERR_INVALPARAM : estr = "Invalid Parameter"; break; case LINEERR_INVALPARKID : estr = "Invalid Park ID"; break; case LINEERR_INVALPARKMODE : estr = "Invaldi Park Mode"; break; case LINEERR_INVALPOINTER : estr = "Invalid Pointer"; break; case LINEERR_INVALPRIVSELECT : estr = "Invalid Privilege Select"; break; case LINEERR_INVALRATE : estr = "Invalid Rate"; break; case LINEERR_INVALREQUESTMODE : estr = "Invalid Request Mode"; break; case LINEERR_INVALTERMINALID : estr = "Invalid Terminal ID"; break; case LINEERR_INVALTERMINALMODE : estr = "Invalid Terminal Mode"; break; case LINEERR_INVALTIMEOUT : estr = "Invalid Timeout"; break; case LINEERR_INVALTONE : estr = "Invalid Tone"; break; case LINEERR_INVALTONELIST : estr = "Invalid Tone List"; break; case LINEERR_INVALTONEMODE : estr = "Invalid Tone Mode"; break; case LINEERR_INVALTRANSFERMODE : estr = "Invalid Transfer Mode"; break; case LINEERR_LINEMAPPERFAILED : estr = "Line Mapper Failed"; break; case LINEERR_NOCONFERENCE : estr = "No Conference available"; break; case LINEERR_NODEVICE : estr = "No Device available"; break; case LINEERR_NODRIVER : estr = "No Driver available"; break; case LINEERR_NOMEM : estr = "No memory available"; break; case LINEERR_NOREQUEST : estr = "No Request"; break; case LINEERR_NOTOWNER : estr = "Not owner"; break; case LINEERR_NOTREGISTERED : estr = "Not Registered"; break; case LINEERR_OPERATIONFAILED : estr = "Operation Failed"; break; case LINEERR_OPERATIONUNAVAIL : estr = "Operation Unavailable"; break; case LINEERR_RATEUNAVAIL : estr = "Rate Unavailable"; break; case LINEERR_RESOURCEUNAVAIL : estr = "Resource Unavailable"; break; case LINEERR_REQUESTOVERRUN : estr = "Request Overrun"; break; case LINEERR_STRUCTURETOOSMALL : estr = "Structure Too Small"; break; case LINEERR_TARGETNOTFOUND : estr = "Target Not Found"; break; case LINEERR_TARGETSELF : estr = "Target Self"; break; case LINEERR_UNINITIALIZED : estr = "TAPI Unititialized"; break; case LINEERR_USERUSERINFOTOOBIG : estr = "User Info Too Big"; break; case LINEERR_REINIT : estr = "TAPI Reinitialization Required"; break; case LINEERR_ADDRESSBLOCKED : estr = "Address Blocked"; break; case LINEERR_BILLINGREJECTED : estr = "Billing Rejected"; break; case LINEERR_INVALFEATURE : estr = "Invalid Feature"; break; case LINEERR_NOMULTIPLEINSTANCE : estr = "Multiple Instances not supported"; break; #ifdef COMMENT /* TAPI 2.0 */ case LINEERR_INVALAGENTID : estr = "Invalid Agent ID"; break; case LINEERR_INVALAGENTGROUP : estr = "Invalid Agent Group"; break; case LINEERR_INVALPASSWORD : estr = "Invalid Password"; break; case LINEERR_INVALAGENTSTATE : estr = "Invalid Agent State"; break; case LINEERR_INVALAGENTACTIVITY : estr = "Invalid Agent Activity"; break; case LINEERR_DIALVOICEDETECT : estr = "Voice detected during dialing"; break; #endif /* COMMENT */ default: estr = ((LONG) error) > 0 ? "Request ID" : "Unknown TAPI error"; break; } return estr; } void UpdateStatusBar( char * str, long param1, long param2 ) { char buf[1024]; sprintf(buf,"%s::%d,%d",str,param1,param2); debug(F110,"TAPI Status Message",buf,0); if ( dialdpy ) printf( "%s\n",str ) ; } void OutputDebugLineError( long param, char * str ) { char buf[1024]; sprintf(buf,"%s %s",str,cktapiErrorString(param)); #ifdef BETADEBUG printf("TAPI Debug Line Error: %s=%s(0x%x)\n",str, cktapiErrorString(param),param); #endif /* BETADEBUG */ debug(F111,"TAPI Debug Line Error",buf,param); } void OutputDebugLineCallback( DWORD dwDevice, DWORD dwMsg, DWORD dwCallbackInstance, DWORD dwParam1, DWORD dwParam2, DWORD dwParam3) { char buf[1024]; sprintf(buf,"(%d,%d,%d,%d,%d,%d)", dwDevice,dwMsg,dwCallbackInstance, dwParam1,dwParam2,dwParam3); debug(F110,"TAPI Line Callback",buf,0); } // // FUNCTION: DoLineReply(..) // // PURPOSE: Handle LINE_REPLY asynchronous messages. // // PARAMETERS: // dwDevice - Line Handle associated with this LINE_REPLY. // dwMsg - Should always be LINE_REPLY. // dwCallbackInstance - Unused by this sample. // dwParam1 - Asynchronous request ID. // dwParam2 - success or LINEERR error value. // dwParam3 - Unused. // // RETURN VALUE: // none // // COMMENTS: // // All line API calls that return an asynchronous request ID // will eventually cause a LINE_REPLY message. Handle it. // // This sample assumes only one call at time, and that we wait // for a LINE_REPLY before making any other line API calls. // // The only exception to the above is that we might shut down // the line before receiving a LINE_REPLY. // // void DoLineReply( DWORD dwDevice, DWORD dwMessage, DWORD dwCallbackInstance, DWORD dwParam1, DWORD dwParam2, DWORD dwParam3) { debug(F111,"TAPI LINE REPLY","Requested ID",g_dwRequestedID); debug(F111,"TAPI LINE REPLY","Message ID",dwParam1); OutputDebugLineError((long) dwParam2, "LINE_REPLY error: "); while ( g_dwRequestedID == 0 ) { msleep(100); } // If we are currently waiting for this async Request ID // then set the global variables to acknowledge it. if (g_dwRequestedID == dwParam1) { #ifdef BETADEBUG printf("LINE_REPLY: dwRequestedID == dwParam1\n"); #endif g_lAsyncReply = (long) dwParam2; g_bReplyReceived = TRUE; } #ifdef BETADEBUG else { printf("LINE_REPLY: dwRequestedID != dwParam1\n"); } #endif } // // FUNCTION: DoLineClose(..) // // PURPOSE: Handle LINE_CLOSE asynchronous messages. // // PARAMETERS: // dwDevice - Line Handle that was closed. // dwMsg - Should always be LINE_CLOSE. // dwCallbackInstance - Unused by this sample. // dwParam1 - Unused. // dwParam2 - Unused. // dwParam3 - Unused. // // RETURN VALUE: // none // // COMMENTS: // // This message is sent when something outside our app shuts // down a line in use. // // The hLine (and any hCall on this line) are no longer valid. // // void DoLineClose( DWORD dwDevice, DWORD dwMessage, DWORD dwCallbackInstance, DWORD dwParam1, DWORD dwParam2, DWORD dwParam3) { // Line has been shut down. Clean up our internal variables. if ( (HLINE) dwDevice == g_hLine ) { cktapicloseasync(); debug(F110,"TAPI","Line was shutdown by TAPI",0); printf("%s was shut down.\n",szModemName); } } // // FUNCTION: DoLineCreate(..) // // PURPOSE: Handle LINE_LINECREATE asynchronous messages. // // PARAMETERS: // dwDevice - Unused. // dwMsg - Should always be LINE_CREATE. // dwCallbackInstance - Unused. // dwParam1 - dwDeviceID of new Line created. // dwParam2 - Unused. // dwParam3 - Unused. // // RETURN VALUE: // none // // COMMENTS: // // This message is new for Windows 95. It is sent when a new line is // added to the system. This allows us to handle new lines without having // to REINIT. This allows for much more graceful Plug and Play. // // void DoLineCreate( DWORD dwDevice, DWORD dwMessage, DWORD dwCallbackInstance, DWORD dwParam1, DWORD dwParam2, DWORD dwParam3) { // dwParam1 is the Device ID of the new line. // Add one to get the number of total devices. if (g_dwNumDevs <= dwParam1) g_dwNumDevs = dwParam1+1; g_DataDevices = cktapidevenum() ; debug(F111,"TAPI","A new line device has been added to the system", g_DataDevices); #ifdef BETADEBUG printf("A new line device has been added to the system.\n"); #endif /* BETADEBUG */ } // // FUNCTION: DoLineDevState(..) // // PURPOSE: Handle LINE_LINEDEVSTATE asynchronous messages. // // PARAMETERS: // dwDevice - Line Handle that was closed. // dwMsg - Should always be LINE_LINEDEVSTATE. // dwCallbackInstance - Unused by this sample. // dwParam1 - LINEDEVSTATE constant. // dwParam2 - Depends on dwParam1. // dwParam3 - Depends on dwParam1. // // RETURN VALUE: // none // // COMMENTS: // // The LINE_LINEDEVSTATE message is received if the state of the line // changes. Examples are RINGING, MAINTENANCE, MSGWAITON. // // Assuming that any LINEDEVSTATE that removes the line from use by TAPI // will also send a LINE_CLOSE message. // // void DoLineDevState( DWORD dwDevice, DWORD dwMessage, DWORD dwCallbackInstance, DWORD dwParam1, DWORD dwParam2, DWORD dwParam3) { switch(dwParam1) { case LINEDEVSTATE_RINGING: { UpdateStatusBar("Line Ringing",1,0); break; } case LINEDEVSTATE_REINIT: // This is an important case! Usually means that a service provider // has changed in such a way that requires TAPI to REINIT. // Note that there are both 'soft' REINITs and 'hard' REINITs. // Soft REINITs don't actually require a full shutdown but is instead // just an informational change that historically required a REINIT // to force the application to deal with. TAPI API Version 1.3 apps // will still need to do a full REINIT for both hard and soft REINITs. switch(dwParam2) { // This is the hard REINIT. No reason given, just REINIT. // TAPI is waiting for everyone to shutdown. // Our response is to immediately shutdown any calls, // shutdown our use of TAPI and notify the user. case 0: #ifdef BETADEBUG printf("Line configuration has changed\n"); #endif /* BETADEBUG */ if ( (HLINE) dwDevice == g_hLine ) { cktapicloseasync(); printf("TAPI line configuration has changed. Shutdown required.\n"); debug(F111,"TAPI LINEDEVSTATE_REINIT-0","Shutdown required",dwDevice); } break; case LINE_CREATE: #ifdef BETADEBUG printf("Soft REINIT: LINE_CREATE.\n"); #endif /* BETADEBUG */ DoLineCreate(dwDevice, dwParam2, dwCallbackInstance, dwParam3, 0, 0); break; case LINE_LINEDEVSTATE: #ifdef BETADEBUG printf("Soft REINIT: LINE_LINEDEVSTATE.\n"); #endif /* BETADEBUG */ DoLineDevState(dwDevice, dwParam2, dwCallbackInstance, dwParam3, 0, 0); break; // There might be other reasons to send a soft reinit. // No need to to shutdown for these. default: #ifdef BETADEBUG printf("Ignoring soft REINIT\n"); #endif /* BETADEBUG */ break; } break; case LINEDEVSTATE_OUTOFSERVICE: if ( (HLINE) dwDevice == g_hLine ) { cktapicloseasync(); printf("%s is now Out of Service\n",szModemName); debug(F111,"TAPI LINEDEVSTATE_OUTOFSERVICE",szModemName,dwDevice); } break; case LINEDEVSTATE_DISCONNECTED: if ( (HLINE) dwDevice == g_hLine && g_hCall != (HCALL) 0 ) { cktapidisconnect(); printf("%s is now disconnected\n",szModemName); debug(F111,"TAPI LINEDEVSTATE_DISCONNECTED",szModemName,dwDevice); } break; case LINEDEVSTATE_MAINTENANCE: if ( (HLINE) dwDevice == g_hLine ) { cktapicloseasync(); printf("%s is now out for maintenance\n",szModemName); debug(F111,"TAPI LINEDEVSTATE_MAINTENANCE",szModemName,dwDevice); } break; case LINEDEVSTATE_TRANSLATECHANGE: #ifdef BETADEBUG printf("Translate Change\n"); #endif debug(F100,"TAPI LINEDEVSTATE_TRANSLATECHANGE","",0); #ifndef NODIAL if ( 1 || tapiconv == CK_ON || tapiconv == CK_AUTO && tttapi && !tapipass ) { /* Reload TAPI Location Information From Scratch */ tapilocid = -1; CopyTapiLocationInfoToKermitDialCmd(); } #endif /* NODIAL */ break; case LINEDEVSTATE_REMOVED: #ifdef BETADEBUG printf("A Line device has been removed; no action taken.\n"); #endif if (g_dwNumDevs <= dwParam1) g_dwNumDevs = dwParam1+1; g_DataDevices = cktapidevenum() ; debug(F111,"TAPI LINEDEVSTATE_REMOVED", "A line device has been removed; no action taken", g_DataDevices); break; case LINEDEVSTATE_CLOSE: #ifdef BETADEBUG printf("A Line device has been closed; no action taken.\n"); #endif /* BETADEBUG */ debug(F110,"TAPI LINEDEVSTATE_CLOSE","A Line device has been closed; no action taken", 0); break; case LINEDEVSTATE_OPEN: #ifdef BETADEBUG printf("A Line device has been opened; no action taken.\n"); #endif /* BETADEBUG */ debug(F110,"TAPI LINEDEVSTATE_OPEN","A Line device has been openned; no action taken", 0); break; default: #ifdef BETADEBUG printf("Unhandled LINEDEVSTATE message\n"); #endif debug(F111,"TAPI LINEDEVSTATE_???", "Unhandled LINEDEVSTATE message", dwParam1); break; } } // // FUNCTION: DoLineCallState(..) // // PURPOSE: Handle LINE_CALLSTATE asynchronous messages. // // PARAMETERS: // dwDevice - Handle to Call who's state is changing. // dwMsg - Should always be LINE_CALLSTATE. // dwCallbackInstance - Unused by this sample. // dwParam1 - LINECALLSTATE constant specifying state change. // dwParam2 - Specific to dwParam1. // dwParam3 - LINECALLPRIVILEGE change, if any. // // RETURN VALUE: // none // // COMMENTS: // // This message is received whenever a call changes state. Lots of // things we do, ranging from notifying the user to closing the line // to actually connecting to the target of our phone call. // // What we do is usually obvious based on the call state change. // void DoLineCallState( DWORD dwDevice, DWORD dwMessage, DWORD dwCallbackInstance, DWORD dwParam1, DWORD dwParam2, DWORD dwParam3) { // Error if this CALLSTATE doesn't apply to our call in progress. if ( g_hCall != (HCALL)0 && (HCALL) dwDevice != g_hCall || g_hCall == (HCALL)0 && !g_bDialing && !g_bAnswering ) { int rc=0; debug(F101,"LINE_CALLSTATE: Unknown device ID '0x%lx'.","",dwDevice); #ifdef BETADEBUG printf("LINE_CALLSTATE: Unknown device ID '0x%lx\n",dwDevice); #endif rc = (*cklineDeallocateCall)((HCALL)dwDevice); OutputDebugLastError(rc,"DoLineCallState() lineDeallocateCall: "); #ifdef BETADEBUG printf(" DoLineCallState() lineDeallocateCall = %x\n",rc); #endif return; } // This sets the global g_dwCallState variable so if we are waiting // for a specific call state change, we will know when it happens. g_dwCallState = dwParam1; g_bCallStateReceived = TRUE; // dwParam3 contains changes to LINECALLPRIVILEGE, if there are any. switch (dwParam3) { case 0: break; // no change to call state // close line if we are made monitor. Shouldn't happen! case LINECALLPRIVILEGE_MONITOR: #ifdef BETADEBUG printf("line has monitor privilege\n"); #endif //cktapiclose(); break; // close line if we are made owner. Shouldn't happen! case LINECALLPRIVILEGE_OWNER: #ifdef BETADEBUG printf("line has owner privilege\n"); #endif //cktapiclose(); break; default: // Shouldn't happen! All cases handled. #ifdef BETADEBUG printf("Unknown LINECALLPRIVILEGE message\n"); #endif //cktapiclose(); return; } // dwParam1 is the specific CALLSTATE change that is occurring. switch (dwParam1) { case LINECALLSTATE_DIALTONE: if ( g_bDialing ) UpdateStatusBar("Dial Tone",1,0); break; case LINECALLSTATE_DIALING: if ( g_bDialing ) UpdateStatusBar("Dialing Call",1,0); break; case LINECALLSTATE_PROCEEDING: if ( g_bDialing ) UpdateStatusBar("Call is Proceeding",1,0); break; case LINECALLSTATE_RINGBACK: UpdateStatusBar("RingBack",1,0); break; case LINECALLSTATE_BUSY: if ( g_bDialing ) { UpdateStatusBar("Line is busy",1,0); PostTAPIConnectSem(); } break; case LINECALLSTATE_IDLE: msleep(1000); UpdateStatusBar("Line is idle",1,0); if ( ttyfd != -1 && ttyfd != -2 ) { cktapidisconnect(); SetConnectMode(FALSE); } PostTAPIConnectSem(); break; case LINECALLSTATE_SPECIALINFO: UpdateStatusBar("Special Info, probably couldn't dial number",1,0); PostTAPIConnectSem(); break; case LINECALLSTATE_DISCONNECTED: { LPSTR pszReasonDisconnected; switch (dwParam2) { case LINEDISCONNECTMODE_NORMAL: pszReasonDisconnected = "Remote Party Disconnected"; break; case LINEDISCONNECTMODE_UNKNOWN: pszReasonDisconnected = "Disconnected: Unknown reason"; break; case LINEDISCONNECTMODE_REJECT: pszReasonDisconnected = "Remote Party rejected call"; break; case LINEDISCONNECTMODE_PICKUP: pszReasonDisconnected = "Disconnected: Local phone picked up"; break; case LINEDISCONNECTMODE_FORWARDED: pszReasonDisconnected = "Disconnected: Forwarded"; break; case LINEDISCONNECTMODE_BUSY: pszReasonDisconnected = "Disconnected: Busy"; break; case LINEDISCONNECTMODE_NOANSWER: pszReasonDisconnected = "Disconnected: No Answer"; break; case LINEDISCONNECTMODE_BADADDRESS: pszReasonDisconnected = "Disconnected: Bad Address"; break; case LINEDISCONNECTMODE_UNREACHABLE: pszReasonDisconnected = "Disconnected: Unreachable"; break; case LINEDISCONNECTMODE_CONGESTION: pszReasonDisconnected = "Disconnected: Congestion"; break; case LINEDISCONNECTMODE_INCOMPATIBLE: pszReasonDisconnected = "Disconnected: Incompatible"; break; case LINEDISCONNECTMODE_UNAVAIL: pszReasonDisconnected = "Disconnected: Unavail"; break; case LINEDISCONNECTMODE_NODIALTONE: pszReasonDisconnected = "Disconnected: No Dial Tone"; break; default: pszReasonDisconnected = "Disconnected: LINECALLSTATE; Bad Reason"; break; } if ( ttyfd != -1 && ttyfd != -2 ) { cktapidisconnect(); SetConnectMode(FALSE); } PostTAPIConnectSem() ; UpdateStatusBar(pszReasonDisconnected,1,0); break; } case LINECALLSTATE_CONNECTED: // CONNECTED!!! { int rc; LPVARSTRING lpVarString = NULL; DWORD dwSizeofVarString = sizeof(VARSTRING) + 1024; long lReturn; // Very first, make sure this isn't a duplicated message. // A CALLSTATE message can be sent whenever there is a // change to the capabilities of a line, meaning that it is // possible to receive multiple CONNECTED messages per call. // The CONNECTED CALLSTATE message is the only one in TapiComm // where it would cause problems if it where sent more // than once. if ( g_bConnected && (HCALL) dwDevice == g_hCall ) break; if (!(g_bDialing || g_bAnswering)) { /* Get the hCall */ g_hCall = (HCALL) dwDevice; debug(F110,"TAPI LINECALLSTATE_CONNECTED", "were not Dialing and we're not Answering",0); if ( dwParam3 == LINECALLPRIVILEGE_OWNER ) { /* Need to check the Bearer Mode of the call */ /* are we even answering calls? */ rc = (*cklineHandoff)(g_hCall, NULL, LINEMEDIAMODE_DATAMODEM); OutputDebugLastError(rc,"lineHandoff:"); rc = (*cklineDeallocateCall)(g_hCall); OutputDebugLastError(rc,"lineDeallocateCall:"); if ( rc < 0 ) { cktapidisconnect(); } else { g_hCall = (HCALL)0; } } else /* if ( dwParam3 == LINECALLPRIVILEGE_MONITOR ) */ { rc = (*cklineDeallocateCall)(g_hCall); OutputDebugLastError(rc,"lineDeallocateCall:"); g_hCall = (HCALL)0; } break; } if ( g_bAnswering && g_hCall == (HCALL)0 ) { UpdateStatusBar("Incoming call being offered in connected state.",1,0); g_hCall = (HCALL) dwDevice; PostTAPIAnswerSem(); } UpdateStatusBar("Connection complete.",1,0); g_bConnected = TRUE; // Get the handle to the comm port from the driver so we can start // communicating. This is returned in a LPVARSTRING structure. do { // Free any preexiting VARSTRING if ( lpVarString != NULL ) free(lpVarString); // Allocate the VARSTRING structure lpVarString = malloc( dwSizeofVarString ) ; if (lpVarString == NULL) goto ErrorConnecting; lpVarString->dwTotalSize = dwSizeofVarString; // Fill the VARSTRING structure lReturn = (*cklineGetID)(0, 0, g_hCall, LINECALLSELECT_CALL, lpVarString, "comm/datamodem"); if (HandleLineErr(lReturn)) ; // Still need to check if structure was big enough. else { OutputDebugLineError(lReturn, "lineGetID unhandled error:"); goto ErrorConnecting; } // If the VARSTRING wasn't big enough, loop again. if ((lpVarString -> dwNeededSize) > (lpVarString -> dwTotalSize)) { dwSizeofVarString = lpVarString -> dwNeededSize; lReturn = -1; // Lets loop again. } } while(lReturn != SUCCESS); // Again, the handle to the comm port is contained in a // LPVARSTRING structure. Thus, the handle is the very first // thing after the end of the structure. Note that the name of // the comm port is right after the handle, but I don't want it. debug(F111,"TAPI DoLineCallState","ttyfd",ttyfd); (HANDLE) ttyfd = *((LPHANDLE)((LPBYTE)lpVarString + lpVarString -> dwStringOffset)); debug(F111,"TAPI DoLineCallState","ttyfd",ttyfd); lReturn = SetCommMask( (HANDLE) ttyfd, EV_RXCHAR ) ; debug(F111,"TAPI DoLineCallState","SetCommMask",lReturn); lReturn = SetupComm( (HANDLE) ttyfd, 20000, 20000 ) ; debug(F111,"TAPI DoLineCallState","SetupComm",lReturn); lReturn = PurgeComm( (HANDLE) ttyfd, PURGE_RXABORT | PURGE_TXABORT | PURGE_RXCLEAR | PURGE_TXCLEAR ); debug(F111,"TAPI DoLineCallState","PurgeComm",lReturn); ErrorConnecting: PostTAPIConnectSem() ; debug(F110,"TAPI DoLineCallState","TAPI Connect Sem posted",0); if (lpVarString) free(lpVarString); break; } case LINECALLSTATE_OFFERING: { int rc; LPLINECALLINFO lpCallInfo = NULL; DWORD dwSize = sizeof(LINECALLINFO); LONG lrc = 0; DWORD dwMediaMode= LINEMEDIAMODE_UNKNOWN; DWORD dwNumRings = 0; UpdateStatusBar("Incoming call being offered",1,0); g_hCall = (HCALL) dwDevice; /* Check Media Mode */ /* The next four lines prepare a VARSTRING structure to pass to Windows though lineGetID */ lpCallInfo = (LPLINECALLINFO) malloc (dwSize); if ( !lpCallInfo ) { cktapidisconnect(); return ; } memset(lpCallInfo,0,dwSize); lpCallInfo->dwTotalSize = dwSize; do { /* get modem handle associated with the line */ lrc = (*cklineGetCallInfo)(g_hCall, lpCallInfo); if ( ( lrc == LINEERR_STRUCTURETOOSMALL || lrc == 0 ) && (lpCallInfo->dwTotalSize < lpCallInfo->dwNeededSize) ) { /* the next six lines reallocate the VARSTRING */ dwSize = lpCallInfo->dwNeededSize ; free(lpCallInfo); lpCallInfo = (LPLINECALLINFO) malloc(dwSize); if ( !lpCallInfo ) { cktapidisconnect(); return; } memset(lpCallInfo,0,dwSize); lpCallInfo->dwTotalSize = dwSize ; } else if ( lrc ) { /* some kind of TAPI error */ OutputDebugLastError(lrc,"lineGetCallInfo:"); free(lpCallInfo); cktapidisconnect(); return; } else break; /* success */ } while ( TRUE ); dwMediaMode = lpCallInfo->dwMediaMode; free(lpCallInfo); #ifdef BETADEBUG /* what is the media mode */ if ( dwMediaMode & LINEMEDIAMODE_UNKNOWN ) printf(" MediaMode is UNKNOWN (it may be one of the following)\n"); if ( dwMediaMode & LINEMEDIAMODE_INTERACTIVEVOICE ) printf(" MediaMode is Interactive Voice\n"); if ( dwMediaMode & LINEMEDIAMODE_AUTOMATEDVOICE ) printf(" MediaMode is Automated Voice\n"); if ( dwMediaMode & LINEMEDIAMODE_TDD ) printf(" MediaMode is TDD\n"); if ( dwMediaMode & LINEMEDIAMODE_DIGITALDATA ) printf(" MediaMode is Digital Data\n"); if ( dwMediaMode & LINEMEDIAMODE_TELETEX ) printf(" MediaMode is TeleTex\n"); if ( dwMediaMode & LINEMEDIAMODE_VIDEOTEX ) printf(" MediaMode is VideoTex\n"); if ( dwMediaMode & LINEMEDIAMODE_MIXED ) printf(" MediaMode is Mixed\n"); if ( dwMediaMode & LINEMEDIAMODE_ADSI ) printf(" MediaMode is ADSI\n"); if ( dwMediaMode & LINEMEDIAMODE_VOICEVIEW ) printf(" MediaMode is VoiceView\n"); if ( dwMediaMode & LINEMEDIAMODE_DATAMODEM ) printf(" MediaMode is DataModem\n"); if ( dwMediaMode & LINEMEDIAMODE_G3FAX ) printf(" MediaMode is G3Fax\n"); if ( dwMediaMode & LINEMEDIAMODE_G4FAX ) printf(" MediaMode is G4Fax\n"); if ( dwMediaMode > LAST_LINEMEDIAMODE*2-1 ) printf(" MediaMode is %x\n", dwMediaMode ); #endif /* BETADEBUG */ #ifdef COMMENT /* Activate Media Mode Monitoring by the Service Provider */ (*cklineMonitorMedia)( g_hCall, dwMediaMode & ~LINEMEDIAMODE_UNKNOWN ); #endif /* COMMENT */ #ifdef BETADEBUG (*cklineGetNumRings)(g_hLine,0,&dwNumRings); printf(" User requests we wait %d rings before answering.\n", dwNumRings); #endif /* BETADEBUG */ /* Get the hCall */ if ( dwParam3 == LINECALLPRIVILEGE_OWNER ) { /* Need to check the Bearer Mode of the call */ /* are we even answering calls? */ if ( g_bAnswering ) PostTAPIAnswerSem(); else { rc = (*cklineHandoff)(g_hCall, NULL, LINEMEDIAMODE_DATAMODEM); OutputDebugLastError(rc,"lineHandoff:"); rc = (*cklineDeallocateCall)(g_hCall); OutputDebugLastError(rc,"lineDeallocateCall:"); if ( rc < 0 ) { cktapidisconnect(); } else { g_hCall = (HCALL)0; } } } else /* if ( dwParam3 == LINECALLPRIVILEGE_MONITOR ) */ { if ( g_bAnswering && !(dwMediaMode & ~(LINEMEDIAMODE_DATAMODEM | LINEMEDIAMODE_UNKNOWN)) ) { rc = (*cklineSetCallPrivilege)( g_hCall, LINECALLPRIVILEGE_OWNER ); OutputDebugLastError(rc,"lineSetCallPrivilege:"); if ( !rc ) { PostTAPIAnswerSem(); } else { rc = (*cklineDeallocateCall)(g_hCall); OutputDebugLastError(rc,"lineDeallocateCall:"); g_hCall = (HCALL)0; } } else { rc = (*cklineDeallocateCall)(g_hCall); OutputDebugLastError(rc,"lineDeallocateCall:"); g_hCall = (HCALL)0; } } break; } case LINECALLSTATE_ACCEPTED: UpdateStatusBar("Incoming call has been accepted",1,0); break; default: UpdateStatusBar("?Unhandled LINECALLSTATE message",1,0); break; } } void CALLBACK cklineCallbackFunc( DWORD dwDevice, DWORD dwMsg, DWORD dwCallbackInstance, DWORD dwParam1, DWORD dwParam2, DWORD dwParam3) { OutputDebugLineCallback( dwDevice, dwMsg, dwCallbackInstance, dwParam1, dwParam2, dwParam3); // All we do is dispatch the dwMsg to the correct handler. switch(dwMsg) { case LINE_CALLSTATE: debug(F110,"TAPI Callback","Line Callstate",0); #ifdef BETADEBUG printf("TAPI Callback - Line Callstate %x,%x,%x\n", dwParam1, dwParam2, dwParam3); #endif DoLineCallState(dwDevice, dwMsg, dwCallbackInstance, dwParam1, dwParam2, dwParam3); break; case LINE_CLOSE: debug(F110,"TAPI Callback","Line Close",0); #ifdef BETADEBUG printf("TAPI Callback - Line Close\n"); #endif DoLineClose(dwDevice, dwMsg, dwCallbackInstance, dwParam1, dwParam2, dwParam3); break; case LINE_LINEDEVSTATE: debug(F110,"TAPI Callback","Line LineDevState",0); #ifdef BETADEBUG printf("TAPI Callback - Line LineDevState %x,%x,%x\n", dwParam1, dwParam2, dwParam3); #endif DoLineDevState(dwDevice, dwMsg, dwCallbackInstance, dwParam1, dwParam2, dwParam3); break; case LINE_REPLY: debug(F110,"TAPI Callback","Line Reply",0); #ifdef BETADEBUG printf("TAPI Callback - Line Reply %x,%x,%x\n", dwParam1, dwParam2, dwParam3); #endif DoLineReply(dwDevice, dwMsg, dwCallbackInstance, dwParam1, dwParam2, dwParam3); break; case LINE_CREATE: debug(F110,"TAPI Callback","Line Create",0); #ifdef BETADEBUG printf("TAPI Callback - Line Create\n"); #endif DoLineCreate(dwDevice, dwMsg, dwCallbackInstance, dwParam1, dwParam2, dwParam3); break; default: debug(F110,"TAPI Callback","default",0); #ifdef BETADEBUG printf("TAPI Callback - default\n"); #endif break; } return; } BOOL HandleLineErr(long lLineErr) { debug(F101,"TAPI HandleLineErr","",lLineErr); if ( lLineErr ) return FALSE; else return TRUE ; } BOOL HandleNoDevicesInstalled(void) { return FALSE; } BOOL g_bLineInitialized = FALSE; void wintapiinit( void ) { long lReturn; BOOL bTryReInit = TRUE ; // Initialize TAPI do { debug(F111,"TAPI wintapiinit","g_hLineApp",g_hLineApp); debug(F111,"TAPI wintapiinit","hInst",hInst); debug(F111,"TAPI wintapiinit","cklineCallbackFunc",cklineCallbackFunc); debug(F111,"TAPI wintapiinit","g_dwNumDevs",g_dwNumDevs); lReturn = (*cklineInitialize)(&g_hLineApp, hInst, cklineCallbackFunc, "Kermit-95", &g_dwNumDevs); OutputDebugLastError(lReturn,"lineInitialize:"); // If we get this error, its because some other app has yet // to respond to the REINIT message. Wait 5 seconds and try // again. If it still doesn't respond, tell the user. if (lReturn == LINEERR_REINIT) { if (bTryReInit) { sleep(5); /* wait 5 secs, try again */ bTryReInit = FALSE; continue; } else { MessageBox(g_hDlgParentWindow, "A change to the system configuration requires that " "all Telephony applications relinquish their use of " "Telephony before any can progress. " "Some have not yet done so." ,"Warning",MB_OK); g_bInitializing = FALSE; PostTAPIInitSem(); return; } } if (lReturn == LINEERR_NODEVICE) { if (HandleNoDevicesInstalled()) continue; else { printf("No devices installed.\n"); g_bInitializing = FALSE; PostTAPIInitSem(); return; } } if (HandleLineErr(lReturn)) continue; else { OutputDebugLineError(lReturn, "lineInitialize unhandled error: "); g_bInitializing = FALSE; PostTAPIInitSem(); return; } } while(lReturn != SUCCESS); debug(F111,"TAPI wintapiinit SUCCESS","g_hLineApp",g_hLineApp); debug(F111,"TAPI wintapiinit SUCCESS","hInst",hInst); debug(F111,"TAPI wintapiinit SUCCESS","cklineCallbackFunc",cklineCallbackFunc); debug(F111,"TAPI wintapiinit SUCCESS","g_dwNumDevs",g_dwNumDevs); g_bLineInitialized = TRUE; PostTAPIInitSem(); debug(F111,"TAPI wintapiinit SUCCESS","g_bLineInitialized",g_bLineInitialized); } void wintapishutdown(void) { DWORD rc ; debug(F101,"wintapishutdown","",g_hLineApp); rc = (*cklineShutdown)( g_hLineApp ) ; OutputDebugLastError(rc,"lineShutdown:"); g_hLineApp = (HLINEAPP)0 ; PostTAPIInitSem(); } int cktapiopen(void) { debug(F111,"TAPI cktapiopen","tapiopen",tapiopen); if ( g_bClosing ) { int n=0; if ( dialdpy ) printf("Waiting for previous Close request to complete...\n"); debug(F110,"TAPI cktapiopen","Close in progress",0); while ( g_bClosing && n++ < 30) msleep(500); if ( n >= 30 ) { debug(F110,"TAPI cktapiopen","Close never completed",0); printf("?ERROR in Windows Telephony: close never completed.\n"); bleep(BP_FAIL); return(FALSE); } } if ( tapiopen ) { tapiopen++ ; debug(F111,"TAPI cktapiopen","tapiopen",tapiopen); return TRUE ; } debug(F110,"TAPI cktapiopen","sending OPT_TAPI_INIT",0); g_bLineInitialized = FALSE; ResetTAPIInitSem(); PostMessage( hwndGUI, OPT_TAPI_INIT, 0, 0 ) ; /* Wait for completion */ if (!WaitAndResetTAPIInitSem(60000)) { debug(F110,"TAPI cktapiopen","TAPIInitSem never completed",0); return FALSE; } if ( !g_bLineInitialized ) { debug(F110,"TAPI cktapiopen","Line not Initialized",0); return FALSE; } tapiopen++; debug(F111,"TAPI cktapiopen","tapiopen",tapiopen); return TRUE; } int cktapidevenum( void ) { int i = 0 ; DWORD dwAPIVersion ; LINEEXTENSIONID ExtensionID ; int datalines = 0 ; LONG rc; debug(F111,"TAPI Enumerate Devices","g_dwNumDevs",g_dwNumDevs); /* Free existing LineDevCaps */ for ( i = 0 ; i < g_dwNumDevs ; i++ ) { if ( g_lpLineDevCaps[i] ) { free( g_lpLineDevCaps[i] ) ; g_lpLineDevCaps[i] = NULL ; } } /* Enumerate current LineDevCaps */ for ( i=0 ; i < g_dwNumDevs ; i++ ) { g_lpLineDevCaps[i] = (LPLINEDEVCAPS) malloc (sizeof(LINEDEVCAPS)) ; if ( g_lpLineDevCaps[i] == NULL ) { debug(F111,"TAPI cktapidevenum", "unable to allocate memory for Device Caps",i); continue; } g_lpLineDevCaps[i]->dwTotalSize = sizeof(LINEDEVCAPS) ; if ( rc = (*cklineNegotiateAPIVersion)(g_hLineApp, i, TAPI_CURRENT_VERSION, TAPI_CURRENT_VERSION, &dwAPIVersion, &ExtensionID)) { OutputDebugLastError(rc,"lineNegotiateAPIVersion:"); free(g_lpLineDevCaps[i]); g_lpLineDevCaps[i] = NULL ; continue; } if (rc = (*cklineGetDevCaps)(g_hLineApp, i, dwAPIVersion, 0, g_lpLineDevCaps[i])) { OutputDebugLastError(rc,"lineGetDevCaps:"); free(g_lpLineDevCaps[i]); g_lpLineDevCaps[i] = NULL ; continue; } if ( g_lpLineDevCaps[i]->dwNeededSize > g_lpLineDevCaps[i]->dwTotalSize ) { DWORD NeededSize = g_lpLineDevCaps[i]->dwNeededSize; free(g_lpLineDevCaps[i]) ; g_lpLineDevCaps[i] = (LPLINEDEVCAPS) malloc (NeededSize) ; g_lpLineDevCaps[i]->dwTotalSize = NeededSize ; if ((*cklineGetDevCaps)(g_hLineApp, i, dwAPIVersion, 0, g_lpLineDevCaps[i])) { OutputDebugLastError(rc,"lineGetDevCaps:"); free(g_lpLineDevCaps[i]); g_lpLineDevCaps[i] = NULL ; continue; } } /* We now have a successful LineDevCaps structure */ if ( g_lpLineDevCaps[i]->dwMediaModes & LINEMEDIAMODE_DATAMODEM ) { /* then this is a valid line to use for data connections */ datalines++ ; } } debug(F111,"TAPI Enumerate Devices","datalines",datalines); return datalines ; } int cktapihangup( void ) { int rc; if ( g_bHangingUp ) { int n=0; debug(F110,"TAPI Hangup","already in progress",0); while (g_bHangingUp && n++ < 30) { msleep(500); } if (n < 30) { debug(F110,"TAPI Hangup","previous hangup request completed",0); return TRUE; } else { debug(F110,"TAPI Hangup","previous hangup request didn't complete",0); g_bHangingUp = FALSE; } } debug(F111,"TAPI Hangup","hCall",g_hCall); if ( g_hCall ) { #ifdef BETADEBUG if ( tapipass ) printf( "TAPI: Closing the line\n"); else printf("TAPI: Hanging up call\n"); #endif g_bReplyReceived = FALSE; g_lAsyncReply = SUCCESS; g_bHangingUp = TRUE; if ( tapipass ) { /* lineSetCallParams */ g_dwRequestedID = 0; rc = g_dwRequestedID = (cklineSetCallParams)(g_hCall,LINEBEARERMODE_VOICE,3100,3100,NULL); OutputDebugLastError(rc,"lineSetCallParams:"); if ( rc > 0 ) { int x=0; /* Wait for LineReply */ while ( !g_bReplyReceived ) { msleep(100); x += 100; if ( x == 5000 ) { debug(F110,"TAPI Hangup","lineSetCallParams reply never received",0); break; } } if ( x < 5000 ) OutputDebugLastError(g_lAsyncReply,"lineSetCallParams (Async):"); } } if ( dialdpy && !tapipass ) printf("Dropping the call, wait...\n"); g_bReplyReceived = FALSE; g_lAsyncReply = SUCCESS; g_dwRequestedID = 0; rc = g_dwRequestedID = (*cklineDrop)(g_hCall, NULL, 0 ); OutputDebugLastError(rc,"lineDrop:"); if ( rc > 0 ) { int x=0; /* Wait for LineReply */ while ( !g_bReplyReceived && g_hCall != (HCALL)0 ) { msleep(100); x += 100; if ( x == 30000 ) { debug(F110,"TAPI Hangup","lineDrop reply never received",0); g_bHangingUp = FALSE; if ( !g_bClosing ) { return cktapiclose(); } return FALSE; } } OutputDebugLastError(g_lAsyncReply,"lineDrop (Async):"); if ( g_hCall != (HCALL)0 ) { rc = (*cklineDeallocateCall)(g_hCall); OutputDebugLastError(rc,"TAPI Hangup - lineDeallocateCall:"); g_hCall = (HCALL)0; } } else { // g_hCall = NULL; g_bHangingUp = FALSE; return FALSE; } g_bHangingUp = FALSE; } if ( g_hLine != (HLINE)0 ) { debug(F111,"TAPI Hangup","ttyfd",ttyfd); if ( ttyfd != -1 && ttyfd != -2 ) { rc = CloseHandle( (HANDLE) ttyfd ); debug(F111,"TAPI Debug Last Error", rc?"CloseHandle: Success" : "CloseHandle: Failure", rc?0:GetLastError()); ttyfd = -2; } } return TRUE; } int cktapiclose(void) { DWORD rc ; debug(F111,"TAPI cktapiclose","g_bClosing",g_bClosing); if ( g_bClosing ) { int n=0; debug(F110,"TAPI Close","already in progress",0); while ( g_bClosing && n++ < 30 ) msleep(500); if ( n >= 30 ) { debug(F110,"TAPI Close","Previous Close never completed",0); return FALSE; } return TRUE; } debug(F111,"TAPI cktapiclose","tapiopen",tapiopen); if ( tapiopen > 0 ) { tapiopen-- ; if ( tapiopen == 1 ) { g_bClosing = TRUE; debug(F100,"TAPI Close","",0); cktapihangup(); if ( g_hLine ) { debug(F101,"Calling TAPI lineClose","",g_hLine); rc = (*cklineClose)( g_hLine ); OutputDebugLastError(rc,"lineClose:"); g_hLine = (HLINE)0 ; ttyfd = -1; } } if ( tapiopen == 0 ) { ResetTAPIInitSem(); PostMessage( hwndGUI, OPT_TAPI_SHUTDOWN, 0, 0 ) ; /* Wait for completion */ if (!WaitAndResetTAPIInitSem(60000)) { debug(F100,"TAPIInitSem never completed","",0); return FALSE; } } g_bClosing = FALSE; } debug(F100,"TAPI Close successful","",0); return TRUE; } int cktapiconfigline() { LPDEVCFG lpDevCfg = NULL; LPCOMMCONFIG lpCommConfig = NULL; LPMODEMSETTINGS lpModemSettings = NULL; DCB * lpDCB = NULL; if (!cktapiGetModemSettings( &lpDevCfg, &lpModemSettings, &lpCommConfig, &lpDCB )) { return FALSE; } if ( !tapiusecfg ) { /* we need to set TAPI values for tapilights; tapipreterm; tapipostterm; tapimanual; tapiinactivity; tapibong; */ lpDevCfg->dfgHdr.fwOptions = (tapilights ? 8 : 0) + (tapipreterm ? 1 : 0) + (tapipostterm ? 2 : 0) + (tapimanual ? 4 : 0) ; lpDevCfg->dfgHdr.wWaitBong = tapibong; lpModemSettings->dwCallSetupFailTimer = waitct; lpModemSettings->dwInactivityTimeout = tapiinactivity; lpDCB->BaudRate = speed; lpDCB->fBinary = TRUE ; lpDCB->fErrorChar = FALSE ; lpDCB->fAbortOnError = FALSE ; lpDCB->ErrorChar = '?' ; lpDCB->Parity = NOPARITY ; lpDCB->fParity = TRUE ; /* Tell Win32 not to perform any Parity checking at all */ lpDCB->ByteSize = 8 ; lpDCB->StopBits = ONESTOPBIT ; lpDCB->fDsrSensitivity = FALSE ; lpDCB->fDtrControl = DTR_CONTROL_ENABLE ; #ifndef NODIAL if ( dialec ) lpModemSettings->dwPreferredModemOptions |= MDM_ERROR_CONTROL; else lpModemSettings->dwPreferredModemOptions &= ~MDM_ERROR_CONTROL; if ( dialdc ) lpModemSettings->dwPreferredModemOptions |= MDM_COMPRESSION; else lpModemSettings->dwPreferredModemOptions &= ~MDM_COMPRESSION; #ifdef COMMENT if ( mdmspd ) lpModemSettings->dwPreferredModemOptions |= MDM_SPEED_ADJUST; else lpModemSettings->dwPreferredModemOptions &= ~MDM_SPEED_ADJUST; #endif /* COMMENT */ if ( dialidt ) lpModemSettings->dwPreferredModemOptions |= MDM_BLIND_DIAL; else lpModemSettings->dwPreferredModemOptions &= ~MDM_BLIND_DIAL; if ( dialmth == XYDM_T ) { lpModemSettings->dwPreferredModemOptions |= MDM_TONE_DIAL; dialmauto = 0; } else if ( dialmth == XYDM_D ) { lpModemSettings->dwPreferredModemOptions &= ~MDM_TONE_DIAL; dialmauto = 0; } if ( dialfc == FLO_XONX ) { lpModemSettings->dwPreferredModemOptions &= ~MDM_FLOWCONTROL_HARD; lpModemSettings->dwPreferredModemOptions |= MDM_FLOWCONTROL_SOFT; } else if ( dialfc == FLO_RTSC ) { lpModemSettings->dwPreferredModemOptions |= MDM_FLOWCONTROL_HARD; lpModemSettings->dwPreferredModemOptions &= ~MDM_FLOWCONTROL_SOFT; } else if ( dialfc == FLO_NONE ) { lpModemSettings->dwPreferredModemOptions &= ~MDM_FLOWCONTROL_HARD; lpModemSettings->dwPreferredModemOptions &= ~MDM_FLOWCONTROL_SOFT; } #endif /* NODIAL */ switch(flow) { case FLO_XONX: lpDCB->fOutX = TRUE ; lpDCB->fInX = TRUE ; lpDCB->fRtsControl = RTS_CONTROL_ENABLE ; lpDCB->fOutxCtsFlow = FALSE ; lpDCB->fTXContinueOnXoff = FALSE ; #ifndef NODIAL if ( dialfc == FLO_AUTO ) #endif /* NODIAL */ { lpModemSettings->dwPreferredModemOptions &= ~MDM_FLOWCONTROL_HARD; lpModemSettings->dwPreferredModemOptions |= MDM_FLOWCONTROL_SOFT; } break; case FLO_RTSC: lpDCB->fOutX = FALSE ; lpDCB->fInX = FALSE ; lpDCB->fRtsControl = RTS_CONTROL_HANDSHAKE ; lpDCB->fOutxCtsFlow = TRUE ; lpDCB->fTXContinueOnXoff = TRUE ; #ifndef NODIAL if ( dialfc == FLO_AUTO ) #endif /* NODIAL */ { lpModemSettings->dwPreferredModemOptions |= MDM_FLOWCONTROL_HARD; lpModemSettings->dwPreferredModemOptions &= ~MDM_FLOWCONTROL_SOFT; } break; case FLO_KEEP: /* leave things exactly as they are */ break; case FLO_NONE: /* turn off all flow control completely */ lpDCB->fOutX = FALSE ; lpDCB->fInX = FALSE ; lpDCB->fRtsControl = RTS_CONTROL_ENABLE ; lpDCB->fOutxCtsFlow = FALSE ; lpDCB->fTXContinueOnXoff = TRUE ; #ifndef NODIAL if ( dialfc == FLO_AUTO ) #endif /* NODIAL */ { lpModemSettings->dwPreferredModemOptions &= ~MDM_FLOWCONTROL_HARD; lpModemSettings->dwPreferredModemOptions &= ~MDM_FLOWCONTROL_SOFT; } break; } #ifndef NODIAL /* Speaker settings */ lpModemSettings->dwSpeakerMode = mdmspk; lpModemSettings->dwSpeakerVolume = mdmvol-1; #endif /* NODIAL */ lpDCB->XonChar = 0x11 ; lpDCB->XoffChar = 0x13; lpDCB->XonLim = 10 ; lpDCB->XoffLim = 10 ; } if (!cktapiSetModemSettings(lpDevCfg,lpCommConfig)) { return FALSE; } return (TRUE); } #ifndef NODIAL int cktapidial(char * number) { LINECALLPARAMS lcp; int rc=0; fail_code = 0; if ( tapipass ) { debug(F110,"cktapidial - should never have been called",number,0); return FALSE; } debug(F110,"cktapidial",number,0); g_bReplyReceived = FALSE; g_bConnected = FALSE; g_bDialing = TRUE; g_lAsyncReply = SUCCESS; ResetTAPIConnectSem(); if ( g_hCall == (HCALL)0 ) { cktapiconfigline(); memset(&lcp,0,sizeof(LINECALLPARAMS)); lcp.dwBearerMode = LINEBEARERMODE_VOICE; lcp.dwMediaMode = LINEMEDIAMODE_DATAMODEM; lcp.dwTotalSize = sizeof(LINECALLPARAMS); lcp.dwCallParamFlags = LINECALLPARAMFLAGS_IDLE | LINECALLPARAMFLAGS_SECURE; #ifdef COMMENT lcp.dwNoAnswerTimeout = waitct; /* TAPI 2.0 */ #endif /* COMMENT */ g_dwRequestedID = 0; rc = g_dwRequestedID = (*cklineMakeCall)( g_hLine, &g_hCall, number, 0, &lcp ) ; OutputDebugLastError(rc,"lineMakeCall:"); } else { g_dwRequestedID = 0; rc = g_dwRequestedID = (*cklineDial)( g_hCall, number, 0 ) ; OutputDebugLastError(rc,"lineDial:"); } if ( rc < 0 ) { if ( rc == LINEERR_CALLUNAVAIL || rc == LINEERR_INUSE || rc == LINEERR_NODEVICE ) { fail_code = F_MINIT; } #ifdef BETADEBUG printf("lineMakeCall failed rc=%x\n",rc ) ; #endif if ( dialdpy ) printf("Call failed: %s\n",cktapiErrorString(rc)); g_hCall = (HCALL)0; cktapiclose(); g_bDialing = FALSE; return FALSE; } else { int x = 0; #ifdef BETADEBUG printf("lineMakeCall successful\n"); #endif /* Wait for LineReply */ while ( !g_bReplyReceived && fail_code == 0 ) { msleep(100); x += 100; if ( x == 5000 ) { debug(F110,"cktapidial", "lineMakeCall/Dial Reply never received",0); break; } } if ( fail_code == 0 ) OutputDebugLastError(g_lAsyncReply, "lineMakeCall/Dial (Async):"); else debug(F111,"cktapidial","fail_code",fail_code); if ( fail_code == F_INT || fail_code == F_MINIT ) { /* Catch early if possible */ cktapihangup(); g_bDialing = FALSE; return FALSE; } if ( g_lAsyncReply != SUCCESS ) { #ifdef BETADEBUG printf("lineMakeCall failed (Async Reply) rc=%x\n",g_lAsyncReply ) ; #endif if ( dialdpy ) printf("Call failed: %s\n",cktapiErrorString(g_lAsyncReply)); g_hCall = (HCALL)0; cktapiclose(); g_bDialing = FALSE; return FALSE; } /* Are we partial dialing? */ if ( number[strlen(number)-1] == ';' ) return TRUE; /* Wait for Success or Failure of Connection */ if (!WaitAndResetTAPIConnectSem(waitct*1000)) { debug(F101,"TAPI Connect Timeout","",waitct); #ifdef BETADEBUG printf("TAPI connect semaphore never posted\n"); #endif if ( dialdpy ) printf("Call failed: Timeout\n"); g_bDialing = FALSE; return FALSE; } if ( fail_code == F_INT || fail_code == F_MINIT ) { cktapihangup(); g_bDialing = FALSE; return FALSE; } } if ( !g_bConnected ) { cktapihangup(); g_bDialing = FALSE; return FALSE; } if ( ttyfd == -1 || ttyfd == -2 ) { /* if we did not get the Comm handle via the CONNECT message */ /* then get it now */ ttyfd = (int) GetModemHandleFromLine( g_hLine ); SetCommMask( (HANDLE) ttyfd, EV_RXCHAR ) ; SetupComm( (HANDLE) ttyfd, 20000, 20000 ) ; PurgeComm( (HANDLE) ttyfd, PURGE_RXABORT | PURGE_TXABORT | PURGE_RXCLEAR | PURGE_TXCLEAR ) ; } if ( !ttyfd || ttyfd == -1 ) { ttyfd = -2 ; g_bDialing = FALSE; return FALSE; } #ifdef BETADEBUG DisplayCommProperties((HANDLE)ttyfd); #endif /* BETADEBUG */ g_bDialing = FALSE; return TRUE; } int cktapianswer( void ) { int rc=0,x=0; extern int dialatmo; char * filename=NULL, *p=NULL; filename = GetLoadPath(); if ( filename && *filename ) { p = filename + strlen(filename); while ( p != filename ) { if ( *p == '\\' || *p == '/' ) { filename = p + 1 ; break; } p--; } if ( filename >= p ) { rc = (*cklineSetAppPriority)(filename,LINEMEDIAMODE_DATAMODEM, NULL,0,NULL,1); OutputDebugLastError(rc,"lineSetAppPriority:"); #ifdef BETADEBUG printf(" lineSetAppPriority rc=0x%x\n",rc); #endif } } /* Wait for LINECALLSTATE_OFFERING to get the hCall */ fail_code = 0; g_bAnswering = TRUE; ResetTAPIAnswerSem(); rc = WaitAndResetTAPIAnswerSem(dialatmo<=0?INFINITE:dialatmo*1000); if ( !rc ) { #ifdef BETADEBUG printf("TAPI Answer Sem never SET\n",rc ) ; #endif if ( dialdpy ) printf("Answer failed: Timeout\n"); return FALSE; } if ( fail_code == F_INT ) { g_bAnswering = FALSE; cktapihangup(); return FALSE; } /* Then use lineAnswer() to CONNECT to the call */ g_bReplyReceived = FALSE; g_lAsyncReply = SUCCESS; g_bConnected = FALSE; ResetTAPIConnectSem(); g_dwRequestedID = 0; rc = g_dwRequestedID = (*cklineAccept)( g_hCall, NULL, 0) ; OutputDebugLastError(rc,"lineAccept:"); if ( rc < 0 ) { #ifdef BETADEBUG printf("lineAccept failed rc=%x\n",rc ) ; #endif if ( dialdpy ) printf("Answer failed: %s\n",cktapiErrorString(rc)); g_bAnswering = FALSE; cktapihangup(); return FALSE; } /* Wait for LineReply */ while ( !g_bReplyReceived && fail_code == 0 ) { msleep(100); x += 100; if ( x == 5000 ) { debug(F110,"cktapianswer", "lineAccept Reply never received",0); if ( dialdpy ) printf("Answer failed: required TAPI reply never received.\n"); g_bAnswering = FALSE; cktapihangup(); return FALSE; } } if ( g_lAsyncReply != SUCCESS && g_lAsyncReply != LINEERR_OPERATIONUNAVAIL) { #ifdef BETADEBUG printf("lineAccept failed (Async Reply) rc=%x\n",g_lAsyncReply ) ; #endif if ( dialdpy ) printf("Answer failed: %s\n",cktapiErrorString(g_lAsyncReply)); g_bAnswering = FALSE; cktapihangup(); return FALSE; } #ifdef BETADEBUG printf("lineAccept successful\n"); #endif g_bReplyReceived = FALSE; g_lAsyncReply = SUCCESS; g_dwRequestedID = 0; rc = g_dwRequestedID = (*cklineAnswer)( g_hCall, NULL, 0) ; OutputDebugLastError(rc,"lineAnswer:"); if ( rc < 0 ) { #ifdef BETADEBUG printf("lineAnswer failed rc=%x\n",rc ) ; #endif if ( dialdpy ) printf("Answer failed: %s\n",cktapiErrorString(rc)); g_bAnswering = FALSE; cktapihangup(); return FALSE; } /* Wait for LineReply */ while ( !g_bReplyReceived && fail_code == 0 ) { msleep(100); x += 100; if ( x == waitct*1000 ) { debug(F110,"cktapianswer", "lineAnswer Reply never received",0); if ( dialdpy ) printf("Answer failed: required TAPI reply never received.\n"); g_bAnswering = FALSE; cktapihangup(); return FALSE; } } OutputDebugLastError(g_lAsyncReply,"lineAnswer (Async):"); if ( g_lAsyncReply != SUCCESS ) { #ifdef BETADEBUG printf("lineAnswer failed (Async Reply) rc=%x\n",g_lAsyncReply ) ; #endif if ( dialdpy ) printf("Answer failed: %s\n",cktapiErrorString(g_lAsyncReply)); g_bAnswering = FALSE; cktapihangup(); return FALSE; } #ifdef BETADEBUG printf("lineAnswer successful\n"); #endif /* Wait for Success or Failure of Connection */ if (!WaitAndResetTAPIConnectSem(waitct>0?waitct*1000:60000)) { #ifdef BETADEBUG printf("TAPI connect semaphore never posted\n"); #endif if ( dialdpy ) printf("Answer failed: Carrier Detect Timeout\n"); g_bAnswering = FALSE; cktapihangup(); return FALSE; } if ( fail_code == F_INT || !g_bConnected ) { g_bAnswering = FALSE; cktapihangup(); return FALSE; } #ifdef BETADEBUG /* But is the call of the correct Media Mode? */ { LPLINECALLINFO lpCallInfo = NULL; DWORD dwSize = sizeof(LINECALLINFO); LONG lrc = 0; lpCallInfo = (LPLINECALLINFO) malloc (dwSize); if ( !lpCallInfo ) { g_bAnswering = FALSE; cktapihangup(); return FALSE; } memset(lpCallInfo,0,dwSize); lpCallInfo->dwTotalSize = dwSize; do { /* get modem handle associated with the line */ lrc = (*cklineGetCallInfo)(g_hCall, lpCallInfo); if ( ( lrc == LINEERR_STRUCTURETOOSMALL || lrc == 0 ) && (lpCallInfo->dwTotalSize < lpCallInfo->dwNeededSize) ) { /* the next six lines reallocate the VARSTRING */ dwSize = lpCallInfo->dwNeededSize ; free(lpCallInfo); lpCallInfo = (LPLINECALLINFO) malloc(dwSize); if ( !lpCallInfo ) { g_bAnswering = FALSE; cktapihangup(); return FALSE; } memset(lpCallInfo,0,dwSize); lpCallInfo->dwTotalSize = dwSize ; } else if ( lrc ) { /* some kind of TAPI error */ OutputDebugLastError(lrc,"lineGetCallInfo:"); free(lpCallInfo); g_bAnswering = FALSE; cktapihangup(); return FALSE; } else break; /* success */ } while ( TRUE ); /* what is the media mode */ if ( lpCallInfo->dwMediaMode & LINEMEDIAMODE_UNKNOWN ) printf(" MediaMode is UNKNOWN (it may be one of the following)\n"); if ( lpCallInfo->dwMediaMode & LINEMEDIAMODE_INTERACTIVEVOICE ) printf(" MediaMode is Interactive Voice\n"); if ( lpCallInfo->dwMediaMode & LINEMEDIAMODE_AUTOMATEDVOICE ) printf(" MediaMode is Automated Voice\n"); if ( lpCallInfo->dwMediaMode & LINEMEDIAMODE_TDD ) printf(" MediaMode is TDD\n"); if ( lpCallInfo->dwMediaMode & LINEMEDIAMODE_DIGITALDATA ) printf(" MediaMode is Digital Data\n"); if ( lpCallInfo->dwMediaMode & LINEMEDIAMODE_TELETEX ) printf(" MediaMode is TeleTex\n"); if ( lpCallInfo->dwMediaMode & LINEMEDIAMODE_VIDEOTEX ) printf(" MediaMode is VideoTex\n"); if ( lpCallInfo->dwMediaMode & LINEMEDIAMODE_MIXED ) printf(" MediaMode is Mixed\n"); if ( lpCallInfo->dwMediaMode & LINEMEDIAMODE_ADSI ) printf(" MediaMode is ADSI\n"); if ( lpCallInfo->dwMediaMode & LINEMEDIAMODE_VOICEVIEW ) printf(" MediaMode is VoiceView\n"); if ( lpCallInfo->dwMediaMode & LINEMEDIAMODE_DATAMODEM ) printf(" MediaMode is DataModem\n"); if ( lpCallInfo->dwMediaMode & LINEMEDIAMODE_G3FAX ) printf(" MediaMode is G3Fax\n"); if ( lpCallInfo->dwMediaMode & LINEMEDIAMODE_G4FAX ) printf(" MediaMode is G4Fax\n"); if ( lpCallInfo->dwMediaMode > LAST_LINEMEDIAMODE*2-1 ) printf(" MediaMode is %x\n", lpCallInfo->dwMediaMode ); free(lpCallInfo); } #endif /* BETADEBUG */ if ( ttyfd == -1 || ttyfd == -2 ) { /* if we did not get the Comm handle via the CONNECT message */ /* then get it now */ ttyfd = (int) GetModemHandleFromLine( g_hLine ); SetCommMask( (HANDLE) ttyfd, EV_RXCHAR ) ; SetupComm( (HANDLE) ttyfd, 20000, 20000 ) ; PurgeComm( (HANDLE) ttyfd, PURGE_RXABORT | PURGE_TXABORT | PURGE_RXCLEAR | PURGE_TXCLEAR ) ; } if ( !ttyfd || ttyfd == -1 ) { ttyfd = -2 ; g_bAnswering = FALSE; return FALSE; } #ifdef BETADEBUG DisplayCommProperties((HANDLE)ttyfd); #endif /* BETADEBUG */ /* turn off media montoring since we have already accepted the call */ /* as a data modem call */ (*cklineMonitorMedia)(g_hCall,0); g_bAnswering = FALSE; return TRUE; } #endif /* NODIAL */ int cktapiBuildLineTable( struct keytab ** pTable, struct keytab ** pTable2, int * pN ) { int i, n ; if ( *pTable ) { for ( i=0 ; i < *pN ; i++ ) free( (*pTable)[i].kwd ) ; free ( *pTable ) ; } if ( *pTable2 ) { for ( i=0 ; i < *pN ; i++ ) free( (*pTable2)[i].kwd ) ; free ( *pTable2 ) ; } *pTable = NULL ; *pTable2 = NULL ; *pN = 0 ; if (!TAPIAvail) return(0); cktapiopen() ; n = cktapidevenum() ; cktapiclose() ; debug(F100,"TAPI cktapiBuildLineTable","",0); if ( n ) { *pTable = malloc( sizeof(struct keytab) * n ) ; *pTable2 = malloc( sizeof(struct keytab) * n ) ; for ( i=0 ; i < g_dwNumDevs ; i++ ) { if ( g_lpLineDevCaps[i] == NULL ) { debug(F111,"TAPI LineDevCaps entry is NULL","i",i); } else if ( g_lpLineDevCaps[i]->dwMediaModes & LINEMEDIAMODE_DATAMODEM ) { char * newstr = _strdup( ((char *)(g_lpLineDevCaps[i]))+g_lpLineDevCaps[i]->dwLineNameOffset) ; char * newstr2 = _strdup( ((char *)(g_lpLineDevCaps[i]))+g_lpLineDevCaps[i]->dwLineNameOffset) ; int newval = i; int j = 0, len = 0; debug(F111,"TAPI LINEMEDIAMODE_DATAMODEM",newstr,i); /* Make a version that uses Underscores instead of spaces */ len = strlen(newstr2); for ( j=0 ; j 0 ) { tempval = (*pTable)[j].kwval; tempstr = (*pTable)[j].kwd; tempstr2 = (*pTable2)[j].kwd; (*pTable)[j].kwd = newstr ; (*pTable)[j].kwval = newval; (*pTable2)[j].kwd = newstr2 ; (*pTable2)[j].kwval = newval; newval = tempval; newstr = tempstr; (*pTable)[j].flgs = 0; newstr2 = tempstr2; (*pTable2)[j].flgs = 0; } } (*pTable)[*pN].kwd = newstr ; (*pTable)[*pN].kwval = newval; (*pTable)[*pN].flgs = 0 ; (*pTable2)[*pN].kwd = newstr2 ; (*pTable2)[*pN].kwval = newval; (*pTable2)[*pN].flgs = 0 ; (*pN)++ ; } else { debug(F111,"TAPI ~LINEMEDIAMODE_DATAMODEM", ((char *)(g_lpLineDevCaps[i]))+g_lpLineDevCaps[i]->dwLineNameOffset, i); } } if ( *pN == 0 ) { /* TAPI Devices exist, but none can be used by Kermit */ free ( *pTable ) ; free ( *pTable2 ) ; *pTable = NULL; *pTable2 = NULL; } } return(1); } int cktapiBuildLocationTable( struct keytab ** pTable, int * pN ) { LPLINETRANSLATECAPS lpTranslateCaps = NULL; DWORD dwSizeofTranslateCaps = sizeof(LINETRANSLATECAPS); long lReturn = 0; DWORD dwCounter; LPLINELOCATIONENTRY lpLocationEntry; LPLINECARDENTRY lpLineCardEntry = NULL; int i = 0 ; if ( *pTable ) { for ( i=0 ; i < *pN ; i++ ) free( (*pTable)[i].kwd ) ; free ( *pTable ) ; } *pTable = NULL ; *pN = 0 ; if (!TAPIAvail) return(0); cktapiopen() ; // First, get the TRANSLATECAPS do { lpTranslateCaps = (LPLINETRANSLATECAPS) CheckAndReAllocBuffer( (LPVOID) lpTranslateCaps, dwSizeofTranslateCaps, "cktapiBuildLocationTable"); if (lpTranslateCaps == NULL) { cktapiclose(); return 0; } lReturn = (*cklineGetTranslateCaps)(g_hLineApp, TAPI_CURRENT_VERSION, lpTranslateCaps); if (HandleLineErr(lReturn)) ; else { OutputDebugLineError(lReturn, "lineGetTranslateCaps unhandled error: "); LocalFree(lpTranslateCaps); cktapiclose(); return 0; } if ((lpTranslateCaps -> dwNeededSize) > (lpTranslateCaps -> dwTotalSize)) { dwSizeofTranslateCaps = lpTranslateCaps ->dwNeededSize; lReturn = -1; // Lets loop again. } } while(lReturn != SUCCESS); cktapiclose() ; debug(F100,"TAPI cktapiBuildLocationTable","",0); // Find the location information in the TRANSLATECAPS lpLocationEntry = (LPLINELOCATIONENTRY) (((LPBYTE) lpTranslateCaps) + lpTranslateCaps->dwLocationListOffset); if ( lpTranslateCaps->dwNumLocations > 0 ) { *pTable = malloc( sizeof(struct keytab) * lpTranslateCaps->dwNumLocations ) ; // enumerate all the locations for(dwCounter = 0; dwCounter < lpTranslateCaps -> dwNumLocations; dwCounter++) { // Put each one into the keytab char * newstr = _strdup((((LPBYTE) lpTranslateCaps) + lpLocationEntry[dwCounter].dwLocationNameOffset)) ; int newval = lpLocationEntry[dwCounter].dwPermanentLocationID; int j = 0, len = 0; debug(F111,"TAPI lpLocationEntry.dwLocationName",newstr,i); /* Use Underscores instead of spaces */ len = strlen(newstr); for ( j=0;j 0 ) { tempval = (*pTable)[j].kwval; tempstr = (*pTable)[j].kwd; (*pTable)[j].kwd = newstr ; (*pTable)[j].kwval = newval; newval = tempval; newstr = tempstr; (*pTable)[j].flgs = 0; } } (*pTable)[*pN].kwd = newstr; (*pTable)[*pN].kwval = newval ; (*pTable)[*pN].flgs = 0 ; (*pN)++ ; } } LocalFree(lpTranslateCaps); return(1); } int cktapiGetCurrentLocationID( void ) { LPLINETRANSLATECAPS lpTranslateCaps = NULL; DWORD dwSizeofTranslateCaps = sizeof(LINETRANSLATECAPS); long lReturn; int locationID=-1; debug(F100,"cktapiGetCurrentLocationID","",0); // First, get the TRANSLATECAPS do { lpTranslateCaps = (LPLINETRANSLATECAPS) CheckAndReAllocBuffer((LPVOID) lpTranslateCaps, dwSizeofTranslateCaps, "cktapiGetCurrentLocationID"); if (lpTranslateCaps == NULL) { debug(F110,"cktapiGetCurrentLocationID","lpTranslateCaps == NULL",0); return -1; } lReturn = (*cklineGetTranslateCaps)(g_hLineApp, TAPI_CURRENT_VERSION, lpTranslateCaps); debug(F111,"cktapiGetCurrentLocationID","cklineGetTranslateCaps returns",lReturn); if (!HandleLineErr(lReturn)) { OutputDebugLineError(lReturn, "lineGetTranslateCaps unhandled error: "); LocalFree(lpTranslateCaps); return -1; } if ((lpTranslateCaps -> dwNeededSize) > (lpTranslateCaps -> dwTotalSize)) { dwSizeofTranslateCaps = lpTranslateCaps ->dwNeededSize; lReturn = -1; // Lets loop again. } } while(lReturn != SUCCESS); locationID = lpTranslateCaps->dwCurrentLocationID; LocalFree(lpTranslateCaps); debug(F111,"cktapiGetCurrentLocationID","locationID",locationID); return locationID; } void cktapiDisplayTapiLocationInfo( void ) { printf("TAPI Location (%d): %s\n", tapilocid, tapiloc ); printf(" Country ID = %d\n", tapiCountryID); printf(" CountryCode = %d\n", tapiCountryCode); printf(" CountryName = %s\n", tapiCountryName); printf(" SameAreaRule = %s\n", tapiSameAreaRule); printf(" LongDistanceRule = %s\n", tapiLongDistanceRule); printf(" InternationalRule = %s\n", tapiInternationalRule); printf(" AreaCode = %s\n", tapiAreaCode); printf(" PreferredCardID = %d\n", tapiPreferredCardID); printf(" LocalAccessCode = %s\n", tapiLocalAccessCode); printf(" LongDistAccessCode = %s\n", tapiLongDistAccessCode); printf(" TollPrefixList = %s\n", tapiTollPrefixList); printf(" CancelCallWaiting = %s\n", tapiCancelCallWaiting); printf(" Options = %d\n", tapiOptions); } void SaveTapiLocationInfo( LPLINETRANSLATECAPS lpTranslateCaps, LPLINELOCATIONENTRY lpLocationEntry ) { LPLINECOUNTRYLIST lpCountryList = NULL; LPLINECOUNTRYENTRY lpCountryEntry = NULL; DWORD dwSizeofCountryList = sizeof(LINECOUNTRYLIST); long lReturn=0; int i=0; debug(F111,"SaveTapiLocationInfo","lpTranslateCaps",lpTranslateCaps); debug(F111,"SaveTapiLocationInfo","lpLocationEntry",lpLocationEntry); tapilocid = lpLocationEntry->dwPermanentLocationID; tapiCountryID = lpLocationEntry->dwCountryID; tapiCountryCode = lpLocationEntry->dwCountryCode; strncpy(tapiloc, (((LPSTR) lpTranslateCaps) + lpLocationEntry->dwLocationNameOffset), lpLocationEntry->dwLocationNameSize >= 256 ? 256 : lpLocationEntry->dwLocationNameSize); tapiloc[256]='\0'; debug(F111,"SaveTapiLocationInfo",tapiloc,lpLocationEntry->dwLocationNameSize); do { lpCountryList = (LPLINECOUNTRYLIST) CheckAndReAllocBuffer((LPVOID) lpCountryList, dwSizeofCountryList, "SaveTapiLocationInfo"); if (lpCountryList == NULL) return; /* Win95 doesn't return anything is CountryID is 1 */ lReturn = (*cklineGetCountry)(isWin95()?0:tapiCountryID, TAPI_CURRENT_VERSION, lpCountryList); if (HandleLineErr(lReturn)) ; else { OutputDebugLineError(lReturn, "lineGetCountry unhandled error: "); LocalFree(lpCountryList); return; } if ((lpCountryList -> dwNeededSize) > (lpCountryList -> dwTotalSize)) { dwSizeofCountryList = lpCountryList ->dwNeededSize; lReturn = -1; // Lets loop again. } } while(lReturn != SUCCESS); for ( i=0; idwNumCountries; i++) { lpCountryEntry = (LPLINECOUNTRYENTRY) ((BYTE *)lpCountryList + lpCountryList->dwCountryListOffset + (i * sizeof(LINECOUNTRYENTRY))); if ( lpCountryEntry->dwCountryID == tapiCountryID ) break; } if ( i == lpCountryList->dwNumCountries ) lpCountryEntry = NULL; if ( lpCountryEntry ) { /* 'E' = Country Code */ /* 'F' = Area Code */ /* 'G' = Local Number */ strncpy(tapiCountryName, ((LPSTR) lpCountryList + lpCountryEntry->dwCountryNameOffset), lpCountryEntry->dwCountryNameSize >= 64 ? 64 : lpCountryEntry->dwCountryNameSize); tapiCountryName[64]='\0'; strncpy(tapiSameAreaRule,((LPSTR) lpCountryList + lpCountryEntry->dwSameAreaRuleOffset), lpCountryEntry->dwSameAreaRuleSize >= 64 ? 64 : lpCountryEntry->dwSameAreaRuleSize); tapiSameAreaRule[64]='\0'; strncpy(tapiLongDistanceRule,((LPSTR) lpCountryList + lpCountryEntry->dwLongDistanceRuleOffset), lpCountryEntry->dwLongDistanceRuleSize >= 64 ? 64 : lpCountryEntry->dwLongDistanceRuleSize); tapiLongDistanceRule[64]='\0'; strncpy(tapiInternationalRule,((LPSTR) lpCountryList + lpCountryEntry->dwInternationalRuleOffset), lpCountryEntry->dwInternationalRuleSize >= 64 ? 64 : lpCountryEntry->dwInternationalRuleSize); tapiInternationalRule[64]='\0'; } else { tapiCountryName[0] = '\0'; tapiSameAreaRule[0] = '\0'; tapiLongDistanceRule[0] = '\0'; tapiInternationalRule[0] = '\0'; } strncpy(tapiAreaCode, (((LPSTR) lpTranslateCaps) + lpLocationEntry->dwCityCodeOffset), lpLocationEntry->dwCityCodeSize >= 64 ? 64 : lpLocationEntry->dwCityCodeSize); tapiAreaCode[64]='\0'; tapiPreferredCardID = lpLocationEntry->dwPreferredCardID; tapiOptions = lpLocationEntry->dwOptions; strncpy(tapiLocalAccessCode, (((LPSTR) lpTranslateCaps) + lpLocationEntry->dwLocalAccessCodeOffset), lpLocationEntry->dwLocalAccessCodeSize >= 64 ? 64 : lpLocationEntry->dwLocalAccessCodeSize); tapiLocalAccessCode[64]='\0'; strncpy(tapiLongDistAccessCode, (((LPSTR) lpTranslateCaps) + lpLocationEntry->dwLongDistanceAccessCodeOffset), lpLocationEntry->dwLongDistanceAccessCodeSize >= 64 ? 64 : lpLocationEntry->dwLongDistanceAccessCodeSize); tapiLongDistAccessCode[64]='\0'; strncpy(tapiTollPrefixList, (((LPSTR) lpTranslateCaps) + lpLocationEntry->dwTollPrefixListOffset), lpLocationEntry->dwTollPrefixListSize >= 4096 ? 4096 : lpLocationEntry->dwTollPrefixListSize); tapiTollPrefixList[4096]='\0'; strncpy(tapiCancelCallWaiting, (((LPSTR) lpTranslateCaps) + lpLocationEntry->dwCancelCallWaitingOffset), lpLocationEntry->dwCancelCallWaitingSize >= 64 ? 64 : lpLocationEntry->dwCancelCallWaitingSize); tapiCancelCallWaiting[64]='\0'; #ifdef BETADEBUG cktapiDisplayTapiLocationInfo(); #endif /* BETADEBUG */ LocalFree(lpCountryList); } int cktapiFetchLocationInfoByName( char * CurrentLocation ) { LPLINETRANSLATECAPS lpTranslateCaps = NULL; DWORD dwSizeofTranslateCaps = sizeof(LINETRANSLATECAPS); long lReturn; DWORD dwCounter; LPLINELOCATIONENTRY lpLocationEntry; LPLINECARDENTRY lpLineCardEntry = NULL; /* If no name specified, use Current Location */ if ( !CurrentLocation || !CurrentLocation[0] ) { int ID = cktapiGetCurrentLocationID(); return cktapiFetchLocationInfoByID( ID ); } // First, get the TRANSLATECAPS do { lpTranslateCaps = (LPLINETRANSLATECAPS) CheckAndReAllocBuffer( (LPVOID) lpTranslateCaps, dwSizeofTranslateCaps, "cktapiFetchLocationInfoByName"); if (lpTranslateCaps == NULL) return FALSE; lReturn = (*cklineGetTranslateCaps)(g_hLineApp, TAPI_CURRENT_VERSION, lpTranslateCaps); if (HandleLineErr(lReturn)) ; else { OutputDebugLineError(lReturn, "lineGetTranslateCaps unhandled error: "); LocalFree(lpTranslateCaps); return FALSE; } if ((lpTranslateCaps -> dwNeededSize) > (lpTranslateCaps -> dwTotalSize)) { dwSizeofTranslateCaps = lpTranslateCaps ->dwNeededSize; lReturn = -1; // Lets loop again. } } while(lReturn != SUCCESS); // Find the location information in the TRANSLATECAPS lpLocationEntry = (LPLINELOCATIONENTRY) (((LPBYTE) lpTranslateCaps) + lpTranslateCaps->dwLocationListOffset); debug(F110,"cktapiFetchLocationInfoByName","lpLocationEntry",lpLocationEntry); // loop through all locations, looking for a location match for(dwCounter = 0; dwCounter < lpTranslateCaps -> dwNumLocations; dwCounter++) { if (_stricmp((((LPSTR) lpTranslateCaps) + lpLocationEntry[dwCounter].dwLocationNameOffset), CurrentLocation) == 0) { // Found it! Set the current location, if necessary. int ID = cktapiGetCurrentLocationID(); if ( ID != lpLocationEntry[dwCounter].dwPermanentLocationID ) { lReturn = (*cklineSetCurrentLocation)(g_hLineApp, lpLocationEntry[dwCounter].dwPermanentLocationID); OutputDebugLastError(lReturn,"lineSetCurrentLocation:"); } break; } } if ( dwCounter == lpTranslateCaps -> dwNumLocations ) { debug(F110,"cktapiFetchLocationInfoByName","LocationEntry not found",0); LocalFree(lpTranslateCaps); return FALSE; } // Was a match for lpszCurrentLocation found? if (lpLocationEntry[dwCounter].dwPreferredCardID == MAXDWORD) { debug(F110,"cktapiFetchLocationInfoByName","LocationEntry not found",0); LocalFree(lpTranslateCaps); return FALSE; } SaveTapiLocationInfo( lpTranslateCaps, &lpLocationEntry[dwCounter] ); LocalFree(lpTranslateCaps); return TRUE; } int cktapiFetchLocationInfoByID( int LocationID ) { LPLINETRANSLATECAPS lpTranslateCaps = NULL; DWORD dwSizeofTranslateCaps = sizeof(LINETRANSLATECAPS); long lReturn; DWORD dwCounter; LPLINELOCATIONENTRY lpLocationEntry; LPLINECARDENTRY lpLineCardEntry = NULL; // First, get the TRANSLATECAPS do { lpTranslateCaps = (LPLINETRANSLATECAPS) CheckAndReAllocBuffer( (LPVOID) lpTranslateCaps, dwSizeofTranslateCaps, "cktapiFetchLocationInfoByID"); if (lpTranslateCaps == NULL) return FALSE; lReturn = (*cklineGetTranslateCaps)(g_hLineApp, TAPI_CURRENT_VERSION, lpTranslateCaps); if (HandleLineErr(lReturn)) ; else { OutputDebugLineError(lReturn, "lineGetTranslateCaps unhandled error: "); LocalFree(lpTranslateCaps); return FALSE; } if ((lpTranslateCaps -> dwNeededSize) > (lpTranslateCaps -> dwTotalSize)) { dwSizeofTranslateCaps = lpTranslateCaps ->dwNeededSize; lReturn = -1; // Lets loop again. } } while(lReturn != SUCCESS); // Find the location information in the TRANSLATECAPS lpLocationEntry = (LPLINELOCATIONENTRY) (((LPBYTE) lpTranslateCaps) + lpTranslateCaps->dwLocationListOffset); debug(F110,"cktapiFetchLocationInfoByID","lpLocationEntry",lpLocationEntry); // If lpszCurrentLocation, then make that location 'current' if (LocationID == -1) { LocationID = cktapiGetCurrentLocationID(); } // loop through all locations, looking for a location match for(dwCounter = 0; dwCounter < lpTranslateCaps -> dwNumLocations; dwCounter++) { if ( LocationID == lpLocationEntry[dwCounter].dwPermanentLocationID ) { // Found it! Set the current location, if necessary. int ID = cktapiGetCurrentLocationID(); if ( ID != lpLocationEntry[dwCounter].dwPermanentLocationID ) { lReturn = (*cklineSetCurrentLocation)(g_hLineApp, lpLocationEntry[dwCounter].dwPermanentLocationID); OutputDebugLastError(lReturn,"lineSetCurrentLocation:"); } break; } } if ( dwCounter == lpTranslateCaps -> dwNumLocations ) { debug(F110,"cktapiFetchLocationInfoByID","LocationEntry not found",0); LocalFree(lpTranslateCaps); return FALSE; } // Was a match for lpszCurrentLocation found? if (lpLocationEntry[dwCounter].dwPreferredCardID == MAXDWORD) { debug(F110,"cktapiFetchLocationInfoByID","PreferredCardID == MAXDWORD",0); LocalFree(lpTranslateCaps); return FALSE; } SaveTapiLocationInfo( lpTranslateCaps, &lpLocationEntry[dwCounter] ); LocalFree(lpTranslateCaps); return TRUE; } #ifndef NODIAL void CopyTapiLocationInfoToKermitDialCmd( void ) { extern char *dialnpr; /* DIAL PREFIX */ extern char *diallac; /* DIAL LOCAL-AREA-CODE */ extern char *diallcc; /* DIAL LOCAL-COUNTRY-CODE */ extern char *dialixp; /* DIAL INTL-PREFIX */ extern char *dialixs; /* DIAL INTL-SUFFIX */ extern char *diallcp; /* DIAL LOCAL-PREFIX */ extern char *diallcs; /* DIAL LOCAL-SUFFIX */ extern char *dialldp; /* DIAL LD-PREFIX */ extern char *diallds; /* DIAL LD-SUFFIX */ extern char *dialpxx; /* DIAL PBX-EXCHANGE */ extern char *dialpxi; /* DIAL INTERNAL-PREFIX */ extern char *dialpxo; /* DIAL OUTSIDE-PREFIX */ extern char *dialsfx; /* DIAL SUFFIX */ extern char *dialtfp; /* DIAL TOLL-FREE-PREFIX */ extern int dialmth; /* DIAL METHOD TONE/PULSE */ char * p = NULL; debug(F111,"CopyTapiLocationInfoToKermitDialCmd","tapilocid",tapilocid); /* Make sure there are valid values */ if ( tapilocid == -1 ) { tapilocid = cktapiGetCurrentLocationID(); if ( tapilocid == -1 ) { debug(F111,"CopyTapiLocationInfoToKermitDialCmd", "tapilocid still -1",tapilocid); return; } cktapiFetchLocationInfoByID( tapilocid ); } debug(F110,"CopyTapiLocationInfoToKermitDialCmd", "copying string values",0); /* Local Country Code */ if ( diallcc ) free( diallcc ); diallcc = (char *) malloc( 20 ) ; if ( !diallcc ) return; _itoa( tapiCountryCode, diallcc, 10 ); /* Local Area Code */ if ( diallac ) free(diallac); diallac = strdup( tapiAreaCode ); /* Long Distance Prefix */ if ( dialldp ) free(dialldp); /* The true Long Distance Prefix is the tapiLongDistAccessCode */ /* plus the prefix portion of the tapiLongDistanceRule */ dialldp = (char *) malloc(strlen(tapiLongDistAccessCode) + strlen(tapiLongDistanceRule) + 1); if ( dialldp ) { strcpy(dialldp,tapiLongDistAccessCode); p = dialldp; /* find the beginning of the prefix */ while ( *p == ' ' || *p == 'N' || *p == 'S' ) { *p = ' '; p++; } /* find the end of the prefix and null terminate it */ while ( *p && *p != 'E' && *p != 'F' && *p != 'G' ) p++; *p = '\0'; strcpy(p,tapiLongDistanceRule); /* find the beginning of the prefix */ while ( *p == ' ' || *p == 'N' || *p == 'S' ) { *p = ' '; p++; } /* find the end of the prefix and null terminate it */ while ( *p && *p != 'E' && *p != 'F' && *p != 'G' ) p++; *p = '\0'; } /* The Long Distance Suffix is the suffix portion of the */ /* tapiLongDistanceRule (if any) */ if ( diallds ) free(diallds); diallds = strdup( tapiLongDistanceRule ); if ( diallds ) { p = diallds; /* blank out the prefix */ while ( *p && *p != 'E' && *p != 'F' && *p != 'G') { *p = ' '; p++; } /* and then the dialing rule */ while ( *p == 'E' || *p == 'F' || *p == 'G' ) { *p = ' '; p++; } if ( *p == '\0' ) { free(diallds); diallds = NULL; } } /* Toll Free Prefix */ if ( dialtfp ) free(dialtfp); /* The true Toll Free Prefix is the tapiLongDistAccessCode */ /* plus the prefix portion of the tapiLongDistanceRule */ dialtfp = (char *) malloc(strlen(tapiLongDistAccessCode) + strlen(tapiLongDistanceRule) + 1); if ( dialtfp ) { strcpy(dialtfp,tapiLongDistAccessCode); p = dialtfp; /* find the beginning of the prefix */ while ( *p == ' ' || *p == 'N' || *p == 'S' ) { *p = ' '; p++; } /* find the end of the prefix and null terminate it */ while ( *p && *p != 'E' && *p != 'F' && *p != 'G' ) p++; *p = '\0'; strcpy(p,tapiLongDistanceRule); /* find the beginning of the prefix */ while ( *p == ' ' || *p == 'N' || *p == 'S' ) { *p = ' '; p++; } /* find the end of the prefix and null terminate it */ while ( *p && *p != 'E' && *p != 'F' && *p != 'G' ) p++; *p = '\0'; } /* The International Prefix is the prefix portion of the */ /* tapiInternationalRule */ if ( dialixp ) free(dialixp); /* The true International Prefix is the tapiLongDistAccessCode */ /* plus the prefix portion of the tapiInternationalRule */ dialixp = (char *) malloc(strlen(tapiLongDistAccessCode) + strlen(tapiInternationalRule) + 1); if ( dialixp ) { strcpy(dialixp,tapiLongDistAccessCode); p = dialixp; /* find the beginning of the prefix */ while ( *p == ' ' || *p == 'N' || *p == 'S' ) { *p = ' '; p++; } /* find the end of the prefix and null terminate it */ while ( *p && *p != 'E' && *p != 'F' && *p != 'G' ) p++; *p = '\0'; strcpy(p,tapiInternationalRule); /* find the beginning of the prefix */ while ( *p == ' ' || *p == 'N' || *p == 'S' ) { *p = ' '; p++; } /* find the end of the prefix and null terminate it */ while ( *p && *p != 'E' && *p != 'F' && *p != 'G' ) p++; *p = '\0'; } /* The International Suffix is the suffix portion of the */ /* tapiInternationalRule (if any) */ if ( dialixs ) free(dialixs); dialixs = strdup( tapiInternationalRule ); if ( dialixs ) { p = dialixs; /* blank out the prefix */ while ( *p && *p != 'E' && *p != 'F' && *p != 'G') { *p = ' '; p++; } /* and then the dialing rule */ while ( *p == 'E' || *p == 'F' || *p == 'G' ) { *p = ' '; p++; } if ( *p == '\0' ) { free(dialixs); dialixs = NULL; } } /* Local Prefix */ if ( diallcp ) free(diallcp); /* The true Local Prefix is the tapiLocalAccessCode */ /* plus the prefix portion of the tapiSameAreaRule */ diallcp = (char *) malloc(strlen(tapiLocalAccessCode) + strlen(tapiSameAreaRule) + 1); if ( diallcp ) { strcpy(diallcp,tapiLocalAccessCode); p = diallcp; /* find the beginning of the prefix */ while ( *p == ' ' || *p == 'N' || *p == 'S' ) { *p = ' '; p++; } /* find the end of the prefix and null terminate it */ while ( *p && *p != 'E' && *p != 'F' && *p != 'G' ) p++; *p = '\0'; strcpy(p,tapiSameAreaRule); /* find the beginning of the prefix */ while ( *p == ' ' || *p == 'N' || *p == 'S' ) { *p = ' '; p++; } /* find the end of the prefix and null terminate it */ while ( *p && *p != 'E' && *p != 'F' && *p != 'G' ) p++; *p = '\0'; } /* The Local Access Suffix is the suffix portion of the */ /* tapiLocalAccessRule (if any) */ if ( diallcs ) free(diallcs); diallcs = strdup( tapiSameAreaRule ); if ( diallcs ) { p = diallcs; /* blank out the prefix */ while ( *p && *p != 'E' && *p != 'F' && *p != 'G') { *p = ' '; p++; } /* and then the dialing rule */ while ( *p == 'E' || *p == 'F' || *p == 'G' ) { *p = ' '; p++; } if ( *p == '\0' ) { free(diallcs); diallcs = NULL; } } /* All purpose Prefix */ if ( dialnpr ) free( dialnpr ); dialnpr = strdup( tapiCancelCallWaiting ); /* Pulse Dialing? */ if ( tapiOptions & LINELOCATIONOPTION_PULSEDIAL ) dialmth = XYDM_P; else dialmth = XYDM_T; debug(F110,"CopyTapiLocationInfoToKermitDialCmd","done",0); } #endif /* NODIAL */ typedef struct tagCommID { HANDLE hModem ; char szModemName[1] ; } CommID ; HANDLE GetModemHandleFromLine( HLINE hLine ) { CommID * cid; VARSTRING *vs; ULONG lrc ; DWORD dwSize; HANDLE hModem ; if ( hLine == (HLINE) 0 ) hLine = g_hLine; if ( hLine == (HLINE) 0 ) return NULL; /* The next four lines prepare a VARSTRING structure to pass to Windows though lineGetID */ vs = (VARSTRING *) malloc (1024); if ( !vs ) return NULL; memset(vs,0,1024); vs->dwTotalSize = 1024; do { /* get modem handle associated with the line */ lrc = (*cklineGetID)(hLine, 0L, (HCALL)0, LINECALLSELECT_LINE, vs, "comm/datamodem") ; if ( ( lrc == LINEERR_STRUCTURETOOSMALL || lrc == 0 ) && (vs->dwTotalSize < vs->dwNeededSize) ) { /* the next six lines reallocate the VARSTRING */ dwSize = vs->dwNeededSize ; free(vs); vs = (VARSTRING *) malloc(dwSize); if ( !vs ) return NULL; memset(vs,0,sizeof(vs)); vs->dwTotalSize = dwSize ; } else if ( lrc ) { /* some kind of TAPI error */ OutputDebugLastError(lrc,"lineGetID:"); free(vs); return NULL; } else break; /* success */ } while ( TRUE ); cid = (CommID *) ((LPSTR)vs + vs->dwStringOffset); if ( !cid->hModem ) { SECURITY_ATTRIBUTES security ; security.nLength = sizeof(SECURITY_ATTRIBUTES); security.lpSecurityDescriptor = NULL ; security.bInheritHandle = TRUE ; strcpy( szModemName, "\\\\.\\" ) ; strcat( szModemName, &cid->szModemName[0] ) ; hModem = CreateFile( szModemName, GENERIC_READ | GENERIC_WRITE, TRUE, /* do not share */ &security, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL); } else { lstrcpy( szModemName, &cid->szModemName[0] ) ; hModem = cid->hModem ; } free(vs); return hModem; } void cktapiConfigureLine( int lineID ) { LPVARSTRING lpVarString = NULL; DWORD dwSizeofVarString = sizeof(VARSTRING) + 1024; LPCSTR binaryConfigString=NULL; LONG lReturn=-1; if ( !cktapiopen() ) return; if ( lineID == -1 ) lineID = LineDeviceId; debug(F111,"TAPI Configure Line Dialog","lineID",lineID); (*cklineConfigDialog)( lineID, hwndConsole, NULL ); do { if ( lpVarString != NULL ) free(lpVarString); // Allocate the VARSTRING structure lpVarString = malloc( dwSizeofVarString ) ; if (lpVarString == NULL) goto ErrorConfiguring; lpVarString->dwTotalSize = dwSizeofVarString; // Fill the VARSTRING structure lReturn = (*cklineGetDevConfig)( lineID, lpVarString, "comm/datamodem" ); OutputDebugLastError(lReturn,"lineGetDevConfig:"); if (HandleLineErr(lReturn)) ; // Still need to check if structure was big enough. else { OutputDebugLineError(lReturn, "lineGetDevConfig unhandled error: "); goto ErrorConfiguring; } // If the VARSTRING wasn't big enough, loop again. if ((lpVarString -> dwNeededSize) > (lpVarString -> dwTotalSize)) { dwSizeofVarString = lpVarString -> dwNeededSize; lReturn = -1; // Lets loop again. } } while(lReturn != SUCCESS); /* See cktapiGetModemSettings; we may know the format of this string */ binaryConfigString = ((LPCSTR)((LPBYTE)lpVarString + lpVarString->dwStringOffset)); ErrorConfiguring: if (lpVarString) free(lpVarString); cktapiclose(); } void cktapiDialingProp( void ) { DWORD dwAPIVersion ; LINEEXTENSIONID ExtensionID ; LONG rc; if ( !cktapiopen() ) return; debug(F111,"TAPI Dialing Properties Dialog","device ID",LineDeviceId); rc = (*cklineNegotiateAPIVersion)(g_hLineApp, LineDeviceId == -1 ? 0 : LineDeviceId, TAPI_CURRENT_VERSION, TAPI_CURRENT_VERSION, &dwAPIVersion, &ExtensionID); rc = (*cklineTranslateDialog)( g_hLineApp, LineDeviceId == -1 ? 0 : LineDeviceId, dwAPIVersion, hwndConsole, NULL ); tapilocid = -1; #ifndef NODIAL CopyTapiLocationInfoToKermitDialCmd(); #endif /* NODIAL */ cktapiclose(); } int cktapiConvertPhoneNumber(char * source, char ** converted) { DWORD dwAPIVersion ; LINEEXTENSIONID ExtensionID ; DWORD dwCard=0; DWORD dwTranslateOptions=LINETRANSLATEOPTION_CANCELCALLWAITING; LPLINETRANSLATEOUTPUT lplineTranslateOutput=NULL; DWORD dwSize=0; LONG rc = 0; if ( !cktapiopen() ) return FALSE; rc = (*cklineNegotiateAPIVersion)(g_hLineApp, LineDeviceId == -1 ? 0 : LineDeviceId, TAPI_CURRENT_VERSION, TAPI_CURRENT_VERSION, &dwAPIVersion, &ExtensionID); if ( rc ) { cktapiclose(); return FALSE; } dwSize = sizeof(LINETRANSLATEOUTPUT); lplineTranslateOutput = (LPLINETRANSLATEOUTPUT) malloc( dwSize ) ; if ( !lplineTranslateOutput ) { cktapiclose(); return FALSE; } memset(lplineTranslateOutput,0,dwSize); lplineTranslateOutput->dwTotalSize = dwSize ; do { rc = (*cklineTranslateAddress)(g_hLineApp, LineDeviceId == -1 ? 0 : LineDeviceId, dwAPIVersion, source, dwCard, dwTranslateOptions, lplineTranslateOutput ); if ( ( rc == LINEERR_STRUCTURETOOSMALL || rc == 0 ) && (lplineTranslateOutput->dwTotalSize < lplineTranslateOutput->dwNeededSize) ) { /* the next six lines reallocate the LINETRANSLATEOUTPUT struct */ dwSize = lplineTranslateOutput->dwNeededSize ; free(lplineTranslateOutput); lplineTranslateOutput = (LPLINETRANSLATEOUTPUT) malloc( dwSize ) ; if ( !lplineTranslateOutput ) { cktapiclose(); return FALSE; } memset(lplineTranslateOutput,0,dwSize); lplineTranslateOutput->dwTotalSize = dwSize ; } else if ( rc ) { /* some kind of TAPI error */ OutputDebugLastError(rc,"lineTranslateAddress:"); free(lplineTranslateOutput); cktapiclose(); return FALSE; } else break; /* success */ } while ( TRUE ); /* we now have the result, lets do something with it */ *converted = (char *) malloc( lplineTranslateOutput->dwDialableStringSize+1); strncpy( *converted, (LPCSTR) lplineTranslateOutput + lplineTranslateOutput->dwDialableStringOffset, lplineTranslateOutput->dwDialableStringSize); (*converted)[lplineTranslateOutput->dwDialableStringSize]='\0'; free(lplineTranslateOutput); cktapiclose(); return TRUE; } int tapi_open( char * devicename ) { extern struct keytab * tapilinetab ; extern int ntapiline ; int i ; LINEEXTENSIONID ExtId ; int rc ; LPDEVCFG lpDevCfg = NULL; LPCOMMCONFIG lpCommConfig = NULL; LPMODEMSETTINGS lpModemSettings = NULL; DCB * lpDCB = NULL; debug(F110,"tapi_open devicename",devicename,0); if ( !cktapiopen() ) { debug(F100,"tapi_open !cktapiopen()","",0); printf("TAPI Open fails\n"); return -1; } /* Find the Line ID */ for ( i=0 ; idwNumAddresses ; LineMediaModes = g_lpLineDevCaps[LineDeviceId]->dwMediaModes ; if ( g_hLine == (HLINE)0 ) { /* Call lineOpen() */ rc = -1 ; while ( rc < 0 ) { rc = (*cklineOpen)( g_hLineApp, LineDeviceId, &g_hLine, LineDeviceAPIVersion, 0, (DWORD) hInstance, LINECALLPRIVILEGE_OWNER | LINECALLPRIVILEGE_MONITOR, LINEMEDIAMODE_DATAMODEM, NULL); OutputDebugLastError(rc,"lineOpen:"); switch ( rc ) { case LINEERR_ALLOCATED: printf("TAPI Device already in use by a non-TAPI application.\n"); cktapiclose(); return -1; default: if ( HandleLineErr(rc) ) { continue; } else { debug(F111,"TAPI lineOpen","g_hLine",g_hLine); printf("Error opening Line Device: %s\n",cktapiErrorString(rc)); g_hLine = (HLINE)0; cktapiclose(); return -1; } } } } /* Specify which event messages we are interested in */ rc = (*cklineSetStatusMessages)(g_hLine, LINEDEVSTATE_CONNECTED | LINEDEVSTATE_DISCONNECTED | LINEDEVSTATE_OUTOFSERVICE | LINEDEVSTATE_MAINTENANCE | LINEDEVSTATE_OPEN | LINEDEVSTATE_CLOSE | LINEDEVSTATE_RINGING | LINEDEVSTATE_OTHER | LINEDEVSTATE_REINIT, 0); OutputDebugLastError(rc,"lineSetStatusMessages:"); if ( rc ) { cktapiclose(); return -1 ; } if ( tapipass ) { /* Try to make a call without specifying an address */ LINECALLPARAMS lcp; memset(&lcp,0,sizeof(LINECALLPARAMS)); lcp.dwBearerMode = LINEBEARERMODE_PASSTHROUGH; lcp.dwMediaMode = LINEMEDIAMODE_DATAMODEM; lcp.dwTotalSize = sizeof(LINECALLPARAMS); lcp.dwMinRate = lcp.dwMaxRate = 3100 ; lcp.dwAddressMode = LINEADDRESSMODE_ADDRESSID ; lcp.dwCallParamFlags = LINECALLPARAMFLAGS_IDLE | LINECALLPARAMFLAGS_SECURE ; #ifndef NODIAL fail_code = 0; #endif /* NODIAL */ g_bReplyReceived = FALSE; g_lAsyncReply = SUCCESS; g_bConnected = FALSE; g_bDialing = TRUE; ResetTAPIConnectSem(); g_dwRequestedID = 0; rc = g_dwRequestedID = (*cklineMakeCall)( g_hLine, &g_hCall, NULL, 0, &lcp) ; OutputDebugLastError(rc,"lineMakeCall:"); if ( rc < 0 ) { #ifdef BETADEBUG printf("lineMakeCall failed rc=%x\n",rc ) ; #endif if ( dialdpy ) printf("Open failed: %s\n",cktapiErrorString(rc)); g_hCall = (HCALL)0; cktapiclose(); g_bDialing = FALSE; return -1; } else { int x = 0; /* Wait for LineReply */ while ( !g_bReplyReceived #ifndef NODIAL && fail_code == 0 #endif /* NODIAL */ ) { msleep(100); x += 100; if ( x == 5000 ) { debug(F110,"tapi_open", "lineMakeCall Reply never received",0); if ( dialdpy ) printf("Open failed: required TAPI reply never received.\n"); g_hCall = (HCALL)0; cktapiclose(); g_bDialing = FALSE; return -1; } } OutputDebugLastError(g_lAsyncReply,"lineMakeCall (Async):"); if ( g_lAsyncReply != SUCCESS ) { #ifdef BETADEBUG printf("lineMakeCall failed rc=%x\n",g_lAsyncReply ) ; #endif if ( dialdpy ) printf("Open failed: %s\n",cktapiErrorString(g_lAsyncReply)); g_hCall = (HCALL)0; cktapiclose(); g_bDialing = FALSE; return -1; } /* Wait for Success or Failure of Connection */ if (!WaitAndResetTAPIConnectSem(10000)) { debug(F111,"TAPI Connect Timeout","seconds",10); #ifdef BETADEBUG printf("TAPI connect semaphore never posted\n"); #endif if ( dialdpy ) printf("Open failed: Timeout\n"); cktapiclose(); g_bDialing = FALSE; return -1; } #ifndef NODIAL if ( fail_code == F_INT ) { cktapiclose(); g_bDialing = FALSE; return FALSE; } #endif /* NODIAL */ } if ( ttyfd == -1 || ttyfd == -2 ) { /* if we did not get the Comm handle via the CONNECT message */ /* then get it now */ ttyfd = (int) GetModemHandleFromLine( g_hLine ); SetCommMask( (HANDLE) ttyfd, EV_RXCHAR ) ; SetupComm( (HANDLE) ttyfd, 20000, 20000 ) ; PurgeComm( (HANDLE) ttyfd, PURGE_RXABORT | PURGE_TXABORT | PURGE_RXCLEAR | PURGE_TXCLEAR ) ; } if ( !ttyfd || ttyfd == -1 ) { ttyfd = -1 ; cktapiclose(); g_bDialing = FALSE; return -1; } #ifdef BETADEBUG DisplayCommProperties((HANDLE)ttyfd); #endif /* BETADEBUG */ g_bDialing = FALSE; } else { /* Use TAPI based dialing */ ttyfd = -2; /* We don't have a real handle yet */ /* Do this just to set the name of the Modem */ CloseHandle( GetModemHandleFromLine( g_hLine ) ); } #ifndef NODIAL modemp[n_TAPI] = cktapiGetModemInf(LineDeviceId,(HANDLE)ttyfd); if ( !modemp[n_TAPI] ) modemp[n_TAPI] = &GENERIC; #endif /* NODIAL */ rc = cktapiGetModemSettings(&lpDevCfg,&lpModemSettings,&lpCommConfig,&lpDCB); debug(F101,"tapi_open cktapiGetModemSettings()","",rc); if ( rc ) { extern long speed; extern int parity, flow; extern int ttmdm; /* Modem or Direct */ #ifndef NODIAL extern int dialec, /* DIAL ERROR-CORRECTION */ dialdc, /* DIAL COMPRESSION */ dialfc, /* DIAL FLOW-CONTROL */ dialmth, /* DIAL METHOD */ mdmspd, /* SPEED-MATCHING */ mdmspk, /* SPEAKER ON/OFF */ mdmvol; /* SPEAKER VOLUME */ extern int dialtmo; /* DIAL TIMEOUT */ #endif /* NODIAL */ speed = lpDCB->BaudRate; parity = lpDCB->Parity; #ifndef NODIAL dialtmo = lpModemSettings->dwCallSetupFailTimer; dialec = lpModemSettings->dwPreferredModemOptions & MDM_ERROR_CONTROL; dialdc = lpModemSettings->dwPreferredModemOptions & MDM_COMPRESSION; #ifdef COMMENT mdmspd = lpModemSettings->dwPreferredModemOptions & MDM_SPEED_ADJUST; #endif /* COMMENT */ dialmth = (lpModemSettings->dwPreferredModemOptions & MDM_TONE_DIAL) ? XYDM_T : XYDM_D ; dialfc = FLO_AUTO; if ( lpModemSettings->dwPreferredModemOptions & MDM_FLOWCONTROL_HARD ) flow = FLO_RTSC; else if ( lpModemSettings->dwPreferredModemOptions & MDM_FLOWCONTROL_SOFT ) flow = FLO_XONX; else flow = FLO_NONE; mdmspk = lpModemSettings->dwSpeakerMode; mdmvol = lpModemSettings->dwSpeakerVolume+1; debug(F111,"tapi_open","dialtmo",dialtmo); debug(F111,"tapi_open","speed",speed); debug(F111,"tapi_open","parity",parity); debug(F111,"tapi_open","dialec",dialec); debug(F111,"tapi_open","dialdc",dialdc); debug(F111,"tapi_open","dialmth",dialmth); debug(F111,"tapi_open","dialfc",dialfc); debug(F111,"tapi_open","flow",flow); debug(F111,"tapi_open","mdmspk",mdmspk); debug(F111,"tapi_open","mdmvol",mdmvol); #endif /* NODIAL */ if ( !tapipass ) { if ( cktapiIsModem() ) ttmdm = 38; /* ckudia.c */ else ttmdm = 0; } #ifdef BETADEBUG cktapiDisplayModemSettings(lpDevCfg,lpModemSettings,lpCommConfig,lpDCB); #endif } return 0; } int tapi_clos( void ) { cktapiclose() ; return -1; } int cktapiCallInProgress( void ) { LPLINEDEVSTATUS lpLineDevStatus=NULL; DWORD dwSizeofLineDevStatus = sizeof(LINEDEVSTATUS); LONG lReturn; int InProgress = TRUE; if ( g_hCall != (HCALL)0 ) return FALSE; if ( g_hLine == (HLINE)0 ) return TRUE; do { lpLineDevStatus = (LPLINEDEVSTATUS) CheckAndReAllocBuffer((LPVOID) lpLineDevStatus, dwSizeofLineDevStatus, "cktapiCallInProgress"); if (lpLineDevStatus == NULL) { return TRUE; } lReturn = (*cklineGetLineDevStatus)(g_hLine, lpLineDevStatus); if (HandleLineErr(lReturn)) ; else { OutputDebugLineError(lReturn, "lineGetDevStatus unhandled error: "); LocalFree(lpLineDevStatus); return TRUE; } if ((lpLineDevStatus -> dwNeededSize) > (lpLineDevStatus -> dwTotalSize)) { dwSizeofLineDevStatus = lpLineDevStatus ->dwNeededSize; lReturn = -1; // Lets loop again. } } while(lReturn != SUCCESS); InProgress = lpLineDevStatus->dwNumActiveCalls + lpLineDevStatus->dwNumOnHoldCalls + lpLineDevStatus->dwNumOnHoldPendCalls - (g_hCall!=(HCALL)0?1:0); LocalFree( lpLineDevStatus ); return InProgress; } int cktapiIsModem(void) { LPCSTR lpModemKey; HKEY hkModemKey=0; HKEY hkSubKey=0; CHAR lpszKeyValue[256]; DWORD dwType=0; DWORD dwSize=0; CHAR *lpszValueName=NULL; int modem = 0; if ( LineDeviceId == (DWORD) -1 || g_lpLineDevCaps[LineDeviceId]->dwDevSpecificSize == 0 ) return 0; lpModemKey = ((char *)g_lpLineDevCaps[LineDeviceId] + g_lpLineDevCaps[LineDeviceId]->dwDevSpecificOffset + 8); if ( RegOpenKeyEx(HKEY_LOCAL_MACHINE, lpModemKey, 0, KEY_READ, &hkModemKey) ) return 0; /* failed */ if ( !RegOpenKeyEx(hkModemKey, "Answer", 0, KEY_READ, &hkSubKey) ) { dwSize = sizeof(lpszKeyValue); lpszValueName = "1"; if ( !RegQueryValueEx( hkSubKey, lpszValueName, NULL, &dwType, lpszKeyValue, &dwSize )) { modem = strcmp("CLIENTSERVER",lpszKeyValue); } RegCloseKey( hkSubKey ); } if ( !RegOpenKeyEx(hkModemKey, "Settings", 0, KEY_READ, &hkSubKey) ) { dwSize = sizeof(lpszKeyValue); lpszValueName = "DialPrefix"; if ( !RegQueryValueEx( hkSubKey, lpszValueName, NULL, &dwType, lpszKeyValue, &dwSize )) { modem &= strcmp("CLIENT",lpszKeyValue); } RegCloseKey( hkSubKey ); } RegCloseKey( hkModemKey ); return modem; } int cktapiDisplayModemSettings( LPDEVCFG lpDevCfg, LPMODEMSETTINGS lpModemSettings, LPCOMMCONFIG lpCommConfig, DCB * lpDCB ) { printf("TAPI UniModem Configuration:\n"); printf(" Modem Name: %s\n", szModemName ); if ( LineDeviceId != (DWORD) -1 && g_lpLineDevCaps[LineDeviceId]->dwDevSpecificSize ) { printf(" Registry Key: %s\n", (char *)g_lpLineDevCaps[LineDeviceId] + g_lpLineDevCaps[LineDeviceId]->dwDevSpecificOffset + 8); cktapiDisplayRegistryModemInfo((char *)g_lpLineDevCaps[LineDeviceId] + g_lpLineDevCaps[LineDeviceId]->dwDevSpecificOffset + 8); } if ( lpDevCfg ) { printf(" Version = %x\n",lpDevCfg->dfgHdr.dwVersion); if ( lpDevCfg->dfgHdr.fwOptions == 0 ) printf(" No Unimodem options\n"); else { printf(" Unimodem options:\n"); if ( lpDevCfg->dfgHdr.fwOptions & 1 ) printf(" Pre-dial Terminal Screen\n"); if ( lpDevCfg->dfgHdr.fwOptions & 2 ) printf(" Post-dial Terminal Screen\n"); if ( lpDevCfg->dfgHdr.fwOptions & 4 ) printf(" Manual Dialing\n"); if ( lpDevCfg->dfgHdr.fwOptions & 8 ) printf(" Display Launch Lights (modem tray icon)\n"); } printf(" Wait for bong = %d seconds\n",lpDevCfg->dfgHdr.wWaitBong); } if ( lpModemSettings ) { printf(" Modem Settings (read/write):\n"); printf(" CallSetupFailTimer = %d seconds\n", lpModemSettings->dwCallSetupFailTimer); printf(" InactivityTimeout = %d seconds\n", lpModemSettings->dwInactivityTimeout); printf(" SpeakerVolume = %d (0-Low,1-Medium,2-High)\n", lpModemSettings->dwSpeakerVolume); printf(" SpeakerMode = %d (0-Off,1-Dial,2-On,3-CallSetup)\n", lpModemSettings->dwSpeakerMode); if ( lpModemSettings->dwPreferredModemOptions == 0 ) printf(" No Preferred Modem Options\n"); else { printf(" Preferred Modem Options:\n"); if ( lpModemSettings->dwPreferredModemOptions & MDM_COMPRESSION ) printf(" Modem Compression\n"); if ( lpModemSettings->dwPreferredModemOptions & MDM_ERROR_CONTROL ) printf(" Error Control\n"); if ( lpModemSettings->dwPreferredModemOptions & MDM_FORCED_EC ) printf(" Forced Error Control\n"); if ( lpModemSettings->dwPreferredModemOptions & MDM_CELLULAR ) printf(" Cellular\n"); if ( lpModemSettings->dwPreferredModemOptions & MDM_FLOWCONTROL_HARD ) printf(" Hardware Flow Control\n"); if ( lpModemSettings->dwPreferredModemOptions & MDM_FLOWCONTROL_SOFT ) printf(" Xon/Xoff Flow Control\n"); if ( lpModemSettings->dwPreferredModemOptions & MDM_CCITT_OVERRIDE ) printf(" CCITT Override\n"); if ( lpModemSettings->dwPreferredModemOptions & MDM_SPEED_ADJUST ) printf(" Speed Adjust (Modulation)\n"); if ( lpModemSettings->dwPreferredModemOptions & MDM_TONE_DIAL ) printf(" Tone Dial\n"); if ( lpModemSettings->dwPreferredModemOptions & MDM_BLIND_DIAL ) printf(" Blind Dial\n"); if ( lpModemSettings->dwPreferredModemOptions & MDM_V23_OVERRIDE ) printf(" V.23 Override\n"); } printf(" Modem Settings (read only) from current call (if any):\n"); if ( lpModemSettings->dwNegotiatedModemOptions == 0 ) printf(" No Negotiated Modem Options\n"); else { printf(" Negotiated Modem Options:\n"); if ( lpModemSettings->dwNegotiatedModemOptions & MDM_COMPRESSION ) printf(" Modem Compression\n"); if ( lpModemSettings->dwNegotiatedModemOptions & MDM_ERROR_CONTROL ) printf(" Error Control\n"); if ( lpModemSettings->dwNegotiatedModemOptions & MDM_FORCED_EC ) printf(" Forced Error Control\n"); if ( lpModemSettings->dwNegotiatedModemOptions & MDM_CELLULAR ) printf(" Cellular\n"); if ( lpModemSettings->dwNegotiatedModemOptions & MDM_FLOWCONTROL_HARD ) printf(" Hardware Flow Control\n"); if ( lpModemSettings->dwNegotiatedModemOptions & MDM_FLOWCONTROL_SOFT ) printf(" Xon/Xoff Flow Control\n"); if ( lpModemSettings->dwNegotiatedModemOptions & MDM_CCITT_OVERRIDE ) printf(" CCITT Override\n"); if ( lpModemSettings->dwNegotiatedModemOptions & MDM_SPEED_ADJUST ) printf(" Speed Adjust (modulation)\n"); if ( lpModemSettings->dwNegotiatedModemOptions & MDM_TONE_DIAL ) printf(" Tone Dial\n"); if ( lpModemSettings->dwNegotiatedModemOptions & MDM_BLIND_DIAL ) printf(" Blind Dial\n"); if ( lpModemSettings->dwNegotiatedModemOptions & MDM_V23_OVERRIDE ) printf(" V.23 Override\n"); } printf(" NegotiatedDCERate = %d bits/s\n",lpModemSettings->dwNegotiatedDCERate); } if ( lpCommConfig ) { printf(" Communication Settings:\n"); printf(" ProviderSubType = "); switch ( lpCommConfig->dwProviderSubType ) { case PST_UNSPECIFIED : printf("Unspecified"); break; case PST_RS232 : printf("RS232"); break; case PST_PARALLELPORT : printf("Parallel Port"); break; case PST_RS422 : printf("RS422"); break; case PST_RS423 : printf("RS423"); break; case PST_RS449 : printf("RS449"); break; case PST_MODEM : printf("Modem"); break; case PST_FAX : printf("Fax"); break; case PST_SCANNER : printf("Scanner"); case PST_NETWORK_BRIDGE : printf("Network Bridge"); break; case PST_LAT : printf("LAT"); break; case PST_TCPIP_TELNET : printf("TCP/IP Telnet"); break; case PST_X25 : printf("X.25"); break; default: printf("Unknown"); } printf("\n"); } if ( lpDCB ) { printf(" BaudRate = %d\n",lpDCB->BaudRate); printf(" Binary Mode (no EOF check) = %d\n",lpDCB->fBinary); printf(" Enable Parity Checking = %d\n",lpDCB->fParity); printf(" CTS Handshaking on output = %d\n",lpDCB->fOutxCtsFlow); printf(" DSR Handshaking on output = %d\n",lpDCB->fOutxDsrFlow); printf(" DTR Flow Control = %d\n",lpDCB->fDtrControl); printf(" DSR Sensitivity = %d\n",lpDCB->fDsrSensitivity); printf(" Continue TX when Xoff sent = %d\n",lpDCB->fTXContinueOnXoff); printf(" Enable output X-ON/X-OFF = %d\n",lpDCB->fOutX); printf(" Enable input X-ON/X-OFF = %d\n",lpDCB->fInX); printf(" Enable Err Replacement = %d\n",lpDCB->fErrorChar); printf(" Enable Null stripping = %d\n",lpDCB->fNull); printf(" RTS flow control = %d\n",lpDCB->fRtsControl); printf(" Abort all I/O on Error = %d\n",lpDCB->fAbortOnError); printf(" Transmit X-ON threshold = %d\n",lpDCB->XonLim); printf(" Transmit X-OFF threshold = %d\n",lpDCB->XoffLim); printf(" Num of bits/byte, 4-8 = %d\n",lpDCB->ByteSize); printf(" Parity (0-4=N,O,E,M,S) = %d\n",lpDCB->Parity); printf(" StopBits (0,1,2 = 1, 1.5, 2) = %d\n",lpDCB->StopBits); printf(" Tx and Rx X-ON character = %d\n",lpDCB->XonChar); printf(" Tx and Rx X-OFF character = %d\n",lpDCB->XoffChar); printf(" Error replacement char = %d\n",lpDCB->ErrorChar); printf(" End of Input character = %d\n",lpDCB->EofChar); printf(" Received Event character = %d\n",lpDCB->EvtChar); printf("\n"); } return TRUE; } int cktapiGetModemSettings( LPDEVCFG * lppDevCfg, LPMODEMSETTINGS * lppModemSettings, LPCOMMCONFIG * lppCommConfig, DCB ** lppDCB ) { static VARSTRING *vs=NULL; DWORD dwSize=0; ULONG lrc=0 ; LPDEVCFG lpDevCfg = NULL; LPCOMMCONFIG lpCommConfig = NULL; LPMODEMSETTINGS lpModemSettings = NULL; DCB * lpDCB = NULL; if ( lppDevCfg ) *lppDevCfg = NULL; if ( lppCommConfig ) *lppCommConfig = NULL; if ( lppDCB ) *lppDCB = NULL; if ( lppModemSettings ) *lppModemSettings = NULL; if ( vs != NULL ) { /* free previous VARSTRING */ free(vs); vs = NULL; } if ( g_hLine == (HLINE)0 ) { debug(F100,"cktapiGetModemSettings g_hLine == NULL","",0); return FALSE; } /* The next four lines prepare a VARSTRING structure to pass to Windows though lineGetID */ vs = (VARSTRING *) malloc (1024); if ( !vs ) { debug(F100,"cktapiGetModemSettings malloc failed","",0); return FALSE; } memset(vs,0,1024); vs->dwTotalSize = 1024; do { /* get Modem Device Configuration */ lrc = (*cklineGetDevConfig)( LineDeviceId, vs, "comm/datamodem" ); if ( ( lrc == LINEERR_STRUCTURETOOSMALL || lrc == 0 ) && (vs->dwTotalSize < vs->dwNeededSize) ) { /* the next six lines reallocate the VARSTRING */ dwSize = vs->dwNeededSize ; free(vs); vs = (VARSTRING *) malloc(dwSize); if ( !vs ) { debug(F100,"cktapiGetModemSettings malloc 2 failed","",0); return FALSE; } memset(vs,0,sizeof(vs)); vs->dwTotalSize = dwSize ; } else if ( lrc ) { /* some kind of TAPI error */ OutputDebugLastError(lrc,"lineGetDevConfig:"); free(vs); debug(F101,"cktapiGetModemSettings tapi error","",lrc); return FALSE; } else break; /* success */ } while ( TRUE ); lpDevCfg = (LPDEVCFG) ((LPSTR)vs + vs->dwStringOffset); if ( lpDevCfg == NULL ) { debug(F100,"cktapiGetModemSettings lpDevCfg == NULL","",0); free(vs); return FALSE; } lpCommConfig = (LPCOMMCONFIG) &lpDevCfg->commconfig; lpDCB = &lpCommConfig->dcb; lpModemSettings = (LPMODEMSETTINGS)((LPSTR)lpCommConfig + lpCommConfig->dwProviderOffset); if ( lppDevCfg ) *lppDevCfg = lpDevCfg; if ( lppCommConfig ) *lppCommConfig = lpCommConfig; if ( lppDCB ) *lppDCB = lpDCB; if ( lppModemSettings ) *lppModemSettings = lpModemSettings; return TRUE; } int cktapiSetModemSettings( LPDEVCFG lpDevCfg, LPCOMMCONFIG lpCommConfig ) { LONG lrc=0 ; HANDLE hModem = NULL; if ( lpDevCfg == NULL ) return FALSE; /* First try with a Modem Handle */ hModem = GetModemHandleFromLine((HLINE)0); if ( hModem ) { lrc = SetCommConfig( hModem, lpCommConfig, lpCommConfig->dwSize ); CloseHandle(hModem); hModem = NULL; if ( lrc ) return(TRUE); lrc = GetLastError(); debug(F111,"cktapiSetModemSettings","SetCommConfig",lrc); } lrc = (*cklineSetDevConfig)( LineDeviceId, lpDevCfg, lpDevCfg->dfgHdr.dwSize, "comm/datamodem" ); OutputDebugLastError(lrc,"lineSetDevConfig:"); if ( lrc < 0 ) { debug(F111,"cktapiSetModemSettings","lineSetDevConfig",lrc); #ifdef BETADEBUG printf("cktapiSetModemSettings rc=%x\n",lrc); #endif /* BETADEBUG */ return(FALSE); } return(TRUE); } int cktapidisconnect( void ) { int i=5; if ( !g_bHangingUp && !g_bClosing ) { _beginthread( cktapihangup, 65535, 0 ); } do { msleep(50); } while ( (g_bHangingUp || g_bClosing) && i-- ); return !(g_bHangingUp || g_bClosing) ; } int cktapicloseasync( void ) { int i=5; if ( !g_bClosing ) { _beginthread( cktapiclose, 65535, 0 ); } do { msleep(50); } while ( g_bClosing && i-- ); return !g_bClosing; } #ifndef NODIAL _PROTOTYP (int getok, (int,int) ); struct mdminf * cktapiGetModemInf( DWORD LineID, HANDLE hModem ) { LPCSTR lpModemKey = (char *)g_lpLineDevCaps[LineID] + g_lpLineDevCaps[LineID]->dwDevSpecificOffset + 8; HKEY hkModemKey=0; HKEY hkSubKey=0; CHAR lpszKeyValue[256]="", lpszBlindOff[256]=""; CHAR lpszPrefix[16]=""; CHAR lpszPostfix[16]=""; CHAR lpszBuf[256]=""; DWORD dwType=0; DWORD dwSize=0; CHAR *lpszValueName=NULL; COMMPROP * lpCommProp = NULL; LPMODEMDEVCAPS lpModemDevCaps = NULL; int i=0,j=0,rc=0; static struct mdminf mdmInf = { NULL, NULL, NULL, 0, NULL, 0, NULL, 0, NULL, NULL, NULL, NULL, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, 0, getok }; /* initialize the MDMINF structure */ if ( mdmInf.name ) { free(mdmInf.name); mdmInf.name = NULL; } if ( mdmInf.pulse ) { free(mdmInf.pulse); mdmInf.pulse = NULL; } if ( mdmInf.tone ) { free(mdmInf.tone); mdmInf.tone = NULL; } mdmInf.dial_time = 0; if ( mdmInf.pause_chars ) { free(mdmInf.pause_chars); mdmInf.pause_chars = NULL; } mdmInf.pause_time = 0; if ( mdmInf.wake_str ) { free(mdmInf.wake_str); mdmInf.wake_str = NULL; } mdmInf.wake_rate=0; if ( mdmInf.dmode_str ) { free(mdmInf.dmode_str); mdmInf.dmode_str = NULL; } if ( mdmInf.dmode_prompt ) { free(mdmInf.dmode_prompt); mdmInf.dmode_prompt = NULL; } if ( mdmInf.dial_str ) { free(mdmInf.dial_str); mdmInf.dial_str = NULL; } mdmInf.dial_rate = 0; mdmInf.esc_time = 0; mdmInf.esc_char = 0; if ( mdmInf.hup_str ) { free(mdmInf.hup_str); mdmInf.hup_str = NULL; } if ( mdmInf.hwfc_str ) { free(mdmInf.hwfc_str); mdmInf.hwfc_str = NULL; } if ( mdmInf.swfc_str ) { free(mdmInf.swfc_str); mdmInf.swfc_str = NULL; } if ( mdmInf.nofc_str ) { free(mdmInf.nofc_str); mdmInf.nofc_str = NULL; } if ( mdmInf.ec_on_str ) { free(mdmInf.ec_on_str); mdmInf.ec_on_str = NULL; } if ( mdmInf.ec_off_str ) { free(mdmInf.ec_off_str); mdmInf.ec_off_str = NULL; } if ( mdmInf.dc_on_str ) { free(mdmInf.dc_on_str); mdmInf.dc_on_str = NULL; } if ( mdmInf.dc_off_str ) { free(mdmInf.dc_off_str); mdmInf.dc_off_str = NULL; } if ( mdmInf.aa_on_str ) { free(mdmInf.aa_on_str); mdmInf.aa_on_str = NULL; } if ( mdmInf.aa_off_str ) { free(mdmInf.aa_off_str); mdmInf.aa_off_str = NULL; } if ( mdmInf.sb_on_str ) { free(mdmInf.sb_on_str); mdmInf.sb_on_str = NULL; } if ( mdmInf.sb_off_str ) { free(mdmInf.sb_off_str); mdmInf.sb_off_str = NULL; } if ( mdmInf.sp_on_str ) { free(mdmInf.sp_on_str); mdmInf.sp_on_str = NULL; } if ( mdmInf.sp_off_str ) { free(mdmInf.sp_off_str); mdmInf.sp_off_str = NULL; } if ( mdmInf.vol1_str ) { free(mdmInf.vol1_str); mdmInf.vol1_str = NULL; } if ( mdmInf.vol2_str ) { free(mdmInf.vol2_str); mdmInf.vol2_str = NULL; } if ( mdmInf.vol3_str ) { free(mdmInf.vol3_str); mdmInf.vol3_str = NULL; } if ( mdmInf.ignoredt ) { free(mdmInf.ignoredt); mdmInf.ignoredt = NULL; } if ( mdmInf.ini2 ) { free(mdmInf.ini2); mdmInf.ini2 = NULL; } mdmInf.max_speed=0; mdmInf.capas=0; if ( LineDeviceId == (DWORD) -1 || g_lpLineDevCaps[LineDeviceId]->dwDevSpecificSize == 0 ) return NULL; if ( RegOpenKeyEx(HKEY_LOCAL_MACHINE, lpModemKey, 0, KEY_READ, &hkModemKey) ) return NULL; /* failed */ dwSize = sizeof(lpszKeyValue); lpszValueName = "FriendlyName"; if ( !RegQueryValueEx( hkModemKey, lpszValueName, NULL, &dwType, lpszKeyValue, &dwSize )) { mdmInf.name = strdup(lpszKeyValue); } else { dwSize = sizeof(lpszKeyValue); lpszValueName = "Model"; if ( !RegQueryValueEx( hkModemKey, lpszValueName, NULL, &dwType, lpszKeyValue, &dwSize )) { mdmInf.name = strdup(lpszKeyValue); } } #ifdef COMMENT /* There is no place appropriate to place this stuff */ dwSize = sizeof(lpszKeyValue); lpszValueName = "Reset"; if ( !RegQueryValueEx( hkModemKey, lpszValueName, NULL, &dwType, lpszKeyValue, &dwSize )) { for ( i=0,j=0;j", &lpszKeyValue[j], 4 ) ) { lpszBuf[i] = '\015' ; j += 3; } else if ( !strncmp( "<#>", &lpszKeyValue[j], 3 ) ) { lpszBuf[i] = '0' ; j += 2; } else lpszBuf[i] = lpszKeyValue[j]; } else { lpszBuf[i] = lpszKeyValue[j]; } } mdmInf.?????_str = strdup(lpszBuf); } #endif /* COMMENT */ if ( !RegOpenKeyEx(hkModemKey, "Settings", 0, KEY_READ, &hkSubKey) ) { dwSize = sizeof(lpszKeyValue); lpszValueName = "Prefix"; if ( !RegQueryValueEx( hkSubKey, lpszValueName, NULL, &dwType, lpszKeyValue, &dwSize )) { for ( i=0,j=0;j", &lpszKeyValue[j], 4 ) ) { lpszPrefix[i] = '\015' ; j += 3; } else if ( !strncmp( "<#>", &lpszKeyValue[j], 3 ) ) { lpszPrefix[i] = '0' ; j += 2; } else lpszPrefix[i] = lpszKeyValue[j]; } else { lpszPrefix[i] = lpszKeyValue[j]; } } } #ifdef COMMENT else strcpy(lpszPrefix,"AT"); #endif dwSize = sizeof(lpszKeyValue); lpszValueName = "Terminator"; if ( !RegQueryValueEx( hkSubKey, lpszValueName, NULL, &dwType, lpszKeyValue, &dwSize )) { for ( i=0,j=0;j", &lpszKeyValue[j], 4 ) ) { lpszPostfix[i] = '\015' ; j += 3; } else if ( !strncmp( "<#>", &lpszKeyValue[j], 3 ) ) { lpszPostfix[i] = '0' ; j += 2; } else lpszPostfix[i] = lpszKeyValue[j]; } else { lpszPostfix[i] = lpszKeyValue[j]; } } } #ifdef COMMENT else strcpy(lpszPostfix,"\015"); #endif /* COMMENT */ dwSize = sizeof(lpszKeyValue); lpszValueName = "DialPrefix"; if ( !RegQueryValueEx( hkSubKey, lpszValueName, NULL, &dwType, lpszKeyValue, &dwSize )) { sprintf(lpszBuf,"%s%s%s%s",lpszPrefix,lpszKeyValue,"%s",lpszPostfix); mdmInf.dial_str = strdup(lpszBuf); } else mdmInf.dial_str = strdup("ATD%s\015"); dwSize = sizeof(lpszKeyValue); lpszValueName = "FlowControl_Hard"; if ( !RegQueryValueEx( hkSubKey, lpszValueName, NULL, &dwType, lpszKeyValue, &dwSize )) { sprintf(lpszBuf,"%s%s%s",lpszPrefix,lpszKeyValue,lpszPostfix); mdmInf.hwfc_str = strdup(lpszBuf); } else mdmInf.hwfc_str = strdup(""); dwSize = sizeof(lpszKeyValue); lpszValueName = "FlowControl_Soft"; if ( !RegQueryValueEx( hkSubKey, lpszValueName, NULL, &dwType, lpszKeyValue, &dwSize )) { sprintf(lpszBuf,"%s%s%s",lpszPrefix,lpszKeyValue,lpszPostfix); mdmInf.swfc_str = strdup(lpszBuf); } else mdmInf.swfc_str = strdup(""); dwSize = sizeof(lpszKeyValue); lpszValueName = "FlowControl_Off"; if ( !RegQueryValueEx( hkSubKey, lpszValueName, NULL, &dwType, lpszKeyValue, &dwSize )) { sprintf(lpszBuf,"%s%s%s",lpszPrefix,lpszKeyValue,lpszPostfix); mdmInf.nofc_str = strdup(lpszBuf); } else mdmInf.nofc_str = strdup(""); dwSize = sizeof(lpszKeyValue); lpszValueName = "ErrorControl_On"; if ( !RegQueryValueEx( hkSubKey, lpszValueName, NULL, &dwType, lpszKeyValue, &dwSize )) { sprintf(lpszBuf,"%s%s%s",lpszPrefix,lpszKeyValue,lpszPostfix); mdmInf.ec_on_str = strdup(lpszBuf); } else mdmInf.ec_on_str = strdup(""); dwSize = sizeof(lpszKeyValue); lpszValueName = "ErrorControl_Off"; if ( !RegQueryValueEx( hkSubKey, lpszValueName, NULL, &dwType, lpszKeyValue, &dwSize )) { sprintf(lpszBuf,"%s%s%s",lpszPrefix,lpszKeyValue,lpszPostfix); mdmInf.ec_off_str = strdup(lpszBuf); } else mdmInf.ec_off_str = strdup(""); dwSize = sizeof(lpszKeyValue); lpszValueName = "Compression_On"; if ( !RegQueryValueEx( hkSubKey, lpszValueName, NULL, &dwType, lpszKeyValue, &dwSize )) { sprintf(lpszBuf,"%s%s%s",lpszPrefix,lpszKeyValue,lpszPostfix); mdmInf.dc_on_str = strdup(lpszBuf); } else mdmInf.dc_on_str = strdup(""); dwSize = sizeof(lpszKeyValue); lpszValueName = "Compression_Off"; if ( !RegQueryValueEx( hkSubKey, lpszValueName, NULL, &dwType, lpszKeyValue, &dwSize )) { sprintf(lpszBuf,"%s%s%s",lpszPrefix,lpszKeyValue,lpszPostfix); mdmInf.dc_off_str = strdup(lpszBuf); } else mdmInf.dc_off_str = strdup(""); dwSize = sizeof(lpszKeyValue); lpszValueName = "SpeakerMode_Dial"; if ( !RegQueryValueEx( hkSubKey, lpszValueName, NULL, &dwType, lpszKeyValue, &dwSize )) { sprintf(lpszBuf,"%s%s%s",lpszPrefix,lpszKeyValue,lpszPostfix); mdmInf.sp_on_str = strdup(lpszBuf); } else mdmInf.sp_on_str = strdup(""); dwSize = sizeof(lpszKeyValue); lpszValueName = "SpeakerMode_Off"; if ( !RegQueryValueEx( hkSubKey, lpszValueName, NULL, &dwType, lpszKeyValue, &dwSize )) { sprintf(lpszBuf,"%s%s%s",lpszPrefix,lpszKeyValue,lpszPostfix); mdmInf.sp_off_str = strdup(lpszBuf); } else mdmInf.sp_off_str = strdup(""); dwSize = sizeof(lpszKeyValue); lpszValueName = "SpeakerVolume_Low"; if ( !RegQueryValueEx( hkSubKey, lpszValueName, NULL, &dwType, lpszKeyValue, &dwSize )) { sprintf(lpszBuf,"%s%s%s",lpszPrefix,lpszKeyValue,lpszPostfix); mdmInf.vol1_str = strdup(lpszBuf); } else mdmInf.vol1_str = strdup(""); dwSize = sizeof(lpszKeyValue); lpszValueName = "SpeakerVolume_Med"; if ( !RegQueryValueEx( hkSubKey, lpszValueName, NULL, &dwType, lpszKeyValue, &dwSize )) { sprintf(lpszBuf,"%s%s%s",lpszPrefix,lpszKeyValue,lpszPostfix); mdmInf.vol2_str = strdup(lpszBuf); } else mdmInf.vol2_str = strdup(""); dwSize = sizeof(lpszKeyValue); lpszValueName = "SpeakerVolume_High"; if ( !RegQueryValueEx( hkSubKey, lpszValueName, NULL, &dwType, lpszKeyValue, &dwSize )) { sprintf(lpszBuf,"%s%s%s",lpszPrefix,lpszKeyValue,lpszPostfix); mdmInf.vol3_str = strdup(lpszBuf); } else mdmInf.vol3_str = strdup(""); dwSize = sizeof(lpszKeyValue); lpszValueName = "Pulse"; if ( !RegQueryValueEx( hkSubKey, lpszValueName, NULL, &dwType, lpszKeyValue, &dwSize )) { sprintf(lpszBuf,"%s%s%s",lpszPrefix,lpszKeyValue,lpszPostfix); mdmInf.pulse = strdup(lpszBuf); } else mdmInf.pulse = strdup(""); dwSize = sizeof(lpszKeyValue); lpszValueName = "Tone"; if ( !RegQueryValueEx( hkSubKey, lpszValueName, NULL, &dwType, lpszKeyValue, &dwSize )) { sprintf(lpszBuf,"%s%s%s",lpszPrefix,lpszKeyValue,lpszPostfix); mdmInf.tone = strdup(lpszBuf); } else mdmInf.tone = strdup(""); /* We save Blind_Off and then append it to the Init string */ dwSize = sizeof(lpszKeyValue); lpszValueName = "Blind_Off"; RegQueryValueEx( hkSubKey, lpszValueName, NULL, &dwType, lpszBlindOff, &dwSize ); dwSize = sizeof(lpszKeyValue); lpszValueName = "Blind_On"; if ( !RegQueryValueEx( hkSubKey, lpszValueName, NULL, &dwType, lpszKeyValue, &dwSize )) { sprintf(lpszBuf,"%s%s%s",lpszPrefix,lpszKeyValue,lpszPostfix); mdmInf.ignoredt = strdup(lpszBuf); } dwSize = sizeof(lpszKeyValue); lpszValueName = "SpeedNegotiation_On"; if ( !RegQueryValueEx( hkSubKey, lpszValueName, NULL, &dwType, lpszKeyValue, &dwSize )) { sprintf(lpszBuf,"%s%s%s",lpszPrefix,lpszKeyValue,lpszPostfix); mdmInf.sb_on_str = strdup(lpszBuf); } else mdmInf.sb_on_str = strdup(""); dwSize = sizeof(lpszKeyValue); lpszValueName = "SpeedNegotiation_Off"; if ( !RegQueryValueEx( hkSubKey, lpszValueName, NULL, &dwType, lpszKeyValue, &dwSize )) { sprintf(lpszBuf,"%s%s%s",lpszPrefix,lpszKeyValue,lpszPostfix); mdmInf.sb_off_str = strdup(lpszBuf); } else mdmInf.sb_off_str = strdup(""); RegCloseKey( hkSubKey ); } if ( !RegOpenKeyEx(hkModemKey, "Hangup", 0, KEY_READ, &hkSubKey) ) { dwSize = sizeof(lpszKeyValue); lpszValueName = "1"; if ( !RegQueryValueEx( hkSubKey, lpszValueName, NULL, &dwType, lpszKeyValue, &dwSize )) { for ( i=0,j=0;j", &lpszKeyValue[j], 4 ) ) { lpszBuf[i] = '\015' ; j += 3; } else if ( !strncmp( "<#>", &lpszKeyValue[j], 3 ) ) { lpszBuf[i] = '0' ; j += 2; } else lpszBuf[i] = lpszKeyValue[j]; } else { lpszBuf[i] = lpszKeyValue[j]; } } mdmInf.hup_str = strdup(lpszBuf); } RegCloseKey( hkSubKey ); } if ( !RegOpenKeyEx(hkModemKey, "Init", 0, KEY_READ, &hkSubKey) ) { dwSize = sizeof(lpszKeyValue); lpszValueName = "1"; if ( !RegQueryValueEx( hkSubKey, lpszValueName, NULL, &dwType, lpszKeyValue, &dwSize )) { if ( ckstrcmp(lpszKeyValue,"None",-1,0) == 0 ) { lpszBuf[0] = '\0'; i++; } else { for ( i=0,j=0;j", &lpszKeyValue[j], 4 ) ) { lpszBuf[i] = '\015' ; j += 3; } else if ( !strncmp( "<#>", &lpszKeyValue[j], 3 ) ) { lpszBuf[i] = '0' ; j += 2; } else lpszBuf[i] = lpszKeyValue[j]; } else if ( lpszKeyValue[j] == ' ' ) { i--; /* skip the space */ } else { lpszBuf[i] = lpszKeyValue[j]; } } } } dwSize = sizeof(lpszKeyValue); lpszValueName = "2"; if ( !RegQueryValueEx( hkSubKey, lpszValueName, NULL, &dwType, lpszKeyValue, &dwSize )) { if ( ckstrcmp(lpszKeyValue,"NoResponse",-1,0) != 0 ) { i--; j=0; /* Remove Postfix if necessary */ if ( !strcmp(&lpszBuf[i-strlen(lpszPostfix)],lpszPostfix) ) { i -= strlen(lpszPostfix); } if ( !strncmp(lpszKeyValue,lpszPrefix,strlen(lpszPrefix)) ) { /* skip the prefix */ j += strlen(lpszPrefix); } for ( ;j", &lpszKeyValue[j], 4 ) ) { lpszBuf[i] = '\015' ; j += 3; } else if ( !strncmp( "<#>", &lpszKeyValue[j], 3 ) ) { lpszBuf[i] = '0' ; j += 2; } else lpszBuf[i] = lpszKeyValue[j]; } else if ( lpszKeyValue[j] == ' ' ) { i--; /* skip the space */ } else { lpszBuf[i] = lpszKeyValue[j]; } } } } RegCloseKey( hkSubKey ); if ( lpszBlindOff[0] ) { i--; /* Remove Postfix if necessary */ if ( !strcmp(&lpszBuf[i-strlen(lpszPostfix)],lpszPostfix) ) { i -= strlen(lpszPostfix); } strcpy(&lpszBuf[i],lpszBlindOff); i += strlen(lpszBlindOff); strcpy(&lpszBuf[i],lpszPostfix); i += strlen(lpszPostfix); i++; } mdmInf.wake_str = strdup(lpszBuf); dwSize = sizeof(lpszKeyValue); lpszValueName = "UserInit"; if ( !RegQueryValueEx( hkModemKey, lpszValueName, NULL, &dwType, lpszKeyValue, &dwSize )) { if ( lpszKeyValue[0] ) { sprintf(lpszBuf,"%s%s%s",lpszPrefix,lpszKeyValue,lpszPostfix); mdmInf.ini2 = strdup(lpszBuf); } } } RegCloseKey( hkModemKey ); /* Things we just set to default values */ mdmInf.dial_time = 60; mdmInf.pause_chars = strdup(",$@W"); mdmInf.pause_time = 2; mdmInf.wake_rate = 0; mdmInf.wake_prompt = strdup("OK\015"); mdmInf.dmode_prompt = strdup(""); mdmInf.dial_rate = 0; mdmInf.esc_time = 1100; mdmInf.esc_char = 43; mdmInf.aa_on_str = strdup("ATS0=1\015"); mdmInf.aa_off_str = strdup("ATS0=0\015"); /* leave enough room for provider specific information */ lpCommProp = (COMMPROP *) malloc( 1024 ); if ( lpCommProp != NULL ) { memset( lpCommProp, 0, 1024 ); lpCommProp->wPacketLength = 1024; lpCommProp->dwProvSpec1 = COMMPROP_INITIALIZED; rc = GetCommProperties( hModem, lpCommProp ); } else rc = 0; if ( rc && lpCommProp->dwProvSubType == PST_MODEM && lpCommProp->wcProvChar[0]) { lpModemDevCaps = (LPMODEMDEVCAPS) lpCommProp->wcProvChar; mdmInf.max_speed = lpModemDevCaps->dwMaxDTERate; mdmInf.capas = (!_stricmp("AT",lpszPrefix) ? CKD_AT : 0) | (lpModemDevCaps->dwModemOptions & MDM_FLOWCONTROL_HARD ? CKD_HW : 0) | (lpModemDevCaps->dwModemOptions & MDM_FLOWCONTROL_SOFT ? CKD_SW : 0) | (lpModemDevCaps->dwModemOptions & MDM_SPEED_ADJUST ? 0 : CKD_SB) | (lpModemDevCaps->dwModemOptions & MDM_COMPRESSION ? CKD_DC : 0) | (lpModemDevCaps->dwModemOptions & MDM_ERROR_CONTROL ? CKD_EC : 0); } else { mdmInf.max_speed=115200; /* Define the modem capabilities */ mdmInf.capas = (!_stricmp("AT",lpszPrefix) ? CKD_AT : 0) | ((mdmInf.sb_on_str[0] || mdmInf.ec_on_str[0] && mdmInf.dc_on_str[0]) ? CKD_SB : 0) | (mdmInf.ec_on_str[0] ? CKD_EC : 0) | (mdmInf.dc_on_str[0] ? CKD_DC : 0) | (mdmInf.hwfc_str[0] ? CKD_HW : 0) | (mdmInf.swfc_str[0] ? CKD_SW : 0) ; } if ( lpCommProp ) free(lpCommProp); return &mdmInf; } #endif /* NODIAL */ void cktapiDisplayRegistryModemInfo(LPCSTR lpModemKey ) { HKEY hkModemKey=0; HKEY hkSubKey=0; CHAR lpszKeyValue[256]; DWORD dwType=0; DWORD dwSize=0; CHAR *lpszValueName=NULL; printf(" Modem Registry Info:\n"); if ( RegOpenKeyEx(HKEY_LOCAL_MACHINE, lpModemKey, 0, KEY_READ, &hkModemKey) ) return; /* failed */ dwSize = sizeof(lpszKeyValue); lpszValueName = "AttachedTo"; if ( !RegQueryValueEx( hkModemKey, lpszValueName, NULL, &dwType, lpszKeyValue, &dwSize )) { printf(" %s: %s\n", lpszValueName, lpszKeyValue); } dwSize = sizeof(lpszKeyValue); lpszValueName = "FriendlyName"; if ( !RegQueryValueEx( hkModemKey, lpszValueName, NULL, &dwType, lpszKeyValue, &dwSize )) { printf(" %s: %s\n", lpszValueName, lpszKeyValue); } dwSize = sizeof(lpszKeyValue); lpszValueName = "Manufacturer"; if ( !RegQueryValueEx( hkModemKey, lpszValueName, NULL, &dwType, lpszKeyValue, &dwSize )) { printf(" %s: %s\n", lpszValueName, lpszKeyValue); } dwSize = sizeof(lpszKeyValue); lpszValueName = "Model"; if ( !RegQueryValueEx( hkModemKey, lpszValueName, NULL, &dwType, lpszKeyValue, &dwSize )) { printf(" %s: %s\n", lpszValueName, lpszKeyValue); } dwSize = sizeof(lpszKeyValue); lpszValueName = "Reset"; if ( !RegQueryValueEx( hkModemKey, lpszValueName, NULL, &dwType, lpszKeyValue, &dwSize )) { printf(" %s: %s\n", lpszValueName, lpszKeyValue); } dwSize = sizeof(lpszKeyValue); lpszValueName = "PortDriver"; if ( !RegQueryValueEx( hkModemKey, lpszValueName, NULL, &dwType, lpszKeyValue, &dwSize )) { printf(" %s: %s\n", lpszValueName, lpszKeyValue); } dwSize = sizeof(lpszKeyValue); lpszValueName = "InfPath"; if ( !RegQueryValueEx( hkModemKey, lpszValueName, NULL, &dwType, lpszKeyValue, &dwSize )) { printf(" %s: %s\n", lpszValueName, lpszKeyValue); } dwSize = sizeof(lpszKeyValue); lpszValueName = "InfSection"; if ( !RegQueryValueEx( hkModemKey, lpszValueName, NULL, &dwType, lpszKeyValue, &dwSize )) { printf(" %s: %s\n", lpszValueName, lpszKeyValue); } dwSize = sizeof(lpszKeyValue); lpszValueName = "ProviderName"; if ( !RegQueryValueEx( hkModemKey, lpszValueName, NULL, &dwType, lpszKeyValue, &dwSize )) { printf(" %s: %s\n", lpszValueName, lpszKeyValue); } dwSize = sizeof(lpszKeyValue); lpszValueName = "DriverDesc"; if ( !RegQueryValueEx( hkModemKey, lpszValueName, NULL, &dwType, lpszKeyValue, &dwSize )) { printf(" %s: %s\n", lpszValueName, lpszKeyValue); } dwSize = sizeof(lpszKeyValue); lpszValueName = "ResponsesKeyName"; if ( !RegQueryValueEx( hkModemKey, lpszValueName, NULL, &dwType, lpszKeyValue, &dwSize )) { printf(" %s: %s\n", lpszValueName, lpszKeyValue); } if ( !RegOpenKeyEx(hkModemKey, "EnableCallerID", 0, KEY_READ, &hkSubKey) ) { printf(" EnableCallerID:\n"); dwSize = sizeof(lpszKeyValue); lpszValueName = "1"; if ( !RegQueryValueEx( hkSubKey, lpszValueName, NULL, &dwType, lpszKeyValue, &dwSize )) { printf(" %s: %s\n", lpszValueName, lpszKeyValue); } RegCloseKey( hkSubKey ); } if ( !RegOpenKeyEx(hkModemKey, "Answer", 0, KEY_READ, &hkSubKey) ) { printf(" Answer:\n"); dwSize = sizeof(lpszKeyValue); lpszValueName = "1"; if ( !RegQueryValueEx( hkSubKey, lpszValueName, NULL, &dwType, lpszKeyValue, &dwSize )) { printf(" %s: %s\n", lpszValueName, lpszKeyValue); } RegCloseKey( hkSubKey ); } if ( !RegOpenKeyEx(hkModemKey, "Hangup", 0, KEY_READ, &hkSubKey) ) { printf(" Hangup:\n"); dwSize = sizeof(lpszKeyValue); lpszValueName = "1"; if ( !RegQueryValueEx( hkSubKey, lpszValueName, NULL, &dwType, lpszKeyValue, &dwSize )) { printf(" %s: %s\n", lpszValueName, lpszKeyValue); } RegCloseKey( hkSubKey ); } if ( !RegOpenKeyEx(hkModemKey, "Init", 0, KEY_READ, &hkSubKey) ) { printf(" Init:\n"); dwSize = sizeof(lpszKeyValue); lpszValueName = "1"; if ( !RegQueryValueEx( hkSubKey, lpszValueName, NULL, &dwType, lpszKeyValue, &dwSize )) { printf(" %s: %s\n", lpszValueName, lpszKeyValue); } dwSize = sizeof(lpszKeyValue); lpszValueName = "2"; if ( !RegQueryValueEx( hkSubKey, lpszValueName, NULL, &dwType, lpszKeyValue, &dwSize )) { printf(" %s: %s\n", lpszValueName, lpszKeyValue); } RegCloseKey( hkSubKey ); } if ( !RegOpenKeyEx(hkModemKey, "Monitor", 0, KEY_READ, &hkSubKey) ) { printf(" Monitor:\n"); dwSize = sizeof(lpszKeyValue); lpszValueName = "1"; if ( !RegQueryValueEx( hkSubKey, lpszValueName, NULL, &dwType, lpszKeyValue, &dwSize )) { printf(" %s: %s\n", lpszValueName, lpszKeyValue); } dwSize = sizeof(lpszKeyValue); lpszValueName = "2"; if ( !RegQueryValueEx( hkSubKey, lpszValueName, NULL, &dwType, lpszKeyValue, &dwSize )) { printf(" %s: %s\n", lpszValueName, lpszKeyValue); } RegCloseKey( hkSubKey ); } if ( !RegOpenKeyEx(hkModemKey, "Settings", 0, KEY_READ, &hkSubKey) ) { printf(" Settings:\n"); dwSize = sizeof(lpszKeyValue); lpszValueName = "Prefix"; if ( !RegQueryValueEx( hkSubKey, lpszValueName, NULL, &dwType, lpszKeyValue, &dwSize )) { printf(" %s: %s\n", lpszValueName, lpszKeyValue); } dwSize = sizeof(lpszKeyValue); lpszValueName = "Terminator"; if ( !RegQueryValueEx( hkSubKey, lpszValueName, NULL, &dwType, lpszKeyValue, &dwSize )) { printf(" %s: %s\n", lpszValueName, lpszKeyValue); } dwSize = sizeof(lpszKeyValue); lpszValueName = "DialPrefix"; if ( !RegQueryValueEx( hkSubKey, lpszValueName, NULL, &dwType, lpszKeyValue, &dwSize )) { printf(" %s: %s\n", lpszValueName, lpszKeyValue); } dwSize = sizeof(lpszKeyValue); lpszValueName = "DialSuffix"; if ( !RegQueryValueEx( hkSubKey, lpszValueName, NULL, &dwType, lpszKeyValue, &dwSize )) { printf(" %s: %s\n", lpszValueName, lpszKeyValue); } dwSize = sizeof(lpszKeyValue); lpszValueName = "SpeakerVolume_Low"; if ( !RegQueryValueEx( hkSubKey, lpszValueName, NULL, &dwType, lpszKeyValue, &dwSize )) { printf(" %s: %s\n", lpszValueName, lpszKeyValue); } dwSize = sizeof(lpszKeyValue); lpszValueName = "SpeakerVolume_Med"; if ( !RegQueryValueEx( hkSubKey, lpszValueName, NULL, &dwType, lpszKeyValue, &dwSize )) { printf(" %s: %s\n", lpszValueName, lpszKeyValue); } dwSize = sizeof(lpszKeyValue); lpszValueName = "SpeakerVolume_High"; if ( !RegQueryValueEx( hkSubKey, lpszValueName, NULL, &dwType, lpszKeyValue, &dwSize )) { printf(" %s: %s\n", lpszValueName, lpszKeyValue); } dwSize = sizeof(lpszKeyValue); lpszValueName = "SpeakerMode_Off"; if ( !RegQueryValueEx( hkSubKey, lpszValueName, NULL, &dwType, lpszKeyValue, &dwSize )) { printf(" %s: %s\n", lpszValueName, lpszKeyValue); } dwSize = sizeof(lpszKeyValue); lpszValueName = "SpeakerMode_Dial"; if ( !RegQueryValueEx( hkSubKey, lpszValueName, NULL, &dwType, lpszKeyValue, &dwSize )) { printf(" %s: %s\n", lpszValueName, lpszKeyValue); } dwSize = sizeof(lpszKeyValue); lpszValueName = "SpeakerMode_On"; if ( !RegQueryValueEx( hkSubKey, lpszValueName, NULL, &dwType, lpszKeyValue, &dwSize )) { printf(" %s: %s\n", lpszValueName, lpszKeyValue); } dwSize = sizeof(lpszKeyValue); lpszValueName = "SpeakerMode_Setup"; if ( !RegQueryValueEx( hkSubKey, lpszValueName, NULL, &dwType, lpszKeyValue, &dwSize )) { printf(" %s: %s\n", lpszValueName, lpszKeyValue); } dwSize = sizeof(lpszKeyValue); lpszValueName = "FlowControl_Hard"; if ( !RegQueryValueEx( hkSubKey, lpszValueName, NULL, &dwType, lpszKeyValue, &dwSize )) { printf(" %s: %s\n", lpszValueName, lpszKeyValue); } dwSize = sizeof(lpszKeyValue); lpszValueName = "FlowControl_Off"; if ( !RegQueryValueEx( hkSubKey, lpszValueName, NULL, &dwType, lpszKeyValue, &dwSize )) { printf(" %s: %s\n", lpszValueName, lpszKeyValue); } dwSize = sizeof(lpszKeyValue); lpszValueName = "FlowControl_Soft"; if ( !RegQueryValueEx( hkSubKey, lpszValueName, NULL, &dwType, lpszKeyValue, &dwSize )) { printf(" %s: %s\n", lpszValueName, lpszKeyValue); } dwSize = sizeof(lpszKeyValue); lpszValueName = "ErrorControl_On"; if ( !RegQueryValueEx( hkSubKey, lpszValueName, NULL, &dwType, lpszKeyValue, &dwSize )) { printf(" %s: %s\n", lpszValueName, lpszKeyValue); } dwSize = sizeof(lpszKeyValue); lpszValueName = "ErrorControl_Off"; if ( !RegQueryValueEx( hkSubKey, lpszValueName, NULL, &dwType, lpszKeyValue, &dwSize )) { printf(" %s: %s\n", lpszValueName, lpszKeyValue); } dwSize = sizeof(lpszKeyValue); lpszValueName = "ErrorControl_Forced"; if ( !RegQueryValueEx( hkSubKey, lpszValueName, NULL, &dwType, lpszKeyValue, &dwSize )) { printf(" %s: %s\n", lpszValueName, lpszKeyValue); } dwSize = sizeof(lpszKeyValue); lpszValueName = "Compression_On"; if ( !RegQueryValueEx( hkSubKey, lpszValueName, NULL, &dwType, lpszKeyValue, &dwSize )) { printf(" %s: %s\n", lpszValueName, lpszKeyValue); } dwSize = sizeof(lpszKeyValue); lpszValueName = "Compression_Off"; if ( !RegQueryValueEx( hkSubKey, lpszValueName, NULL, &dwType, lpszKeyValue, &dwSize )) { printf(" %s: %s\n", lpszValueName, lpszKeyValue); } dwSize = sizeof(lpszKeyValue); lpszValueName = "Modulation_CCITT"; if ( !RegQueryValueEx( hkSubKey, lpszValueName, NULL, &dwType, lpszKeyValue, &dwSize )) { printf(" %s: %s\n", lpszValueName, lpszKeyValue); } dwSize = sizeof(lpszKeyValue); lpszValueName = "Modulation_Bell"; if ( !RegQueryValueEx( hkSubKey, lpszValueName, NULL, &dwType, lpszKeyValue, &dwSize )) { printf(" %s: %s\n", lpszValueName, lpszKeyValue); } dwSize = sizeof(lpszKeyValue); lpszValueName = "Pulse"; if ( !RegQueryValueEx( hkSubKey, lpszValueName, NULL, &dwType, lpszKeyValue, &dwSize )) { printf(" %s: %s\n", lpszValueName, lpszKeyValue); } dwSize = sizeof(lpszKeyValue); lpszValueName = "Tone"; if ( !RegQueryValueEx( hkSubKey, lpszValueName, NULL, &dwType, lpszKeyValue, &dwSize )) { printf(" %s: %s\n", lpszValueName, lpszKeyValue); } dwSize = sizeof(lpszKeyValue); lpszValueName = "Blind_Off"; if ( !RegQueryValueEx( hkSubKey, lpszValueName, NULL, &dwType, lpszKeyValue, &dwSize )) { printf(" %s: %s\n", lpszValueName, lpszKeyValue); } dwSize = sizeof(lpszKeyValue); lpszValueName = "Blind_On"; if ( !RegQueryValueEx( hkSubKey, lpszValueName, NULL, &dwType, lpszKeyValue, &dwSize )) { printf(" %s: %s\n", lpszValueName, lpszKeyValue); } dwSize = sizeof(lpszKeyValue); lpszValueName = "CallSetupFailTimer"; if ( !RegQueryValueEx( hkSubKey, lpszValueName, NULL, &dwType, lpszKeyValue, &dwSize )) { printf(" %s: %s\n", lpszValueName, lpszKeyValue); } dwSize = sizeof(lpszKeyValue); lpszValueName = "InactivityTimeout"; if ( !RegQueryValueEx( hkSubKey, lpszValueName, NULL, &dwType, lpszKeyValue, &dwSize )) { printf(" %s: %s\n", lpszValueName, lpszKeyValue); } dwSize = sizeof(lpszKeyValue); lpszValueName = "SpeedNegotiation_Off"; if ( !RegQueryValueEx( hkSubKey, lpszValueName, NULL, &dwType, lpszKeyValue, &dwSize )) { printf(" %s: %s\n", lpszValueName, lpszKeyValue); } dwSize = sizeof(lpszKeyValue); lpszValueName = "SpeedNegotiation_On"; if ( !RegQueryValueEx( hkSubKey, lpszValueName, NULL, &dwType, lpszKeyValue, &dwSize )) { printf(" %s: %s\n", lpszValueName, lpszKeyValue); } RegCloseKey( hkSubKey ); } dwSize = sizeof(lpszKeyValue); lpszValueName = "UserInit"; if ( !RegQueryValueEx( hkModemKey, lpszValueName, NULL, &dwType, lpszKeyValue, &dwSize )) { printf(" %s: %s\n", lpszValueName, lpszKeyValue); } if ( !RegOpenKeyEx(hkModemKey, "Settings\\Init", 0, KEY_READ, &hkSubKey) ) { printf("\n Settings\\Init:\n"); dwSize = sizeof(lpszKeyValue); lpszValueName = "1"; if ( !RegQueryValueEx( hkSubKey, lpszValueName, NULL, &dwType, lpszKeyValue, &dwSize )) { printf(" %s: %s\n", lpszValueName, lpszKeyValue); } dwSize = sizeof(lpszKeyValue); lpszValueName = "2"; if ( !RegQueryValueEx( hkSubKey, lpszValueName, NULL, &dwType, lpszKeyValue, &dwSize )) { printf(" %s: %s\n", lpszValueName, lpszKeyValue); } RegCloseKey( hkSubKey ); } RegCloseKey( hkModemKey ); printf("\n"); return; } #endif /* CK_TAPI */