/*++ 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; iAdd.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; iAdd.IPAdd); pstr = IpAddressToString(pMasterMaps->Add.IPAdd); if (pstr == NULL) break; col = IPToIndex(pstr, MasterOwners); // clean out memory WinsFreeMemory(pstr); // // 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 - [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); }