📄 tspi.c
字号:
// TSPI_lineGetDevConfig returns the default device configuration for the specified device.
// This is done so applications can avoid storing the devcfg when the user wants the default
// settings. If the settings are different than the default, then the application needs to store
// them and set them via lineSetDevConfig whether lineGetDevConfig returns defaults or not.
//
LONG TSPIAPI
TSPI_lineGetDevConfig(
DWORD dwDeviceID,
LPVARSTRING lpDeviceConfig,
LPCWSTR lpszDeviceClass
)
{
PTLINEDEV pLineDev;
DWORD dwRet = SUCCESS;
DWORD cbSize;
PDEVMINICFG pDevMiniCfg;
DEBUGMSG(ZONE_FUNC, (TEXT("UNIMODEM:+TSPI_lineGetDevConfig\n")));
// Validate the requested device class
//
if (lpszDeviceClass != NULL)
{
if (!ValidateDevCfgClass(lpszDeviceClass))
return LINEERR_INVALDEVICECLASS;
}
// Validate the buffer
//
if (lpDeviceConfig == NULL)
return LINEERR_INVALPOINTER;
if (lpDeviceConfig->dwTotalSize < sizeof(VARSTRING))
return LINEERR_STRUCTURETOOSMALL;
// Validate the device ID
//
if ((pLineDev = GetLineDevfromID (dwDeviceID)) == NULL)
return LINEERR_NODEVICE;
// Validate the buffer size
//
cbSize = sizeof(DEVMINICFG);
lpDeviceConfig->dwUsedSize = sizeof(VARSTRING);
lpDeviceConfig->dwNeededSize = sizeof(VARSTRING) + cbSize;
if (lpDeviceConfig->dwTotalSize >= lpDeviceConfig->dwNeededSize)
{
pDevMiniCfg = (PDEVMINICFG)(((LPBYTE)lpDeviceConfig) + sizeof(VARSTRING));
// If someone does a SetDevCfg for some provider who needs a post-dial-terminal
// and they then want to create a new connection via GetDevCfg/CfgDialogEdit,
// they will end up with the default connection lookin like the original.
// To work around this, I will always return the default config here. If the app
// needs to remember a specific config for later edit, they must store it themselves.
getDefaultDevConfig( pLineDev, pDevMiniCfg );
lpDeviceConfig->dwStringFormat = STRINGFORMAT_BINARY;
lpDeviceConfig->dwStringSize = cbSize;
lpDeviceConfig->dwStringOffset = sizeof(VARSTRING);
lpDeviceConfig->dwUsedSize += cbSize;
DEBUGMSG(ZONE_FUNC|ZONE_CALLS,
(TEXT("UNIMODEM:TSPI_lineGetDevConfig (DevID %d): dwModemOptions x%X, fwOptions x%X, dwCallSetupFail x%X\n"),
dwDeviceID, pDevMiniCfg->dwModemOptions, pDevMiniCfg->fwOptions, pDevMiniCfg->dwCallSetupFailTimer));
}
else
{
// Not enough room
DEBUGMSG(ZONE_FUNC,
(TEXT("UNIMODEM:TSPI_lineGetDevConfig needed %d bytes, had %d\n"),
lpDeviceConfig->dwNeededSize, lpDeviceConfig->dwTotalSize));
};
DEBUGMSG(ZONE_FUNC,
(TEXT("UNIMODEM:-TSPI_lineGetDevConfig x%X (Used %d, Need %d)\n"),
dwRet, lpDeviceConfig->dwUsedSize, lpDeviceConfig->dwNeededSize));
return dwRet;
}
typedef HICON (WINAPI * PFN_LOADICON)(HINSTANCE, LPCWSTR);
LONG
TSPIAPI
TSPI_lineGetIcon(
DWORD dwDeviceID,
LPCWSTR lpszDeviceClass,
LPHICON lphIcon
)
{
LONG rc;
PFN_LOADICON pfnLoadIcon;
DEBUGMSG(ZONE_FUNC, (TEXT("UNIMODEM:+TSPI_lineGetIcon\n")));
rc = LINEERR_RESOURCEUNAVAIL;
//
// TODO: First check that the device class corresponds to the icon
//
if (TspiGlobals.hIconLine == NULL) {
if (IsAPIReady(SH_WMGR)) {
if (pfnLoadIcon = (PFN_LOADICON)GetProcAddress(g_hCoreDLL, L"LoadIconW")) {
TspiGlobals.hIconLine = pfnLoadIcon(
TspiGlobals.hInstance,
(LPCWSTR)MAKEINTRESOURCE(LINE_ICON)
);
rc = 0;
}
}
} else {
rc = 0;
}
*lphIcon = TspiGlobals.hIconLine;
DEBUGMSG(ZONE_FUNC, (TEXT("UNIMODEM:-TSPI_lineGetIcon returning %x\n"), rc));
return rc;
} // TSPI_lineGetIcon
//
// Get the device ID for the specified device. The caller
// can use the returned ID with the corresponding media (i.e. for
// serial lines the ID can be passed to ReadFile(), WriteFile(),
// etc).
//
LONG TSPIAPI
TSPI_lineGetID(
HDRVLINE hdLine,
DWORD dwAddressID,
HDRVCALL hdCall,
DWORD dwSelect,
LPVARSTRING lpDeviceID,
LPCWSTR lpszDeviceClass
)
{
PTLINEDEV pLineDev;
UINT cbPort;
UINT idClass;
DEBUGMSG(ZONE_FUNC, (TEXT("UNIMODEM:+TSPI_lineGetID - ProcPerm=0x%X\n"),
GetCurrentPermissions()));
switch (dwSelect)
{
case LINECALLSELECT_ADDRESS:
if (dwAddressID != 0)
{
DEBUGMSG(ZONE_FUNC, (TEXT("UNIMODEM:-TSPI_lineGetID - INVALADDRESSID\n")));
return LINEERR_INVALADDRESSID;
}
// FALLTHROUGH
case LINECALLSELECT_LINE:
if ((pLineDev = GetLineDevfromHandle ((DWORD)hdLine)) == NULL)
{
DEBUGMSG(ZONE_FUNC, (TEXT("UNIMODEM:-TSPI_lineGetID - INVALLINEHANDLE\n")));
return LINEERR_INVALLINEHANDLE;
}
break;
case LINECALLSELECT_CALL:
if ((pLineDev = GetLineDevfromHandle ((DWORD)hdCall)) == NULL)
{
DEBUGMSG(ZONE_FUNC, (TEXT("UNIMODEM:-TSPI_lineGetID - INVALCALLHANDLE\n")));
return LINEERR_INVALCALLHANDLE;
}
break;
default:
DEBUGMSG(ZONE_FUNC,
(TEXT("UNIMODEM:-TSPI_lineGetID - Invalid dwSelect x%X\n"),
dwSelect));
return LINEERR_OPERATIONFAILED;
}
// Determine the device class
//
for (idClass = 0; idClass < MAX_SUPPORT_CLASS; idClass++)
{
DEBUGMSG(ZONE_FUNC, (TEXT("UNIMODEM:TSPI_lineGetID Comparing strings %s to %s\n"),
lpszDeviceClass, aGetID[idClass].szClassName));
if (wcsicmp(lpszDeviceClass, aGetID[idClass].szClassName) == 0)
break;
};
DEBUGMSG(ZONE_FUNC, (TEXT("UNIMODEM:TSPI_lineGetID Class ID = %d (%s)\n"), idClass,
aGetID[idClass].szClassName));
// Determine the required size
//
switch (idClass)
{
case TAPILINE:
cbPort = sizeof(DWORD);
break;
case COMM:
cbPort = (wcslen(pLineDev->szFriendlyName) + 1) * sizeof(WCHAR);
break;
case COMMMODEM:
cbPort = (wcslen(pLineDev->szFriendlyName) + 1) * sizeof(WCHAR) + sizeof(DWORD);
break;
case NDIS:
cbPort = sizeof(g_szDeviceClass) + sizeof(DWORD);
break;
default:
DEBUGMSG(ZONE_FUNC,
(TEXT("UNIMODEM:-TSPI_lineGetID - Invalid ID Class x%X\n"),
idClass ));
return LINEERR_OPERATIONFAILED;
};
// Calculate the required size
//
//lpDeviceID->dwUsedSize = sizeof(VARSTRING); // TAPI fills it in.
lpDeviceID->dwNeededSize = sizeof(VARSTRING) + cbPort;
lpDeviceID->dwStringFormat = aGetID[idClass].dwFormat;
ASSERT(lpDeviceID->dwUsedSize == sizeof(VARSTRING));
if ((lpDeviceID->dwTotalSize - lpDeviceID->dwUsedSize) <
cbPort)
{
DEBUGMSG(ZONE_FUNC, (TEXT("UNIMODEM:-TSPI_lineGetID - Inusufficient space\n")));
return SUCCESS;
}
// We have enough space to return valid information
//
lpDeviceID->dwStringSize = cbPort;
lpDeviceID->dwStringOffset = sizeof(VARSTRING);
lpDeviceID->dwUsedSize += cbPort;
// Return the useful information
switch (idClass)
{
case TAPILINE:
{
LPDWORD lpdwDeviceID;
lpdwDeviceID = (LPDWORD)(((LPBYTE)lpDeviceID) + sizeof(VARSTRING));
*lpdwDeviceID = (DWORD) pLineDev->dwDeviceID;
DEBUGMSG(ZONE_MISC,
(TEXT("UNIMODEM:-TSPI_lineGetID TAPILINE - Device ID x%X\n"),
pLineDev->dwDeviceID));
break;
}
case COMM:
{
wcsncpy( (LPWSTR)((LPBYTE)lpDeviceID + sizeof(VARSTRING)),
pLineDev->szFriendlyName, (cbPort/sizeof(WCHAR)) );
DEBUGMSG(ZONE_MISC,
(TEXT("UNIMODEM:-TSPI_lineGetID COMM - Device name \"%s\" (len %d)\n"),
pLineDev->szFriendlyName, (cbPort/sizeof(WCHAR))));
break;
}
case COMMMODEM:
{
LPDWORD lpdwDeviceHandle;
lpdwDeviceHandle = (LPDWORD)(((LPBYTE)lpDeviceID) + sizeof(VARSTRING));
if (pLineDev->hDevice != (HANDLE)INVALID_DEVICE)
{
*lpdwDeviceHandle = (DWORD)pLineDev->hDevice;
SetHandleOwner((HANDLE)*lpdwDeviceHandle, GetCallerProcess());
}
else
{
*lpdwDeviceHandle = (DWORD)NULL;
};
wcscpy((LPWSTR)(lpdwDeviceHandle+1), pLineDev->szFriendlyName );
DEBUGMSG(ZONE_MISC,
(TEXT("UNIMODEM:-TSPI_lineGetID COMMMODEM - Device Handle x%X, Device name %s\n"),
*lpdwDeviceHandle, pLineDev->szFriendlyName));
break;
}
case NDIS:
{
LPDWORD lpdwDeviceID;
lpdwDeviceID = (LPDWORD)(((LPBYTE)lpDeviceID) + sizeof(VARSTRING));
*lpdwDeviceID = (pLineDev->hDevice != (HANDLE)INVALID_DEVICE ?
(DWORD)pLineDev->hDevice_r0 : (DWORD)NULL);
wcscpy((LPWSTR)(lpdwDeviceID+1), g_szDeviceClass);
DEBUGMSG(ZONE_MISC,
(TEXT("UNIMODEM:-TSPI_lineGetID NDIS - Device Handle x%X, Device name %s\n"),
*lpdwDeviceID, g_szDeviceClass));
break;
}
};
DEBUGMSG(ZONE_FUNC, (TEXT("UNIMODEM:-TSPI_lineGetID\n")));
return SUCCESS;
}
LONG
TSPIAPI
TSPI_lineGetLineDevStatus(
HDRVLINE hdLine,
LPLINEDEVSTATUS lpLineDevStatus
)
{
LONG rc;
PTLINEDEV pLineDev;
DEBUGMSG(ZONE_FUNC, (TEXT("UNIMODEM:+TSPI_lineGetLineDevStatus\n")));
InitVarData((LPVOID)lpLineDevStatus, sizeof(LINEDEVSTATUS));
if ((pLineDev = GetLineDevfromHandle ((DWORD)hdLine)) == NULL) {
DEBUGMSG(ZONE_ERROR, (TEXT("UNIMODEM:TSPI_lineGetLineDevStatus ** Invalid Handle\n")));
rc = LINEERR_INVALLINEHANDLE;
goto exitPoint;
}
rc = 0;
if (pLineDev->dwCallFlags & CALL_ACTIVE) {
lpLineDevStatus->dwNumActiveCalls = 1;
lpLineDevStatus->dwLineFeatures = 0;
} else {
lpLineDevStatus->dwNumActiveCalls = 0;
lpLineDevStatus->dwLineFeatures = (pLineDev->dwCallFlags & CALL_ALLOCATED) ?
0 : LINEFEATURE_MAKECALL;
}
// Line hardware information
//
lpLineDevStatus->dwSignalLevel = 0x0000FFFF;
lpLineDevStatus->dwBatteryLevel = 0x0000FFFF;
lpLineDevStatus->dwRoamMode = LINEROAMMODE_UNAVAIL;
// Always allow TAPI calls
//
lpLineDevStatus->dwDevStatusFlags = LINEDEVSTATUSFLAGS_CONNECTED;
/* TODO
if (!(pLineDev->fdwResources & LINEDEVFLAGS_OUTOFSERVICE)) {
lpLineDevStatus->dwDevStatusFlags |= LINEDEVSTATUSFLAGS_INSERVICE;
} */
exitPoint:
DEBUGMSG(ZONE_FUNC, (TEXT("UNIMODEM:-TSPI_lineGetLineDevStatus 0x%x\n"), rc));
return rc;
} // TSPI_lineGetLineDevStatus
LONG
TSPIAPI
TSPI_lineGetNumAddressIDs(
HDRVLINE hdLine,
LPDWORD lpdwNumAddressIDs
)
{
LONG rc;
DEBUGMSG(ZONE_FUNC, (TEXT("UNIMODEM:+TSPI_lineGetNumAddressIDs\n")));
if (GetLineDevfromHandle ((DWORD)hdLine) == NULL) {
DEBUGMSG(ZONE_ERROR, (TEXT("UNIMODEM:TSPI_lineGetNumAddressIDs ** Invalid Handle\n")));
rc = LINEERR_INVALLINEHANDLE;
} else {
rc = 0;
*lpdwNumAddressIDs = 1;
}
DEBUGMSG(ZONE_FUNC, (TEXT("UNIMODEM:-TSPI_lineGetNumAddressIDs 0x%x\n"), rc));
return rc;
} // TSPI_lineGetNumAddressIDs
LONG TSPIAPI
TSPI_lineMakeCall(
DRV_REQUESTID dwRequestID,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -