📄 tspi.c
字号:
DWORD dwSize,
LPVARSTRING lpDeviceConfigOut
)
{
PTLINEDEV pLineDev;
DWORD cbSize;
DWORD dwRet = SUCCESS;
DEBUGMSG(ZONE_FUNC, (TEXT("UNIMODEM:+TSPI_lineConfigDialogEdit\n")));
// Validate the input/output buffer
//
if (lpDeviceConfigOut == NULL) {
DEBUGMSG(ZONE_FUNC|ZONE_ERROR, (TEXT("UNIMODEM:-TSPI_lineConfigDialogEdit Invalid lpDeviceConfigOut\n")));
return LINEERR_INVALPOINTER;
}
if (lpDeviceConfigIn == NULL) {
DEBUGMSG(ZONE_FUNC|ZONE_ERROR, (TEXT("UNIMODEM:-TSPI_lineConfigDialogEdit Invalid lpDeviceConfigIn\n")));
return LINEERR_INVALPOINTER;
}
if (lpDeviceConfigOut->dwTotalSize < sizeof(VARSTRING)) {
DEBUGMSG(ZONE_FUNC|ZONE_ERROR, (TEXT("UNIMODEM:-TSPI_lineConfigDialogEdit lpDeviceConfigOut too small\n")));
return LINEERR_STRUCTURETOOSMALL;
}
// Validate the requested device class
//
if (lpszDeviceClass != NULL)
{
if (!ValidateDevCfgClass(lpszDeviceClass))
return LINEERR_INVALDEVICECLASS;
};
// Validate the device ID
//
if ((pLineDev = GetLineDevfromID(dwDeviceID)) == NULL)
return LINEERR_NODEVICE;
// Validate the device configuration structure
//
if (pLineDev->DevMiniCfg.wVersion != ((PDEVMINICFG)lpDeviceConfigIn)->wVersion)
return LINEERR_INVALPARAM;
// Set the output buffer size
//
cbSize = sizeof( DEVMINICFG );
lpDeviceConfigOut->dwUsedSize = sizeof(VARSTRING);
lpDeviceConfigOut->dwNeededSize = sizeof(VARSTRING) + cbSize;
// Validate the output buffer size
//
if (lpDeviceConfigOut->dwTotalSize >= lpDeviceConfigOut->dwNeededSize)
{
PDEVMINICFG pDevMiniConfig;
// Initialize the buffer
//
lpDeviceConfigOut->dwStringFormat = STRINGFORMAT_BINARY;
lpDeviceConfigOut->dwStringSize = cbSize;
lpDeviceConfigOut->dwStringOffset = sizeof(VARSTRING);
lpDeviceConfigOut->dwUsedSize += cbSize;
pDevMiniConfig = (PDEVMINICFG)(lpDeviceConfigOut+1);
// Bring up property sheets for modems and get the updated commconfig
//
if (!TSPI_EditMiniConfig(hwndOwner, pLineDev, (PDEVMINICFG)lpDeviceConfigIn, pDevMiniConfig))
{
DEBUGMSG(ZONE_MISC,(TEXT("UNIMODEM:TSPI_lineConfigDialogEdit User canceled in line config dialog\n")));
dwRet = LINEERR_OPERATIONFAILED;
}
DEBUGMSG(ZONE_DIAL,
(TEXT("UNIMODEM:TSPI_lineConfigDialogEdit After config dialog edit, Dial Modifier %s\n"), pDevMiniConfig->szDialModifier));
}
else
{
DEBUGMSG(ZONE_FUNC,
(TEXT("UNIMODEM:TSPI_lineConfigDialogEdit Insufficient space in output buffer (passed %d, needed %d)\n"),
lpDeviceConfigOut->dwTotalSize, lpDeviceConfigOut->dwNeededSize));
}
DEBUGMSG(ZONE_FUNC,
(TEXT("UNIMODEM:-TSPI_lineConfigDialogEdit x%X (Used %d, Need %d)\n"),
dwRet, lpDeviceConfigOut->dwUsedSize, lpDeviceConfigOut->dwNeededSize));
return dwRet;
}
//
// Unimodem specific extensions - see common\oak\inc\unimodem.h for more details. Currently only setting properties of
// a DEVMINCONFIG is supported.
//
LONG TSPIAPI
TSPI_lineDevSpecific(
DRV_REQUESTID dwRequestID,
HDRVLINE hdLine,
DWORD dwAddressID,
HDRVCALL hdCall,
LPVOID lpParams,
DWORD dwSize
)
{
DWORD rc;
LPDWORD lpdwCmd;
PTLINEDEV pLineDev;
BOOL bEnumExterns;
DEBUGMSG(ZONE_FUNC, (TEXT("UNIMODEM:+TSPI_lineDevSpecific\n")));
lpdwCmd = (LPDWORD)lpParams; // The first 4 bytes is the command code
// Validate command code
switch (*lpdwCmd) {
case UNIMDM_CMD_CHG_DEVCFG:
case UNIMDM_CMD_GET_DEVCFG:
break;
case 0xED000000: // Special value indicating DLL_SYSTEM_STARTED
if (0xED000000 == dwRequestID) {
// Delay enumerating the external modems until after DLL_SYSTEM_STARTED
// so a "real" device will appear first in the list.
EnterCriticalSection(&TspiGlobals.LineDevsCS);
bEnumExterns = !TspiGlobals.bExternModems;
if (bEnumExterns) {
TspiGlobals.bExternModems = TRUE;
}
LeaveCriticalSection(&TspiGlobals.LineDevsCS);
if (bEnumExterns) {
// Note that the only devices that we actually enumerate are
// the external modems. All other entries are created when the
// device loader loads the physical device and notifies us about
// it.
EnumExternModems();
}
rc = 0;
} else {
rc = LINEERR_OPERATIONFAILED;
}
goto exitPoint;
break;
default:
rc = LINEERR_OPERATIONUNAVAIL;
goto exitPoint;
break;
}
if ((pLineDev = GetLineDevfromHandle ((DWORD)hdLine)) == NULL) {
DEBUGMSG(ZONE_ERROR, (TEXT("UNIMODEM:TSPI_lineDevSpecific ** Invalid Line Handle\n")));
rc = LINEERR_OPERATIONFAILED;
goto exitPoint;
}
SetAsyncOp(pLineDev, PENDING_LINEDEVSPECIFIC);
switch (*lpdwCmd) {
case UNIMDM_CMD_CHG_DEVCFG:
if (rc = DevSpecificLineConfigEdit(pLineDev,(PUNIMDM_CHG_DEVCFG)lpParams)) {
goto exitPoint;
}
break;
case UNIMDM_CMD_GET_DEVCFG:
if (rc = DevSpecificLineConfigGet(pLineDev,(PUNIMDM_CHG_DEVCFG)lpParams)) {
goto exitPoint;
}
break;
}
SetAsyncStatus(pLineDev, 0);
rc = SetAsyncID(pLineDev, dwRequestID);
exitPoint:
DEBUGMSG(ZONE_FUNC, (TEXT("UNIMODEM:-TSPI_lineDevSpecific, rc x%X\n"), rc));
return rc;
} // TSPI_lineDevSpecific
LONG TSPIAPI
TSPI_lineDial(
DRV_REQUESTID dwRequestID,
HDRVCALL hdCall,
LPCWSTR lpszDestAddress,
DWORD dwCountryCode
)
{
PTLINEDEV pLineDev;
LONG rc;
DEBUGMSG(ZONE_FUNC|ZONE_CALLS, (TEXT("UNIMODEM:+TSPI_lineDial\n")));
if ((pLineDev = GetLineDevfromHandle ((DWORD)hdCall)) == NULL) {
DEBUGMSG(ZONE_ERROR|ZONE_CALLS, (TEXT("UNIMODEM:TSPI_lineDial ** Invalid Call Handle\n")));
rc = LINEERR_INVALLINEHANDLE;
goto exitPoint;
}
if (pLineDev->DevState != DEVST_PORTCONNECTWAITFORLINEDIAL) {
DEBUGMSG(ZONE_ERROR|ZONE_CALLS, (TEXT("UNIMODEM:TSPI_lineDial ** DevState != DEVST_PORTCONNECTWAITFORLINEDIAL\n")));
rc = LINEERR_INVALCALLSTATE;
goto exitPoint;
}
// Validate lpszDestAddress and get the processed form of it.
DEBUGMSG(ZONE_MISC|ZONE_CALLS, (TEXT("UNIMODEM:TSPI_lineDial - validating destination address\n")));
rc = ValidateAddress(pLineDev, lpszDestAddress, pLineDev->szAddress);
if (SUCCESS != rc){
DEBUGMSG(ZONE_FUNC|ZONE_ERROR|ZONE_CALLS, (TEXT("UNIMODEM:TSPI_lineDial ** Invalid Address\n")));
goto exitPoint;
}
rc = ControlThreadCmd(pLineDev, PENDING_LINEDIAL, dwRequestID);
if (!(rc & 0x80000000)) {
rc = SetAsyncID(pLineDev, dwRequestID);
}
exitPoint:
DEBUGMSG(ZONE_FUNC|ZONE_CALLS, (TEXT("UNIMODEM:-TSPI_lineDial, rc x%X\n"), rc));
return rc;
} // TSPI_lineDial
//
// Terminate a call or abandon a call attempt in progress
//
LONG TSPIAPI
TSPI_lineDrop(DRV_REQUESTID dwRequestID,
HDRVCALL hdCall,
LPCSTR lpsUserUserInfo,
DWORD dwSize
)
{
PTLINEDEV pLineDev;
LONG rc;
BOOL bPassThru;
DEBUGMSG(ZONE_FUNC|ZONE_CALLS, (TEXT("UNIMODEM:+TSPI_lineDrop\n")));
if ((pLineDev = GetLineDevfromHandle ((DWORD)hdCall)) == NULL) {
DEBUGMSG(ZONE_ERROR|ZONE_CALLS, (TEXT("UNIMODEM:-TSPI_lineDrop ** Invalid Call Handle\n")));
return LINEERR_INVALCALLHANDLE;
}
if (pLineDev->dwCallState == LINECALLSTATE_IDLE) {
DEBUGMSG(ZONE_ERROR|ZONE_CALLS, (TEXT("UNIMODEM:-TSPI_lineDrop ** Invalid Call State\n")));
return LINEERR_INVALCALLSTATE;
}
EnterCriticalSection(&pLineDev->OpenCS);
bPassThru = pLineDev->fTakeoverMode;
pLineDev->dwCallFlags |= CALL_DROPPING; // Flag that this call is going away
pLineDev->dwCallFlags &= ~CALL_ACTIVE;
if (bPassThru) {
pLineDev->fTakeoverMode = FALSE;
pLineDev->DevState = DEVST_DISCONNECTED;
}
LeaveCriticalSection(&pLineDev->OpenCS);
if (bPassThru) {
DEBUGMSG(1, (TEXT("UNIMODEM:TSPI_lineDrop Passthrough\n")));
NewCallState(pLineDev, LINECALLSTATE_DISCONNECTED, LINEDISCONNECTMODE_NORMAL);
NewCallState(pLineDev, LINECALLSTATE_IDLE, 0);
SetAsyncOp(pLineDev, PENDING_LINEDROP);
rc = 0;
} else {
rc = ControlThreadCmd(pLineDev, PENDING_LINEDROP, dwRequestID);
}
if (!(rc & 0x80000000)) {
rc = SetAsyncID(pLineDev, dwRequestID);
if (bPassThru) {
SetAsyncStatus(pLineDev, 0);
}
}
DEBUGMSG(ZONE_FUNC|ZONE_CALLS, (TEXT("UNIMODEM:-TSPI_lineDrop, rc x%X\n"), rc));
return rc;
} // TSPI_lineDrop
LONG
TSPIAPI
TSPI_lineGetAddressCaps(
DWORD dwDeviceID,
DWORD dwAddressID,
DWORD dwTSPIVersion,
DWORD dwExtVersion,
LPLINEADDRESSCAPS lpAddressCaps
)
{
LONG rc;
PTLINEDEV pLineDev;
int cbDevClassLen;
int cbAvailMem;
DEBUGMSG(ZONE_FUNC, (TEXT("UNIMODEM:+TSPI_lineGetAddressCaps\n")));
rc = 0;
InitVarData((LPVOID)lpAddressCaps, sizeof(LINEADDRESSCAPS));
// Validate the device ID
if ((pLineDev = GetLineDevfromID(dwDeviceID)) == NULL) {
DEBUGMSG(ZONE_ERROR, (TEXT("UNIMODEM:TSPI_lineGetAddressCaps ** Invalid DeviceID\n")));
rc = LINEERR_NODEVICE;
goto exitPoint;
}
// Validate the address ID
if(dwAddressID != 0) {
DEBUGMSG(ZONE_ERROR, (TEXT("UNIMODEM:TSPI_lineGetAddressCaps ** Invalid AddressID\n")));
rc = LINEERR_INVALADDRESSID;
goto exitPoint;
}
lpAddressCaps->dwLineDeviceID = dwDeviceID;
lpAddressCaps->dwAddressSharing = LINEADDRESSSHARING_PRIVATE;
lpAddressCaps->dwCallInfoStates = LINECALLINFOSTATE_APPSPECIFIC | LINECALLINFOSTATE_MEDIAMODE;
lpAddressCaps->dwCallerIDFlags = LINECALLPARTYID_UNAVAIL;
lpAddressCaps->dwCalledIDFlags = LINECALLPARTYID_UNAVAIL;
lpAddressCaps->dwConnectedIDFlags = LINECALLPARTYID_UNAVAIL;
lpAddressCaps->dwRedirectionIDFlags = LINECALLPARTYID_UNAVAIL;
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_UNAVAIL |
LINEDISCONNECTMODE_NORMAL |
LINEDISCONNECTMODE_BUSY |
LINEDISCONNECTMODE_NODIALTONE |
LINEDISCONNECTMODE_NOANSWER;
lpAddressCaps->dwMaxNumActiveCalls = 1;
lpAddressCaps->dwAddrCapFlags = LINEADDRCAPFLAGS_PARTIALDIAL;
if (!IS_NULL_MODEM(pLineDev)) {
lpAddressCaps->dwAddrCapFlags |= LINEADDRCAPFLAGS_DIALED;
}
lpAddressCaps->dwCallFeatures = LINECALLFEATURE_ANSWER |
LINECALLFEATURE_ACCEPT |
LINECALLFEATURE_SETCALLPARAMS |
LINECALLFEATURE_DIAL |
LINECALLFEATURE_DROP;
cbAvailMem = (int) (lpAddressCaps->dwTotalSize - lpAddressCaps->dwUsedSize);
cbDevClassLen = sizeof(g_szzClassList);
// Copy device classes if it fits
if (cbAvailMem >= cbDevClassLen) {
memcpy((LPBYTE)lpAddressCaps + lpAddressCaps->dwUsedSize, g_szzClassList, cbDevClassLen);
lpAddressCaps->dwDeviceClassesSize = cbDevClassLen;
lpAddressCaps->dwDeviceClassesOffset= lpAddressCaps->dwUsedSize;
lpAddressCaps->dwUsedSize += cbDevClassLen;
cbAvailMem -= cbDevClassLen;
} else {
lpAddressCaps->dwDeviceClassesSize = 0;
lpAddressCaps->dwDeviceClassesOffset = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -