Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

729 lines
16 KiB

  1. /*++
  2. Copyright (C) 1999 Microsoft Corporation
  3. --*/
  4. #include "precomp.h"
  5. #define WCHARTONUM(wchr) (iswalpha(wchr)?(towlower(wchr)-L'a')+10:wchr-L'0')
  6. UCHAR StringToHexA(IN LPCWSTR pwcString)
  7. {
  8. UCHAR ch = (CHAR)0x00;
  9. if( pwcString is NULL )
  10. return ch;
  11. while(*pwcString != L'\0')
  12. {
  13. ch <<= 4;
  14. ch |= WCHARTONUM(*pwcString);
  15. pwcString++;
  16. }
  17. return ch;
  18. }
  19. ULONG LA_TableSize = 0;
  20. VOID
  21. FreeLATable(ULONG TableSize)
  22. {
  23. DWORD i = 0;
  24. if( IsBadReadPtr((void *)LA_Table, TableSize) is FALSE &&
  25. TableSize > 0 )
  26. {
  27. for( i=0; i<TableSize; i++ )
  28. {
  29. if( IsBadStringPtr(LA_Table[i], 20*sizeof(WCHAR)) is FALSE )
  30. {
  31. WinsFreeMemory((PVOID)LA_Table[i]);
  32. LA_Table[i] = NULL;
  33. }
  34. }
  35. WinsFreeMemory((PVOID)LA_Table);
  36. LA_Table = NULL;
  37. }
  38. }
  39. VOID
  40. FreeSOTable(ULONG TableSize)
  41. {
  42. DWORD i = 0;
  43. if( SO_Table )
  44. {
  45. for( i=0; i<TableSize; i++ )
  46. {
  47. if( SO_Table[i] )
  48. {
  49. WinsFreeMemory((PVOID)SO_Table[i]);
  50. SO_Table[i] = NULL;
  51. }
  52. }
  53. WinsFreeMemory((PVOID)SO_Table);
  54. SO_Table = NULL;
  55. }
  56. }
  57. VOID
  58. DumpSOTable(
  59. IN DWORD MasterOwners,
  60. IN BOOL fFile,
  61. IN FILE * pFile
  62. )
  63. {
  64. ULONG i;
  65. ULONG j;
  66. DisplayMessage(g_hModule,
  67. MSG_WINS_SOTABLE_HEADER);
  68. if( fFile is TRUE )
  69. {
  70. DumpMessage(g_hModule,
  71. pFile,
  72. FMSG_WINS_SOTABLE_HEADER);
  73. }
  74. for (i = 0; i < MasterOwners; i++)
  75. {
  76. DisplayMessage(g_hModule,
  77. MSG_WINS_MASTEROWNER_INDEX,
  78. i);
  79. if( fFile )
  80. {
  81. DumpMessage(g_hModule,
  82. pFile,
  83. FMSG_WINS_MASTEROWNER_INDEX,
  84. i);
  85. }
  86. }
  87. DisplayMessage(g_hModule,
  88. WINS_FORMAT_LINE);
  89. if( fFile )
  90. {
  91. DumpMessage(g_hModule,
  92. pFile,
  93. WINS_FORMAT_LINE);
  94. }
  95. for (i = 0; i < MasterOwners; i++)
  96. {
  97. DisplayMessage(g_hModule,
  98. MSG_WINS_MASTEROWNER_INDEX1,
  99. i);
  100. if( fFile )
  101. {
  102. DumpMessage(g_hModule,
  103. pFile,
  104. FMSG_WINS_MASTEROWNER_INDEX1,
  105. i);
  106. }
  107. for (j = 0; j < MasterOwners; j++)
  108. {
  109. DisplayMessage(g_hModule,
  110. MSG_WINS_MASTEROWNER_INDEX,
  111. SO_Table[i][j]);
  112. if( fFile )
  113. {
  114. DumpMessage(g_hModule,
  115. pFile,
  116. FMSG_WINS_MASTEROWNER_INDEX,
  117. SO_Table[i][j]);
  118. }
  119. }
  120. DisplayMessage(g_hModule,
  121. WINS_FORMAT_LINE);
  122. if( fFile )
  123. {
  124. DumpMessage(g_hModule,
  125. pFile,
  126. WINS_FORMAT_LINE);
  127. }
  128. }
  129. DisplayMessage(g_hModule,
  130. MSG_WINS_MAP_SOURCE);
  131. if( fFile )
  132. {
  133. DumpMessage(g_hModule,
  134. pFile,
  135. FMSG_WINS_MAP_SOURCE);
  136. }
  137. DumpLATable(MasterOwners, fFile, pFile);
  138. }
  139. VOID
  140. DumpLATable(
  141. IN DWORD MasterOwners,
  142. IN BOOL fFile,
  143. IN FILE * pFile
  144. )
  145. {
  146. ULONG i;
  147. ULONG j;
  148. DisplayMessage(g_hModule,
  149. MSG_WINS_INDEXTOIP_TABLE);
  150. if( fFile )
  151. {
  152. DumpMessage(g_hModule,
  153. pFile,
  154. FMSG_WINS_INDEXTOIP_TABLE);
  155. }
  156. for (i = 0; i < MasterOwners; i++)
  157. {
  158. if (LA_Table[i][0] == '0')
  159. {
  160. break;
  161. }
  162. DisplayMessage(g_hModule,
  163. MSG_WINS_INDEXTOIP_ENTRY,
  164. i,
  165. LA_Table[i]);
  166. if( pFile )
  167. {
  168. DumpMessage(g_hModule,
  169. pFile,
  170. FMSG_WINS_INDEXTOIP_ENTRY,
  171. i,
  172. LA_Table[i]);
  173. }
  174. }
  175. DisplayMessage(g_hModule,
  176. WINS_FORMAT_LINE);
  177. if( fFile )
  178. {
  179. DumpMessage(g_hModule,
  180. pFile,
  181. WINS_FORMAT_LINE);
  182. }
  183. }
  184. LONG
  185. IPToIndex(
  186. IN LPWSTR IpAddr,
  187. DWORD NoOfOwners
  188. )
  189. {
  190. ULONG i=0;
  191. WCHAR **pTempLA = NULL;
  192. //
  193. // Get the Row #
  194. //
  195. for ( i = 0; i < NoOfOwners; i++) {
  196. if (wcscmp(LA_Table[i], IpAddr) == 0) {
  197. return i;
  198. }
  199. //
  200. // The first NULL entry indicates end
  201. //
  202. if (LA_Table[i][0] is L'0') {
  203. break;
  204. }
  205. }
  206. //
  207. // Entry not found - add
  208. //
  209. wcscpy(LA_Table[i], IpAddr);
  210. LA_TableSize = i+1;
  211. return i;
  212. }
  213. //
  214. // Check if the diagonal elements are the max in their cols.
  215. //
  216. VOID
  217. CheckSOTableConsistency(
  218. DWORD MasterOwners
  219. )
  220. {
  221. ULONG i;
  222. ULONG j;
  223. BOOLEAN fProblem = FALSE;
  224. for (i = 0; i < MasterOwners; i++)
  225. {
  226. //
  227. // Is the diagonal element at i the largest in its column?
  228. //
  229. for (j = 0; j < MasterOwners; j++)
  230. {
  231. if (i == j)
  232. {
  233. continue;
  234. }
  235. //
  236. // Compare only non-zero values
  237. //
  238. if (SO_Table[i][i].QuadPart &&
  239. SO_Table[j][i].QuadPart &&
  240. (SO_Table[i][i].QuadPart < SO_Table[j][i].QuadPart))
  241. {
  242. DisplayMessage(g_hModule, EMSG_WINS_VERSION_HIGHER, LA_Table[j], LA_Table[i]);
  243. fProblem = TRUE;
  244. }
  245. }
  246. }
  247. if ( fProblem is FALSE )
  248. {
  249. DisplayMessage(g_hModule, EMSG_WINS_VERSION_CORRECT);
  250. }
  251. }
  252. DWORD
  253. InitLATable(
  254. PWINSINTF_ADD_VERS_MAP_T pAddVersMaps,
  255. DWORD MasterOwners, // 0 first time
  256. DWORD NoOfOwners
  257. )
  258. {
  259. ULONG i, j, k;
  260. if( LA_Table is NULL )
  261. {
  262. LA_Table = WinsAllocateMemory(MAX_WINS*sizeof(LPWSTR));
  263. if( LA_Table is NULL )
  264. {
  265. return 0;
  266. }
  267. for( i=0; i< MAX_WINS; i++ )
  268. {
  269. LA_Table[i] = WinsAllocateMemory(20*sizeof(WCHAR));
  270. if( LA_Table[i] is NULL )
  271. {
  272. FreeLATable(i);
  273. return 0;
  274. }
  275. }
  276. }
  277. if (MasterOwners == 0)
  278. {
  279. //
  280. // first time - init the LA table
  281. //
  282. for (i = 0; i < NoOfOwners; i++, pAddVersMaps++)
  283. {
  284. struct in_addr InAddr;
  285. LPWSTR pwsz = IpAddressToString(pAddVersMaps->Add.IPAdd);
  286. if( pwsz is NULL )
  287. {
  288. FreeLATable(MAX_WINS);
  289. return 0;
  290. }
  291. wcscpy(LA_Table[i], pwsz);
  292. WinsFreeMemory(pwsz);
  293. pwsz = NULL;
  294. }
  295. }
  296. else
  297. {
  298. //
  299. // More came in this time - add them to the LA table after the others
  300. //
  301. for (i = 0; i < NoOfOwners; i++, pAddVersMaps++)
  302. {
  303. LPWSTR pwszIp = IpAddressToString(pAddVersMaps->Add.IPAdd);
  304. if( pwszIp is NULL )
  305. {
  306. FreeLATable(MAX_WINS);
  307. return 0;
  308. }
  309. //
  310. // If this entry is not in the LA table, insert
  311. //
  312. for (j = 0; j < MasterOwners; j++)
  313. {
  314. if (wcscmp(LA_Table[j], pwszIp) is 0 )
  315. {
  316. WinsFreeMemory(pwszIp);
  317. pwszIp = NULL;
  318. break;
  319. }
  320. }
  321. if (j == MasterOwners)
  322. {
  323. //
  324. // Insert
  325. //
  326. wcscpy(LA_Table[MasterOwners], pwszIp);
  327. MasterOwners++;
  328. }
  329. if( pwszIp )
  330. {
  331. WinsFreeMemory(pwszIp);
  332. pwszIp = NULL;
  333. }
  334. }
  335. }
  336. if( SO_Table is NULL )
  337. {
  338. SO_Table = WinsAllocateMemory((MAX_WINS+1)*sizeof(LARGE_INTEGER *));
  339. if (SO_Table == NULL)
  340. {
  341. FreeLATable(MAX_WINS);
  342. return 0;
  343. }
  344. for( i=0; i<MAX_WINS+1; i++ )
  345. {
  346. SO_Table[i] = WinsAllocateMemory((MAX_WINS+1)*sizeof(LARGE_INTEGER));
  347. if( SO_Table[i] is NULL )
  348. {
  349. FreeLATable(MAX_WINS);
  350. FreeSOTable(MAX_WINS+1);
  351. return 0;
  352. }
  353. }
  354. }
  355. LA_TableSize = NoOfOwners;
  356. return MasterOwners;
  357. }
  358. VOID
  359. AddSOTableEntry (
  360. IN LPWSTR IpAddr,
  361. PWINSINTF_ADD_VERS_MAP_T pMasterMaps,
  362. DWORD NoOfOwners,
  363. DWORD MasterOwners
  364. )
  365. {
  366. ULONG i;
  367. LONG Row;
  368. struct in_addr InAddr;
  369. Row = IPToIndex(IpAddr, MasterOwners);
  370. //
  371. // Fill the row
  372. //
  373. for ( i = 0; i < NoOfOwners; i++, pMasterMaps++)
  374. {
  375. LONG col;
  376. LPTSTR pstr;
  377. InAddr.s_addr = htonl(pMasterMaps->Add.IPAdd);
  378. pstr = IpAddressToString(pMasterMaps->Add.IPAdd);
  379. if (pstr == NULL)
  380. break;
  381. col = IPToIndex(pstr, MasterOwners);
  382. //
  383. // Place only a non-deleted entry
  384. //
  385. if (!((pMasterMaps->VersNo.HighPart == MAXLONG) &&
  386. (pMasterMaps->VersNo.LowPart == MAXULONG))) {
  387. //
  388. // Also if the entry above us was 0, write 0 there so as to make the fail case stand out
  389. //
  390. if (Row && SO_Table[Row-1][col].QuadPart == 0)
  391. {
  392. SO_Table[Row][col].QuadPart = 0;
  393. }
  394. else
  395. {
  396. SO_Table[Row][col] = pMasterMaps->VersNo;
  397. }
  398. }
  399. }
  400. }
  401. VOID
  402. RemoveFromSOTable(
  403. IN LPWSTR IpAddr,
  404. IN DWORD MasterOwners
  405. )
  406. {
  407. ULONG i;
  408. LONG Row;
  409. struct in_addr InAddr;
  410. Row = IPToIndex(IpAddr, MasterOwners);
  411. //
  412. // Mark the row and col as down (0's)
  413. //
  414. for (i = 0; i < MasterOwners; i++)
  415. {
  416. SO_Table[Row][i].QuadPart = SO_Table[i][Row].QuadPart = 0;
  417. }
  418. }
  419. //
  420. // Get the <owner address> - <version #> [OV table] mapping tables from each WINS server on the net and check for inconsistencies.
  421. //
  422. VOID
  423. CheckVersionNumbers(
  424. IN LPCSTR pStartIp,
  425. IN BOOL fFile,
  426. OUT FILE * pFile
  427. )
  428. {
  429. DWORD Status = NO_ERROR;
  430. ULONG i, k;
  431. PWINSINTF_ADD_VERS_MAP_T pAddVersMaps;
  432. PWINSINTF_ADD_VERS_MAP_T pMasterMaps; // master OV maps used to place into the OV table
  433. DWORD NoOfOwners=0;
  434. DWORD MasterOwners=0;
  435. struct in_addr InAddr;
  436. WINSINTF_RESULTS_NEW_T ResultsN;
  437. DWORD ret;
  438. handle_t hBindTemp = g_hBind;
  439. WINSINTF_BIND_DATA_T BindDataTemp = g_BindData;
  440. LPWSTR wszStartIp = NULL;
  441. if( pStartIp is NULL )
  442. return;
  443. wszStartIp = WinsOemToUnicode(pStartIp, NULL);
  444. if( wszStartIp is NULL )
  445. {
  446. DisplayMessage(g_hModule,
  447. EMSG_WINS_OUT_OF_MEMORY);
  448. return;
  449. }
  450. //
  451. // Get the OV table from this server
  452. //
  453. if (NO_ERROR isnot (Status = GetStatus(TRUE, &ResultsN, TRUE, FALSE, pStartIp)) )
  454. {
  455. DisplayErrorMessage(EMSG_SRVR_CHECK_VERSION,
  456. Status);
  457. WinsFreeMemory(wszStartIp);
  458. wszStartIp = NULL;
  459. return;
  460. }
  461. else
  462. {
  463. DisplayMessage(g_hModule,
  464. MSG_WINS_GETSTATUS_SUCCESS);
  465. DisplayMessage(g_hModule,
  466. WINS_FORMAT_LINE);
  467. }
  468. MasterOwners = NoOfOwners = ResultsN.NoOfOwners;
  469. pMasterMaps = pAddVersMaps = ResultsN.pAddVersMaps;
  470. ret = InitLATable(pAddVersMaps, 0, NoOfOwners);
  471. if( LA_Table is NULL )
  472. {
  473. DisplayMessage(g_hModule,
  474. EMSG_WINS_OUT_OF_MEMORY);
  475. WinsFreeMemory(wszStartIp);
  476. wszStartIp = NULL;
  477. return;
  478. }
  479. if( SO_Table is NULL )
  480. {
  481. DisplayMessage(g_hModule,
  482. EMSG_WINS_OUT_OF_MEMORY);
  483. FreeLATable(MAX_WINS);
  484. WinsFreeMemory(wszStartIp);
  485. wszStartIp = NULL;
  486. return;
  487. }
  488. AddSOTableEntry(wszStartIp, pMasterMaps, NoOfOwners, MasterOwners);
  489. if( ResultsN.pAddVersMaps )
  490. {
  491. WinsFreeMem(ResultsN.pAddVersMaps);
  492. ResultsN.pAddVersMaps = NULL;
  493. }
  494. //
  495. // For each server X (other than Start addr) in the LA table:
  496. //
  497. for ( i = 0; i < MasterOwners; i++)
  498. {
  499. LPSTR pszName = NULL;
  500. if( wcscmp(LA_Table[i], wszStartIp) is 0 )
  501. {
  502. continue;
  503. }
  504. //
  505. // Get X's OV table
  506. //
  507. pszName = WinsUnicodeToOem(LA_Table[i], NULL);
  508. if( pszName is NULL )
  509. {
  510. DisplayMessage(g_hModule,
  511. EMSG_WINS_OUT_OF_MEMORY);
  512. if( SO_Table )
  513. {
  514. FreeSOTable(MAX_WINS+1);
  515. }
  516. if( wszStartIp )
  517. {
  518. WinsFreeMemory(wszStartIp);
  519. wszStartIp = NULL;
  520. }
  521. if( LA_Table )
  522. {
  523. FreeLATable(MAX_WINS);
  524. }
  525. return;
  526. }
  527. if( NO_ERROR isnot (Status = GetStatus(TRUE, &ResultsN, TRUE, FALSE, pszName) ) )
  528. {
  529. RemoveFromSOTable(LA_Table[i], MasterOwners);
  530. if( pszName )
  531. {
  532. WinsFreeMemory(pszName);
  533. pszName = NULL;
  534. }
  535. if( ResultsN.pAddVersMaps )
  536. {
  537. WinsFreeMem(ResultsN.pAddVersMaps);
  538. ResultsN.pAddVersMaps = NULL;
  539. }
  540. DisplayErrorMessage(EMSG_WINS_GETSTATUS_FAILED,
  541. Status);
  542. continue;
  543. }
  544. else
  545. {
  546. DisplayMessage(g_hModule,
  547. MSG_WINS_GETSTATUS_SUCCESS);
  548. }
  549. if (MasterOwners < ResultsN.NoOfOwners)
  550. {
  551. ret = InitLATable(ResultsN.pAddVersMaps, MasterOwners, ResultsN.NoOfOwners);
  552. if( LA_Table is NULL or
  553. SO_Table is NULL )
  554. {
  555. DisplayMessage(g_hModule,
  556. EMSG_WINS_OUT_OF_MEMORY);
  557. if( pszName )
  558. {
  559. WinsFreeMemory(pszName);
  560. pszName = NULL;
  561. }
  562. if( ResultsN.pAddVersMaps )
  563. {
  564. WinsFreeMem(ResultsN.pAddVersMaps);
  565. ResultsN.pAddVersMaps = NULL;
  566. }
  567. if( SO_Table )
  568. {
  569. WinsFreeMemory(SO_Table);
  570. SO_Table = NULL;
  571. }
  572. if( LA_Table )
  573. {
  574. WinsFreeMemory(LA_Table);
  575. LA_Table = NULL;
  576. }
  577. if( wszStartIp )
  578. {
  579. WinsFreeMemory(wszStartIp);
  580. wszStartIp = NULL;
  581. }
  582. return;
  583. }
  584. MasterOwners = ret;
  585. }
  586. //
  587. // Place entry in the SO Table in proper order
  588. //
  589. AddSOTableEntry(LA_Table[i], ResultsN.pAddVersMaps, ResultsN.NoOfOwners, MasterOwners);
  590. if( pszName )
  591. {
  592. WinsFreeMemory(pszName);
  593. pszName = NULL;
  594. }
  595. if( ResultsN.pAddVersMaps )
  596. {
  597. WinsFreeMem(ResultsN.pAddVersMaps);
  598. ResultsN.pAddVersMaps = NULL;
  599. }
  600. }
  601. //
  602. // Check if diagonal elements in the [SO] table are the highest in their cols.
  603. //
  604. CheckSOTableConsistency(MasterOwners);
  605. DumpSOTable(MasterOwners,
  606. fFile,
  607. pFile);
  608. //
  609. // Destroy SO table
  610. //
  611. FreeSOTable(MasterOwners+1);
  612. FreeLATable(MasterOwners);
  613. }