home *** CD-ROM | disk | FTP | other *** search
- /*++
-
- Copyright (c) 1995-1997 Microsoft Corporation
-
- Module Name:
-
- atsp.c
-
- Notes:
-
- --*/
-
-
- #include "atsp.h"
-
-
- BOOL
- WINAPI
- DllMain(
- HANDLE hDLL,
- DWORD dwReason,
- LPVOID lpReserved
- )
- {
- if (dwReason == DLL_PROCESS_ATTACH)
- {
- ghInst = hDLL;
-
- #if DBG
- {
- HKEY hKey;
- DWORD dwDataSize, dwDataType;
- char szAtsp32DebugLevel[] = "Atsp32DebugLevel";
-
-
- RegOpenKeyExA(
- HKEY_LOCAL_MACHINE,
- gszAtspKey,
- 0,
- KEY_ALL_ACCESS,
- &hKey
- );
-
- dwDataSize = sizeof (DWORD);
- gdwDebugLevel=0;
-
- RegQueryValueEx(
- hKey,
- szAtsp32DebugLevel,
- 0,
- &dwDataType,
- (LPBYTE) &gdwDebugLevel,
- &dwDataSize
- );
-
- RegCloseKey (hKey);
- }
- #endif
-
- }
-
- return TRUE;
- }
-
-
- void
- CommThread(
- PDRVLINE pLine
- )
- {
- char buf[4];
- DWORD dwThreadID = GetCurrentThreadId(), dwNumBytes;
- HANDLE hComm = pLine->hComm, hEvent;
- LPOVERLAPPED pOverlapped = &pLine->Overlapped;
-
-
- DBGOUT((
- 3,
- "CommThread (id=%d): enter, port=%s",
- dwThreadID,
- pLine->szComm
- ));
-
- hEvent = pOverlapped->hEvent;
- buf[0] = buf[1] = '.';
-
-
- //
- // Loop waiting for i/o to complete (either the Write done in
- // TSPI_lineMakeCall or the Reads done to retrieve status info).
- // Note that TSPI_lineDrop or TSPI_lineCloseCall may set the
- // event to alert us that they're tearing down the call, in
- // which case we just exit.
- //
-
- for (;;)
- {
- if (WaitForSingleObject (hEvent, ATSP_TIMEOUT) == WAIT_OBJECT_0)
- {
- if (pLine->bDropInProgress == TRUE)
- {
- DBGOUT((2, "CommThread (id=%d): drop in progress"));
- goto CommThread_exit;
- }
-
- GetOverlappedResult (hComm, pOverlapped, &dwNumBytes, FALSE);
- ResetEvent (hEvent);
- }
- else
- {
- DBGOUT((2, "CommThread (id=%d): wait timeout"));
- SetCallState (pLine, LINECALLSTATE_IDLE, 0);
- goto CommThread_exit;
- }
-
- buf[1] &= 0x7f; // nuke the parity bit
-
- DBGOUT((
- 3,
- "CommThread (id=%d): read '%c'",
- dwThreadID,
- (buf[1] == '\r' ? '.' : buf[1])
- ));
-
- switch ((buf[0] << 8) + buf[1])
- {
- case 'CT': // "CONNECT"
- case 'OK': // "OK"
-
- SetCallState (pLine, LINECALLSTATE_CONNECTED, 0);
- goto CommThread_exit;
-
- case 'SY': // "BUSY"
- case 'OR': // "ERROR"
- case 'NO': // "NO ANSWER", "NO DIALTONE", "NO CARRIER"
-
- SetCallState (pLine, LINECALLSTATE_IDLE, 0);
- goto CommThread_exit;
-
- default:
-
- break;
- }
-
- buf[0] = buf[1];
-
- ZeroMemory (pOverlapped, sizeof (OVERLAPPED) - sizeof (HANDLE));
- ReadFile (hComm, &buf[1], 1, &dwNumBytes, pOverlapped);
- }
-
- CommThread_exit:
-
- CloseHandle (hEvent);
- DBGOUT((3, "CommThread (id=%d): exit", dwThreadID));
- ExitThread (0);
- }
-
-
- //
- // We get a slough of C4047 (different levels of indrection) warnings down
- // below in the initialization of FUNC_PARAM structs as a result of the
- // real func prototypes having params that are types other than DWORDs,
- // so since these are known non-interesting warnings just turn them off
- //
-
- #pragma warning (disable:4047)
-
-
- //
- // --------------------------- TAPI_lineXxx funcs -----------------------------
- //
-
- LONG
- TSPIAPI
- TSPI_lineClose(
- HDRVLINE hdLine
- )
- {
- LONG lResult = 0;
- #if DBG
- FUNC_PARAM params[] =
- {
- { gszhdLine, hdLine }
- };
- FUNC_INFO info =
- {
- "TSPI_lineClose",
- 1,
- params,
- };
- #endif
-
- Prolog (&info);
- DrvFree ((PDRVLINE) hdLine);
- return (Epilog (&info, lResult));
- }
-
-
- LONG
- TSPIAPI
- TSPI_lineCloseCall(
- HDRVCALL hdCall
- )
- {
- PDRVLINE pLine = (PDRVLINE) hdCall;
- #if DBG
- FUNC_PARAM params[] =
- {
- { gszhdCall, hdCall }
- };
- FUNC_INFO info =
- {
- "TSPI_lineCloseCall",
- 1,
- params
- };
- #endif
-
-
- //
- // Note that in TAPI 2.0 TSPI_lineCloseCall can get called
- // without TSPI_lineDrop ever being called, so we need to
- // be prepared for either case.
- //
-
- Prolog (&info);
- DropActiveCall (pLine);
- pLine->htCall = NULL;
- return (Epilog (&info, 0));
- }
-
-
- LONG
- TSPIAPI
- TSPI_lineConditionalMediaDetection(
- HDRVLINE hdLine,
- DWORD dwMediaModes,
- LPLINECALLPARAMS const lpCallParams
- )
- {
- #if DBG
- FUNC_PARAM params[] =
- {
- { gszhdLine, hdLine },
- { "dwMediaModes", dwMediaModes },
- { gszlpCallParams, lpCallParams }
- };
- FUNC_INFO info =
- {
- "TSPI_lineConditionalMediaDetection",
- 3,
- params
- };
- #endif
-
-
- //
- // This func is really a no-op for us, since we don't look
- // for incoming calls (though we do say we support them to
- // make apps happy)
- //
-
- Prolog (&info);
- return (Epilog (&info, 0));
- }
-
-
- LONG
- TSPIAPI
- TSPI_lineDrop(
- DRV_REQUESTID dwRequestID,
- HDRVCALL hdCall,
- LPCSTR lpsUserUserInfo,
- DWORD dwSize
- )
- {
- PDRVLINE pLine = (PDRVLINE) hdCall;
- #if DBG
- FUNC_PARAM params[] =
- {
- { gszdwRequestID, dwRequestID },
- { gszhdCall, hdCall },
- { "lpsUserUserInfo", lpsUserUserInfo },
- { gszdwSize, dwSize }
- };
- FUNC_INFO info =
- {
- "TSPI_lineDrop",
- 4,
- params
- };
- #endif
-
-
- Prolog (&info);
- DropActiveCall (pLine);
- SetCallState (pLine, LINECALLSTATE_IDLE, 0);
- (*gpfnCompletionProc)(dwRequestID, 0);
- return (Epilog (&info, dwRequestID));
- }
-
-
- LONG
- TSPIAPI
- TSPI_lineGetAddressCaps(
- DWORD dwDeviceID,
- DWORD dwAddressID,
- DWORD dwTSPIVersion,
- DWORD dwExtVersion,
- LPLINEADDRESSCAPS lpAddressCaps
- )
- {
-
- #if DBG
- FUNC_PARAM params[] =
- {
- { gszdwDeviceID, dwDeviceID },
- { "dwAddressID", dwAddressID },
- { "dwTSPIVersion", dwTSPIVersion },
- { "dwExtVersion", dwExtVersion },
- { "lpAddressCaps", lpAddressCaps }
- };
- FUNC_INFO info =
- {
- "TSPI_lineGetAddressCaps",
- 5,
- params
- };
- #endif
-
- LONG lResult = 0;
-
-
- Prolog (&info);
-
- if (dwAddressID != 0)
- {
- lResult = LINEERR_INVALADDRESSID;
- }
-
- lpAddressCaps->dwNeededSize =
- lpAddressCaps->dwUsedSize = sizeof(LINEADDRESSCAPS);
-
- lpAddressCaps->dwLineDeviceID = dwDeviceID;
- lpAddressCaps->dwAddressSharing = LINEADDRESSSHARING_PRIVATE;
- lpAddressCaps->dwCallInfoStates = LINECALLINFOSTATE_MEDIAMODE |
- LINECALLINFOSTATE_APPSPECIFIC;
- lpAddressCaps->dwCallerIDFlags =
- lpAddressCaps->dwCalledIDFlags =
- lpAddressCaps->dwRedirectionIDFlags =
- lpAddressCaps->dwRedirectingIDFlags = LINECALLPARTYID_UNAVAIL;
- lpAddressCaps->dwCallStates = LINECALLSTATE_IDLE |
- LINECALLSTATE_OFFERING |
- LINECALLSTATE_ACCEPTED |
- LINECALLSTATE_DIALTONE |
- LINECALLSTATE_DIALING |
- LINECALLSTATE_CONNECTED |
- LINECALLSTATE_PROCEEDING |
- LINECALLSTATE_DISCONNECTED |
- LINECALLSTATE_UNKNOWN;
- lpAddressCaps->dwDialToneModes = LINEDIALTONEMODE_UNAVAIL;
- lpAddressCaps->dwBusyModes = LINEBUSYMODE_UNAVAIL;
- lpAddressCaps->dwSpecialInfo = LINESPECIALINFO_UNAVAIL;
- lpAddressCaps->dwDisconnectModes = LINEDISCONNECTMODE_NORMAL |
- LINEDISCONNECTMODE_BUSY |
- LINEDISCONNECTMODE_NOANSWER |
- LINEDISCONNECTMODE_UNAVAIL |
- LINEDISCONNECTMODE_NODIALTONE;
- lpAddressCaps->dwMaxNumActiveCalls = 1;
- lpAddressCaps->dwAddrCapFlags = LINEADDRCAPFLAGS_DIALED;
- lpAddressCaps->dwCallFeatures = LINECALLFEATURE_ACCEPT |
- LINECALLFEATURE_ANSWER |
- LINECALLFEATURE_DROP |
- LINECALLFEATURE_SETCALLPARAMS;
- lpAddressCaps->dwAddressFeatures = LINEADDRFEATURE_MAKECALL;
-
- return (Epilog (&info, lResult));
- }
-
-
- LONG
- TSPIAPI
- TSPI_lineGetAddressStatus(
- HDRVLINE hdLine,
- DWORD dwAddressID,
- LPLINEADDRESSSTATUS lpAddressStatus
- )
- {
- #if DBG
- FUNC_PARAM params[] =
- {
- { gszhdLine, hdLine },
- { "dwAddressID", dwAddressID },
- { "lpAddressStatus", lpAddressStatus }
- };
- FUNC_INFO info =
- {
- "TSPI_lineGetAddressStatus",
- 3,
- params
- };
- #endif
-
- LONG lResult = 0;
- PDRVLINE pLine = (PDRVLINE) hdLine;
-
-
- Prolog (&info);
-
- lpAddressStatus->dwNeededSize =
- lpAddressStatus->dwUsedSize = sizeof(LINEADDRESSSTATUS);
-
- lpAddressStatus->dwNumActiveCalls = (pLine->htCall ? 1 : 0);
- lpAddressStatus->dwAddressFeatures = LINEADDRFEATURE_MAKECALL;
-
- return (Epilog (&info, lResult));
- }
-
-
- LONG
- TSPIAPI
- TSPI_lineGetCallAddressID(
- HDRVCALL hdCall,
- LPDWORD lpdwAddressID
- )
- {
- #if DBG
- FUNC_PARAM params[] =
- {
- { gszhdCall, hdCall },
- { "lpdwAddressID", lpdwAddressID }
- };
- FUNC_INFO info =
- {
- "TSPI_lineGetCallAddressID",
- 2,
- params
- };
- #endif
-
-
- //
- // We only support 1 address (id=0)
- //
-
- Prolog (&info);
- *lpdwAddressID = 0;
- return (Epilog (&info, 0));
- }
-
-
- LONG
- TSPIAPI
- TSPI_lineGetCallInfo(
- HDRVCALL hdCall,
- LPLINECALLINFO lpLineInfo
- )
- {
- #if DBG
- FUNC_PARAM params[] =
- {
- { gszhdCall, hdCall },
- { "lpLineInfo", lpLineInfo }
- };
- FUNC_INFO info =
- {
- "TSPI_lineGetCallInfo",
- 2,
- params
- };
- #endif
- LONG lResult = 0;
- PDRVLINE pLine = (PDRVLINE) hdCall;
-
-
- Prolog (&info);
-
- lpLineInfo->dwNeededSize =
- lpLineInfo->dwUsedSize = sizeof(LINECALLINFO);
-
- lpLineInfo->dwBearerMode = LINEBEARERMODE_VOICE;
- lpLineInfo->dwMediaMode = pLine->dwMediaMode;
- lpLineInfo->dwCallStates = LINECALLSTATE_IDLE |
- LINECALLSTATE_DIALTONE |
- LINECALLSTATE_DIALING |
- LINECALLSTATE_CONNECTED |
- LINECALLSTATE_PROCEEDING |
- LINECALLSTATE_DISCONNECTED |
- LINECALLSTATE_UNKNOWN;
- lpLineInfo->dwOrigin = LINECALLORIGIN_OUTBOUND;
- lpLineInfo->dwReason = LINECALLREASON_DIRECT;
- lpLineInfo->dwCallerIDFlags =
- lpLineInfo->dwCalledIDFlags =
- lpLineInfo->dwConnectedIDFlags =
- lpLineInfo->dwRedirectionIDFlags =
- lpLineInfo->dwRedirectingIDFlags = LINECALLPARTYID_UNAVAIL;
-
- return (Epilog (&info, lResult));
- }
-
-
- LONG
- TSPIAPI
- TSPI_lineGetCallStatus(
- HDRVCALL hdCall,
- LPLINECALLSTATUS lpLineStatus
- )
- {
- #if DBG
- FUNC_PARAM params[] =
- {
- { gszhdCall, hdCall },
- { "lpLineStatus", lpLineStatus }
- };
- FUNC_INFO info =
- {
- "TSPI_lineGetCallStatus",
- 2,
- params
- };
- #endif
- LONG lResult = 0;
- PDRVLINE pLine = (PDRVLINE) hdCall;
-
-
- Prolog (&info);
-
- lpLineStatus->dwNeededSize =
- lpLineStatus->dwUsedSize = sizeof(LINECALLSTATUS);
-
- lpLineStatus->dwCallState = pLine->dwCallState;
-
- if (pLine->dwCallState != LINECALLSTATE_IDLE)
- {
- lpLineStatus->dwCallFeatures = LINECALLFEATURE_DROP;
- }
-
- return (Epilog (&info, lResult));
- }
-
-
- LONG
- TSPIAPI
- TSPI_lineGetDevCaps(
- DWORD dwDeviceID,
- DWORD dwTSPIVersion,
- DWORD dwExtVersion,
- LPLINEDEVCAPS lpLineDevCaps
- )
- {
- #if DBG
- FUNC_PARAM params[] =
- {
- { gszdwDeviceID, dwDeviceID },
- { "dwTSPIVersion", dwTSPIVersion },
- { "dwExtVersion", dwExtVersion },
- { "lpLineDevCaps", lpLineDevCaps }
- };
- FUNC_INFO info =
- {
- "TSPI_lineGetDevCaps",
- 4,
- params
- };
- #endif
-
- LONG lResult = 0;
- static WCHAR szProviderInfo[] = L"AT-compatible modem service provider";
-
- #define PROVIDER_INFO_SIZE (37 * sizeof (WCHAR))
-
- Prolog (&info);
-
- lpLineDevCaps->dwNeededSize = sizeof (LINEDEVCAPS) + PROVIDER_INFO_SIZE +
- (MAX_DEV_NAME_LENGTH + 1) * sizeof (WCHAR);
-
- if (lpLineDevCaps->dwTotalSize >= lpLineDevCaps->dwNeededSize)
- {
- #define LINECONFIG_SIZE (2 * (MAX_DEV_NAME_LENGTH + 1) + 40)
-
- char szLineConfig[LINECONFIG_SIZE], szLineN[16], *p;
- HKEY hKey;
- DWORD dwDataSize, dwDataType;
-
-
- lpLineDevCaps->dwUsedSize = lpLineDevCaps->dwNeededSize;
-
- lpLineDevCaps->dwProviderInfoSize = PROVIDER_INFO_SIZE;
- lpLineDevCaps->dwProviderInfoOffset = sizeof(LINEDEVCAPS);
-
- My_lstrcpyW ((WCHAR *)(lpLineDevCaps + 1), szProviderInfo);
-
- RegOpenKeyEx(
- HKEY_LOCAL_MACHINE,
- gszAtspKey,
- 0,
- KEY_ALL_ACCESS,
- &hKey
- );
-
- dwDataSize = LINECONFIG_SIZE;
- wsprintf (szLineN, "Line%d", dwDeviceID - gdwLineDeviceIDBase);
- lstrcpy (szLineConfig, gszDefLineConfigParams);
-
- RegQueryValueEx(
- hKey,
- szLineN,
- 0,
- &dwDataType,
- (LPBYTE) szLineConfig,
- &dwDataSize
- );
-
- RegCloseKey (hKey);
-
- for (p = szLineConfig; *p != ','; p++);
- *p = 0;
-
- lpLineDevCaps->dwLineNameSize = (lstrlen (szLineConfig) + 1) *
- sizeof (WCHAR);
- lpLineDevCaps->dwLineNameOffset = sizeof(LINEDEVCAPS) +
- PROVIDER_INFO_SIZE;
-
- MultiByteToWideChar(
- CP_ACP,
- MB_PRECOMPOSED,
- szLineConfig,
- -1,
- (WCHAR *) ((LPBYTE) (lpLineDevCaps + 1) + PROVIDER_INFO_SIZE),
- lpLineDevCaps->dwLineNameSize
- );
- }
- else
- {
- lpLineDevCaps->dwUsedSize = sizeof(LINEDEVCAPS);
- }
-
- lpLineDevCaps->dwStringFormat = STRINGFORMAT_ASCII;
- lpLineDevCaps->dwAddressModes = LINEADDRESSMODE_ADDRESSID;
- lpLineDevCaps->dwNumAddresses = 1;
- lpLineDevCaps->dwBearerModes = LINEBEARERMODE_VOICE;
- lpLineDevCaps->dwMaxRate = 9600;
- lpLineDevCaps->dwMediaModes = LINEMEDIAMODE_INTERACTIVEVOICE |
- LINEMEDIAMODE_DATAMODEM;
- lpLineDevCaps->dwDevCapFlags = LINEDEVCAPFLAGS_CLOSEDROP |
- LINEDEVCAPFLAGS_DIALBILLING |
- LINEDEVCAPFLAGS_DIALQUIET |
- LINEDEVCAPFLAGS_DIALDIALTONE;
- lpLineDevCaps->dwMaxNumActiveCalls = 1;
- lpLineDevCaps->dwRingModes = 1;
- lpLineDevCaps->dwLineFeatures = LINEFEATURE_MAKECALL;
-
- return (Epilog (&info, lResult));
- }
-
-
- LONG
- TSPIAPI
- TSPI_lineGetID(
- HDRVLINE hdLine,
- DWORD dwAddressID,
- HDRVCALL hdCall,
- DWORD dwSelect,
- LPVARSTRING lpDeviceID,
- LPCWSTR lpszDeviceClass,
- HANDLE hTargetProcess
- )
- {
- #if DBG
- FUNC_PARAM params[] =
- {
- { gszhdLine, hdLine },
- { "dwAddressID", dwAddressID },
- { gszhdCall, hdCall },
- { "dwSelect", dwSelect },
- { "lpDeviceID", lpDeviceID },
- { "lpszDeviceClass", lpszDeviceClass },
- { "hTargetProcess", hTargetProcess }
- };
- FUNC_INFO info =
- {
- "TSPI_lineGetID",
- 7,
- params
- };
- #endif
-
- DWORD dwNeededSize = sizeof(VARSTRING) + sizeof (DWORD);
- LONG lResult = 0;
- PDRVLINE pLine = (dwSelect == LINECALLSELECT_CALL ?
- (PDRVLINE) hdCall : (PDRVLINE) hdLine);
-
-
- Prolog (&info);
-
- if (lstrcmpiW (lpszDeviceClass, L"tapi/line") == 0)
- {
- if (lpDeviceID->dwTotalSize < dwNeededSize)
- {
- lpDeviceID->dwUsedSize = 3*sizeof(DWORD);
- }
- else
- {
- lpDeviceID->dwUsedSize = dwNeededSize;
-
- lpDeviceID->dwStringFormat = STRINGFORMAT_BINARY;
- lpDeviceID->dwStringSize = sizeof(DWORD);
- lpDeviceID->dwStringOffset = sizeof(VARSTRING);
-
- *((LPDWORD)(lpDeviceID + 1)) = pLine->dwDeviceID;
- }
-
- lpDeviceID->dwNeededSize = dwNeededSize;
- }
- else if (lstrcmpiW (lpszDeviceClass, L"comm/datamodem") == 0)
- {
- dwNeededSize += (strlen (pLine->szComm) + 1) * sizeof (WCHAR);
-
- if (lpDeviceID->dwTotalSize < dwNeededSize)
- {
- lpDeviceID->dwUsedSize = 3 * sizeof(DWORD);
- }
- else
- {
- HANDLE hCommDup = NULL;
-
-
- if (!pLine->htCall)
- {
- DBGOUT((1, "TSPI_lineGetID32: error, no active call"));
-
- lResult = LINEERR_OPERATIONFAILED;
-
- goto TSPI_lineGetID_epilog;
- }
-
- if (!DuplicateHandle(
- GetCurrentProcess(),
- pLine->hComm,
- hTargetProcess,
- &hCommDup,
- 0,
- TRUE,
- DUPLICATE_SAME_ACCESS
- ))
- {
- DBGOUT((
- 1,
- "TSPI_lineGetID: DupHandle failed, err=%ld",
- GetLastError()
- ));
-
- lResult = LINEERR_OPERATIONFAILED;
-
- goto TSPI_lineGetID_epilog;
- }
-
- lpDeviceID->dwUsedSize = dwNeededSize;
-
- lpDeviceID->dwStringFormat = STRINGFORMAT_BINARY;
- lpDeviceID->dwStringSize = dwNeededSize - sizeof(VARSTRING);
- lpDeviceID->dwStringOffset = sizeof(VARSTRING);
-
- *((HANDLE *)(lpDeviceID + 1)) = hCommDup;
-
- lstrcpy(
- ((char *)(lpDeviceID + 1)) + sizeof (HANDLE),
- pLine->szComm
- );
-
- MultiByteToWideChar(
- CP_ACP,
- 0,
- pLine->szComm,
- -1,
- ((WCHAR *)(lpDeviceID + 1)) + sizeof (HANDLE),
- 256
- );
- }
-
- lpDeviceID->dwNeededSize = dwNeededSize;
- }
- else
- {
- lResult = LINEERR_NODEVICE;
- }
-
- TSPI_lineGetID_epilog:
-
- return (Epilog (&info, lResult));
- }
-
-
- LONG
- TSPIAPI
- TSPI_lineGetLineDevStatus(
- HDRVLINE hdLine,
- LPLINEDEVSTATUS lpLineDevStatus
- )
- {
- #if DBG
- FUNC_PARAM params[] =
- {
- { gszhdLine, hdLine },
- { "lpLineDevStatus", lpLineDevStatus }
- };
- FUNC_INFO info =
- {
- "TSPI_lineGetLineDevStatus",
- 2,
- params
- };
- #endif
-
- LONG lResult = 0;
- PDRVLINE pLine = (PDRVLINE) hdLine;
-
-
- Prolog (&info);
-
- lpLineDevStatus->dwUsedSize =
- lpLineDevStatus->dwNeededSize = sizeof (LINEDEVSTATUS);
-
- lpLineDevStatus->dwNumActiveCalls = (pLine->htCall ? 1 : 0);
- //lpLineDevStatus->dwLineFeatures =
- lpLineDevStatus->dwDevStatusFlags = LINEDEVSTATUSFLAGS_CONNECTED |
- LINEDEVSTATUSFLAGS_INSERVICE;
- return (Epilog (&info, lResult));
- }
-
-
- LONG
- TSPIAPI
- TSPI_lineGetNumAddressIDs(
- HDRVLINE hdLine,
- LPDWORD lpdwNumAddressIDs
- )
- {
- #if DBG
- FUNC_PARAM params[] =
- {
- { gszhdLine, hdLine },
- { "lpdwNumAddressIDs", lpdwNumAddressIDs }
- };
- FUNC_INFO info =
- {
- "TSPI_lineGetNumAddressIDs",
- 2,
- params
- };
- #endif
-
- LONG lResult = 0;
- PDRVLINE pLine = (PDRVLINE) hdLine;
-
-
- //
- // We only support 1 address (id=0)
- //
-
- Prolog (&info);
- *lpdwNumAddressIDs = 1;
- return (Epilog (&info, lResult));
- }
-
-
- LONG
- TSPIAPI
- TSPI_lineMakeCall(
- DRV_REQUESTID dwRequestID,
- HDRVLINE hdLine,
- HTAPICALL htCall,
- LPHDRVCALL lphdCall,
- LPCWSTR lpszDestAddress,
- DWORD dwCountryCode,
- LPLINECALLPARAMS const lpCallParams
- )
- {
- char szCommands[64], szCommand[64], szDestAddress[128];
- DWORD dwThreadID, dwNumBytes, dwError;
- PDRVLINE pLine = (PDRVLINE) hdLine;
- #if DBG
- FUNC_PARAM params[] =
- {
- { gszdwRequestID, dwRequestID },
- { gszhdLine, hdLine },
- { "htCall", htCall },
- { "lphdCall", lphdCall },
- { "lpszDestAddress", szDestAddress },
- { "dwCountryCode", dwCountryCode },
- { gszlpCallParams, lpCallParams }
- };
- FUNC_INFO info =
- {
- "TSPI_lineMakeCall",
- 7,
- params
- };
- #endif
-
-
- if (lpszDestAddress)
- {
- WideCharToMultiByte(
- CP_ACP,
- 0,
- lpszDestAddress,
- -1,
- (LPSTR) szDestAddress,
- 128,
- NULL,
- NULL
- );
- }
-
- Prolog (&info);
-
-
- //
- // Check to see if there's already another call
- //
-
- if (pLine->htCall)
- {
- (*gpfnCompletionProc)(dwRequestID, LINEERR_CALLUNAVAIL);
- goto TSPI_lineMakeCall_return;
- }
-
-
- //
- // Since we don't support TSPI_lineDial, fail if app tries
- // to pass a NULL lpszDestAddress (implying that app just
- // wants to go offhook)
- //
-
- if (lpszDestAddress == NULL)
- {
- (*gpfnCompletionProc)(dwRequestID, LINEERR_INVALADDRESS);
- goto TSPI_lineMakeCall_return;
- }
-
-
- //
- // Get the line's config info
- //
-
- {
- HKEY hKey;
- DWORD dwDataSize, dwDataType;
- char szLineN[8], *pszConfig, *p, *p2;
-
-
- wsprintf(
- szLineN,
- "Line%d",
- ((PDRVLINE) hdLine)->dwDeviceID - gdwLineDeviceIDBase
- );
-
- dwDataSize = 256;
-
- pszConfig = DrvAlloc (dwDataSize);
-
- RegOpenKeyEx(
- HKEY_LOCAL_MACHINE,
- gszAtspKey,
- 0,
- KEY_ALL_ACCESS,
- &hKey
- );
-
- RegQueryValueEx(
- hKey,
- szLineN,
- 0,
- &dwDataType,
- (LPBYTE) pszConfig,
- &dwDataSize
- );
-
- pszConfig[dwDataSize] = '\0'; // *pszConfig = "MyLine,COM1,L0"
-
- RegCloseKey (hKey);
-
-
- //
- // szComm
- //
-
- for (p = pszConfig; *p != ','; p++);
- p++; // *p = "COM1,L0"
- for (p2 = p; *p2 != ','; p2++);
- *p2 = 0; // *p = "COM1"
-
- lstrcpy (pLine->szComm, p);
-
-
- //
- // szCommands
- //
-
- p2++; // *p2 = "L0"
- lstrcpy (szCommands, p2);
-
- DrvFree (pszConfig);
- }
-
-
- //
- // Open the port
- //
-
- if ((pLine->hComm = CreateFile(
- pLine->szComm,
- GENERIC_READ | GENERIC_WRITE,
- 0, //FILE_SHARE_READ | FILE_SHARE_WRITE, // BUGBUG
- NULL, // no security attrs
- OPEN_EXISTING,
- FILE_FLAG_OVERLAPPED,
- NULL // no template file
-
- )) == INVALID_HANDLE_VALUE)
- {
- DBGOUT((
- 3,
- "TSPI_lineMakeCall: CreateFile(%s) failed, err=%ld",
- pLine->szComm,
- GetLastError()
- ));
-
- (*gpfnCompletionProc)(dwRequestID, LINEERR_RESOURCEUNAVAIL);
- goto TSPI_lineMakeCall_return;
- }
-
-
- //
- // Setup up the modem command string. If there's an initial 'T'
- // or 'P' (for Tone or Pulse) in the dest address then disregard
- // it. Also if it's a voice call add the semi colon so we return
- // to cmd mode.
- //
-
- {
- char *p = (char *) szDestAddress;
-
-
- if (*p == 'T' || *p == 'P')
- {
- p++;
- }
-
- if (lpCallParams &&
- lpCallParams->dwMediaMode != LINEMEDIAMODE_INTERACTIVEVOICE)
- {
- wsprintf (szCommand, "AT%sDT%s\r", szCommands, p);
- }
- else
- {
- wsprintf (szCommand, "AT%sDT%s;\r", szCommands, p);
- }
- }
-
-
- //
- // Init the data structure & tell tapi our handle to the call
- //
-
- pLine->htCall = htCall;
- pLine->bDropInProgress = FALSE;
- pLine->dwMediaMode = (lpCallParams ? lpCallParams->dwMediaMode :
- LINEMEDIAMODE_INTERACTIVEVOICE);
-
- *lphdCall = (HDRVCALL) pLine;
-
-
- //
- // Do an overlapped write, the comm thread will deal with the results
- //
-
- pLine->Overlapped.hEvent = CreateEvent (NULL, TRUE, FALSE, NULL);
-
- if (!WriteFile(
- pLine->hComm,
- szCommand,
- lstrlen (szCommand),
- &dwNumBytes,
- &pLine->Overlapped
- )
-
- && (dwError = GetLastError()) != ERROR_IO_PENDING)
- {
- DBGOUT((
- 1,
- "TSPI_lineMakeCall: WriteFile(%s) failed, error=%d",
- pLine->szComm,
- dwError
- ));
-
- pLine->htCall = NULL;
- CloseHandle (pLine->hComm);
- CloseHandle (pLine->Overlapped.hEvent);
- (*gpfnCompletionProc)(dwRequestID, LINEERR_OPERATIONFAILED);
- goto TSPI_lineMakeCall_return;
- }
-
-
- //
- // Complete the requests & set the initial call state
- //
-
- (*gpfnCompletionProc)(dwRequestID, 0);
- SetCallState (pLine, LINECALLSTATE_DIALING, 0);
-
-
- //
- // Spin the comm thread to handle the results of the Write above
- //
-
- {
- HANDLE hCommThread;
-
-
- if (!(hCommThread = CreateThread(
- (LPSECURITY_ATTRIBUTES) NULL,
- 0,
- (LPTHREAD_START_ROUTINE) CommThread,
- pLine,
- 0,
- &dwThreadID
- )))
- {
- DBGOUT((
- 1,
- "TSPI_lineMakeCall: CreateThread failed, err=%ld",
- GetLastError()
- ));
-
- GetOverlappedResult(
- pLine->hComm,
- &pLine->Overlapped,
- &dwNumBytes,
- TRUE
- );
-
- SetCallState (pLine, LINECALLSTATE_IDLE, 0);
- CloseHandle (pLine->hComm);
- CloseHandle (pLine->Overlapped.hEvent);
- goto TSPI_lineMakeCall_return;
- }
-
- CloseHandle (hCommThread);
- }
-
-
- TSPI_lineMakeCall_return:
-
- return (Epilog (&info, dwRequestID));
- }
-
-
- LONG
- TSPIAPI
- TSPI_lineNegotiateTSPIVersion(
- DWORD dwDeviceID,
- DWORD dwLowVersion,
- DWORD dwHighVersion,
- LPDWORD lpdwTSPIVersion
- )
- {
- LONG lResult = 0;
- #if DBG
- FUNC_PARAM params[] =
- {
- { gszdwDeviceID, dwDeviceID },
- { "dwLowVersion", dwLowVersion },
- { "dwHighVersion", dwHighVersion },
- { "lpdwTSPIVersion", lpdwTSPIVersion }
- };
- FUNC_INFO info =
- {
- "TSPI_lineNegotiateTSPIVersion",
- 4,
- params
- };
- #endif
-
- Prolog (&info);
- *lpdwTSPIVersion = 0x00020000;
- return (Epilog (&info, lResult));
- }
-
-
- LONG
- TSPIAPI
- TSPI_lineOpen(
- DWORD dwDeviceID,
- HTAPILINE htLine,
- LPHDRVLINE lphdLine,
- DWORD dwTSPIVersion,
- LINEEVENT lpfnEventProc
- )
- {
- LONG lResult;
- PDRVLINE pLine;
- #if DBG
- FUNC_PARAM params[] =
- {
- { gszdwDeviceID, dwDeviceID },
- { "htLine", htLine },
- { "lphdLine", lphdLine },
- { "dwTSPIVersion", dwTSPIVersion },
- { "lpfnEventProc", lpfnEventProc }
- };
- FUNC_INFO info =
- {
- "TSPI_lineOpen",
- 5,
- params
- };
- #endif
-
-
- Prolog (&info);
-
- if ((pLine = DrvAlloc (sizeof (DRVLINE))))
- {
- pLine->htLine = htLine;
- pLine->pfnEventProc = lpfnEventProc;
- pLine->dwDeviceID = dwDeviceID;
-
- *lphdLine = (HDRVLINE) pLine;
-
- lResult = 0;
- }
- else
- {
- lResult = LINEERR_NOMEM;
- }
-
- return (Epilog (&info, lResult));
- }
-
-
- LONG
- TSPIAPI
- TSPI_lineSetDefaultMediaDetection(
- HDRVLINE hdLine,
- DWORD dwMediaModes
- )
- {
- #if DBG
- FUNC_PARAM params[] =
- {
- { gszhdLine, hdLine },
- { "dwMediaModes", dwMediaModes }
- };
- FUNC_INFO info =
- {
- "TSPI_lineSetDefaultMediaDetection",
- 2,
- params
- };
- #endif
-
-
- //
- // This func is really a no-op for us, since we don't look
- // for incoming calls (though we do say we support them to
- // make apps happy)
- //
-
- Prolog (&info);
- return (Epilog (&info, 0));
- }
-
-
- //
- // ------------------------- TSPI_providerXxx funcs ---------------------------
- //
-
- LONG
- TSPIAPI
- TSPI_providerConfig(
- HWND hwndOwner,
- DWORD dwPermanentProviderID
- )
- {
- //
- // Although this func is never called by TAPI v2.0, we export
- // it so that the Telephony Control Panel Applet knows that it
- // can configure this provider via lineConfigProvider(),
- // otherwise Telephon.cpl will not consider it configurable
- //
-
- return 0;
- }
-
-
- LONG
- TSPIAPI
- TSPI_providerGenericDialogData(
- DWORD dwObjectID,
- DWORD dwObjectType,
- LPVOID lpParams,
- DWORD dwSize
- )
- {
- LONG lResult = 0;
- #if DBG
- FUNC_PARAM params[] =
- {
- { "dwObjectID", dwObjectID },
- { "dwObjectType", dwObjectType },
- { "lpParams", lpParams },
- { "dwSize", dwSize }
- };
- FUNC_INFO info =
- {
- "TSPI_providerGenericDialogData",
- 4,
- params
- };
- #endif
-
-
- Prolog (&info);
- return (Epilog (&info, lResult));
- }
-
-
- LONG
- TSPIAPI
- TSPI_providerInit(
- DWORD dwTSPIVersion,
- DWORD dwPermanentProviderID,
- DWORD dwLineDeviceIDBase,
- DWORD dwPhoneDeviceIDBase,
- DWORD dwNumLines,
- DWORD dwNumPhones,
- ASYNC_COMPLETION lpfnCompletionProc,
- LPDWORD lpdwTSPIOptions
- )
- {
- LONG lResult = 0;
- #if DBG
- FUNC_PARAM params[] =
- {
- { "dwTSPIVersion", dwTSPIVersion },
- { gszdwPermanentProviderID, dwPermanentProviderID },
- { "dwLineDeviceIDBase", dwLineDeviceIDBase },
- { "dwPhoneDeviceIDBase", dwPhoneDeviceIDBase },
- { "dwNumLines", dwNumLines },
- { "dwNumPhones", dwNumPhones },
- { "lpfnCompletionProc", lpfnCompletionProc }
- };
- FUNC_INFO info =
- {
- "TSPI_providerInit",
- 7,
- params
- };
- #endif
-
- Prolog (&info);
- gdwLineDeviceIDBase = dwLineDeviceIDBase;
- gpfnCompletionProc = lpfnCompletionProc;
- *lpdwTSPIOptions = LINETSPIOPTION_NONREENTRANT;
- return (Epilog (&info, lResult));
- }
-
-
- LONG
- TSPIAPI
- TSPI_providerInstall(
- HWND hwndOwner,
- DWORD dwPermanentProviderID
- )
- {
- //
- // Although this func is never called by TAPI v2.0, we export
- // it so that the Telephony Control Panel Applet knows that it
- // can add this provider via lineAddProvider(), otherwise
- // Telephon.cpl will not consider it installable
- //
- //
-
- return 0;
- }
-
-
- LONG
- TSPIAPI
- TSPI_providerRemove(
- HWND hwndOwner,
- DWORD dwPermanentProviderID
- )
- {
- //
- // Although this func is never called by TAPI v2.0, we export
- // it so that the Telephony Control Panel Applet knows that it
- // can remove this provider via lineRemoveProvider(), otherwise
- // Telephon.cpl will not consider it removable
- //
-
- return 0;
- }
-
-
- LONG
- TSPIAPI
- TSPI_providerShutdown(
- DWORD dwTSPIVersion,
- DWORD dwPermanentProviderID
- )
- {
- LONG lResult = 0;
- #if DBG
- FUNC_PARAM params[] =
- {
- { "dwTSPIVersion", dwTSPIVersion },
- { gszdwPermanentProviderID, dwPermanentProviderID }
- };
- FUNC_INFO info =
- {
- "TSPI_providerShutdown",
- 2,
- params
- };
- #endif
-
-
- Prolog (&info);
-
- return (Epilog (&info, lResult));
- }
-
-
- LONG
- TSPIAPI
- TSPI_providerEnumDevices(
- DWORD dwPermanentProviderID,
- LPDWORD lpdwNumLines,
- LPDWORD lpdwNumPhones,
- HPROVIDER hProvider,
- LINEEVENT lpfnLineCreateProc,
- PHONEEVENT lpfnPhoneCreateProc
- )
- {
- HKEY hKey;
- DWORD dwNumLines, dwDataType, dwDataSize;
-
-
- //
- // Retrieve the number of devices we're
- // configured for from our registry section
- //
-
- RegOpenKeyEx(
- HKEY_LOCAL_MACHINE,
- gszAtspKey,
- 0,
- KEY_ALL_ACCESS,
- &hKey
- );
-
- dwDataSize = sizeof(dwNumLines);
- dwNumLines = 0;
-
- RegQueryValueEx(
- hKey,
- gszNumLines,
- 0,
- &dwDataType,
- (LPBYTE) &dwNumLines,
- &dwDataSize
- );
-
- RegCloseKey (hKey);
-
- *lpdwNumLines = dwNumLines;
- *lpdwNumPhones = 0;
- return 0;
- }
-
-
- LONG
- TSPIAPI
- TSPI_providerUIIdentify(
- LPWSTR lpszUIDLLName
- )
- {
- LONG lResult = 0;
- #if DBG
- FUNC_PARAM params[] =
- {
- { "lpsUIDLLName", lpszUIDLLName }
- };
- FUNC_INFO info =
- {
- "TSPI_providerUIIdentify",
- 1,
- params
- };
- #endif
-
-
- Prolog (&info);
- My_lstrcpyW(lpszUIDLLName, L"atsp32.tsp");
- return (Epilog (&info, lResult));
- }
-
-
- //
- // ---------------------------- TUISPI_xxx funcs ------------------------------
- //
-
- LONG
- TSPIAPI
- TUISPI_lineConfigDialog(
- TUISPIDLLCALLBACK lpfnUIDLLCallback,
- DWORD dwDeviceID,
- HWND hwndOwner,
- LPCWSTR lpszDeviceClass
- )
- {
- char szDeviceClass[128];
- LONG lResult = 0;
- #if DBG
- FUNC_PARAM params[] =
- {
- { "lpfnUIDLLCallback", lpfnUIDLLCallback },
- { gszdwDeviceID, dwDeviceID },
- { gszhwndOwner, hwndOwner },
- { "lpszDeviceClass", szDeviceClass }
- };
- FUNC_INFO info =
- {
- "TUISPI_lineConfigDialog",
- 4,
- params
- };
- #endif
-
-
- if (lpszDeviceClass)
- {
- WideCharToMultiByte(
- CP_ACP,
- 0,
- lpszDeviceClass,
- -1,
- (LPSTR) szDeviceClass,
- 128,
- NULL,
- NULL
- );
- }
-
- Prolog (&info);
-
- DialogBoxParam(
- ghInst,
- MAKEINTRESOURCE(IDD_DIALOG1),
- hwndOwner,
- (DLGPROC) ConfigDlgProc,
- 0
- );
-
- return (Epilog (&info, lResult));
- }
-
-
- LONG
- TSPIAPI
- TUISPI_providerConfig(
- TUISPIDLLCALLBACK lpfnUIDLLCallback,
- HWND hwndOwner,
- DWORD dwPermanentProviderID
- )
- {
- LONG lResult = 0;
- #if DBG
- FUNC_PARAM params[] =
- {
- { "lpfnUIDLLCallback", lpfnUIDLLCallback },
- { gszhwndOwner, hwndOwner },
- { gszdwPermanentProviderID, dwPermanentProviderID }
- };
- FUNC_INFO info =
- {
- "TUISPI_providerConfig",
- 3,
- params
- };
- #endif
-
-
- Prolog (&info);
-
- DialogBoxParam(
- ghInst,
- MAKEINTRESOURCE(IDD_DIALOG1),
- hwndOwner,
- (DLGPROC) ConfigDlgProc,
- 0
- );
-
- return (Epilog (&info, lResult));
- }
-
-
- LONG
- TSPIAPI
- TUISPI_providerInstall(
- TUISPIDLLCALLBACK lpfnUIDLLCallback,
- HWND hwndOwner,
- DWORD dwPermanentProviderID
- )
- {
- LONG lResult;
-
-
- if ((lResult = ProviderInstall ("atsp32.tsp", TRUE)) == 0)
- {
- DialogBoxParam(
- ghInst,
- MAKEINTRESOURCE(IDD_DIALOG1),
- hwndOwner,
- (DLGPROC) ConfigDlgProc,
- 0
- );
- }
-
- return lResult;
- }
-
-
- LONG
- TSPIAPI
- TUISPI_providerRemove(
- TUISPIDLLCALLBACK lpfnUIDLLCallback,
- HWND hwndOwner,
- DWORD dwPermanentProviderID
- )
- {
- HKEY hKey;
- char szSoftwareMsft[] = "Software\\Microsoft", szATSP[] = "ATSP";
-
-
- //
- // Clean up our registry section
- //
-
- RegOpenKeyExA(
- HKEY_LOCAL_MACHINE,
- szSoftwareMsft,
- 0,
- KEY_ALL_ACCESS,
- &hKey
- );
-
- RegDeleteKeyA (hKey, szATSP);
- RegCloseKey (hKey);
- return 0;
- }
-
-
- #pragma warning (default:4047)
-
-
- //
- // ---------------------- Misc private support routines -----------------------
- //
-
- LPWSTR
- PASCAL
- My_lstrcpyW(
- WCHAR *pString1,
- WCHAR *pString2
- )
- {
- WCHAR *p = pString1;
-
-
- for (; (*p = *pString2); p++, pString2++);
- return pString1;
- }
-
-
- void
- PASCAL
- EnableChildren(
- HWND hwnd,
- BOOL bEnable
- )
- {
- int i;
- static int aiControlIDs[] =
- {
- IDC_DEVICES,
- IDC_NAME,
- IDC_PORT,
- IDC_COMMANDS,
- IDC_REMOVE,
- 0
- };
-
-
- for (i = 0; aiControlIDs[i]; i++)
- {
- EnableWindow (GetDlgItem (hwnd, aiControlIDs[i]), bEnable);
- }
- }
-
-
- void
- PASCAL
- SelectDevice(
- HWND hwnd,
- int iDevice
- )
- {
- SendDlgItemMessage (hwnd, IDC_DEVICES, LB_SETCURSEL, iDevice, 0);
- PostMessage(hwnd, WM_COMMAND, IDC_DEVICES | (LBN_SELCHANGE << 16), 0);
- }
-
-
- BOOL
- CALLBACK
- ConfigDlgProc(
- HWND hwnd,
- UINT msg,
- WPARAM wParam,
- LPARAM lParam
- )
- {
- static HKEY hAtspKey;
-
- DWORD dwDataSize;
- DWORD dwDataType;
-
-
- switch (msg)
- {
- case WM_INITDIALOG:
- {
- char *pBuf;
- DWORD i, iNumLines;
-
-
- //
- // Create or open our configuration key in the registry. If the
- // create fails it may well be that the current user does not
- // have write access to this portion of the registry, so we'll
- // just show a "read only" dialog and not allow user to make any
- // changes
- //
-
- {
- LONG lResult;
- DWORD dwDisposition;
-
-
- if ((lResult = RegCreateKeyEx(
- HKEY_LOCAL_MACHINE,
- gszAtspKey,
- 0,
- "",
- REG_OPTION_NON_VOLATILE,
- KEY_ALL_ACCESS,
- (LPSECURITY_ATTRIBUTES) NULL,
- &hAtspKey,
- &dwDisposition
-
- )) != ERROR_SUCCESS)
- {
- DBGOUT((
- 3,
- "RegCreateKeyEx(%s,ALL_ACCESS) failed, err=%d",
- gszAtspKey,
- lResult
- ));
-
- if ((lResult = RegOpenKeyEx(
- HKEY_LOCAL_MACHINE,
- gszAtspKey,
- 0,
- KEY_QUERY_VALUE,
- &hAtspKey
-
- )) != ERROR_SUCCESS)
- {
- DBGOUT((
- 3,
- "RegOpenKeyEx(%s,ALL_ACCESS) failed, err=%d",
- gszAtspKey,
- lResult
- ));
-
- EndDialog (hwnd, 0);
- return FALSE;
- }
-
- {
- int i;
- static int aiControlIDs[] =
- {
- IDC_NAME,
- IDC_PORT,
- IDC_COMMANDS,
- IDC_ADD,
- IDC_REMOVE,
- IDOK,
- 0
- };
-
-
- for (i = 0; aiControlIDs[i]; i++)
- {
- EnableWindow(
- GetDlgItem (hwnd, aiControlIDs[i]),
- FALSE
- );
- }
- }
- }
- }
-
-
- //
- // Retrieve our configuration info from the registry
- //
-
- dwDataSize = sizeof(iNumLines);
- iNumLines = 0;
-
- RegQueryValueEx(
- hAtspKey,
- gszNumLines,
- 0,
- &dwDataType,
- (LPBYTE) &iNumLines,
- &dwDataSize
- );
-
- SendDlgItemMessage(
- hwnd,
- IDC_NAME,
- EM_LIMITTEXT,
- MAX_DEV_NAME_LENGTH,
- 0
- );
-
- SendDlgItemMessage(
- hwnd,
- IDC_COMMANDS,
- EM_LIMITTEXT,
- MAX_DEV_NAME_LENGTH,
- 0
- );
-
- pBuf = DrvAlloc (256);
-
- for (i = 0; i < iNumLines; i++)
- {
- char *p, *p2, szLineN[8];
- PDRVLINECONFIG pLineConfig = DrvAlloc (sizeof(DRVLINECONFIG));
- LONG lResult;
-
-
- wsprintf (szLineN, "Line%d", i);
-
- dwDataSize = 256;
-
- lResult = RegQueryValueEx(
- hAtspKey,
- szLineN,
- 0,
- &dwDataType,
- (LPBYTE) pBuf,
- &dwDataSize
- );
-
-
- //
- // If there was a problem, use the default config
- //
-
- if (0 != lResult)
- {
- lstrcpy (pBuf, gszDefLineConfigParams);
- }
-
- for (p = pBuf; *p != ','; p++);
- *p = 0;
-
- SendDlgItemMessage(
- hwnd,
- IDC_DEVICES,
- LB_ADDSTRING,
- 0,
- (LPARAM) pBuf
- );
-
- SendDlgItemMessage(
- hwnd,
- IDC_DEVICES,
- LB_SETITEMDATA,
- i,
- (LPARAM) pLineConfig
- );
-
- p++;
- for (p2 = p; *p2 != ','; p2++);
- *p2 = 0;
-
- lstrcpy (pLineConfig->szPort, p);
-
- p = p2 + 1;
-
- lstrcpy (pLineConfig->szCommands, p);
- }
-
- DrvFree (pBuf);
-
-
- //
- // Fill up the various controls with configuration options
- //
-
- {
- static char *aszPorts[] = { "COM1","COM2","COM3",NULL };
-
- for (i = 0; aszPorts[i]; i++)
- {
- SendDlgItemMessage(
- hwnd,
- IDC_PORT,
- LB_ADDSTRING,
- 0,
- (LPARAM) aszPorts[i]
- );
- }
- }
-
- if (iNumLines == 0)
- {
- EnableChildren (hwnd, FALSE);
- }
- else
- {
- SelectDevice (hwnd, 0);
- }
-
- break;
- }
- case WM_COMMAND:
- {
- int iSelection;
- PDRVLINECONFIG pLineConfig;
-
-
- iSelection = SendDlgItemMessage(
- hwnd,
- IDC_DEVICES,
- LB_GETCURSEL,
- 0,
- 0
- );
-
- pLineConfig = (PDRVLINECONFIG) SendDlgItemMessage(
- hwnd,
- IDC_DEVICES,
- LB_GETITEMDATA,
- (WPARAM) iSelection,
- 0
- );
-
- switch (LOWORD((DWORD)wParam))
- {
- case IDC_DEVICES:
-
- if (HIWORD(wParam) == LBN_SELCHANGE)
- {
- char buf[MAX_DEV_NAME_LENGTH + 1];
-
-
- SendDlgItemMessage(
- hwnd,
- IDC_DEVICES,
- LB_GETTEXT,
- iSelection,
- (LPARAM) buf
- );
-
- SetDlgItemText (hwnd, IDC_NAME, buf);
-
- SendDlgItemMessage(
- hwnd,
- IDC_PORT,
- LB_SELECTSTRING,
- (WPARAM) -1,
- (LPARAM) pLineConfig->szPort
- );
-
- SetDlgItemText (hwnd, IDC_COMMANDS, pLineConfig->szCommands);
- }
-
- break;
-
- case IDC_NAME:
-
- if ((HIWORD(wParam) == EN_CHANGE) && (iSelection != LB_ERR))
- {
- char buf[MAX_DEV_NAME_LENGTH + 1];
-
-
- GetDlgItemText (hwnd, IDC_NAME, buf, MAX_DEV_NAME_LENGTH);
-
- SendDlgItemMessage(
- hwnd,
- IDC_DEVICES,
- LB_DELETESTRING,
- iSelection,
- 0
- );
-
- SendDlgItemMessage(
- hwnd,
- IDC_DEVICES,
- LB_INSERTSTRING,
- iSelection,
- (LPARAM) buf
- );
-
- SendDlgItemMessage(
- hwnd,
- IDC_DEVICES,
- LB_SETCURSEL,
- iSelection,
- 0
- );
-
- SendDlgItemMessage(
- hwnd,
- IDC_DEVICES,
- LB_SETITEMDATA,
- iSelection,
- (LPARAM) pLineConfig
- );
- }
-
- break;
-
- case IDC_PORT:
-
- if (HIWORD(wParam) == LBN_SELCHANGE)
- {
- iSelection = SendDlgItemMessage(
- hwnd,
- IDC_PORT,
- LB_GETCURSEL,
- 0,
- 0
- );
-
- SendDlgItemMessage(
- hwnd,
- IDC_PORT,
- LB_GETTEXT,
- iSelection,
- (LPARAM) pLineConfig->szPort
- );
- }
-
- break;
-
- case IDC_COMMANDS:
-
- if ((HIWORD(wParam) == EN_CHANGE) && (iSelection != LB_ERR))
- {
- GetDlgItemText(
- hwnd,
- IDC_COMMANDS,
- pLineConfig->szCommands,
- 63
- );
- }
-
- break;
-
- case IDC_ADD:
- {
- int iNumLines, i = 2;
- char szLineName[32];
- PDRVLINECONFIG pLineConfig = DrvAlloc (sizeof(DRVLINECONFIG));
-
-
- iNumLines = SendDlgItemMessage(
- hwnd,
- IDC_DEVICES,
- LB_GETCOUNT,
- 0,
- 0
- );
-
- lstrcpy (pLineConfig->szPort, "COM1");
-
- lstrcpy (szLineName, "my new line");
-
- find_unique_line_name:
-
- if (SendDlgItemMessage(
- hwnd,
- IDC_DEVICES,
- LB_FINDSTRING,
- (WPARAM) -1,
- (LPARAM) szLineName
-
- ) != LB_ERR)
- {
- wsprintf (szLineName, "my new line%d", i++);
- goto find_unique_line_name;
- }
-
- SendDlgItemMessage(
- hwnd,
- IDC_DEVICES,
- LB_ADDSTRING,
- 0,
- (LPARAM) szLineName
- );
-
- SendDlgItemMessage(
- hwnd,
- IDC_DEVICES,
- LB_SETITEMDATA,
- iNumLines,
- (LPARAM) pLineConfig
- );
-
- EnableChildren (hwnd, TRUE);
-
- SelectDevice (hwnd, iNumLines);
-
- SetFocus (GetDlgItem (hwnd, IDC_NAME));
-
- SendDlgItemMessage(
- hwnd,
- IDC_NAME,
- EM_SETSEL,
- 0,
- (LPARAM) -1
- );
-
- break;
- }
- case IDC_REMOVE:
- {
- int iNumLines;
-
-
- DrvFree (pLineConfig);
-
- iNumLines = SendDlgItemMessage(
- hwnd,
- IDC_DEVICES,
- LB_DELETESTRING,
- iSelection,
- 0
- );
-
- if (iNumLines == 0)
- {
- SetDlgItemText (hwnd, IDC_NAME, "");
- SetDlgItemText (hwnd, IDC_COMMANDS, "");
-
- EnableChildren (hwnd, FALSE);
- }
- else
- {
- SelectDevice (hwnd, 0);
- }
-
- break;
- }
- case IDOK:
- {
- int i, iNumLines;
- char *pBuf;
-
-
- //
- // Update the num lines & num phones values
- //
-
- pBuf = DrvAlloc (256);
-
- iNumLines = SendDlgItemMessage(
- hwnd,
- IDC_DEVICES,
- LB_GETCOUNT,
- 0,
- 0
- );
-
- RegSetValueEx(
- hAtspKey,
- gszNumLines,
- 0,
- REG_DWORD,
- (LPBYTE) &iNumLines,
- sizeof(DWORD)
- );
-
-
- //
- // For each installed device save it's config info
- //
-
- for (i = 0; i < iNumLines; i++)
- {
- char szLineN[8];
- PDRVLINECONFIG pLineConfig;
-
-
- SendDlgItemMessage(
- hwnd,
- IDC_DEVICES,
- LB_GETTEXT,
- i,
- (LPARAM) pBuf
- );
-
- pLineConfig = (PDRVLINECONFIG) SendDlgItemMessage(
- hwnd,
- IDC_DEVICES,
- LB_GETITEMDATA,
- i,
- 0
- );
-
- wsprintf(
- pBuf + strlen (pBuf),
- ",%s,%s",
- pLineConfig->szPort,
- pLineConfig->szCommands
- );
-
- wsprintf (szLineN, "Line%d", i);
-
- RegSetValueEx(
- hAtspKey,
- szLineN,
- 0,
- REG_SZ,
- (LPBYTE) pBuf,
- lstrlen (pBuf) + 1
- );
-
- DrvFree (pLineConfig);
- }
-
- DrvFree (pBuf);
-
- // fall thru to EndDialog...
- }
- case IDCANCEL:
-
- RegCloseKey (hAtspKey);
- EndDialog (hwnd, 0);
- break;
-
- } // switch (LOWORD((DWORD)wParam))
-
- break;
- }
- } // switch (msg)
-
- return FALSE;
- }
-
-
- LPVOID
- PASCAL
- DrvAlloc(
- DWORD dwSize
- )
- {
- return (LocalAlloc (LPTR, dwSize));
- }
-
-
- VOID
- PASCAL
- DrvFree(
- LPVOID lp
- )
- {
- LocalFree (lp);
- }
-
-
- void
- PASCAL
- SetCallState(
- PDRVLINE pLine,
- DWORD dwCallState,
- DWORD dwCallStateMode
- )
- {
- if (dwCallState != pLine->dwCallState)
- {
- pLine->dwCallState = dwCallState;
- pLine->dwCallStateMode = dwCallStateMode;
-
- (*pLine->pfnEventProc)(
- pLine->htLine,
- pLine->htCall,
- LINE_CALLSTATE,
- dwCallState,
- dwCallStateMode,
- pLine->dwMediaMode
- );
- }
- }
-
-
- #if DBG
-
- void
- PASCAL
- Prolog(
- PFUNC_INFO pInfo
- )
- {
- DWORD i;
-
-
- DBGOUT((3, "%s: enter", pInfo->lpszFuncName));
-
- for (i = 0; i < pInfo->dwNumParams; i++)
- {
- if (pInfo->aParams[i].dwVal &&
- pInfo->aParams[i].lpszVal[3] == 'z') // lpszVal = "lpsz..."
- {
- DBGOUT((
- 3,
- "%s%s=x%lx, '%s'",
- gszTab,
- pInfo->aParams[i].lpszVal,
- pInfo->aParams[i].dwVal,
- pInfo->aParams[i].dwVal
- ));
- }
- else
- {
- DBGOUT((
- 3,
- "%s%s=x%lx",
- gszTab,
- pInfo->aParams[i].lpszVal,
- pInfo->aParams[i].dwVal
- ));
- }
- }
- }
-
-
- LONG
- PASCAL
- Epilog(
- PFUNC_INFO pInfo,
- LONG lResult
- )
- {
- DBGOUT((3, "%s: returning x%x", pInfo->lpszFuncName, lResult));
-
- return lResult;
- }
-
-
- void
- CDECL
- DebugOutput(
- DWORD dwDbgLevel,
- LPCSTR lpszFormat,
- ...
- )
- {
- if (dwDbgLevel <= gdwDebugLevel)
- {
- char buf[128] = "ATSP32: ";
- va_list ap;
-
-
- va_start(ap, lpszFormat);
-
- wvsprintf (&buf[8], lpszFormat, ap);
-
- lstrcat (buf, "\n");
-
- OutputDebugString (buf);
-
- va_end(ap);
- }
- }
-
- #endif
-
-
- LONG
- PASCAL
- ProviderInstall(
- char *pszProviderName,
- BOOL bNoMultipleInstance
- )
- {
- LONG lResult;
-
-
- //
- // If only one installation instance of this provider is
- // allowed then we want to check the provider list to see
- // if the provider is already installed
- //
-
- if (bNoMultipleInstance)
- {
- LONG (WINAPI *pfnGetProviderList)();
- DWORD dwTotalSize, i;
- HINSTANCE hTapi32;
- LPLINEPROVIDERLIST pProviderList;
- LPLINEPROVIDERENTRY pProviderEntry;
-
-
- //
- // Load Tapi32.dll & get a pointer to the lineGetProviderList
- // func. We don't want to statically link because this module
- // plays the part of both core SP & UI DLL, and we don't want
- // to incur the performance hit of automatically loading
- // Tapi32.dll when running as a core SP within Tapisrv.exe's
- // context.
- //
-
- if (!(hTapi32 = LoadLibrary ("tapi32.dll")))
- {
- DBGOUT((
- 1,
- "LoadLibrary(tapi32.dll) failed, err=%d",
- GetLastError()
- ));
-
- lResult = LINEERR_OPERATIONFAILED;
- goto ProviderInstall_return;
- }
-
- if (!((FARPROC) pfnGetProviderList = GetProcAddress(
- hTapi32,
- (LPCSTR) "lineGetProviderList"
- )))
- {
- DBGOUT((
- 1,
- "GetProcAddr(lineGetProviderList) failed, err=%d",
- GetLastError()
- ));
-
- lResult = LINEERR_OPERATIONFAILED;
- goto ProviderInstall_unloadTapi32;
- }
-
-
- //
- // Loop until we get the full provider list
- //
-
- dwTotalSize = sizeof (LINEPROVIDERLIST);
-
- goto ProviderInstall_allocProviderList;
-
- ProviderInstall_getProviderList:
-
- if ((lResult = (*pfnGetProviderList)(0x00020000, pProviderList)) != 0)
- {
- goto ProviderInstall_freeProviderList;
- }
-
- if (pProviderList->dwNeededSize > pProviderList->dwTotalSize)
- {
- dwTotalSize = pProviderList->dwNeededSize;
-
- LocalFree (pProviderList);
-
- ProviderInstall_allocProviderList:
-
- if (!(pProviderList = LocalAlloc (LPTR, dwTotalSize)))
- {
- lResult = LINEERR_NOMEM;
- goto ProviderInstall_unloadTapi32;
- }
-
- pProviderList->dwTotalSize = dwTotalSize;
-
- goto ProviderInstall_getProviderList;
- }
-
-
- //
- // Inspect the provider list entries to see if this provider
- // is already installed
- //
-
- pProviderEntry = (LPLINEPROVIDERENTRY) (((LPBYTE) pProviderList) +
- pProviderList->dwProviderListOffset);
-
- for (i = 0; i < pProviderList->dwNumProviders; i++)
- {
- char *pszInstalledProviderName = ((char *) pProviderList) +
- pProviderEntry->dwProviderFilenameOffset,
- *p;
-
-
- //
- // Make sure pszInstalledProviderName points at <filename>
- // and not <path>\filename by walking backeards thru the
- // string searching for last '\\'
- //
-
- p = pszInstalledProviderName +
- lstrlen (pszInstalledProviderName) - 1;
-
- for (; *p != '\\' && p != pszInstalledProviderName; p--);
-
- pszInstalledProviderName =
- (p == pszInstalledProviderName ? p : p + 1);
-
- if (lstrcmpiA (pszInstalledProviderName, pszProviderName) == 0)
- {
- lResult = LINEERR_NOMULTIPLEINSTANCE;
- goto ProviderInstall_freeProviderList;
- }
-
- pProviderEntry++;
- }
-
-
- //
- // If here then the provider isn't currently installed,
- // so do whatever configuration stuff is necessary and
- // indicate SUCCESS
- //
-
- lResult = 0;
-
-
- ProviderInstall_freeProviderList:
-
- LocalFree (pProviderList);
-
- ProviderInstall_unloadTapi32:
-
- FreeLibrary (hTapi32);
- }
- else
- {
- //
- // Do whatever configuration stuff is necessary and return SUCCESS
- //
-
- lResult = 0;
- }
-
- ProviderInstall_return:
-
- return lResult;
- }
-
-
- void
- PASCAL
- DropActiveCall(
- PDRVLINE pLine
- )
- {
- if (pLine->hComm)
- {
- DWORD dwNumBytes, dwError;
- OVERLAPPED overlapped;
-
-
- pLine->bDropInProgress = TRUE;
-
- SetEvent (pLine->Overlapped.hEvent);
-
- ZeroMemory (&overlapped, sizeof (OVERLAPPED));
-
- overlapped.hEvent = CreateEvent (NULL, TRUE, FALSE, NULL);
-
- if (pLine->dwMediaMode != LINEMEDIAMODE_INTERACTIVEVOICE)
- {
- if (!WriteFile(
- pLine->hComm,
- "+++\r", 4,
- &dwNumBytes,
- &overlapped
- ))
- {
- if ((dwError = GetLastError()) == ERROR_IO_PENDING)
- {
- GetOverlappedResult(
- pLine->hComm,
- &overlapped,
- &dwNumBytes,
- TRUE
- );
-
- ResetEvent (overlapped.hEvent);
- }
- else
- {
- }
- }
- }
-
- if (!WriteFile (pLine->hComm, "ATH\r", 4, &dwNumBytes, &overlapped))
- {
- if ((dwError = GetLastError()) == ERROR_IO_PENDING)
- {
- GetOverlappedResult(
- pLine->hComm,
- &overlapped,
- &dwNumBytes,
- TRUE
- );
- }
- else
- {
- }
- }
-
- CloseHandle (overlapped.hEvent);
- CloseHandle (pLine->hComm);
- pLine->hComm = NULL;
- }
- }
-