/****************************************************************************** (C) Copyright MICROSOFT Corp., 1987-1993 Rob Williams, June 93 w/ State machine and parser plagarized from RAS ******************************************************************************/ #include "unimdm.h" #include "mcxp.h" #include "common.h" BOOL WINAPI InitializeModemCommonList( PCOMMON_MODEM_LIST CommonList ) { D_TRACE(McxDpf(999,"InitializeModemCommonList");) CommonList->ListHead=NULL; InitializeCriticalSection( &CommonList->CriticalSection ); traceRegisterObject( &CommonList, TSP_COMMON_LIST_GUID, TSP_COMMON_LIST_VERSION, 0, 0 ); return TRUE; } VOID WINAPI RemoveCommonList( PCOMMON_MODEM_LIST CommonList ) { EnterCriticalSection(&CommonList->CriticalSection); // // we go through the list removing the final reference count from the modem // while (CommonList->ListHead != NULL) { // // The call to RemoveReferenceToCommon() will change CommonList->ListHead // so this is not an infinite loop // ASSERT(CommonList->ListHead->Reference == 1); RemoveReferenceToCommon( CommonList, CommonList->ListHead ); } traceUnRegisterObject(&CommonList, 0, 0); LeaveCriticalSection(&CommonList->CriticalSection); DeleteCriticalSection(&CommonList->CriticalSection); return; } PSTR WINAPI LoadDialElement( HKEY hKey, PSTR SubKeyName ) { CHAR szTemp[MAX_PATH]; CHAR szTemp2[MAX_PATH]; DWORD dwSize; DWORD dwType; LONG Result; PSTR StringToReturn; dwSize=sizeof(szTemp); Result=RegQueryValueExA( hKey, SubKeyName, NULL, &dwType, (VOID *)szTemp, &dwSize ); if (Result != ERROR_SUCCESS || dwType != REG_SZ || dwSize == 0) { return NULL; } ExpandMacros(szTemp, szTemp2, NULL, NULL, 0); StringToReturn=LocalAlloc(LPTR, lstrlenA(szTemp2) + 1); lstrcpyA(StringToReturn,szTemp2); return StringToReturn; } COMMON_MODEM_LIST gCommonList; static CHAR szAnswer[] = "Answer"; static CHAR szMonitor[]= "Monitor"; static CHAR szInit[] = "Init"; static CHAR szHangup[] = "Hangup"; static CHAR DialComponents[COMMON_DIAL_MAX_INDEX+1][20] = { {"Prefix"}, {"DialPrefix"}, {"Blind_On"}, {"Blind_Off"}, {"Tone"}, {"Pulse"}, {"DialSuffix"}, {"Terminator"}}; PVOID WINAPI OpenCommonModemInfo( PCOMMON_MODEM_LIST CommonList, HKEY hKey ) { CHAR IdString[MAX_PATH]; DWORD dwRetSize; LONG Result; DWORD dwType; PCOMMON_MODEM_INFO pCommon; HKEY hSettingsKey; UINT i; dwRetSize = MAX_PATH; // // get the inf file name from the registry // Result=RegQueryValueExA( hKey, "InfPath", NULL, &dwType, (VOID *)IdString, &dwRetSize ); if (ERROR_SUCCESS != Result) { return NULL; } lstrcatA(IdString,"\\"); dwRetSize = MAX_PATH; // // get the inf section name from the registry // Result=RegQueryValueExA( hKey, "InfSection", NULL, &dwType, (VOID *)&IdString[lstrlenA(IdString)], &dwRetSize ); if (ERROR_SUCCESS != Result) { return NULL; } // // the name is now "inf-name\inf-section" // D_TRACE(McxDpf(999,"Common modem info name is %s",IdString);) // // see if this one is already around // EnterCriticalSection(&CommonList->CriticalSection); pCommon=CommonList->ListHead; while (pCommon != NULL) { if (lstrcmpA(IdString, pCommon->IdString) == 0) { // // found, up the ref count and return // pCommon->Reference++; D_TRACE(McxDpf(999,"Found Common modem info Match, ref=%d",pCommon->Reference);) LeaveCriticalSection(&CommonList->CriticalSection); return pCommon; } pCommon=pCommon->Next; } // // did not find it on the list, need to build a new one // pCommon=LocalAlloc(LPTR, sizeof(COMMON_MODEM_INFO)); if (pCommon == NULL) { LeaveCriticalSection(&CommonList->CriticalSection); return NULL; } lstrcpyA(pCommon->IdString, IdString); D_TRACE(McxDpf(999,"Creating new Common modem info");) // // build the response list // pCommon->ResponseList=NewBuildResponsesLinkedList(hKey); if (pCommon->ResponseList == NULL) { D_TRACE(McxDpf(999,"Could not build response list");) goto Fail; } // // get statis init string // pCommon->ModemCommands[COMMON_INIT_COMMANDS]=NewLoadRegCommands(hKey, szInit, NULL); if (pCommon->ModemCommands[COMMON_INIT_COMMANDS] == NULL) { D_TRACE(McxDpf(999,"Could not load init string");) goto Fail; } // // get monitor string // pCommon->ModemCommands[COMMON_MONITOR_COMMANDS]=NewLoadRegCommands(hKey, szMonitor, NULL); if (pCommon->ModemCommands[COMMON_MONITOR_COMMANDS] == NULL) { D_TRACE(McxDpf(999,"Could not load Monitor string");) goto Fail; } // // get answer string // pCommon->ModemCommands[COMMON_ANSWER_COMMANDS]=NewLoadRegCommands(hKey, szAnswer, NULL); if (pCommon->ModemCommands[COMMON_ANSWER_COMMANDS] == NULL) { D_TRACE(McxDpf(999,"Could not Load Answer string");) goto Fail; } #if 0 // // get hangup string // pCommon->ModemCommands[COMMON_HANGUP_COMMANDS]=NewLoadRegCommands(hKey, szHangup, NULL); if (pCommon->ModemCommands[COMMON_HANGUP_COMMANDS] == NULL) { D_TRACE(McxDpf(999,"Could not load hangup string");) goto Fail; } #endif if (RegOpenKeyA(hKey, szSettings, &hSettingsKey)==ERROR_SUCCESS) { for (i=0; iDialComponents[i]=LoadDialElement(hSettingsKey, DialComponents[i]); D_TRACE(if (pCommon->DialComponents[i] == NULL) { McxDpf(999,"Could not load %s", DialComponents[i]); } ) } RegCloseKey(hSettingsKey); } // // set the reference count to 2 here so that when the modem is closed // the common block will stick around until explicitly freed // pCommon->Reference=2; pCommon->Next=CommonList->ListHead; CommonList->ListHead=pCommon; LeaveCriticalSection(&CommonList->CriticalSection); return pCommon; Fail: // // free any dial commands we loaded // for (i=0; iDialComponents[i] != NULL) { LocalFree(pCommon->DialComponents[i]); } } // // free and modem commands that we loaded // for (i=0; iModemCommands[i] != NULL) { LocalFree(pCommon->ModemCommands[i]); } } // // get rid of the response list if we got it // if (pCommon->ResponseList != NULL) { LocalFree(pCommon->ResponseList); } LocalFree(pCommon); LeaveCriticalSection(&CommonList->CriticalSection); return NULL; } VOID WINAPI RemoveReferenceToCommon( PCOMMON_MODEM_LIST CommonList, HANDLE hCommon ) { PCOMMON_MODEM_INFO pCommon=(PCOMMON_MODEM_INFO)hCommon; PCOMMON_MODEM_INFO Current; PCOMMON_MODEM_INFO Prev; UINT i; ASSERT(pCommon != NULL); EnterCriticalSection(&CommonList->CriticalSection); pCommon->Reference--; if (pCommon->Reference > 0) { // // not done with it yet // D_TRACE(McxDpf(999,"RemoveReferenceToCommon, ref=%d", pCommon->Reference);) LeaveCriticalSection(&CommonList->CriticalSection); return; } // // ref count is zero get rid of the common block // Prev=NULL; Current=CommonList->ListHead; while (Current != NULL) { if (Current == pCommon) { if (Prev == NULL) { CommonList->ListHead=Current->Next; } else { Prev->Next=Current->Next; } break; } Prev=Current; Current=Current->Next; } ASSERT(Current != NULL); LeaveCriticalSection(&CommonList->CriticalSection); D_TRACE(McxDpf(999,"RemoveReferenceToCommon, removing common, %s", pCommon->IdString);) // // free any dial commands we loaded // for (i=0; iDialComponents[i] != NULL) { LocalFree(pCommon->DialComponents[i]); } } // // free and modem commands that we loaded // for (i=0; iModemCommands[i] != NULL) { LocalFree(pCommon->ModemCommands[i]); } } // // get rid of the response list if we got it // if (pCommon->ResponseList != NULL) { LocalFree(pCommon->ResponseList); } LocalFree(pCommon); return; } HANDLE WINAPI GetCommonResponseList( HANDLE hCommon ) { PCOMMON_MODEM_INFO pCommon=(PCOMMON_MODEM_INFO)hCommon; return (HANDLE)pCommon->ResponseList; } PSTR WINAPI GetCommonCommandStringCopy( HANDLE hCommon, UINT Index ) { PCOMMON_MODEM_INFO pCommon=(PCOMMON_MODEM_INFO)hCommon; PSTR Commands; PSTR pTemp; pTemp=pCommon->ModemCommands[Index]; while (1) { if (*pTemp++ == '\0') { if (*pTemp++ == '\0') { break; } } } Commands=LocalAlloc(LPTR, pTemp-pCommon->ModemCommands[Index]); if (NULL == Commands) { D_TRACE(McxDpf(999,"GetCommonCommandStringCopy: Alloc failed");) return NULL; } CopyMemory(Commands,pCommon->ModemCommands[Index],pTemp-pCommon->ModemCommands[Index]); return Commands; } DWORD WINAPI GetCommonDialComponent( HANDLE hCommon, PSTR DestString, DWORD DestLength, DWORD Index ) { PCOMMON_MODEM_INFO pCommon=(PCOMMON_MODEM_INFO)hCommon; DWORD Length; if (pCommon->DialComponents[Index] == NULL) { lstrcpyA(DestString,""); return 0; } Length=lstrlenA(pCommon->DialComponents[Index])+1; if (Length+1 > DestLength) { return 0; } lstrcpyA( DestString, pCommon->DialComponents[Index] ); return Length; }