📄 misc.c
字号:
LINEDEVCAPFLAGS_DIALBILLING;
//
// Assume dial billing capability (wait for bong, '$' in a dial string)
//
dwSize = sizeof(DWORD);
if (ERROR_SUCCESS == MdmRegGetValue(ptLineDev, szSettings, szDialBilling,
REG_DWORD, (PUCHAR)&dwTemp, &dwSize) ) {
if (dwTemp == 0) {
ptLineDev->dwDevCapFlags &= ~LINEDEVCAPFLAGS_DIALBILLING;
}
}
// Get the friendly name from registry
dwSize = MAXDEVICENAME;
dwRetCode = MdmRegGetValue(ptLineDev, NULL, szFriendlyName, REG_SZ,
(LPBYTE)ptLineDev->szFriendlyName, &dwSize);
if( dwRetCode != ERROR_SUCCESS ) { // Friendly not found, use something else
// For PCMCIA cards, use PNP-Id. For other devices, use port name.
if( DT_PCMCIA_MODEM == ptLineDev->wDeviceType ) {
DWORD dwType;
WCHAR szPnpId[MAXDEVICENAME];
dwType = REG_SZ;
dwSize = MAXDEVICENAME;
dwRetCode = RegQueryValueEx(hActiveKey,
szPnpIdName,
NULL,
&dwType,
(PUCHAR)szPnpId,
&dwSize);
if ( dwRetCode != ERROR_SUCCESS) {
wcsncpy( ptLineDev->szFriendlyName, TEXT("Generic Hayes PCMCIA Modem"), MAXDEVICENAME );
DEBUGMSG( ZONE_INIT|ZONE_ERROR,
(TEXT("UNIMODEM:Unable to read PnpId, defaulting to %s\r\n"),
ptLineDev->szFriendlyName));
} else {
// Remove the checksum from PnpId
dwSize = wcslen(szPnpId);
if( dwSize > 5 ) {
szPnpId[dwSize - 5] = (WCHAR)0;
}
// Now create a pseudo-friendly name
#ifdef PREPEND_GENERIC_TO_NAME
wcsncpy( ptLineDev->szFriendlyName, TEXT("Generic "), MAXDEVICENAME );
wcsncat( ptLineDev->szFriendlyName, szPnpId, MAXDEVICENAME );
#else
wcsncpy( ptLineDev->szFriendlyName, szPnpId, MAXDEVICENAME );
#endif
DEBUGMSG(ZONE_INIT,
(TEXT("UNIMODEM:Generic PCMCIA, friendly name %s\r\n"),
ptLineDev->szFriendlyName));
}
} else {
// Non PCMCIA & no friendly name, just use the port name
wcsncpy( ptLineDev->szFriendlyName, ptLineDev->szDeviceName, MAXDEVICENAME );
}
}
DEBUGMSG(ZONE_INIT,
(TEXT("UNIMODEM:Done reading friendly name, retcode x%X, name %s\r\n"),
dwRetCode, ptLineDev->szFriendlyName));
//----------------------------------------------------------------------
// OK, now that we have all these names, lets see if this same device
// already exists (it may be a PCMCIA card that was removed and then
// reinserted). If it exists, then just reuse the existing entry and
// let TAPI know that the device reconnected.
//----------------------------------------------------------------------
if( ptExistingDev = LineExists( ptLineDev ) ) {
// We already know about this device
ptExistingDev->hSettingsKey = ptLineDev->hSettingsKey; // Get new handle
TSPIFree( ptLineDev ); // Free the entry we started to create.
// If card is reiniserted, mark it as available.
ptExistingDev->wDeviceAvail = 1;
CallLineEventProc(
ptExistingDev,
0,
LINE_LINEDEVSTATE,
LINEDEVSTATE_CONNECTED|LINEDEVSTATE_INSERVICE,
0,
0);
return ptExistingDev; // And return the original device
} else {
// This really is a new device. Create whatever all we need.
// If we are creating a device, it must be available.
ptLineDev->wDeviceAvail = 1;
// Create an event for timeouts, and one for call completion
ptLineDev->hTimeoutEvent = CreateEvent(0,FALSE,FALSE,NULL);
ptLineDev->hCallComplete = CreateEvent(0,FALSE,FALSE,NULL);
// Close needs a critical section
InitializeCriticalSection(&ptLineDev->OpenCS);
if( IS_NULL_MODEM(ptLineDev) )
ptLineDev->dwBearerModes = LINEBEARERMODE_DATA | LINEBEARERMODE_PASSTHROUGH;
else
ptLineDev->dwBearerModes = LINEBEARERMODE_DATA | LINEBEARERMODE_VOICE | LINEBEARERMODE_PASSTHROUGH;
// And add this new line device to list
InsertHeadLockedList(&TspiGlobals.LineDevs,
&ptLineDev->llist,
&TspiGlobals.LineDevsCS);
DEBUGMSG(ZONE_ALLOC, (TEXT("UNIMODEM:Insert Line Device in List\r\n")));
// OK, lets notify TAPI about our new device
DEBUGMSG(ZONE_FUNCTION|ZONE_INIT,
(TEXT("UNIMODEM:createLineDev, calling TAPI Line Create Proc\r\n")));
// Let TAPI know about our new device
CallLineEventProc(NULL, NULL, LINE_CREATE,
(DWORD)TspiGlobals.hProvider,
(DWORD)&ptLineDev->dwDeviceID, 0L);
DEBUGMSG(ZONE_FUNCTION|ZONE_INIT,
(TEXT("UNIMODEM:createLineDev, TAPI assigned device ID 0x%X\r\n"), ptLineDev->dwDeviceID));
DEBUGMSG(ZONE_FUNC|ZONE_INIT,
(TEXT("UNIMODEM:-createLineDev\r\n")));
return ptLineDev;
}
abort_registry_opened:
RegCloseKey( ptLineDev->hSettingsKey );
abort_buffer_allocated:
TSPIFree( ptLineDev );
DEBUGMSG(ZONE_FUNC|ZONE_INIT,
(TEXT("UNIMODEM:-createLineDev, aborted\r\n")));
return NULL;
}
/* NOT USED
//
// Destroy a LineDev
//
void
DestroyLineDev(
PTLINEDEV ptLineDev
)
{
DEBUGMSG(ZONE_FUNC|ZONE_INIT,
(TEXT("UNIMODEM:+destroyLineDev\r\n")));
// First, we better make sure no one is still trying to use line
DevlineClose ( ptLineDev, TRUE );
// Delete the timeout event and CallComplete event.
CloseHandle( ptLineDev->hTimeoutEvent );
CloseHandle( ptLineDev->hCallComplete );
// Close any critical sections
DeleteCriticalSection( &ptLineDev->OpenCS );
// Remove this line device from the list
InsertHeadLockedList(&TspiGlobals.LineDevs,
&ptLineDev->llist,
&TspiGlobals.LineDevsCS);
DEBUGMSG(ZONE_ALLOC, (TEXT("Removed Line Device from List\r\n")));
// Let TAPI know the device went away
CallLineEventProc(NULL, NULL, LINE_REMOVE,
(DWORD)TspiGlobals.hProvider,
(DWORD)ptLineDev->dwDeviceID, 0L);
DEBUGMSG(ZONE_FUNC|ZONE_INIT,
(TEXT("UNIMODEM:-destroyLineDev\r\n")));
// Close any registry keys we held
RegCloseKey( ptLineDev->hSettingsKey );
// And free the structure
TSPIFree( ptLineDev );
DEBUGMSG(ZONE_FUNC|ZONE_INIT,
(TEXT("UNIMODEM:-destroyLineDev\r\n")));
return;
}
*/
// ****************************************************************************
// GetLineDevfromID()
//
// Function: This function looks for the LineDev associated with an ID
//
// Returns: PLINEDEV pointer (or NULL if not found)
//
// ****************************************************************************
PTLINEDEV
GetLineDevfromID(
DWORD dwDeviceID
)
{
PLIST_ENTRY ptEntry;
PTLINEDEV ptLineDev;
DEBUGMSG(ZONE_LIST,
(TEXT("UNIMODEM:+GetLineDevfromID\r\n")));
// Walk the Line List and find corresponding handle
ptEntry = TspiGlobals.LineDevs.Flink;
while( ptEntry != &TspiGlobals.LineDevs )
{
ptLineDev = CONTAINING_RECORD( ptEntry, TLINEDEV, llist);
DEBUGMSG(ZONE_LIST,
(TEXT("UNIMODEM:GetLineDevfromID ptLineDev->dwDeviceID x%X, dwID x%X\r\n"),
ptLineDev->dwDeviceID, dwDeviceID));
// See if this is the correct Line
if( ptLineDev->dwDeviceID == dwDeviceID )
{
DEBUGMSG(ZONE_LIST,
(TEXT("UNIMODEM:-GetLineDevfromID - Success\r\n")));
return ptLineDev; // Cool, we found it
}
// No match yet, advance to next link
ptEntry = ptEntry->Flink;
}
DEBUGMSG(ZONE_LIST,
(TEXT("UNIMODEM:-GetLineDevfromID - Fail\r\n")));
return NULL;
}
PTLINEDEV
GetLineDevfromName(
LPCWSTR lpszDeviceName,
LPCWSTR lpszFriendlyName
)
{
PLIST_ENTRY ptEntry;
PTLINEDEV ptLineDev;
DEBUGMSG(ZONE_LIST, (TEXT("UNIMODEM:+GetLineDevfromName\r\n")));
// Walk the Line List and find corresponding handle
ptEntry = TspiGlobals.LineDevs.Flink;
while( ptEntry != &TspiGlobals.LineDevs )
{
ptLineDev = CONTAINING_RECORD( ptEntry, TLINEDEV, llist);
// See if this is the correct Line
if (lpszDeviceName && lpszFriendlyName) {
if (!wcscmp(lpszDeviceName, ptLineDev->szDeviceName)) {
if (!wcscmp(lpszFriendlyName, ptLineDev->szFriendlyName)) {
DEBUGMSG(ZONE_LIST, (TEXT("UNIMODEM:-GetLineDevfromName - Success both\r\n")));
return ptLineDev;
}
}
} else if (lpszDeviceName) {
//
// When going by device name, only look at active devices since the removal code
// is calling us and there may be multiple line devices on the same COMn: device.
//
if (ptLineDev->wDeviceAvail) {
if (!wcscmp(lpszDeviceName, ptLineDev->szDeviceName)) {
DEBUGMSG(ZONE_LIST, (TEXT("UNIMODEM:-GetLineDevfromName - Success device name\r\n")));
return ptLineDev;
}
}
} else if (lpszFriendlyName) {
if (!wcscmp(lpszFriendlyName, ptLineDev->szFriendlyName)) {
DEBUGMSG(ZONE_LIST, (TEXT("UNIMODEM:-GetLineDevfromName - Success friendly name\r\n")));
return ptLineDev;
}
}
// Advance to next link.
ptEntry = ptEntry->Flink;
}
DEBUGMSG(ZONE_LIST, (TEXT("UNIMODEM:-GetLineDevfromName - Fail\r\n")));
return NULL;
} // GetLineDevfromName
// ****************************************************************************
//
// Function: This function looks for the LineDev which matches the names and
// device types of the passed in LineDev. This is so that we can
// determine if a lineCreate is really just the reinsertion of a
// PCMCIA card that we already know about.
//
// Returns: PLINEDEV pointer (or NULL if not found)
//
// ****************************************************************************
PTLINEDEV
LineExists(
PTLINEDEV ptNewLine
)
{
PLIST_ENTRY ptEntry;
PTLINEDEV ptOldLine;
DEBUGMSG(ZONE_LIST, (TEXT("UNIMODEM:+LineExists - Device type x%X\r\n"), ptNewLine->wDeviceType));
DEBUGMSG(ZONE_LIST, (TEXT("UNIMODEM:LineExists\tDevice Name : %s\r\n"), ptNewLine->szDeviceName));
DEBUGMSG(ZONE_LIST, (TEXT("UNIMODEM:LineExists\tFriendly Name : %s\r\n"), ptNewLine->szFriendlyName));
// Walk the Line List and find corresponding handle
ptEntry = TspiGlobals.LineDevs.Flink;
while( ptEntry != &TspiGlobals.LineDevs )
{
ptOldLine = CONTAINING_RECORD( ptEntry, TLINEDEV, llist);
DEBUGMSG(ZONE_LIST, (TEXT("UNIMODEM:LineExists - checking old dwDeviceID x%X\r\n"), ptOldLine->dwDeviceID));
DEBUGMSG(ZONE_LIST, (TEXT("UNIMODEM:LineExists\tDevice Type : %x\r\n"), ptOldLine->wDeviceType));
DEBUGMSG(ZONE_LIST, (TEXT("UNIMODEM:LineExists\tDevice Name : %s\r\n"), ptOldLine->szDeviceName));
DEBUGMSG(ZONE_LIST, (TEXT("UNIMODEM:LineExists\tFriendly Name : %s\r\n"), ptOldLine->szFriendlyName));
// See if this is the correct Line
if( (ptOldLine->wDeviceType == ptNewLine->wDeviceType) &&
(! wcscmp(ptOldLine->szDeviceName, ptNewLine->szDeviceName)) &&
(! wcscmp(ptOldLine->szFriendlyName, ptNewLine->szFriendlyName)) )
{
DEBUGMSG(ZONE_LIST, (TEXT("UNIMODEM:-LineExists - previous was ID x%X\r\n"), ptOldLine->dwDeviceID ));
return ptOldLine; // this card has been reinserted
}
// No match yet, advance to next link
ptEntry = ptEntry->Flink;
}
DEBUGMSG(ZONE_LIST, (TEXT("UNIMODEM:-LineExists - Fail\r\n")));
return NULL;
}
// ****************************************************************************
// GetLineDevfromHandle()
//
// Function: This function gets the Line Dev Pointer from a handle
//
// Returns: a pointer to PLINEDEV structure if the handle is valid, or
// NULL otherwise
//
// ****************************************************************************
PTLINEDEV
GetLineDevfromHandle (
DWORD handle
)
{
DEBUGMSG(ZONE_LIST, (TEXT("UNIMODEM:+GetLineDevfromHandle\r\n")));
// The handle IS the pointer.
// However in the future we may need to provide some abstraction (as well
// potential validity checks) so this function prepares for that,
DEBUGMSG(ZONE_LIST, (TEXT("UNIMODEM:-GetLineDevfromHandle\r\n")));
return (PTLINEDEV)handle;
}
//
//
void
InitVarData(
LPVOID lpData,
DWORD dwSize
)
{
LPVARSTRING pVarData = (LPVARSTRING)lpData; // Cast the pointer to a varstring
memset(&(pVarData->dwNeededSize), 0, pVarData->dwTotalSize - sizeof(DWORD));
pVarData->dwNeededSize = dwSize;
pVarData->dwUsedSize = dwSize;
}
//
// This routine is called when the TSPI DLL is loaded. It is primarily
// responsible for initializing TspiGlobals.
//
// Return : void
//
void
TSPIDLL_Load(
void
)
{
DWORD dwRet;
DEBUGMSG(ZONE_FUNCTION|ZONE_INIT,
(TEXT("+TSPIDLL_Load\r\n")));
TspiGlobals.hInstance = 0;
TspiGlobals.dwProviderID = 0;
TspiGlobals.hProvider = 0;
TspiGlobals.fnLineEventProc =0 ;
TspiGlobals.fnCompletionCallback = 0;
// Let's init our linked lists to empty
InitializeListHead( &TspiGlobals.LineDevs );
// And init the linked list critical sections
InitializeCriticalSection( &TspiGlobals.LineDevsCS );
// Go ahead and open the unimodem defaults registry key.
dwRet = RegOpenKeyEx(
HKEY_LOCAL_MACHINE,
szDefaultsName,
0,
KEY_READ,
&TspiGlobals.hDefaultsKey);
if (ERROR_SUCCESS != dwRet)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -