#define STRICT #include <windows.h> #include <windowsx.h> #include "..\..\client\location.h" #if DBG #define DBGOUT(arg) DbgPrt arg void DbgPrt( DWORD dwDbgLevel, PSTR DbgMessage, ... ); #else #define DBGOUT(_x_) #endif const TCHAR gszName[] = "Name"; const TCHAR gszID[] = "ID"; const TCHAR gszAreaCode[] = "AreaCode"; const TCHAR gszCountry[] = "Country"; const TCHAR gszOutsideAccess[] = "OutsideAccess"; const TCHAR gszLongDistanceAccess[] = "LongDistanceAccess"; const TCHAR gszFlags[] = "Flags"; const TCHAR gszCallingCard[] = "CallingCard"; const TCHAR gszDisableCallWaiting[] = "DisableCallWaiting"; const TCHAR gszTollList[] = "TollList"; //const TCHAR gszNumLocations[] = "NumLocations"; //const TCHAR gszCurrLocation[] = "CurrLocation"; //const TCHAR gszNextLocationID[] = "NextLocationID"; const TCHAR gszCard[] = "Card"; const TCHAR gszPin[] = "Pin"; const TCHAR gszCards[] = "Cards"; //const TCHAR gszNumCards[] = "NumCards"; //const TCHAR gszCurrCard[] = "CurrCard"; const TCHAR gszLocalRule[] = "LocalRule"; const TCHAR gszLDRule[] = "LDRule"; const TCHAR gszInternationalRule[] = "InternationalRule"; const TCHAR gszNumEntries[] = "NumEntries"; const TCHAR gszCurrentID[] = "CurrentID"; const TCHAR gszNextID[] = "NextID"; const TCHAR gszEmpty[] = ""; const TCHAR gszLocations[] = "Locations"; const TCHAR gszLocation[] = "Location"; const TCHAR gszCurrentLocation[] = "CurrentLocation"; const TCHAR gszHandoffPriorities[] = "HandoffPriorities"; const TCHAR gszProviders[] = "Providers"; const TCHAR gszProvider[] = "Provider%d"; const TCHAR gszTelephonIni[] = "Telephon.ini"; const TCHAR gszTelephony[] = "Software\\Microsoft\\Windows\\" "CurrentVersion\\Telephony"; void FixPriorityList(HKEY hKeyHandoffPriorities, LPWSTR pszListName); #pragma check_stack ( off ) //*************************************************************************** //*************************************************************************** //*************************************************************************** BOOL ParseSomething( LPCSTR pFormat, LPCSTR pInputString, LPVOID pOutputPtr ) { BYTE c; LPBYTE pOutput = (LPBYTE)pOutputPtr; LPBYTE pInput = (LPBYTE)pInputString; while ( (c = *pFormat) && *pInput ) { #if DBG DBGOUT((11, "Inputstring[%s]\r\n Format[%s]\r\n", pInput, pFormat)); #endif switch ( c ) { case 'n': { DWORD dwValue = 0; BYTE bDigit; // // Parse value from the string // while ( ((bDigit = *pInput) != '\0') && bDigit != ',' ) { dwValue = (dwValue * 10) + ( bDigit - '0' ); #if DBG DBGOUT((11, "val of bDigit=%d dwValue=%ld\r\n", (int)bDigit, dwValue)); #endif bDigit = *(++pInput); } *(LPDWORD)pOutput = dwValue; pOutput += sizeof(DWORD); } break; case 's': { // // If the caller is looking for a string, the first char // MUST be a quotes. So, just step past it. // pInput++; // // Ok, _now_ we're into the meat of the string (if there _is_ // any...) // while ( *pInput != '\0' && *pInput != '"' ) { *pOutput = *pInput; pOutput++; pInput++; } // // Don't forget to put a cap on that thing. // *pOutput = '\0'; pOutput++; // The input should now be at a ->"<- if it's not, the ini // file was hosed, and I'm not fixing it. // So, we step past it, and we're done // if ( *pInput == '"' ) { pInput++; } } break; } // // Step past the comma... // // if ( *pInput == ',' ) { pInput++; } pFormat++; } return TRUE; } //*************************************************************************** //*************************************************************************** //*************************************************************************** //VOID __cdecl main( void ) void main( void ) { DWORD dw; DWORD dwNumEntries; DWORD dwCurrentID; DWORD dwNextID; DWORD dwArray[10]; BYTE bBigArray[5120]; BYTE Buffer[5120]; //Might need tons of room for the tolllist... LPBYTE pSource; HKEY hKey3; HKEY hKey2; HKEY hKey; DWORD dwDisposition; dw = GetPrivateProfileString( gszCards, gszCards, gszEmpty, Buffer, sizeof(Buffer), gszTelephonIni ); // // Is there an existing AND valid TELEPHON.INI file? // There would HAVE TO be at least one card. The SYSTEM cards cannot // be deleted, only hidden. // if ( 0 != dw ) { //[Cards] //Cards=23,23 //Card0=0,"None (Direct Dial)","","","","",1 //Card1=1,"AT&T Direct Dial via 10ATT1","","G","102881FG","10288011EFG",1 #define CARD_INI_ID (0) #define CARD_INI_NAME (1) #define CARD_INI_SNUMBER (2) #define CARD_INI_SARULE (3) #define CARD_INI_LDRULE (4) #define CARD_INI_INTNLRULE (5) #define CARD_INI_HIDDEN (6) #define PC_INI_ID (0) #define PC_INI_NEXTID (1) #define PC_INI_NAME (2) #define PC_INI_SARULE (3) #define PC_INI_LDRULE (4) #define PC_INI_INTNLRULE (5) // // Move CARDS entries to registry // ParseSomething( "nn", Buffer, &dwArray); dwNumEntries = dwArray[0]; dwNextID = dwArray[1]; RegCreateKeyEx( HKEY_CURRENT_USER, //BUGBUG or should this be default user or not at all or what? gszTelephony, 0, "", //Class? What class? REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, 0, &hKey3, &dwDisposition ); RegCreateKeyEx( hKey3, gszCards, 0, "", //Class? What class? REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, 0, &hKey2, &dwDisposition ); RegSetValueEx( hKey2, gszNumEntries, 0, REG_DWORD, (LPBYTE)&dwNumEntries, sizeof(DWORD) ); RegSetValueEx( hKey2, gszNextID, 0, REG_DWORD, (LPBYTE)&dwNextID, sizeof(DWORD) ); for ( dw=0; dw<dwNumEntries; dw++ ) { TCHAR Temp[18]; wsprintf(Temp, "%s%d", gszCard, dw); // // Create the key for this Card // RegCreateKeyEx( hKey2, Temp, 0, "", //Class? What class? REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, 0, &hKey, &dwDisposition ); GetPrivateProfileString( gszCards, Temp, gszEmpty, Buffer, sizeof(Buffer), gszTelephonIni ); ParseSomething("nsssssn", Buffer, bBigArray); pSource = bBigArray; RegSetValueEx( hKey, gszID, 0, REG_DWORD, pSource, sizeof(DWORD) ); pSource += sizeof(DWORD); RegSetValueEx( hKey, gszName, 0, REG_SZ, pSource, lstrlen(pSource)+1 ); pSource += lstrlen(pSource)+1; RegSetValueEx( hKey, gszPin, 0, REG_SZ, pSource, lstrlen(pSource)+1 ); pSource += lstrlen(pSource)+1; RegSetValueEx( hKey, gszLocalRule, 0, REG_SZ, pSource, lstrlen(pSource)+1 ); pSource += lstrlen(pSource)+1; RegSetValueEx( hKey, gszLDRule, 0, REG_SZ, pSource, lstrlen(pSource)+1 ); pSource += lstrlen(pSource)+1; RegSetValueEx( hKey, gszInternationalRule, 0, REG_SZ, pSource, lstrlen(pSource)+1 ); pSource += lstrlen(pSource)+1; RegSetValueEx( hKey, gszFlags, 0, REG_DWORD, pSource, sizeof(DWORD) ); pSource += sizeof(DWORD); RegCloseKey( hKey ); } RegCloseKey( hKey2 ); RegCloseKey( hKey3 ); //--------------------------------------------------------------------------- GetPrivateProfileString( gszLocations, gszCurrentLocation, gszEmpty, Buffer, sizeof(Buffer), gszTelephonIni ); ParseSomething( "nn", Buffer, &dwArray); dwCurrentID = dwArray[0]; //BUGBUG: What's the other one for? GetPrivateProfileString( gszLocations, gszLocations, gszEmpty, Buffer, sizeof(Buffer), gszTelephonIni ); ParseSomething( "nn", Buffer, &dwArray); dwNumEntries = dwArray[0]; dwNextID = dwArray[1]; RegCreateKeyEx( HKEY_LOCAL_MACHINE, gszTelephony, 0, "", //Class? What class? REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, 0, &hKey3, &dwDisposition ); RegCreateKeyEx( hKey3, gszLocations, 0, "", //Class? What class? REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, 0, &hKey2, &dwDisposition ); RegSetValueEx( hKey2, gszCurrentID, 0, REG_DWORD, (LPBYTE)&dwCurrentID, sizeof(DWORD) ); RegSetValueEx( hKey2, gszNumEntries, 0, REG_DWORD, (LPBYTE)&dwNumEntries, sizeof(DWORD) ); RegSetValueEx( hKey2, gszNextID, 0, REG_DWORD, (LPBYTE)&dwNextID, sizeof(DWORD) ); for ( dw=0; dw<dwNumEntries; dw++ ) { TCHAR Temp[18]; DWORD dwFlags = 0; wsprintf(Temp, "%s%d", gszLocation, dw); // // Create the key for this Location // RegCreateKeyEx( hKey2, Temp, 0, "", //Class? What class? REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, 0, &hKey, &dwDisposition ); GetPrivateProfileString( gszLocations, Temp, gszEmpty, Buffer, sizeof(Buffer), gszTelephonIni ); ParseSomething("nssssnnnnsns", Buffer, bBigArray); //BUGBUG if this is upgrade over 3.1, the last 2 fields don't exist //[Locations] //CurrentLocation=1,2 //Locations=3,4 //Location0=0,"Work","9","9","206",1,0,0,1,"",0,"" //Location1=3,"RoadHouse","","","215",1,0,0,0,"",0,"" //Location2=1,"Home","","","206",1,0,0,0,"",0," " // Positions in ini file entries for locations,cards,countries // NOTE: dialing rules are in same positions for locations and cards! //#define LOC_INI_ID (0) //#define LOC_INI_NAME (1) //#define LOC_INI_LPREFIX (2) //#define LOC_INI_LDPREFIX (3) //#define LOC_INI_AREACODE (4) //#define LOC_INI_COUNTRYCODE (5) //#define LOC_INI_CARDID (6) //#define LOC_INI_CARDHINT (7) //#define LOC_INI_INSERTAC (8) //#define LOC_INI_TOLLLIST (9) // //#define LOC_INI_PULSE (10) //#define LOC_INI_CALLWAITING (11) pSource = bBigArray; RegSetValueEx( hKey, gszID, 0, REG_DWORD, pSource, sizeof(DWORD) ); pSource += sizeof(DWORD); RegSetValueEx( hKey, gszName, 0, REG_SZ, pSource, lstrlen(pSource)+1 ); pSource += lstrlen(pSource)+1; RegSetValueEx( hKey, gszOutsideAccess, 0, REG_SZ, pSource, lstrlen(pSource)+1 ); pSource += lstrlen(pSource)+1; RegSetValueEx( hKey, gszLongDistanceAccess, 0, REG_SZ, pSource, lstrlen(pSource)+1 ); pSource += lstrlen(pSource)+1; RegSetValueEx( hKey, gszAreaCode, 0, REG_SZ, pSource, lstrlen(pSource)+1 ); pSource += lstrlen(pSource)+1; RegSetValueEx( hKey, gszCountry, 0, REG_DWORD, pSource, sizeof(DWORD) ); pSource += sizeof(DWORD); // // If the callingcard == 0, it means this location does not // use a calling card. // if ( *(LPDWORD)pSource != 0 ) { dwFlags |= LOCATION_USECALLINGCARD; } RegSetValueEx( hKey, gszCallingCard, 0, REG_DWORD, pSource, sizeof(DWORD) ); pSource += sizeof(DWORD); //BUGBUG What the hell is a CardHint? Or Insert AC, for that matter? pSource += sizeof(DWORD); pSource += sizeof(DWORD); RegSetValueEx( hKey, gszTollList, 0, REG_SZ, pSource, lstrlen(pSource)+1 ); pSource += lstrlen(pSource)+1; // // pSource is currently pointing to the old dwFlags. However, // the only flag that was used was bit 1 which indicated // tone dialing. As luck (yeah, right) would have it, we // use bit 1 to indicate tone dialing as well. // dwFlags |= !((*(LPDWORD)pSource) & 1); pSource += sizeof(DWORD); // // Is there a disablecallwaiting string // dwFlags |= ( lstrlen( pSource ) == 0 ) ? 0 : LOCATION_HASCALLWAITING; RegSetValueEx( hKey, gszDisableCallWaiting, 0, REG_SZ, pSource, lstrlen(pSource)+1 ); pSource += lstrlen(pSource)+1; RegSetValueEx( hKey, gszFlags, 0, REG_DWORD, (LPBYTE)&dwFlags, sizeof(DWORD) ); pSource += sizeof(DWORD); RegCloseKey( hKey ); } //--------------------------------------------------------------------------- // // If we're on Win95, copy the PROVIDERS entries to the // registry for TSP3216L.TSP // { } //--------------------------------------------------------------------------- // // Q: How do we update COUNTRY OVERRIDES? // A: We don't. We assume we've corrected everything by now... // // RegCloseKey( hKey ); RegCloseKey( hKey2 ); RegCloseKey( hKey3 ); } { int i; HKEY hKeyHandoffPriorities; WCHAR *gaszMediaModes[] = { L"", L"unknown", L"interactivevoice", L"automatedvoice", L"datamodem", L"g3fax", L"tdd", L"g4fax", L"digitaldata", L"teletex", L"videotex", L"telex", L"mixed", L"adsi", L"voiceview", NULL }; WCHAR *gszRequestMakeCallW = L"RequestMakeCall"; WCHAR *gszRequestMediaCallW = L"RequestMediaCall"; WCHAR *gszRegKeyHandoffPriorities = L"Software\\Microsoft\\Windows\\CurrentVersion\\Telephony\\HandoffPriorities"; if (RegOpenKeyExW( HKEY_CURRENT_USER, gszRegKeyHandoffPriorities, 0, KEY_ALL_ACCESS, &hKeyHandoffPriorities ) == ERROR_SUCCESS) { for (i = 1; gaszMediaModes[i] != NULL; i++) { FixPriorityList( hKeyHandoffPriorities, gaszMediaModes[i] ); } FixPriorityList( hKeyHandoffPriorities, gszRequestMakeCallW ); FixPriorityList( hKeyHandoffPriorities, gszRequestMediaCallW ); RegCloseKey (hKeyHandoffPriorities); } } { //---------------------------------------------------------------------- //---------------------------------------------------------------------- //---------------------------------------------------------------------- // // Now we discuss someone who is upgrading from beta 2 to RTM. They have // "EVERYONE:FULL CONTROL" access on the LOCATIONS key. Let's change that // to have the same security as the TELEPHONY key. // SECURITY_INFORMATION SecInf; PSECURITY_DESCRIPTOR pSecDesc; DWORD cbSecDesc = 65535; pSecDesc = LocalAlloc( LPTR, cbSecDesc ); if ( pSecDesc ) { RegOpenKeyEx( HKEY_LOCAL_MACHINE, gszTelephony, 0, KEY_ALL_ACCESS, &hKey ); RegCreateKeyEx( hKey, gszLocations, 0, "", //Class? What class? REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, 0, &hKey2, &dwDisposition ); cbSecDesc = 65535; dw = RegGetKeySecurity( hKey, OWNER_SECURITY_INFORMATION, pSecDesc, &cbSecDesc ); if ( ERROR_SUCCESS == dw ) RegSetKeySecurity( hKey2, OWNER_SECURITY_INFORMATION, pSecDesc ); cbSecDesc = 65535; dw = RegGetKeySecurity( hKey, GROUP_SECURITY_INFORMATION, pSecDesc, &cbSecDesc ); if ( ERROR_SUCCESS == dw ) RegSetKeySecurity( hKey2, GROUP_SECURITY_INFORMATION, pSecDesc ); cbSecDesc = 65535; dw = RegGetKeySecurity( hKey, DACL_SECURITY_INFORMATION, pSecDesc, &cbSecDesc ); if ( ERROR_SUCCESS == dw ) RegSetKeySecurity( hKey2, DACL_SECURITY_INFORMATION, pSecDesc ); cbSecDesc = 65535; dw = RegGetKeySecurity( hKey, SACL_SECURITY_INFORMATION, pSecDesc, &cbSecDesc ); if ( ERROR_SUCCESS == dw ) RegSetKeySecurity( hKey2, SACL_SECURITY_INFORMATION, pSecDesc ); RegCloseKey( hKey ); RegCloseKey( hKey2); LocalFree( pSecDesc ); } } return; } void FixPriorityList(HKEY hKeyHandoffPriorities, LPWSTR pszListName) { DWORD dwType, dwNumBytes; LPWSTR pszPriorityList, pszHold; if (RegQueryValueExW( hKeyHandoffPriorities, pszListName, NULL, &dwType, NULL, &dwNumBytes ) == ERROR_SUCCESS && (dwNumBytes != 0)) { pszPriorityList = (LPWSTR) GlobalAlloc ( GPTR, dwNumBytes ); if (pszPriorityList) { pszHold = pszPriorityList; if ( RegQueryValueExW( hKeyHandoffPriorities, pszListName, NULL, &dwType, (LPBYTE)(pszPriorityList), &dwNumBytes ) == ERROR_SUCCESS) { while (*pszPriorityList != L'\0') { if (*pszPriorityList == L',') { *pszPriorityList = L'"'; } pszPriorityList++; } pszPriorityList = pszHold; RegSetValueExW( hKeyHandoffPriorities, pszListName, 0, REG_SZ, (LPBYTE)pszPriorityList, (lstrlenW(pszPriorityList) + 1) * sizeof(WCHAR)); } GlobalFree(pszPriorityList); } } } #if DBG #include "stdarg.h" #include "stdio.h" VOID DbgPrt( DWORD dwDbgLevel, PSTR lpszFormat, ... ) /*++ Routine Description: Formats the incoming debug message & calls DbgPrint Arguments: DbgLevel - level of message verboseness DbgMessage - printf-style format string, followed by appropriate list of arguments Return Value: --*/ { static DWORD gdwDebugLevel = 0; //HACKHACK if (dwDbgLevel <= gdwDebugLevel) { char buf[256] = "TAPIUPR: "; va_list ap; va_start(ap, lpszFormat); wvsprintf (&buf[8], lpszFormat, ap ); lstrcat (buf, "\n"); OutputDebugStringA (buf); va_end(ap); } } #endif