📄 misc.c
字号:
DEBUGMSG(ZONE_ERROR|ZONE_INIT,
(TEXT("TSPIDLL_LOAD - RegOpenKeyEx %s returned %d.\r\n"),
szDefaultsName, dwRet));
}
else
{
DWORD dwValType;
DWORD dwValLen;
DEBUGMSG(ZONE_MISC|ZONE_INIT,
(TEXT("TSPIDLL_LOAD - RegOpenKeyEx %s handle x%X.\r\n"),
szDefaultsName, TspiGlobals.hDefaultsKey));
// Get thread priority
g_dwUnimodemThreadPriority = DEFAULT_THREAD_PRIORITY;
dwValLen = sizeof(DWORD);
RegQueryValueEx(
TspiGlobals.hDefaultsKey,
REGISTRY_PRIORITY_VALUE,
NULL,
&dwValType,
(PUCHAR)&g_dwUnimodemThreadPriority,
&dwValLen);
DEBUGMSG(ZONE_MISC|ZONE_INIT,
(TEXT("TSPIDLL_LOAD - Priority %d\r\n"),
g_dwUnimodemThreadPriority));
}
g_hCoreDLL = LoadLibrary(L"coredll.dll");
DEBUGMSG(ZONE_FUNCTION|ZONE_INIT,
(TEXT("-TSPIDLL_Load\r\n")));
}
//****************************************************************************
//
// NullifyLineDevice()
//
//****************************************************************************
DWORD
NullifyLineDevice (
PTLINEDEV pLineDev,
BOOL bDefaultConfig
)
{
DEBUGMSG(ZONE_FUNC, (TEXT("UNIMODEM:+NullifyLineDevice\r\n")));
// Turn the line device back to its initial state
pLineDev->hDevice = (HANDLE)INVALID_DEVICE;
pLineDev->hDevice_r0 = (HANDLE)INVALID_DEVICE;
pLineDev->hMdmLog = (HANDLE)INVALID_DEVICE;
pLineDev->pidDevice = 0L;
pLineDev->lpfnEvent = NULL;
pLineDev->DevState = DEVST_DISCONNECTED;
pLineDev->hwndLine = NULL;
pLineDev->szAddress[0] = '\0';
pLineDev->hwTermCtrl = NULL;
pLineDev->dwCallFlags = 0L;
pLineDev->dwCallState = LINECALLSTATE_IDLE;
pLineDev->dwCurMediaModes = 0L;
pLineDev->dwDetMediaModes = 0L;
pLineDev->fTakeoverMode = FALSE;
pLineDev->dwMediaModes = pLineDev->dwDefaultMediaModes;
pLineDev->dwDialOptions = 0L;
pLineDev->dwNumRings = 0;
if (bDefaultConfig) {
getDefaultDevConfig( pLineDev, &pLineDev->DevMiniCfg ); // reset the devconfig
}
DEBUGMSG(ZONE_FUNC, (TEXT("UNIMODEM:-NullifyLineDevice\r\n")));
return SUCCESS;
}
//****************************************************************************
//
// ValidateDevCfgClass()
//
//****************************************************************************
BOOL
ValidateDevCfgClass (
LPCWSTR lpszDeviceClass
)
{
UINT idClass;
DEBUGMSG(ZONE_FUNC, (TEXT("UNIMODEM:+ValidateDevCfgClass\r\n")));
// Need the device class
if (lpszDeviceClass == NULL)
return FALSE;
// Determine the device class
//
for (idClass = 0; idClass < MAX_SUPPORT_CLASS; idClass++)
{
if (lstrcmpi(lpszDeviceClass, aGetID[idClass].szClassName) == 0)
break;
};
// Do we support the requested class?
switch (idClass)
{
case TAPILINE:
case COMM:
case COMMMODEM:
DEBUGMSG(ZONE_FUNC, (TEXT("UNIMODEM:-ValidateDevCfgClass (Valid)\r\n")));
return TRUE;
default:
DEBUGMSG(ZONE_FUNC, (TEXT("UNIMODEM:-ValidateDevCfgClass (Invalid)\r\n")));
return FALSE;
};
}
//****************************************************************************
// ValidateAddress()
//
// Function: This function validates a tapi address and creates a version of
// it to pass to the VxD.
//
// Returns: SUCCESS or LINEERR_xxx depending on the failure reason
//
//****************************************************************************
LONG
ValidateAddress(
PTLINEDEV pLineDev,
LPCWSTR lpszInAddress,
LPWSTR lpszOutAddress)
{
LPCWSTR lpszSrc;
int cbOutLen = MAXADDRESSLEN;
WCHAR chContinuation = pLineDev->chContinuation;
ASSERT(lpszOutAddress);
// is lpszInAddress NULL?
if (lpszInAddress == NULL || *lpszInAddress == 0)
{
*lpszOutAddress = 0;
return SUCCESS;
}
// Verify that the first char is a valid single-byte char.
if (AnsiNext(lpszInAddress) - lpszInAddress != 1)
{
return LINEERR_INVALADDRESS;
}
// tone or pulse? set dwDialOptions appropriately
// also, set lpszSrc
switch (*lpszInAddress) {
case 'T': // tone
case 't':
lpszSrc = lpszInAddress + 1;
pLineDev->dwDialOptions |= MDM_TONE_DIAL;
break;
case 'P': // pulse
case 'p':
lpszSrc = lpszInAddress + 1;
pLineDev->dwDialOptions &= ~MDM_TONE_DIAL;
break;
default:
lpszSrc = lpszInAddress;
pLineDev->dwDialOptions |= MDM_TONE_DIAL;
break;
}
// copy In to Out scanning for various dialoptions, returning error if we
// don't support something.
while (*lpszSrc && cbOutLen)
{
switch (*lpszSrc)
{
case '$':
if (!(pLineDev->dwDevCapFlags & LINEDEVCAPFLAGS_DIALBILLING))
{
UINT cCommas;
// Get the wait-for-bong period
cCommas = pLineDev->DevMiniCfg.wWaitBong;
// Calculate the number of commas we need to insert
cCommas = (cCommas/INC_WAIT_BONG) +
(cCommas%INC_WAIT_BONG ? 1 : 0);
// Insert the strings of commas
while (cbOutLen && cCommas)
{
*lpszOutAddress++ = ',';
cbOutLen--;
cCommas--;
};
goto Skip_This_Character;
}
break;
case '@':
if (!(pLineDev->dwDevCapFlags & LINEDEVCAPFLAGS_DIALQUIET))
{
return LINEERR_DIALQUIET;
}
break;
case 'W':
case 'w':
if (!(pLineDev->dwDevCapFlags & LINEDEVCAPFLAGS_DIALDIALTONE))
{
return LINEERR_DIALDIALTONE;
}
break;
case '?':
return LINEERR_DIALPROMPT;
case '|': // subaddress
case '^': // name field
goto Skip_The_Rest;
case ' ':
case '-':
// skip these characters
goto Skip_This_Character;
}
if (*lpszSrc == chContinuation) {
// This signifies the end of a dialable address.
// Use it and skip the rest.
*lpszOutAddress++ = *lpszSrc;
goto Skip_The_Rest;
}
// Copy this character
*lpszOutAddress++ = *lpszSrc;
cbOutLen--;
Skip_This_Character:
// Verify that the next char is a valid single-byte char.
if (AnsiNext(lpszSrc) - lpszSrc != 1)
{
return LINEERR_INVALADDRESS;
}
lpszSrc++;
}
// Did we run out of space in the outgoing buffer?
if (*lpszSrc && cbOutLen == 0)
{
// yes
DEBUGMSG(ZONE_ERROR,
(TEXT("\t*** Address too large.\r\n")));
return LINEERR_INVALADDRESS;
}
Skip_The_Rest:
*lpszOutAddress = 0;
return SUCCESS;
}
//
// Call TAPI's Line Event Proc with status message filtering
//
void
CallLineEventProc(
PTLINEDEV ptLine,
HTAPICALL htCall,
DWORD dwMsg,
DWORD dwParam1,
DWORD dwParam2,
DWORD dwParam3
)
{
HTAPILINE htLine;
htLine = (ptLine) ? ptLine->htLine : NULL;
if (dwMsg == LINE_LINEDEVSTATE) {
//
// Honor the lineSetStatusMessages request
//
if ((dwParam1 & ptLine->dwLineStatesMask) == 0) {
return;
}
}
TspiGlobals.fnLineEventProc(
htLine,
htCall,
dwMsg,
dwParam1,
dwParam2,
dwParam3
);
} // CallLineEventProc
#ifdef DEBUG
LPWSTR
CallStateName(
DWORD dwCallState
)
{
LPWSTR lpszRet;
switch (dwCallState) {
case LINECALLSTATE_IDLE: lpszRet = L"LINECALLSTATE_IDLE"; break;
case LINECALLSTATE_OFFERING: lpszRet = L"LINECALLSTATE_OFFERING"; break;
case LINECALLSTATE_ACCEPTED: lpszRet = L"LINECALLSTATE_ACCEPTED"; break;
case LINECALLSTATE_DIALTONE: lpszRet = L"LINECALLSTATE_DIALTONE"; break;
case LINECALLSTATE_DIALING: lpszRet = L"LINECALLSTATE_DIALING"; break;
case LINECALLSTATE_RINGBACK: lpszRet = L"LINECALLSTATE_RINGBACK"; break;
case LINECALLSTATE_BUSY: lpszRet = L"LINECALLSTATE_BUSY"; break;
case LINECALLSTATE_SPECIALINFO: lpszRet = L"LINECALLSTATE_SPECIALINFO"; break;
case LINECALLSTATE_CONNECTED: lpszRet = L"LINECALLSTATE_CONNECTED"; break;
case LINECALLSTATE_PROCEEDING: lpszRet = L"LINECALLSTATE_PROCEEDING"; break;
case LINECALLSTATE_ONHOLD: lpszRet = L"LINECALLSTATE_ONHOLD"; break;
case LINECALLSTATE_CONFERENCED: lpszRet = L"LINECALLSTATE_CONFERENCED"; break;
case LINECALLSTATE_ONHOLDPENDCONF: lpszRet = L"LINECALLSTATE_ONHOLDPENDCONF"; break;
case LINECALLSTATE_ONHOLDPENDTRANSFER: lpszRet = L"LINECALLSTATE_ONHOLDPENDTRANSFER"; break;
case LINECALLSTATE_DISCONNECTED: lpszRet = L"LINECALLSTATE_DISCONNECTED"; break;
case LINECALLSTATE_UNKNOWN: lpszRet = L"LINECALLSTATE_UNKNOWN"; break;
default: lpszRet = L"UNDEFINED!!!"; break;
}
return lpszRet;
}
#endif
void
NewCallState(
PTLINEDEV pLineDev,
DWORD dwCallState,
DWORD dwCallState2
)
{
DEBUGMSG(ZONE_CALLS, (L"UNIMODEM:NewCallState for Device %d = %s\n", pLineDev->dwDeviceID, CallStateName(dwCallState)));
pLineDev->dwCallState = dwCallState;
pLineDev->dwCallStateMode = dwCallState2;
CallLineEventProc(
pLineDev,
pLineDev->htCall,
LINE_CALLSTATE,
dwCallState,
dwCallState2,
pLineDev->dwCurMediaModes
);
} // NewCallState
typedef int (WINAPI * PFN_LOADSTRING)(HINSTANCE,UINT,LPWSTR,int);
//
// Wrapper to load the termctrl DLL and then call TerminalWindow
//
BOOL
DisplayTerminalWindow(
PTLINEDEV pLineDev,
DWORD dwTitle
)
{
PFNTERMINALWINDOW pfnTerminalWindow;
HANDLE hTermCtrl;
WCHAR szWindowTitle[128];
BOOL bRet;
PFN_LOADSTRING pfnLoadString;
bRet = FALSE;
// Load the termctrl dll, and get the entrypoint
if ((hTermCtrl = LoadLibrary(TEXT("termctrl.dll"))) == NULL) {
DEBUGMSG(ZONE_ERROR|ZONE_INIT,
(TEXT("UNIMODEM:DisplayTerminalWindow *** Unable to load termctrl dll\r\n")));
goto dtw_exit;
}
// OK, lets get the function pointer.
if ((pfnTerminalWindow = (PFNTERMINALWINDOW)GetProcAddress(hTermCtrl, TEXT("TerminalWindow"))) == NULL) {
DEBUGMSG(ZONE_ERROR|ZONE_INIT,
(TEXT("UNIMODEM:DisplayTerminalWindow *** GetProcAddress(TerminalWindow) failed\r\n")));
goto dtw_exit;
}
if ((pfnLoadString = (PFN_LOADSTRING)GetProcAddress(g_hCoreDLL, L"LoadStringW")) == NULL) {
DEBUGMSG(ZONE_ERROR|ZONE_INIT,
(TEXT("UNIMODEM:DisplayTerminalWindow *** GetProcAddress(LoadStringW) failed\r\n")));
goto dtw_exit;
}
pfnLoadString(TspiGlobals.hInstance, dwTitle, szWindowTitle, sizeof(szWindowTitle)/sizeof(WCHAR));
//
// Make UI run in non-realtime thread priority
//
SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_NORMAL);
pLineDev->hwTermCtrl = NULL; // make sure handle is NULL before calling
if (TW_SUCCESS == pfnTerminalWindow(pLineDev->hDevice, szWindowTitle, &pLineDev->hwTermCtrl)) {
bRet = TRUE;
}
pLineDev->hwTermCtrl = NULL; // Zero Window handle now that we are done
CeSetThreadPriority(GetCurrentThread(), g_dwUnimodemThreadPriority);
dtw_exit:
if(hTermCtrl) {
FreeLibrary(hTermCtrl);
}
return bRet;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -