Leaked source code of windows server 2003
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.

731 lines
17 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. // clean out memory
  383. WinsFreeMemory(pstr);
  384. //
  385. // Place only a non-deleted entry
  386. //
  387. if (!((pMasterMaps->VersNo.HighPart == MAXLONG) &&
  388. (pMasterMaps->VersNo.LowPart == MAXULONG))) {
  389. //
  390. // Also if the entry above us was 0, write 0 there so as to make the fail case stand out
  391. //
  392. if (Row && SO_Table[Row-1][col].QuadPart == 0)
  393. {
  394. SO_Table[Row][col].QuadPart = 0;
  395. }
  396. else
  397. {
  398. SO_Table[Row][col] = pMasterMaps->VersNo;
  399. }
  400. }
  401. }
  402. }
  403. VOID
  404. RemoveFromSOTable(
  405. IN LPWSTR IpAddr,
  406. IN DWORD MasterOwners
  407. )
  408. {
  409. ULONG i;
  410. LONG Row;
  411. struct in_addr InAddr;
  412. Row = IPToIndex(IpAddr, MasterOwners);
  413. //
  414. // Mark the row and col as down (0's)
  415. //
  416. for (i = 0; i < MasterOwners; i++)
  417. {
  418. SO_Table[Row][i].QuadPart = SO_Table[i][Row].QuadPart = 0;
  419. }
  420. }
  421. //
  422. // Get the <owner address> - <version #> [OV table] mapping tables from each WINS server on the net and check for inconsistencies.
  423. //
  424. VOID
  425. CheckVersionNumbers(
  426. IN LPCSTR pStartIp,
  427. IN BOOL fFile,
  428. OUT FILE * pFile
  429. )
  430. {
  431. DWORD Status = NO_ERROR;
  432. ULONG i, k;
  433. PWINSINTF_ADD_VERS_MAP_T pAddVersMaps;
  434. PWINSINTF_ADD_VERS_MAP_T pMasterMaps; // master OV maps used to place into the OV table
  435. DWORD NoOfOwners=0;
  436. DWORD MasterOwners=0;
  437. struct in_addr InAddr;
  438. WINSINTF_RESULTS_NEW_T ResultsN;
  439. DWORD ret;
  440. handle_t hBindTemp = g_hBind;
  441. WINSINTF_BIND_DATA_T BindDataTemp = g_BindData;
  442. LPWSTR wszStartIp = NULL;
  443. if( pStartIp is NULL )
  444. return;
  445. wszStartIp = WinsOemToUnicode(pStartIp, NULL);
  446. if( wszStartIp is NULL )
  447. {
  448. DisplayMessage(g_hModule,
  449. EMSG_WINS_OUT_OF_MEMORY);
  450. return;
  451. }
  452. //
  453. // Get the OV table from this server
  454. //
  455. if (NO_ERROR isnot (Status = GetStatus(TRUE, &ResultsN, TRUE, FALSE, pStartIp)) )
  456. {
  457. DisplayErrorMessage(EMSG_SRVR_CHECK_VERSION,
  458. Status);
  459. WinsFreeMemory(wszStartIp);
  460. wszStartIp = NULL;
  461. return;
  462. }
  463. else
  464. {
  465. DisplayMessage(g_hModule,
  466. MSG_WINS_GETSTATUS_SUCCESS);
  467. DisplayMessage(g_hModule,
  468. WINS_FORMAT_LINE);
  469. }
  470. MasterOwners = NoOfOwners = ResultsN.NoOfOwners;
  471. pMasterMaps = pAddVersMaps = ResultsN.pAddVersMaps;
  472. ret = InitLATable(pAddVersMaps, 0, NoOfOwners);
  473. if( LA_Table is NULL )
  474. {
  475. DisplayMessage(g_hModule,
  476. EMSG_WINS_OUT_OF_MEMORY);
  477. WinsFreeMemory(wszStartIp);
  478. wszStartIp = NULL;
  479. return;
  480. }
  481. if( SO_Table is NULL )
  482. {
  483. DisplayMessage(g_hModule,
  484. EMSG_WINS_OUT_OF_MEMORY);
  485. FreeLATable(MAX_WINS);
  486. WinsFreeMemory(wszStartIp);
  487. wszStartIp = NULL;
  488. return;
  489. }
  490. AddSOTableEntry(wszStartIp, pMasterMaps, NoOfOwners, MasterOwners);
  491. if( ResultsN.pAddVersMaps )
  492. {
  493. WinsFreeMem(ResultsN.pAddVersMaps);
  494. ResultsN.pAddVersMaps = NULL;
  495. }
  496. //
  497. // For each server X (other than Start addr) in the LA table:
  498. //
  499. for ( i = 0; i < MasterOwners; i++)
  500. {
  501. LPSTR pszName = NULL;
  502. if( wcscmp(LA_Table[i], wszStartIp) is 0 )
  503. {
  504. continue;
  505. }
  506. //
  507. // Get X's OV table
  508. //
  509. pszName = WinsUnicodeToOem(LA_Table[i], NULL);
  510. if( pszName is NULL )
  511. {
  512. DisplayMessage(g_hModule,
  513. EMSG_WINS_OUT_OF_MEMORY);
  514. if( SO_Table )
  515. {
  516. FreeSOTable(MAX_WINS+1);
  517. }
  518. if( wszStartIp )
  519. {
  520. WinsFreeMemory(wszStartIp);
  521. wszStartIp = NULL;
  522. }
  523. if( LA_Table )
  524. {
  525. FreeLATable(MAX_WINS);
  526. }
  527. return;
  528. }
  529. if( NO_ERROR isnot (Status = GetStatus(TRUE, &ResultsN, TRUE, FALSE, pszName) ) )
  530. {
  531. RemoveFromSOTable(LA_Table[i], MasterOwners);
  532. if( pszName )
  533. {
  534. WinsFreeMemory(pszName);
  535. pszName = NULL;
  536. }
  537. if( ResultsN.pAddVersMaps )
  538. {
  539. WinsFreeMem(ResultsN.pAddVersMaps);
  540. ResultsN.pAddVersMaps = NULL;
  541. }
  542. DisplayErrorMessage(EMSG_WINS_GETSTATUS_FAILED,
  543. Status);
  544. continue;
  545. }
  546. else
  547. {
  548. DisplayMessage(g_hModule,
  549. MSG_WINS_GETSTATUS_SUCCESS);
  550. }
  551. if (MasterOwners < ResultsN.NoOfOwners)
  552. {
  553. ret = InitLATable(ResultsN.pAddVersMaps, MasterOwners, ResultsN.NoOfOwners);
  554. if( LA_Table is NULL or
  555. SO_Table is NULL )
  556. {
  557. DisplayMessage(g_hModule,
  558. EMSG_WINS_OUT_OF_MEMORY);
  559. if( pszName )
  560. {
  561. WinsFreeMemory(pszName);
  562. pszName = NULL;
  563. }
  564. if( ResultsN.pAddVersMaps )
  565. {
  566. WinsFreeMem(ResultsN.pAddVersMaps);
  567. ResultsN.pAddVersMaps = NULL;
  568. }
  569. if( SO_Table )
  570. {
  571. WinsFreeMemory(SO_Table);
  572. SO_Table = NULL;
  573. }
  574. if( LA_Table )
  575. {
  576. WinsFreeMemory(LA_Table);
  577. LA_Table = NULL;
  578. }
  579. if( wszStartIp )
  580. {
  581. WinsFreeMemory(wszStartIp);
  582. wszStartIp = NULL;
  583. }
  584. return;
  585. }
  586. MasterOwners = ret;
  587. }
  588. //
  589. // Place entry in the SO Table in proper order
  590. //
  591. AddSOTableEntry(LA_Table[i], ResultsN.pAddVersMaps, ResultsN.NoOfOwners, MasterOwners);
  592. if( pszName )
  593. {
  594. WinsFreeMemory(pszName);
  595. pszName = NULL;
  596. }
  597. if( ResultsN.pAddVersMaps )
  598. {
  599. WinsFreeMem(ResultsN.pAddVersMaps);
  600. ResultsN.pAddVersMaps = NULL;
  601. }
  602. }
  603. //
  604. // Check if diagonal elements in the [SO] table are the highest in their cols.
  605. //
  606. CheckSOTableConsistency(MasterOwners);
  607. DumpSOTable(MasterOwners,
  608. fFile,
  609. pFile);
  610. //
  611. // Destroy SO table
  612. //
  613. FreeSOTable(MasterOwners+1);
  614. FreeLATable(MasterOwners);
  615. }