//============================================================================ // Copyright (c) 1995, Microsoft Corporation // // File: Upgrade.c // // History: // V Raman July-1-1997 Created. // // Entry points for ISDN upgrade //============================================================================ #include #include #include #include #include #include #include #include #include "upgrade.h" // // upgrade inf section name // #define MAX_CHARS_PER_LINE 128 #define ALIGN_SIZE 0x00000008 #define ALIGN_SHIFT (ALIGN_SIZE - 0x00000001) // 0x00000007 #define ALIGN_MASK (~ALIGN_SHIFT) // 0xfffffff8 #define ALIGN_POINTER(ptr) { \ ((DWORD) (ptr)) += ALIGN_SHIFT; \ ((DWORD) (ptr)) &= ALIGN_MASK; \ } typedef struct _ISDN_STATIC_PARAMS { WCHAR ptszInfId[ MAX_PATH ]; DWORD dwWanEndPoints; DWORD dwNumDChannels; DWORD dwNumBChannelsPerDChannel; } ISDN_STATIC_PARAMS, *PISDN_STATIC_PARAMS; // // New inf Key names // WCHAR c_ptszIsdnNumDChannels[] = L"IsdnNumDChannels"; WCHAR c_ptszIsdnSwitchType[] = L"IsdnSwitchType"; WCHAR c_ptszIsdnNumBChannels[] = L"IsdnNumBChannels"; WCHAR c_ptszIsdnSpid[] = L"IsdnSpid"; WCHAR c_ptszIsdnPhoneNumber[] = L"IsdnPhoneNumber"; //============================================================================ // Values for DIGI Datafire ISDN cards. // // //============================================================================ #define DIGI_MAX_ADAPTERS 3 #define DIGI_MAX_SWITCH_TYPES 12 ISDN_STATIC_PARAMS g_ispDigiParams[] = { { TEXT( "DataFireIsa1U" ), 2, 1, 2 }, { L "DataFireIsa1ST" , 2, 1, 2 }, { L "DataFireIsa4ST" , 8, 4, 2 } }; PWSTR g_ptszDigiSwitchTypes[] = { L "Auto Detect" , L "Generic" , L "ATT" , L "DEFINITY" , L "NTI" , L "NI1" , L "NET3" , L "1TR6" , L "VN3" , L "INS64" , L "AUSTEL" , L "Singapore" }; // // registry keys for DIGI Datafire ISDN card. // WCHAR c_ptszNumberOfLines[] = L "NumberOfLines" ; WCHAR c_ptszLine[] = L "Line" ; WCHAR c_ptszSwitchStyle[] = L "SwitchStyle" ; WCHAR c_ptszLogicalTerminals[] = L "LogicalTerminals" ; WCHAR c_ptszTerminalManagement[] = L "TerminalManagement" ; WCHAR c_ptszLTerm[] = L "LTerm" ; WCHAR c_ptszSPID[] = L "SPID" ; WCHAR c_ptszAddress[] = L "Address" ; //---------------------------------------------------------------------------- // Function: DLLMAIN // // This is the DLL entrypoint handler. //---------------------------------------------------------------------------- BOOL WINAPI DLLMAIN( HINSTANCE hInstance, DWORD dwReason, PVOID pUnused ) { switch(dwReason) { case DLL_PROCESS_ATTACH: DisableThreadLibraryCalls(hInstance); break; case DLL_PROCESS_DETACH: break; default: break; } return TRUE; } //---------------------------------------------------------------------------- // Function: NetWriteDIGIISDNRegistry // // reads the registry layout of DIGI PCIMAC card and write the key // values that need to be updated in the 5.0 setup. //---------------------------------------------------------------------------- DWORD NetWriteDIGIISDNRegistry( IN HKEY hKeyInstanceParameters, IN PCWSTR szPreNT5IndId, IN PCWSTR szNT5InfId, IN PCWSTR szSectionName, OUT PWSTR ** lplplpBuffer, IN OUT PDWORD pdwNumLines ) { DWORD dwInd = 0, dwInd1 = 0, dwErr = ERROR_SUCCESS; DWORD dwMaxKeyLen = 0, dwMaxValueLen = 0, dwType = 0, dwSize = 0, dwNumSubKeys = 0; DWORD dwValue = 0, dwNumDChannels = 0, dwNumLogTerm = 0; DWORD dwMaxLines = 0, dwNumLines = 0; PTCHAR ptszKey = NULL, ptszValue = NULL; PTCHAR ptszBuffer = NULL; WCHAR ptszSubKey[ MAX_PATH ]; PBYTE pb = NULL, pbLine = NULL; PWSTR * lplpOffset; PISDN_STATIC_PARAMS pisp = NULL; do { // // Create IsdnNumDChannel entry // // for each D channel // Create IsdnSwitchType (index into the mulptsz) // Create VendorSpecific\TerminalManagement // Create VendorSpecific\LogicalTerminals // // For each B Channel // Create IsdnSpid // Create IsdnPhoneNumber // // // figure out which card this is // for ( dwInd = 0; dwInd < DIGI_MAX_ADAPTERS; dwInd++ ) { if ( !_wcsicmp( g_ispDigiParams[ dwInd ].ptszInfId, szNT5InfId ) ) { break; } } if ( dwInd >= DIGI_MAX_ADAPTERS ) { break; } pisp = &(g_ispDigiParams[ dwInd ]); // Compute number of lines in buffer as // // 4 (section name, Addreg line, blank line, Addreg section name) + // 1 (IsdnNumDChannels) + // IsdnNumDChannels * ( 3 + // ( IsdnNumBChannels * 2 ) // dwMaxLines = 5 + ( pisp-> dwNumDChannels * ( 3 + pisp-> dwNumBChannelsPerDChannel * 2 ) ); // // allocate buffer big enough to hold these many lines of entries // dwSize = sizeof( PWSTR ) * dwMaxLines + ALIGN_SIZE + dwMaxLines * sizeof( WCHAR ) * MAX_CHARS_PER_LINE; pb = LocalAlloc( 0, dwSize ); if ( pb == NULL ) { break; } ZeroMemory( pb, dwSize ); lplpOffset = (PWSTR *) pb; pbLine = pb + sizeof( PWSTR ) * dwMaxLines; ALIGN_POINTER( pbLine ); // // set the pointers // for ( dwInd = 0; dwInd < dwMaxLines; dwInd++ ) { lplpOffset[ dwInd ] = (PWSTR) ( pbLine + dwInd * sizeof( WCHAR ) * MAX_CHARS_PER_LINE ); } // // write section name // dwNumLines = 0; ptszBuffer = lplpOffset[ dwNumLines++ ]; wsprintfW( ptszBuffer, L"[%s]", szSectionName ); ptszBuffer = lplpOffset[ dwNumLines++ ]; wsprintfW( ptszBuffer, L"AddReg\t= %s.%s.reg", szSectionName, szNT5InfId ); // // Start registry section name // ptszBuffer = lplpOffset[ dwNumLines++ ]; wsprintfW( ptszBuffer, L"[%s.%s.reg]", szSectionName, szNT5InfId ); // // Find size of longest sub key and the size of max value // Allocate buffers for them. // dwErr = RegQueryInfoKey( hKeyInstanceParameters, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &dwMaxKeyLen, &dwMaxValueLen, NULL, NULL ); if ( dwErr != ERROR_SUCCESS ) { dwErr = GetLastError(); break; } ptszKey = HeapAlloc( GetProcessHeap(), 0, (dwMaxKeyLen + 1) * sizeof( WCHAR ) ); if ( ptszKey == NULL ) { dwErr = ERROR_NOT_ENOUGH_MEMORY; break; } ptszValue = HeapAlloc( GetProcessHeap(), 0, (dwMaxValueLen + 1) * sizeof( WCHAR ) ); if ( ptszValue == NULL ) { dwErr = ERROR_NOT_ENOUGH_MEMORY; break; } // // Find number of D channels // dwSize = sizeof( DWORD ); dwErr = RegQueryValueEx( hKeyInstanceParameters, c_ptszNumberOfLines, NULL, &dwType, (PBYTE) &dwNumDChannels, &dwSize ); if ( dwErr != ERROR_SUCCESS ) { break; } ptszBuffer = lplpOffset[ dwNumLines++ ]; wsprintfW( ptszBuffer, L "HKR, , %s, %#.8lx, %d" , c_ptszIsdnNumDChannels, FLG_ADDREG_TYPE_DWORD, dwNumDChannels ); ptszBuffer = lplpOffset[ dwNumLines++ ]; // // for each D channel // for ( dwInd = 0; dwInd < dwNumDChannels; dwInd++ ) { // // Sub key for D channels under which all the info // is to written // wsprintfW( ptszSubKey, L"%d" , dwInd ); // // create switch type key name // wsprintfW( ptszKey, L"%s%d.%s" , c_ptszLine, dwInd, c_ptszSwitchStyle ); // // query protocol key and use look up to determine switch type. // dwSize = dwMaxValueLen * sizeof( WCHAR ); dwErr = RegQueryValueEx( hKeyInstanceParameters, ptszKey, NULL, &dwType, (LPBYTE) ptszValue, &dwSize ); if ( dwErr != ERROR_SUCCESS ) { break; } // // lookup the switchtype in the list of switch types // for ( dwInd1 = 0; dwInd1 < DIGI_MAX_SWITCH_TYPES; dwInd1++ ) { if ( !_wcsicmp( g_ptszDigiSwitchTypes[ dwInd1 ], ptszValue ) ) { break; } } if ( dwInd1 >= DIGI_MAX_SWITCH_TYPES ) { dwInd1 = 1; } wsprintfW( ptszBuffer, L "HKR, %s, %s, %#.8lx, %d" , ptszSubKey, c_ptszIsdnSwitchType, FLG_ADDREG_TYPE_DWORD, dwInd1 ); ptszBuffer = lplpOffset[ dwNumLines++ ]; // // Create key for number of B channels // wsprintfW( ptszKey, L"%s%d.%s" , c_ptszLine, dwInd, c_ptszLogicalTerminals ); // // Find and write number of logical terminals // dwSize = sizeof( DWORD ); dwErr = RegQueryValueEx( hKeyInstanceParameters, ptszKey, NULL, &dwType, (LPBYTE) &dwNumLogTerm, &dwSize ); if ( dwErr != ERROR_SUCCESS ) { break; } wsprintfW( ptszBuffer, L "HKR, %s\\VendorSpecific, %s, %#.8lx, %d" , ptszSubKey, c_ptszLogicalTerminals, FLG_ADDREG_TYPE_DWORD, dwNumLogTerm ); ptszBuffer = lplpOffset[ dwNumLines++ ]; // // Create key for Terminal management // wsprintfW( ptszKey, L"%s%d.%s" , c_ptszLine, dwInd, c_ptszTerminalManagement ); // // Find and write terminal management value // dwSize = dwMaxValueLen * sizeof( WCHAR ); dwErr = RegQueryValueEx( hKeyInstanceParameters, ptszKey, NULL, &dwType, (LPBYTE) ptszValue, &dwSize ); if ( dwErr != ERROR_SUCCESS ) { break; } wsprintfW( ptszBuffer, L "HKR, %s\\VendorSpecific, %s, %#.8lx, %s" , ptszSubKey, c_ptszTerminalManagement, FLG_ADDREG_TYPE_SZ, ptszValue ); ptszBuffer = lplpOffset[ dwNumLines++ ]; // // for each B Channel for this D channels write the // B channel info. // for ( dwInd1 = 0; dwInd1 < pisp-> dwNumBChannelsPerDChannel; dwInd1++ ) { // // sub key for B channel under which all the info. is to // be written. // wsprintfW( ptszSubKey, L"%d\\%d" , dwInd, dwInd1 ); // // create key for SPID // wsprintfW( ptszKey, L"%s%d.%s%d.%s" , c_ptszLine, dwInd, c_ptszLTerm, dwInd1, c_ptszSPID ); // // retrieve and write value of SPID key // dwSize = dwMaxValueLen * sizeof( WCHAR ); dwErr = RegQueryValueEx( hKeyInstanceParameters, ptszKey, NULL, &dwType, (LPBYTE) ptszValue, &dwSize ); if ( dwErr != ERROR_SUCCESS ) { dwErr = ERROR_SUCCESS; break; } wsprintfW( ptszBuffer, L "HKR, %s, %s, %#.8lx, %s" , ptszSubKey, c_ptszIsdnSpid, FLG_ADDREG_TYPE_SZ, ptszValue ); ptszBuffer = lplpOffset[ dwNumLines++ ]; // // create key for Phone Number // wsprintfW( ptszKey, L"%s%d.%s%d.%s" , c_ptszLine, dwInd, c_ptszLTerm, dwInd1, c_ptszAddress ); // // retrieve and write value of phone number key // dwSize = dwMaxValueLen * sizeof( WCHAR ); dwErr = RegQueryValueEx( hKeyInstanceParameters, ptszKey, NULL, &dwType, (LPBYTE) ptszValue, &dwSize ); if ( dwErr != ERROR_SUCCESS ) { dwErr = ERROR_SUCCESS; break; } wsprintfW( ptszBuffer, L"HKR, %s, %s, %#.8lx, %s" , ptszSubKey, c_ptszIsdnPhoneNumber, FLG_ADDREG_TYPE_SZ, ptszValue ); ptszBuffer = lplpOffset[ dwNumLines++ ]; } if ( dwErr != ERROR_SUCCESS ) { break; } } } while ( FALSE ); // // clean up // if ( ptszKey ) { HeapFree( GetProcessHeap(), 0, ptszKey ); } if ( ptszValue ) { HeapFree( GetProcessHeap(), 0, ptszValue ); } if ( dwErr == ERROR_SUCCESS ) { *lplplpBuffer =(PWSTR *) pb; *pdwNumLines = dwNumLines; } return dwErr; }