windows-nt/Source/XPSP1/NT/net/config/upgrade/digiupg/upgrade.c
2020-09-26 16:20:57 +08:00

686 lines
16 KiB
C

//============================================================================
// Copyright (c) 1995, Microsoft Corporation
//
// File: Upgrade.c
//
// History:
// V Raman July-1-1997 Created.
//
// Entry points for ISDN upgrade
//============================================================================
#include <nt.h>
#include <ntrtl.h>
#include <nturtl.h>
#include <windows.h>
#include <setupapi.h>
#include <tchar.h>
#include <stdio.h>
#include <string.h>
#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;
}