730 lines
16 KiB
C
730 lines
16 KiB
C
/*++
|
|
|
|
Copyright (C) 1999 Microsoft Corporation
|
|
|
|
--*/
|
|
|
|
#include "precomp.h"
|
|
|
|
|
|
#define WCHARTONUM(wchr) (iswalpha(wchr)?(towlower(wchr)-L'a')+10:wchr-L'0')
|
|
|
|
UCHAR StringToHexA(IN LPCWSTR pwcString)
|
|
{
|
|
UCHAR ch = (CHAR)0x00;
|
|
|
|
if( pwcString is NULL )
|
|
return ch;
|
|
|
|
while(*pwcString != L'\0')
|
|
{
|
|
ch <<= 4;
|
|
ch |= WCHARTONUM(*pwcString);
|
|
pwcString++;
|
|
}
|
|
|
|
return ch;
|
|
}
|
|
|
|
|
|
|
|
ULONG LA_TableSize = 0;
|
|
|
|
VOID
|
|
FreeLATable(ULONG TableSize)
|
|
{
|
|
DWORD i = 0;
|
|
|
|
if( IsBadReadPtr((void *)LA_Table, TableSize) is FALSE &&
|
|
TableSize > 0 )
|
|
{
|
|
for( i=0; i<TableSize; i++ )
|
|
{
|
|
if( IsBadStringPtr(LA_Table[i], 20*sizeof(WCHAR)) is FALSE )
|
|
{
|
|
WinsFreeMemory((PVOID)LA_Table[i]);
|
|
LA_Table[i] = NULL;
|
|
}
|
|
}
|
|
|
|
WinsFreeMemory((PVOID)LA_Table);
|
|
LA_Table = NULL;
|
|
}
|
|
}
|
|
|
|
VOID
|
|
FreeSOTable(ULONG TableSize)
|
|
{
|
|
DWORD i = 0;
|
|
|
|
if( SO_Table )
|
|
{
|
|
for( i=0; i<TableSize; i++ )
|
|
{
|
|
if( SO_Table[i] )
|
|
{
|
|
WinsFreeMemory((PVOID)SO_Table[i]);
|
|
SO_Table[i] = NULL;
|
|
}
|
|
}
|
|
|
|
WinsFreeMemory((PVOID)SO_Table);
|
|
SO_Table = NULL;
|
|
}
|
|
}
|
|
|
|
VOID
|
|
DumpSOTable(
|
|
IN DWORD MasterOwners,
|
|
IN BOOL fFile,
|
|
IN FILE * pFile
|
|
)
|
|
{
|
|
ULONG i;
|
|
ULONG j;
|
|
|
|
DisplayMessage(g_hModule,
|
|
MSG_WINS_SOTABLE_HEADER);
|
|
if( fFile is TRUE )
|
|
{
|
|
DumpMessage(g_hModule,
|
|
pFile,
|
|
FMSG_WINS_SOTABLE_HEADER);
|
|
}
|
|
|
|
|
|
for (i = 0; i < MasterOwners; i++)
|
|
{
|
|
DisplayMessage(g_hModule,
|
|
MSG_WINS_MASTEROWNER_INDEX,
|
|
i);
|
|
if( fFile )
|
|
{
|
|
DumpMessage(g_hModule,
|
|
pFile,
|
|
FMSG_WINS_MASTEROWNER_INDEX,
|
|
i);
|
|
}
|
|
}
|
|
|
|
DisplayMessage(g_hModule,
|
|
WINS_FORMAT_LINE);
|
|
if( fFile )
|
|
{
|
|
DumpMessage(g_hModule,
|
|
pFile,
|
|
WINS_FORMAT_LINE);
|
|
}
|
|
|
|
for (i = 0; i < MasterOwners; i++)
|
|
{
|
|
DisplayMessage(g_hModule,
|
|
MSG_WINS_MASTEROWNER_INDEX1,
|
|
i);
|
|
if( fFile )
|
|
{
|
|
DumpMessage(g_hModule,
|
|
pFile,
|
|
FMSG_WINS_MASTEROWNER_INDEX1,
|
|
i);
|
|
}
|
|
for (j = 0; j < MasterOwners; j++)
|
|
{
|
|
DisplayMessage(g_hModule,
|
|
MSG_WINS_MASTEROWNER_INDEX,
|
|
SO_Table[i][j]);
|
|
if( fFile )
|
|
{
|
|
DumpMessage(g_hModule,
|
|
pFile,
|
|
FMSG_WINS_MASTEROWNER_INDEX,
|
|
SO_Table[i][j]);
|
|
}
|
|
}
|
|
|
|
DisplayMessage(g_hModule,
|
|
WINS_FORMAT_LINE);
|
|
if( fFile )
|
|
{
|
|
DumpMessage(g_hModule,
|
|
pFile,
|
|
WINS_FORMAT_LINE);
|
|
}
|
|
}
|
|
|
|
|
|
DisplayMessage(g_hModule,
|
|
MSG_WINS_MAP_SOURCE);
|
|
|
|
if( fFile )
|
|
{
|
|
DumpMessage(g_hModule,
|
|
pFile,
|
|
FMSG_WINS_MAP_SOURCE);
|
|
}
|
|
|
|
DumpLATable(MasterOwners, fFile, pFile);
|
|
}
|
|
|
|
VOID
|
|
DumpLATable(
|
|
IN DWORD MasterOwners,
|
|
IN BOOL fFile,
|
|
IN FILE * pFile
|
|
)
|
|
{
|
|
ULONG i;
|
|
ULONG j;
|
|
|
|
|
|
DisplayMessage(g_hModule,
|
|
MSG_WINS_INDEXTOIP_TABLE);
|
|
|
|
if( fFile )
|
|
{
|
|
DumpMessage(g_hModule,
|
|
pFile,
|
|
FMSG_WINS_INDEXTOIP_TABLE);
|
|
|
|
}
|
|
for (i = 0; i < MasterOwners; i++)
|
|
{
|
|
if (LA_Table[i][0] == '0')
|
|
{
|
|
break;
|
|
}
|
|
|
|
DisplayMessage(g_hModule,
|
|
MSG_WINS_INDEXTOIP_ENTRY,
|
|
i,
|
|
LA_Table[i]);
|
|
|
|
if( pFile )
|
|
{
|
|
DumpMessage(g_hModule,
|
|
pFile,
|
|
FMSG_WINS_INDEXTOIP_ENTRY,
|
|
i,
|
|
LA_Table[i]);
|
|
}
|
|
|
|
}
|
|
|
|
DisplayMessage(g_hModule,
|
|
WINS_FORMAT_LINE);
|
|
if( fFile )
|
|
{
|
|
DumpMessage(g_hModule,
|
|
pFile,
|
|
WINS_FORMAT_LINE);
|
|
}
|
|
}
|
|
|
|
LONG
|
|
IPToIndex(
|
|
IN LPWSTR IpAddr,
|
|
DWORD NoOfOwners
|
|
)
|
|
{
|
|
ULONG i=0;
|
|
WCHAR **pTempLA = NULL;
|
|
//
|
|
// Get the Row #
|
|
//
|
|
for ( i = 0; i < NoOfOwners; i++) {
|
|
if (wcscmp(LA_Table[i], IpAddr) == 0) {
|
|
return i;
|
|
}
|
|
//
|
|
// The first NULL entry indicates end
|
|
//
|
|
if (LA_Table[i][0] is L'0') {
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Entry not found - add
|
|
//
|
|
|
|
wcscpy(LA_Table[i], IpAddr);
|
|
|
|
LA_TableSize = i+1;
|
|
return i;
|
|
}
|
|
|
|
//
|
|
// Check if the diagonal elements are the max in their cols.
|
|
//
|
|
VOID
|
|
CheckSOTableConsistency(
|
|
DWORD MasterOwners
|
|
)
|
|
{
|
|
ULONG i;
|
|
ULONG j;
|
|
BOOLEAN fProblem = FALSE;
|
|
|
|
for (i = 0; i < MasterOwners; i++)
|
|
{
|
|
|
|
//
|
|
// Is the diagonal element at i the largest in its column?
|
|
//
|
|
for (j = 0; j < MasterOwners; j++)
|
|
{
|
|
if (i == j)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
//
|
|
// Compare only non-zero values
|
|
//
|
|
if (SO_Table[i][i].QuadPart &&
|
|
SO_Table[j][i].QuadPart &&
|
|
(SO_Table[i][i].QuadPart < SO_Table[j][i].QuadPart))
|
|
{
|
|
|
|
DisplayMessage(g_hModule, EMSG_WINS_VERSION_HIGHER, LA_Table[j], LA_Table[i]);
|
|
fProblem = TRUE;
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( fProblem is FALSE )
|
|
{
|
|
DisplayMessage(g_hModule, EMSG_WINS_VERSION_CORRECT);
|
|
}
|
|
}
|
|
|
|
DWORD
|
|
InitLATable(
|
|
PWINSINTF_ADD_VERS_MAP_T pAddVersMaps,
|
|
DWORD MasterOwners, // 0 first time
|
|
DWORD NoOfOwners
|
|
)
|
|
{
|
|
ULONG i, j, k;
|
|
|
|
if( LA_Table is NULL )
|
|
{
|
|
LA_Table = WinsAllocateMemory(MAX_WINS*sizeof(LPWSTR));
|
|
if( LA_Table is NULL )
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
for( i=0; i< MAX_WINS; i++ )
|
|
{
|
|
LA_Table[i] = WinsAllocateMemory(20*sizeof(WCHAR));
|
|
if( LA_Table[i] is NULL )
|
|
{
|
|
FreeLATable(i);
|
|
return 0;
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
if (MasterOwners == 0)
|
|
{
|
|
//
|
|
// first time - init the LA table
|
|
//
|
|
for (i = 0; i < NoOfOwners; i++, pAddVersMaps++)
|
|
{
|
|
struct in_addr InAddr;
|
|
|
|
LPWSTR pwsz = IpAddressToString(pAddVersMaps->Add.IPAdd);
|
|
if( pwsz is NULL )
|
|
{
|
|
FreeLATable(MAX_WINS);
|
|
return 0;
|
|
}
|
|
|
|
wcscpy(LA_Table[i], pwsz);
|
|
|
|
WinsFreeMemory(pwsz);
|
|
pwsz = NULL;
|
|
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// More came in this time - add them to the LA table after the others
|
|
//
|
|
for (i = 0; i < NoOfOwners; i++, pAddVersMaps++)
|
|
{
|
|
LPWSTR pwszIp = IpAddressToString(pAddVersMaps->Add.IPAdd);
|
|
|
|
if( pwszIp is NULL )
|
|
{
|
|
FreeLATable(MAX_WINS);
|
|
return 0;
|
|
}
|
|
//
|
|
// If this entry is not in the LA table, insert
|
|
//
|
|
for (j = 0; j < MasterOwners; j++)
|
|
{
|
|
if (wcscmp(LA_Table[j], pwszIp) is 0 )
|
|
{
|
|
WinsFreeMemory(pwszIp);
|
|
pwszIp = NULL;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (j == MasterOwners)
|
|
{
|
|
//
|
|
// Insert
|
|
//
|
|
|
|
|
|
wcscpy(LA_Table[MasterOwners], pwszIp);
|
|
MasterOwners++;
|
|
}
|
|
|
|
if( pwszIp )
|
|
{
|
|
WinsFreeMemory(pwszIp);
|
|
pwszIp = NULL;
|
|
}
|
|
}
|
|
}
|
|
|
|
if( SO_Table is NULL )
|
|
{
|
|
SO_Table = WinsAllocateMemory((MAX_WINS+1)*sizeof(LARGE_INTEGER *));
|
|
if (SO_Table == NULL)
|
|
{
|
|
FreeLATable(MAX_WINS);
|
|
return 0;
|
|
}
|
|
|
|
for( i=0; i<MAX_WINS+1; i++ )
|
|
{
|
|
SO_Table[i] = WinsAllocateMemory((MAX_WINS+1)*sizeof(LARGE_INTEGER));
|
|
if( SO_Table[i] is NULL )
|
|
{
|
|
FreeLATable(MAX_WINS);
|
|
FreeSOTable(MAX_WINS+1);
|
|
return 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
LA_TableSize = NoOfOwners;
|
|
return MasterOwners;
|
|
}
|
|
|
|
|
|
|
|
VOID
|
|
AddSOTableEntry (
|
|
IN LPWSTR IpAddr,
|
|
PWINSINTF_ADD_VERS_MAP_T pMasterMaps,
|
|
DWORD NoOfOwners,
|
|
DWORD MasterOwners
|
|
)
|
|
{
|
|
ULONG i;
|
|
LONG Row;
|
|
struct in_addr InAddr;
|
|
|
|
Row = IPToIndex(IpAddr, MasterOwners);
|
|
|
|
//
|
|
// Fill the row
|
|
//
|
|
for ( i = 0; i < NoOfOwners; i++, pMasterMaps++)
|
|
{
|
|
LONG col;
|
|
LPTSTR pstr;
|
|
|
|
InAddr.s_addr = htonl(pMasterMaps->Add.IPAdd);
|
|
|
|
pstr = IpAddressToString(pMasterMaps->Add.IPAdd);
|
|
if (pstr == NULL)
|
|
break;
|
|
|
|
col = IPToIndex(pstr, MasterOwners);
|
|
//
|
|
// Place only a non-deleted entry
|
|
//
|
|
if (!((pMasterMaps->VersNo.HighPart == MAXLONG) &&
|
|
(pMasterMaps->VersNo.LowPart == MAXULONG))) {
|
|
|
|
//
|
|
// Also if the entry above us was 0, write 0 there so as to make the fail case stand out
|
|
//
|
|
if (Row && SO_Table[Row-1][col].QuadPart == 0)
|
|
{
|
|
SO_Table[Row][col].QuadPart = 0;
|
|
}
|
|
else
|
|
{
|
|
SO_Table[Row][col] = pMasterMaps->VersNo;
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
VOID
|
|
RemoveFromSOTable(
|
|
IN LPWSTR IpAddr,
|
|
IN DWORD MasterOwners
|
|
)
|
|
{
|
|
ULONG i;
|
|
LONG Row;
|
|
struct in_addr InAddr;
|
|
|
|
Row = IPToIndex(IpAddr, MasterOwners);
|
|
|
|
//
|
|
// Mark the row and col as down (0's)
|
|
//
|
|
for (i = 0; i < MasterOwners; i++)
|
|
{
|
|
SO_Table[Row][i].QuadPart = SO_Table[i][Row].QuadPart = 0;
|
|
}
|
|
}
|
|
|
|
|
|
//
|
|
// Get the <owner address> - <version #> [OV table] mapping tables from each WINS server on the net and check for inconsistencies.
|
|
//
|
|
VOID
|
|
CheckVersionNumbers(
|
|
IN LPCSTR pStartIp,
|
|
IN BOOL fFile,
|
|
OUT FILE * pFile
|
|
)
|
|
{
|
|
DWORD Status = NO_ERROR;
|
|
ULONG i, k;
|
|
PWINSINTF_ADD_VERS_MAP_T pAddVersMaps;
|
|
PWINSINTF_ADD_VERS_MAP_T pMasterMaps; // master OV maps used to place into the OV table
|
|
DWORD NoOfOwners=0;
|
|
DWORD MasterOwners=0;
|
|
struct in_addr InAddr;
|
|
WINSINTF_RESULTS_NEW_T ResultsN;
|
|
DWORD ret;
|
|
handle_t hBindTemp = g_hBind;
|
|
WINSINTF_BIND_DATA_T BindDataTemp = g_BindData;
|
|
LPWSTR wszStartIp = NULL;
|
|
|
|
if( pStartIp is NULL )
|
|
return;
|
|
|
|
wszStartIp = WinsOemToUnicode(pStartIp, NULL);
|
|
|
|
if( wszStartIp is NULL )
|
|
{
|
|
DisplayMessage(g_hModule,
|
|
EMSG_WINS_OUT_OF_MEMORY);
|
|
return;
|
|
}
|
|
|
|
//
|
|
// Get the OV table from this server
|
|
//
|
|
if (NO_ERROR isnot (Status = GetStatus(TRUE, &ResultsN, TRUE, FALSE, pStartIp)) )
|
|
{
|
|
DisplayErrorMessage(EMSG_SRVR_CHECK_VERSION,
|
|
Status);
|
|
|
|
WinsFreeMemory(wszStartIp);
|
|
wszStartIp = NULL;
|
|
return;
|
|
}
|
|
else
|
|
{
|
|
DisplayMessage(g_hModule,
|
|
MSG_WINS_GETSTATUS_SUCCESS);
|
|
|
|
DisplayMessage(g_hModule,
|
|
WINS_FORMAT_LINE);
|
|
}
|
|
|
|
MasterOwners = NoOfOwners = ResultsN.NoOfOwners;
|
|
|
|
pMasterMaps = pAddVersMaps = ResultsN.pAddVersMaps;
|
|
|
|
ret = InitLATable(pAddVersMaps, 0, NoOfOwners);
|
|
|
|
if( LA_Table is NULL )
|
|
{
|
|
DisplayMessage(g_hModule,
|
|
EMSG_WINS_OUT_OF_MEMORY);
|
|
WinsFreeMemory(wszStartIp);
|
|
wszStartIp = NULL;
|
|
return;
|
|
}
|
|
|
|
if( SO_Table is NULL )
|
|
{
|
|
DisplayMessage(g_hModule,
|
|
EMSG_WINS_OUT_OF_MEMORY);
|
|
FreeLATable(MAX_WINS);
|
|
WinsFreeMemory(wszStartIp);
|
|
wszStartIp = NULL;
|
|
return;
|
|
}
|
|
|
|
AddSOTableEntry(wszStartIp, pMasterMaps, NoOfOwners, MasterOwners);
|
|
|
|
|
|
if( ResultsN.pAddVersMaps )
|
|
{
|
|
WinsFreeMem(ResultsN.pAddVersMaps);
|
|
ResultsN.pAddVersMaps = NULL;
|
|
}
|
|
|
|
|
|
|
|
//
|
|
// For each server X (other than Start addr) in the LA table:
|
|
//
|
|
for ( i = 0; i < MasterOwners; i++)
|
|
{
|
|
LPSTR pszName = NULL;
|
|
|
|
if( wcscmp(LA_Table[i], wszStartIp) is 0 )
|
|
{
|
|
continue;
|
|
}
|
|
|
|
//
|
|
// Get X's OV table
|
|
//
|
|
pszName = WinsUnicodeToOem(LA_Table[i], NULL);
|
|
|
|
if( pszName is NULL )
|
|
{
|
|
DisplayMessage(g_hModule,
|
|
EMSG_WINS_OUT_OF_MEMORY);
|
|
if( SO_Table )
|
|
{
|
|
FreeSOTable(MAX_WINS+1);
|
|
}
|
|
if( wszStartIp )
|
|
{
|
|
WinsFreeMemory(wszStartIp);
|
|
wszStartIp = NULL;
|
|
}
|
|
|
|
if( LA_Table )
|
|
{
|
|
FreeLATable(MAX_WINS);
|
|
}
|
|
return;
|
|
|
|
}
|
|
|
|
if( NO_ERROR isnot (Status = GetStatus(TRUE, &ResultsN, TRUE, FALSE, pszName) ) )
|
|
{
|
|
RemoveFromSOTable(LA_Table[i], MasterOwners);
|
|
if( pszName )
|
|
{
|
|
WinsFreeMemory(pszName);
|
|
pszName = NULL;
|
|
}
|
|
if( ResultsN.pAddVersMaps )
|
|
{
|
|
WinsFreeMem(ResultsN.pAddVersMaps);
|
|
ResultsN.pAddVersMaps = NULL;
|
|
}
|
|
DisplayErrorMessage(EMSG_WINS_GETSTATUS_FAILED,
|
|
Status);
|
|
continue;
|
|
}
|
|
else
|
|
{
|
|
DisplayMessage(g_hModule,
|
|
MSG_WINS_GETSTATUS_SUCCESS);
|
|
}
|
|
|
|
if (MasterOwners < ResultsN.NoOfOwners)
|
|
{
|
|
|
|
ret = InitLATable(ResultsN.pAddVersMaps, MasterOwners, ResultsN.NoOfOwners);
|
|
if( LA_Table is NULL or
|
|
SO_Table is NULL )
|
|
{
|
|
DisplayMessage(g_hModule,
|
|
EMSG_WINS_OUT_OF_MEMORY);
|
|
if( pszName )
|
|
{
|
|
WinsFreeMemory(pszName);
|
|
pszName = NULL;
|
|
}
|
|
if( ResultsN.pAddVersMaps )
|
|
{
|
|
WinsFreeMem(ResultsN.pAddVersMaps);
|
|
ResultsN.pAddVersMaps = NULL;
|
|
}
|
|
|
|
if( SO_Table )
|
|
{
|
|
WinsFreeMemory(SO_Table);
|
|
SO_Table = NULL;
|
|
}
|
|
if( LA_Table )
|
|
{
|
|
WinsFreeMemory(LA_Table);
|
|
LA_Table = NULL;
|
|
}
|
|
|
|
if( wszStartIp )
|
|
{
|
|
WinsFreeMemory(wszStartIp);
|
|
wszStartIp = NULL;
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
MasterOwners = ret;
|
|
}
|
|
|
|
//
|
|
// Place entry in the SO Table in proper order
|
|
//
|
|
AddSOTableEntry(LA_Table[i], ResultsN.pAddVersMaps, ResultsN.NoOfOwners, MasterOwners);
|
|
if( pszName )
|
|
{
|
|
WinsFreeMemory(pszName);
|
|
pszName = NULL;
|
|
}
|
|
|
|
if( ResultsN.pAddVersMaps )
|
|
{
|
|
WinsFreeMem(ResultsN.pAddVersMaps);
|
|
ResultsN.pAddVersMaps = NULL;
|
|
}
|
|
|
|
}
|
|
|
|
//
|
|
// Check if diagonal elements in the [SO] table are the highest in their cols.
|
|
//
|
|
CheckSOTableConsistency(MasterOwners);
|
|
|
|
DumpSOTable(MasterOwners,
|
|
fFile,
|
|
pFile);
|
|
|
|
//
|
|
// Destroy SO table
|
|
//
|
|
FreeSOTable(MasterOwners+1);
|
|
FreeLATable(MasterOwners);
|
|
|
|
}
|