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.

1699 lines
45 KiB

  1. /**********************************************************************/
  2. /** Microsoft Windows/NT **/
  3. /** Copyright(c) Microsoft Corporation, 1997 - 1999 -99 **/
  4. /**********************************************************************/
  5. /*
  6. verify.c
  7. Comment goes here
  8. FILE HISTORY:
  9. */
  10. #include <stdlib.h>
  11. #include <stdio.h>
  12. #include <string.h>
  13. #include "tchar.h"
  14. #include <nt.h>
  15. #include <ntrtl.h>
  16. #include <nturtl.h>
  17. #include <wtypes.h>
  18. #include <fcntl.h>
  19. #include <ctype.h>
  20. #include <windows.h>
  21. #include <windowsx.h>
  22. #include <tdi.h>
  23. #include <winsock.h>
  24. #include <wsahelp.h>
  25. #include <nameser.h>
  26. #include <resolve.h>
  27. #include <nb30.h>
  28. #include <nbtioctl.h>
  29. #define WINS_CLIENT_APIS
  30. #include "winsintf.h"
  31. #include "resource.h"
  32. #include "verify.h"
  33. //
  34. // The format of Adapter Status responses
  35. //
  36. typedef struct
  37. {
  38. ADAPTER_STATUS AdapterInfo;
  39. NAME_BUFFER Names[32];
  40. } tADAPTERSTATUS;
  41. #define WINSTEST_FOUND 0
  42. #define WINSTEST_NOT_FOUND 1
  43. #define WINSTEST_NO_RESPONSE 2
  44. #define WINSTEST_VERIFIED 0
  45. #define WINSTEST_OUT_OF_MEMORY 3
  46. #define WINSTEST_BAD_IP_ADDRESS 4
  47. #define WINSTEST_HOST_NOT_FOUND 5
  48. #define WINSTEST_NOT_VERIFIED 6
  49. #define WINSTEST_INVALID_ARG 7
  50. #define WINSTEST_OPEN_FAILED 8
  51. TCHAR *messages[] = {
  52. L"success",
  53. L"name not found",
  54. L"no response",
  55. L"out of memory",
  56. L"bad ip address",
  57. L"host not found",
  58. L"host address not verified",
  59. L"invalid argument",
  60. L"failed to open NBT driver"
  61. };
  62. #define MAX_NB_NAMES 1000
  63. #define MAX_SERVERS 1000
  64. #define MAX_SIZE 1024
  65. SOCKET sd;
  66. WSADATA WsaData;
  67. HWND g_wndDlg = NULL;
  68. HWND g_hwndParent = NULL;
  69. HANDLE g_hThread = NULL;
  70. HINSTANCE g_hInstance = NULL;
  71. HRESULT foo;
  72. struct sockaddr_in myad;
  73. struct sockaddr_in recvad;
  74. int addrlen;
  75. u_short TranID;
  76. u_long NonBlocking = 1;
  77. int NumWinServers = 0;
  78. int NumNBNames = 0;
  79. u_char * NBNames[MAX_NB_NAMES];
  80. u_long VerifiedAddress[MAX_NB_NAMES];
  81. //char lpResults[MAX_SIZE];
  82. //TCHAR lpResults[MAX_SIZE];
  83. //lpResults = (char*) malloc (64536);
  84. WINSERVERS WinServers[MAX_SERVERS];
  85. #define NBT_NONCODED_NMSZ 17
  86. #define NBT_NAMESIZE 34
  87. ULONG NetbtIpAddress;
  88. CHAR pScope[128];
  89. NTSTATUS
  90. DeviceIoCtrl(
  91. IN HANDLE fd,
  92. IN PVOID ReturnBuffer,
  93. IN ULONG BufferSize,
  94. IN ULONG Ioctl,
  95. IN PVOID pInput,
  96. IN ULONG SizeInput
  97. );
  98. INT_PTR CALLBACK
  99. dlgProc(
  100. HWND hWnd,
  101. UINT Message,
  102. WPARAM wParam,
  103. LPARAM lParam
  104. )
  105. {
  106. int ntest;
  107. switch (Message)
  108. {
  109. case WM_COMMAND:
  110. switch (LOWORD(wParam))
  111. {
  112. case IDCANCEL:
  113. EndDialog(hWnd, IDCANCEL);
  114. return TRUE;
  115. }
  116. break;
  117. case WM_INITDIALOG:
  118. g_wndDlg = hWnd;
  119. break;
  120. default:
  121. return FALSE;
  122. }
  123. return TRUE;
  124. }
  125. void ToWCS(LPCSTR szMBCSString, LPWSTR lpWideString)
  126. {
  127. int nResult;
  128. // determone the size first
  129. nResult = MultiByteToWideChar(
  130. CP_ACP,
  131. MB_COMPOSITE,
  132. szMBCSString,
  133. -1,
  134. lpWideString,
  135. 0);
  136. MultiByteToWideChar(
  137. CP_ACP,
  138. MB_COMPOSITE,
  139. szMBCSString,
  140. -1,
  141. lpWideString,
  142. nResult);
  143. lpWideString[nResult + 1] = '\0';
  144. }
  145. void AddStatusMessageW(LPCWSTR pszMessage)
  146. {
  147. HWND hwndEdit;
  148. MSG msg;
  149. hwndEdit = GetDlgItem(g_wndDlg, IDC_EDIT_MESSAGE);
  150. SetFocus (hwndEdit);
  151. SendMessage (hwndEdit, EM_SETSEL, -1, -1);
  152. SendMessage (hwndEdit, EM_REPLACESEL, 0, (LPARAM) ((LPCTSTR) pszMessage));
  153. // give the window some time to process the message
  154. while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
  155. {
  156. TranslateMessage(&msg);
  157. DispatchMessage(&msg);
  158. }
  159. }
  160. void AddStatusMessage(LPCSTR pszMessage)
  161. {
  162. WCHAR szBuffer[MAX_SIZE];
  163. ToWCS(pszMessage, szBuffer);
  164. AddStatusMessageW(szBuffer);
  165. }
  166. DWORD
  167. GetStatus(
  168. BOOL fPrint,
  169. LPVOID pResultsA,
  170. BOOL fNew,
  171. BOOL fShort,
  172. PUCHAR IpAddr
  173. )
  174. {
  175. DWORD Status, i;
  176. struct in_addr InAddr;
  177. PWINSINTF_RESULTS_T pResults = pResultsA;
  178. PWINSINTF_RESULTS_NEW_T pResultsN = pResultsA;
  179. PWINSINTF_ADD_VERS_MAP_T pAddVersMaps;
  180. DWORD NoOfOwners;
  181. handle_t BindHdl;
  182. WINSINTF_BIND_DATA_T BindData;
  183. char lpResults[MAX_SIZE] = {0};
  184. TCHAR szErrMsg[MAX_SIZE];
  185. WCHAR WcharString1[WINSINTF_MAX_NAME_SIZE] = {0};
  186. int nSize = MultiByteToWideChar(CP_ACP,
  187. MB_PRECOMPOSED,
  188. IpAddr,
  189. -1,
  190. WcharString1,
  191. 0
  192. );
  193. MultiByteToWideChar(CP_ACP,
  194. MB_PRECOMPOSED,
  195. IpAddr,
  196. -1,
  197. WcharString1,
  198. nSize
  199. );
  200. WcharString1[nSize] = '\0';
  201. BindData.fTcpIp = TRUE;
  202. BindData.pServerAdd = (LPSTR) (LPTSTR) WcharString1;
  203. strcpy(lpResults, "");
  204. strcat(lpResults, "*****\r\n" );
  205. strcat(lpResults, "Getting map table from " );
  206. strcat(lpResults, IpAddr);
  207. strcat(lpResults, "\r\n");
  208. AddStatusMessage(lpResults);
  209. BindHdl = WinsBind(&BindData);
  210. if (BindHdl == NULL)
  211. {
  212. strcpy(lpResults, "");
  213. strcat(lpResults, "Unable to bind to " );
  214. strcat(lpResults, IpAddr);
  215. strcat(lpResults, "\r\n");
  216. AddStatusMessage(lpResults);
  217. return STATUS_SUCCESS;
  218. }
  219. if (!fNew)
  220. {
  221. #ifdef WINS_CLIENT_APIS
  222. Status = WinsStatus(BindHdl, WINSINTF_E_CONFIG, pResultsA);
  223. #else
  224. Status = WinsStatus(WINSINTF_E_CONFIG, pResultsA);
  225. #endif WINS_CLIENT_APIS
  226. }
  227. else
  228. {
  229. pResultsN->pAddVersMaps = NULL;
  230. #ifdef WINS_CLIENT_APIS
  231. Status = WinsStatusNew(BindHdl, WINSINTF_E_CONFIG, pResultsN);
  232. #else
  233. Status = WinsStatusNew(WINSINTF_E_CONFIG, pResultsN);
  234. #endif WINS_CLIENT_APIS
  235. }
  236. if (Status == 0)
  237. {
  238. //strcpy(lpResults, "");
  239. //strcat(lpResults, "SUCCESS \r\n");
  240. //AddStatusMessage(lpResults);
  241. }
  242. else
  243. {
  244. wsprintfA(lpResults, "Get Wins Status failed! Error: %d\r\n", Status);
  245. AddStatusMessage(lpResults);
  246. }
  247. if (Status == WINSINTF_SUCCESS)
  248. {
  249. if (fPrint)
  250. {
  251. if (!fNew)
  252. {
  253. pAddVersMaps = pResults->AddVersMaps;
  254. NoOfOwners = pResults->NoOfOwners;
  255. }
  256. else
  257. {
  258. pAddVersMaps = pResultsN->pAddVersMaps;
  259. NoOfOwners = pResultsN->NoOfOwners;
  260. }
  261. if (NoOfOwners == 0)
  262. {
  263. strcpy(lpResults, "");
  264. strcat(lpResults, "The database list of owners is empty.\r\n");
  265. AddStatusMessage(lpResults);
  266. Status = WINSINTF_FAILURE;
  267. }
  268. }
  269. }
  270. WinsUnbind(&BindData, BindHdl);
  271. return(Status);
  272. }
  273. //------------------------------------------------------------------------
  274. NTSTATUS
  275. GetIpAddress(
  276. IN HANDLE fd,
  277. OUT PULONG pIpAddress
  278. )
  279. /*++
  280. Routine Description:
  281. This function calls into netbt to get the ip address.
  282. Arguments:
  283. fd - file handle to netbt
  284. pIpAddress - the ip address returned
  285. Return Value:
  286. ntstatus
  287. History:
  288. 27-Dec-1995 CDermody copied from nbtstat.c
  289. --*/
  290. {
  291. NTSTATUS status;
  292. ULONG BufferSize=100;
  293. PVOID pBuffer;
  294. pBuffer = LocalAlloc(LMEM_FIXED,BufferSize);
  295. if (!pBuffer)
  296. {
  297. return(STATUS_INSUFFICIENT_RESOURCES);
  298. }
  299. status = DeviceIoCtrl(fd,
  300. pBuffer,
  301. BufferSize,
  302. IOCTL_NETBT_GET_IP_ADDRS,
  303. NULL,
  304. 0);
  305. if (NT_SUCCESS(status))
  306. {
  307. *pIpAddress = *(ULONG *)pBuffer;
  308. }
  309. else
  310. {
  311. *pIpAddress = 0;
  312. }
  313. LocalFree(pBuffer);
  314. return(status);
  315. }
  316. //------------------------------------------------------------------------
  317. NTSTATUS
  318. GetInterfaceList
  319. (
  320. char pDeviceName[][MAX_NAME+1]
  321. )
  322. {
  323. HANDLE StreamHandle;
  324. OBJECT_ATTRIBUTES ObjectAttributes;
  325. IO_STATUS_BLOCK IoStatusBlock;
  326. STRING name_string, AnsiString;
  327. UNICODE_STRING uc_name_string;
  328. NTSTATUS status;
  329. char pNbtWinsDeviceName[MAX_NAME] = "\\Device\\NetBt_Wins_Export";
  330. PUCHAR SubKeyParms = "system\\currentcontrolset\\services\\netbt\\parameters";
  331. PUCHAR Scope = "ScopeId";
  332. CHAR pScopeBuffer[BUFF_SIZE];
  333. HKEY Key;
  334. LONG Type;
  335. ULONG size;
  336. NETBT_INTERFACE_INFO *pInterfaceInfo;
  337. ULONG InterfaceInfoSize = 10 * sizeof(NETBT_ADAPTER_INDEX_MAP) + sizeof(ULONG);
  338. PVOID pInput = NULL;
  339. ULONG SizeInput = 0;
  340. LONG i, index = 0;
  341. pInterfaceInfo = LocalAlloc(LMEM_FIXED,InterfaceInfoSize);
  342. if (!pInterfaceInfo)
  343. {
  344. return(STATUS_INSUFFICIENT_RESOURCES);
  345. }
  346. RtlInitString(&name_string, pNbtWinsDeviceName);
  347. RtlAnsiStringToUnicodeString(&uc_name_string, &name_string, TRUE);
  348. InitializeObjectAttributes(
  349. &ObjectAttributes,
  350. &uc_name_string,
  351. OBJ_CASE_INSENSITIVE,
  352. (HANDLE) NULL,
  353. (PSECURITY_DESCRIPTOR) NULL
  354. );
  355. status = NtCreateFile (&StreamHandle,
  356. SYNCHRONIZE | FILE_READ_DATA | FILE_WRITE_DATA,
  357. &ObjectAttributes,
  358. &IoStatusBlock,
  359. NULL,
  360. FILE_ATTRIBUTE_NORMAL,
  361. FILE_SHARE_READ | FILE_SHARE_WRITE,
  362. FILE_OPEN_IF,
  363. 0,
  364. NULL,
  365. 0);
  366. RtlFreeUnicodeString(&uc_name_string);
  367. if (NT_SUCCESS (status))
  368. {
  369. do
  370. {
  371. status = DeviceIoCtrl(StreamHandle,
  372. pInterfaceInfo,
  373. InterfaceInfoSize,
  374. IOCTL_NETBT_GET_INTERFACE_INFO,
  375. pInput,
  376. SizeInput);
  377. if (status == STATUS_BUFFER_OVERFLOW)
  378. {
  379. LocalFree(pInterfaceInfo);
  380. InterfaceInfoSize *= 2;
  381. pInterfaceInfo = LocalAlloc(LMEM_FIXED,InterfaceInfoSize);
  382. if (!pInterfaceInfo || (InterfaceInfoSize == 0xFFFF))
  383. {
  384. NtClose(StreamHandle);
  385. //NlsPerror(COMMON_UNABLE_TO_ALLOCATE_PACKET,0);
  386. return(STATUS_INSUFFICIENT_RESOURCES);
  387. }
  388. }
  389. else if (!NT_SUCCESS (status))
  390. {
  391. NtClose(StreamHandle);
  392. return(status);
  393. }
  394. } while (status == STATUS_BUFFER_OVERFLOW);
  395. NtClose (StreamHandle);
  396. for (i = 0; i<pInterfaceInfo->NumAdapters; i++)
  397. {
  398. RtlInitString(&name_string, NULL);
  399. RtlInitUnicodeString(&uc_name_string, pInterfaceInfo->Adapter[i].Name);
  400. if (NT_SUCCESS(RtlUnicodeStringToAnsiString(&name_string, &uc_name_string, TRUE)))
  401. {
  402. size = (name_string.Length > MAX_NAME) ? MAX_NAME : name_string.Length;
  403. strncpy(pDeviceName[index], name_string.Buffer, size);
  404. pDeviceName[index][size] = '\0';
  405. RtlFreeAnsiString (&name_string);
  406. index++;
  407. }
  408. }
  409. //
  410. // NULL out the next device string ptr
  411. //
  412. if (index < NBT_MAXIMUM_BINDINGS)
  413. {
  414. pDeviceName[index][0] = '\0';
  415. }
  416. //
  417. // Read the ScopeId key!
  418. //
  419. size = BUFF_SIZE;
  420. *pScope = '\0'; // By default
  421. status = RegOpenKeyExA(HKEY_LOCAL_MACHINE,
  422. SubKeyParms,
  423. 0,
  424. KEY_READ,
  425. &Key);
  426. if (status == ERROR_SUCCESS)
  427. {
  428. // now read the Scope key
  429. status = RegQueryValueExA(Key, Scope, NULL, &Type, pScopeBuffer, &size);
  430. if (status == ERROR_SUCCESS)
  431. {
  432. strcpy(pScope,pScopeBuffer);
  433. }
  434. status = RegCloseKey(Key);
  435. }
  436. status = STATUS_SUCCESS;
  437. }
  438. return status;
  439. }
  440. //------------------------------------------------------------------------
  441. NTSTATUS
  442. OpenNbt(
  443. IN char path[][MAX_NAME+1],
  444. OUT PHANDLE pHandle,
  445. int max_paths
  446. )
  447. {
  448. HANDLE StreamHandle;
  449. OBJECT_ATTRIBUTES ObjectAttributes;
  450. IO_STATUS_BLOCK IoStatusBlock;
  451. STRING name_string;
  452. UNICODE_STRING uc_name_string;
  453. NTSTATUS status;
  454. LONG index=0;
  455. ASSERT ( max_paths <= NBT_MAXIMUM_BINDINGS );
  456. while ((path[index][0] != '\0') && (index < max_paths))
  457. {
  458. RtlInitString(&name_string, path[index]);
  459. RtlAnsiStringToUnicodeString(&uc_name_string, &name_string, TRUE);
  460. InitializeObjectAttributes(
  461. &ObjectAttributes,
  462. &uc_name_string,
  463. OBJ_CASE_INSENSITIVE,
  464. (HANDLE) NULL,
  465. (PSECURITY_DESCRIPTOR) NULL
  466. );
  467. status =
  468. NtCreateFile(
  469. &StreamHandle,
  470. SYNCHRONIZE | FILE_READ_DATA | FILE_WRITE_DATA,
  471. &ObjectAttributes,
  472. &IoStatusBlock,
  473. NULL,
  474. FILE_ATTRIBUTE_NORMAL,
  475. FILE_SHARE_READ | FILE_SHARE_WRITE,
  476. FILE_OPEN_IF,
  477. 0,
  478. NULL,
  479. 0);
  480. RtlFreeUnicodeString(&uc_name_string);
  481. if (NT_SUCCESS(status))
  482. {
  483. *pHandle = StreamHandle;
  484. return(status);
  485. }
  486. ++index;
  487. }
  488. return (status);
  489. } // s_open
  490. //------------------------------------------------------------------------
  491. NTSTATUS
  492. DeviceIoCtrl(
  493. IN HANDLE fd,
  494. IN PVOID ReturnBuffer,
  495. IN ULONG BufferSize,
  496. IN ULONG Ioctl,
  497. IN PVOID pInput,
  498. IN ULONG SizeInput
  499. )
  500. /*++
  501. Routine Description:
  502. This procedure performs an ioctl(I_STR) on a stream.
  503. Arguments:
  504. fd - NT file handle
  505. iocp - pointer to a strioctl structure
  506. Return Value:
  507. 0 if successful, non-zero otherwise.
  508. History:
  509. 27-Dec-1995 CDermody copied from nbtstat.c
  510. --*/
  511. {
  512. NTSTATUS status;
  513. int retval;
  514. ULONG QueryType;
  515. IO_STATUS_BLOCK iosb;
  516. status = NtDeviceIoControlFile(
  517. fd, // Handle
  518. NULL, // Event
  519. NULL, // ApcRoutine
  520. NULL, // ApcContext
  521. &iosb, // IoStatusBlock
  522. Ioctl, // IoControlCode
  523. pInput, // InputBuffer
  524. SizeInput, // InputBufferSize
  525. (PVOID) ReturnBuffer, // OutputBuffer
  526. BufferSize); // OutputBufferSize
  527. if (status == STATUS_PENDING)
  528. {
  529. status = NtWaitForSingleObject(
  530. fd, // Handle
  531. TRUE, // Alertable
  532. NULL); // Timeout
  533. if (NT_SUCCESS(status))
  534. {
  535. status = iosb.Status;
  536. }
  537. }
  538. return(status);
  539. }
  540. /****************************************************************************/
  541. /* CheckRemoteTable */
  542. /* */
  543. /* This routine does an adapter status query to get the remote name table */
  544. /* then checks to see if a netbios name is contained in it. */
  545. /* */
  546. /* Parameters: */
  547. /* RemoteName, the IP address (asci nn.nn.nn.nn format) of a server to */
  548. /* query. */
  549. /* SearchName, a net bios name. */
  550. /* */
  551. /* Return: */
  552. /* WINSTEST_VERIFIED The name exists in the remote name table */
  553. /* WINSTEST_NOT_VERIFIED The name does not exist in the remote table */
  554. /* WINSTEST_BAD_IP_ADDRESS inet_addr could not convert the ip address */
  555. /* character string. */
  556. /* WINSTEST_HOST_NOT_FOUND Could not reach ip address */
  557. /* WINSTEST_OUT_OF_MEMORY Out of memory */
  558. /* History: */
  559. /* 27-Dec-1995 CDermody created following example of nbtstat.c */
  560. /****************************************************************************/
  561. int
  562. CheckRemoteTable(
  563. IN HANDLE fd,
  564. IN PCHAR RemoteName,
  565. IN PCHAR SearchName
  566. )
  567. {
  568. LONG Count;
  569. LONG i;
  570. PVOID pBuffer;
  571. ULONG BufferSize=600;
  572. NTSTATUS status;
  573. tADAPTERSTATUS *pAdapterStatus;
  574. NAME_BUFFER *pNames;
  575. CHAR MacAddress[20];
  576. tIPANDNAMEINFO *pIpAndNameInfo;
  577. ULONG SizeInput;
  578. ULONG IpAddress;
  579. USHORT BytesToCopy;
  580. pBuffer = LocalAlloc(LMEM_FIXED,BufferSize);
  581. if (!pBuffer)
  582. {
  583. return(WINSTEST_OUT_OF_MEMORY);
  584. }
  585. status = STATUS_BUFFER_OVERFLOW;
  586. pIpAndNameInfo = LocalAlloc(LMEM_FIXED,sizeof(tIPANDNAMEINFO));
  587. if (!pIpAndNameInfo)
  588. {
  589. LocalFree(pBuffer);
  590. return(WINSTEST_OUT_OF_MEMORY);
  591. }
  592. RtlZeroMemory((PVOID)pIpAndNameInfo,sizeof(tIPANDNAMEINFO));
  593. //
  594. // Convert the remote name which is really a dotted decimal ip address
  595. // into a ulong
  596. //
  597. IpAddress = inet_addr(RemoteName);
  598. //
  599. // Don't allow zero for the address since it sends a broadcast and
  600. // every one responds
  601. //
  602. if ((IpAddress == INADDR_NONE) || (IpAddress == 0))
  603. {
  604. LocalFree(pBuffer);
  605. LocalFree(pIpAndNameInfo);
  606. return(WINSTEST_BAD_IP_ADDRESS);
  607. }
  608. pIpAndNameInfo->IpAddress = ntohl(IpAddress);
  609. pIpAndNameInfo->NetbiosAddress.Address[0].Address[0].NetbiosName[0] = '*';
  610. pIpAndNameInfo->NetbiosAddress.TAAddressCount = 1;
  611. pIpAndNameInfo->NetbiosAddress.Address[0].AddressLength
  612. = sizeof(TDI_ADDRESS_NETBIOS);
  613. pIpAndNameInfo->NetbiosAddress.Address[0].AddressType
  614. = TDI_ADDRESS_TYPE_NETBIOS;
  615. pIpAndNameInfo->NetbiosAddress.Address[0].Address[0].NetbiosNameType
  616. = TDI_ADDRESS_NETBIOS_TYPE_UNIQUE;
  617. SizeInput = sizeof(tIPANDNAMEINFO);
  618. while (status == STATUS_BUFFER_OVERFLOW)
  619. {
  620. status = DeviceIoCtrl(fd,
  621. pBuffer,
  622. BufferSize,
  623. IOCTL_NETBT_ADAPTER_STATUS,
  624. pIpAndNameInfo,
  625. SizeInput);
  626. if (status == STATUS_BUFFER_OVERFLOW)
  627. {
  628. LocalFree(pBuffer);
  629. BufferSize *=2;
  630. pBuffer = LocalAlloc(LMEM_FIXED,BufferSize);
  631. if (!pBuffer || (BufferSize == 0xFFFF))
  632. {
  633. LocalFree(pIpAndNameInfo);
  634. return(WINSTEST_OUT_OF_MEMORY);
  635. }
  636. }
  637. }
  638. pAdapterStatus = (tADAPTERSTATUS *)pBuffer;
  639. if ((pAdapterStatus->AdapterInfo.name_count == 0) ||
  640. (status != STATUS_SUCCESS))
  641. {
  642. LocalFree(pIpAndNameInfo);
  643. LocalFree(pBuffer);
  644. return(WINSTEST_HOST_NOT_FOUND);
  645. }
  646. pNames = pAdapterStatus->Names;
  647. Count = pAdapterStatus->AdapterInfo.name_count;
  648. status = 1;
  649. while (Count--)
  650. {
  651. if (0 == _strnicmp(SearchName, pNames->name, strlen(SearchName)))
  652. {
  653. LocalFree(pIpAndNameInfo);
  654. LocalFree(pBuffer);
  655. return WINSTEST_VERIFIED; // found
  656. }
  657. pNames++;
  658. }
  659. LocalFree(pIpAndNameInfo);
  660. LocalFree(pBuffer);
  661. return WINSTEST_NOT_VERIFIED;
  662. }
  663. /****************************************************************************/
  664. /* VerifyRemote */
  665. /* */
  666. /* This routine checks to see if a netbios name is contained in the remote */
  667. /* name table at a given IP address. */
  668. /* */
  669. /* Parameters: */
  670. /* RemoteName, the IP address (asci nn.nn.nn.nn format) of a server to */
  671. /* query. */
  672. /* NBName, a net bios name. */
  673. /* */
  674. /* Return: */
  675. /* WINSTEST_VERIFIED The name exists in the remote name table */
  676. /* WINSTEST_NOT_VERIFIED The name does not exist in the remote table */
  677. /* WINSTEST_BAD_IP_ADDRESS inet_addr could not convert the ip address */
  678. /* character string. */
  679. /* WINSTEST_OPEN_FAILED Could not open NBT driver or could not read */
  680. /* the NBT driver info from the registry. */
  681. /* WINSTEST_HOST_NOT_FOUND Could not reach ip address */
  682. /* WINSTEST_OUT_OF_MEMORY Out of memory */
  683. /* History: */
  684. /* 27-Dec-1995 CDermody created following example of nbtstat.c */
  685. /****************************************************************************/
  686. int VerifyRemote(IN PCHAR RemoteName, IN PCHAR NBName)
  687. {
  688. NTSTATUS status;
  689. LONG interval=-1;
  690. HANDLE nbt = 0;
  691. int nStatus;
  692. int index;
  693. CHAR pDeviceName[NBT_MAXIMUM_BINDINGS+1][MAX_NAME+1];
  694. status = GetInterfaceList(pDeviceName);
  695. if (!NT_SUCCESS(status))
  696. {
  697. return WINSTEST_OPEN_FAILED;
  698. }
  699. for (index = 0; index < NBT_MAXIMUM_BINDINGS && pDeviceName[index][0]; index++)
  700. {
  701. //
  702. // Open the device of the appropriate streams module to start with.
  703. //
  704. status = OpenNbt(&pDeviceName[index], &nbt, NBT_MAXIMUM_BINDINGS-index);
  705. if (!NT_SUCCESS(status))
  706. {
  707. //
  708. // Try the next binding!
  709. //
  710. continue;
  711. }
  712. GetIpAddress(nbt, &NetbtIpAddress);
  713. if (RemoteName[0] == '\0')
  714. return WINSTEST_INVALID_ARG;
  715. nStatus = CheckRemoteTable(nbt,RemoteName,NBName);
  716. if (nStatus == WINSTEST_VERIFIED)
  717. break;
  718. }
  719. return nStatus;
  720. }
  721. /*************************************************************/
  722. /* NBDecode(name,name2) */
  723. /* */
  724. /* This routine decodes a netbios name from level2 to leve1. */
  725. /* name is 16 bytes long, remember that. */
  726. /* */
  727. /*************************************************************/
  728. void
  729. NBDecode(
  730. unsigned char *name,
  731. unsigned char *name2
  732. )
  733. {
  734. int i;
  735. for (i = 0; i < NBT_NONCODED_NMSZ - 1; i++)
  736. {
  737. name[i] = (name2[2*i+1] - 0x41)*(NBT_NONCODED_NMSZ-1) +
  738. (name2[2*i+2] - 0x41);
  739. }
  740. }
  741. /*************************************************************/
  742. /* NBEncode(name2,name) */
  743. /* */
  744. /* This routine code a netbios name from level1 to level2. */
  745. /* name2 has to be NBT_NAMESIZE bytes long, remember that. */
  746. /*************************************************************/
  747. void
  748. NBEncode(
  749. unsigned char *name2,
  750. unsigned char *name
  751. )
  752. {
  753. int i;
  754. name2[0] = 0x20; /* length of first block */
  755. for (i = 0; i < NBT_NONCODED_NMSZ - 1; i++)
  756. {
  757. name2[ 2*i+1 ] = ((name[ i ] >> 4) & 0x0f) + 0x41;
  758. name2[ 2*i+2 ] = (name[ i ] & 0x0f) + 0x41;
  759. }
  760. name2[ NBT_NAMESIZE-1 ] = 0; /* length of next block */
  761. }
  762. ULONG
  763. AddWins(
  764. IN ULONG IPAddr
  765. )
  766. {
  767. INT i;
  768. for (i = 0; i < MAX_SERVERS; i++)
  769. {
  770. if (WinServers[i].Server.s_addr == IPAddr)
  771. {
  772. return 0;
  773. }
  774. if (WinServers[i].Server.s_addr == 0)
  775. {
  776. WinServers[i].Server.s_addr = IPAddr;
  777. NumWinServers++;
  778. return i;
  779. }
  780. }
  781. return 0;
  782. }
  783. VOID
  784. PurgeWinsAddr(
  785. IN ULONG IPAddr
  786. )
  787. {
  788. INT i;
  789. for (i = 0; i < MAX_SERVERS; i++)
  790. {
  791. if (WinServers[i].Server.s_addr == IPAddr)
  792. {
  793. INT j = i + 1;
  794. while (WinServers[j].Server.s_addr)
  795. {
  796. WinServers[j - 1] = WinServers[j];
  797. j++;
  798. }
  799. //
  800. // Zap the last entry
  801. //
  802. WinServers[j - 1].Server.s_addr = 0;
  803. break;
  804. }
  805. }
  806. }
  807. /*******************************************************************/
  808. /* */
  809. /* Initialize the WinServers table and set NumWinServers to count */
  810. /* */
  811. /*******************************************************************/
  812. BOOLEAN
  813. InitServers(char *szServer, BOOL fVerifyWithPartners)
  814. {
  815. FILE * sf = NULL;
  816. int i = 0;
  817. ULONG j = 0;
  818. u_char buffer[100] = {0};
  819. WINSINTF_RESULTS_NEW_T ResultsN;
  820. struct in_addr InAddr;
  821. char szNum[10] = {0};
  822. char lpResults[MAX_SIZE] = {0};
  823. strcpy(buffer, szServer);
  824. //WinServers[i].Server.s_addr = inet_addr(buffer);
  825. InAddr.s_addr = inet_addr(buffer);
  826. AddWins(InAddr.s_addr);
  827. if (fVerifyWithPartners)
  828. {
  829. if (GetStatus(TRUE, &ResultsN, TRUE, FALSE, inet_ntoa(InAddr)))
  830. {
  831. strcpy(lpResults, "");
  832. strcat(lpResults, "Unable to verify against the WINS server: ");
  833. strcat(lpResults, inet_ntoa(InAddr));
  834. strcat(lpResults, "\r\n\r\n");
  835. AddStatusMessage(lpResults);
  836. return FALSE;
  837. }
  838. //
  839. // Enter all the WINS server names into the server table
  840. //
  841. for (j = 0; j < ResultsN.NoOfOwners; j++)
  842. {
  843. //
  844. // Add addresses; check for duplicates
  845. //
  846. struct in_addr InAddr;
  847. InAddr.s_addr = htonl(ResultsN.pAddVersMaps[j].Add.IPAdd);
  848. (VOID)AddWins(htonl(ResultsN.pAddVersMaps[j].Add.IPAdd));
  849. }
  850. //NumWinServers = ResultsN.NoOfOwners;
  851. strcpy(lpResults, "");
  852. _itoa(NumWinServers, szNum, 10);
  853. strcat(lpResults, szNum);
  854. strcat(lpResults, " Wins servers will be Queried:\r\n");
  855. AddStatusMessage(lpResults);
  856. for (i = 0; i < NumWinServers; i++)
  857. {
  858. struct in_addr InAddr;
  859. InAddr.s_addr = WinServers[i].Server.s_addr;
  860. strcpy(lpResults, "");
  861. strcat(lpResults, inet_ntoa(InAddr));
  862. strcat(lpResults,"\r\n");
  863. AddStatusMessage(lpResults);
  864. }
  865. }
  866. return TRUE;
  867. }
  868. /*******************************************************************/
  869. /* */
  870. /* Send a Name Query to a WINS Server */
  871. /* */
  872. /* name is the name to query */
  873. /* winsaddr is the ip address of the wins server to query */
  874. /* TransID is the transaction ID to use for the query */
  875. /* */
  876. /*******************************************************************/
  877. void
  878. _stdcall
  879. SendNameQuery(
  880. unsigned char *name,
  881. u_long winsaddr,
  882. u_short TransID
  883. )
  884. {
  885. struct sockaddr_in destad;
  886. char lpResults[MAX_SIZE] = {0};
  887. char paddedname[NBT_NONCODED_NMSZ];
  888. struct
  889. {
  890. u_short TransactionID;
  891. u_short Flags;
  892. u_short QuestionCount;
  893. u_short AnswerCount;
  894. u_short NSCount;
  895. u_short AdditionalRec;
  896. u_char QuestionName[NBT_NAMESIZE];
  897. u_short QuestionType;
  898. u_short QuestionClass;
  899. } NameQuery;
  900. memset(paddedname, 0x20, sizeof(paddedname));
  901. memcpy(paddedname, name, strlen(name));
  902. NBEncode(NameQuery.QuestionName, paddedname);
  903. NameQuery.TransactionID = htons(TransID);
  904. NameQuery.Flags = htons(0x0100);
  905. NameQuery.QuestionCount = htons(1);
  906. NameQuery.AnswerCount = 0;
  907. NameQuery.NSCount = 0;
  908. NameQuery.AdditionalRec = 0;
  909. NameQuery.QuestionType = htons(0x0020);
  910. NameQuery.QuestionClass = htons(1);
  911. destad.sin_family = AF_INET;
  912. destad.sin_port = htons(137);
  913. destad.sin_addr.s_addr = winsaddr;
  914. if (sendto(sd, (char *)&NameQuery, sizeof(NameQuery), 0,
  915. (struct sockaddr *)&destad, sizeof(destad)) == SOCKET_ERROR)
  916. {
  917. wsprintfA(lpResults, "sendto() failed. Error %d. \r\n", WSAGetLastError());
  918. AddStatusMessage(lpResults);
  919. // exit(1);
  920. return;
  921. }
  922. }
  923. /*******************************************************************/
  924. /* */
  925. /* Wait for a Name Response which matches the Transaction ID */
  926. /* */
  927. /* recvaddr is the ip address returned by the wins server */
  928. /* */
  929. /*******************************************************************/
  930. int
  931. _stdcall
  932. GetNameResponse(
  933. u_long * recvaddr,
  934. u_short TransactionID
  935. )
  936. {
  937. char lpResults[100] = {0};
  938. int i;
  939. int len;
  940. int rslt;
  941. u_long AnswerAddr;
  942. struct sockaddr_in addr;
  943. NameResponse * pNameResponse = NULL;
  944. BYTE Buf[NAME_RESPONSE_BUFFER_SIZE] = {0};
  945. i = 0;
  946. while (i < 15)
  947. {
  948. addrlen = sizeof(addr);
  949. if ((len=recvfrom(sd, (char *) Buf, sizeof(Buf), 0,
  950. (struct sockaddr *)&addr, &addrlen)) < 0)
  951. {
  952. rslt = WSAGetLastError();
  953. if (rslt == WSAEWOULDBLOCK)
  954. {
  955. Sleep(100);
  956. i++;
  957. continue;
  958. }
  959. else
  960. {
  961. wsprintfA(lpResults, "recvfrom() failed. Error %d. \r\n", rslt);
  962. AddStatusMessage(lpResults);
  963. return WINSTEST_NO_RESPONSE;
  964. }
  965. }
  966. pNameResponse = (NameResponse *) Buf;
  967. if (TransactionID == htons(pNameResponse->TransactionID))
  968. {
  969. if (htons(pNameResponse->AnswerCount) == 0)
  970. {
  971. *recvaddr = 0;
  972. return(WINSTEST_NOT_FOUND);
  973. }
  974. AnswerAddr = (pNameResponse->AnswerAddr2 << 16) | pNameResponse->AnswerAddr1;
  975. *recvaddr = AnswerAddr;
  976. return(WINSTEST_FOUND);
  977. }
  978. }
  979. *recvaddr = 0;
  980. return(WINSTEST_NO_RESPONSE);
  981. }
  982. INT
  983. _stdcall
  984. InitNameCheckSocket()
  985. {
  986. char lpResults[MAX_SIZE];
  987. /* Set up a socket to use for querys and responses */
  988. WSAStartup( 0x0101, &WsaData ); // make sure winsock is happy - noop for now
  989. if ((sd = socket( AF_INET, SOCK_DGRAM, 0)) == INVALID_SOCKET)
  990. {
  991. //wsprintfA(lpResults, "socket() failed. Error %d. \r\n", WSAGetLastError());
  992. //AddStatusMessage(lpResults);
  993. return WSAGetLastError();
  994. }
  995. myad.sin_family = AF_INET;
  996. myad.sin_addr.s_addr = INADDR_ANY;
  997. myad.sin_port = htons(0);
  998. if (bind( sd, (struct sockaddr *)&myad, sizeof(myad) ) < 0)
  999. {
  1000. //wsprintfA(lpResults, "bind() failed. Error %d. \r\n", WSAGetLastError());
  1001. //AddStatusMessage(lpResults);
  1002. closesocket( sd );
  1003. return WSAGetLastError();
  1004. }
  1005. if (ioctlsocket(sd, FIONBIO, &NonBlocking) < 0)
  1006. {
  1007. //wsprintfA(lpResults, "ioctlsocket() failed. Error %d. \r\n", WSAGetLastError());
  1008. //AddStatusMessage(lpResults);
  1009. return WSAGetLastError();
  1010. }
  1011. return 0;
  1012. }
  1013. INT
  1014. _stdcall
  1015. CloseNameCheckSocket()
  1016. {
  1017. closesocket(sd);
  1018. WSACleanup();
  1019. return 0;
  1020. }
  1021. DWORD WINAPI ThreadProc(LPVOID pData)
  1022. {
  1023. DialogBox(g_hInstance,
  1024. MAKEINTRESOURCE(IDD_VERSION_CONSIS),
  1025. g_hwndParent,
  1026. dlgProc);
  1027. return 29;
  1028. }
  1029. void CreateConsistencyStatusWindow(HINSTANCE hInstance, HWND hWndParent)
  1030. {
  1031. // dialog creation
  1032. // create a new window if we don't have one or it possibly went away
  1033. DWORD dwId;
  1034. MSG msg;
  1035. g_hInstance = hInstance;
  1036. g_hwndParent = hWndParent;
  1037. if (g_wndDlg && !IsWindow(g_wndDlg))
  1038. {
  1039. CloseHandle(g_hThread);
  1040. g_wndDlg = NULL;
  1041. }
  1042. if (!g_wndDlg)
  1043. {
  1044. g_hThread = CreateThread(NULL, 0, ThreadProc, NULL, 0, &dwId);
  1045. while (g_wndDlg == NULL)
  1046. {
  1047. // give the thread a chance to run
  1048. Sleep(0);
  1049. // since we are all on the same message pump, we need to
  1050. // give the system a chance to handle messages
  1051. while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
  1052. {
  1053. TranslateMessage(&msg);
  1054. DispatchMessage(&msg);
  1055. }
  1056. }
  1057. }
  1058. }
  1059. void DestroyConsistencyStatusWindow()
  1060. {
  1061. BOOL bResult;
  1062. if (IsWindow(g_wndDlg))
  1063. {
  1064. bResult = PostMessage(g_wndDlg, WM_COMMAND, MAKEWPARAM(0, IDCANCEL), 0);
  1065. }
  1066. if (g_wndDlg)
  1067. {
  1068. WaitForSingleObject(g_hThread, 5000);
  1069. CloseHandle(g_hThread);
  1070. g_hThread = NULL;
  1071. g_wndDlg = NULL;
  1072. }
  1073. }
  1074. void EnableConsistencyCloseButton(BOOL bEnable)
  1075. {
  1076. HWND hButton;
  1077. HMENU hSysMenu;
  1078. RECT rect;
  1079. if (IsWindow(g_wndDlg))
  1080. {
  1081. // enable/disable the button
  1082. hButton = GetDlgItem(g_wndDlg, IDCANCEL);
  1083. EnableWindow(hButton, bEnable);
  1084. // now the system menu
  1085. hSysMenu = GetSystemMenu(GetConsistencyStatusWnd(), FALSE);
  1086. EnableMenuItem(hSysMenu, SC_CLOSE, bEnable ? MF_ENABLED : MF_DISABLED);
  1087. GetWindowRect(GetConsistencyStatusWnd(), &rect);
  1088. InvalidateRect(GetConsistencyStatusWnd(), &rect, TRUE);
  1089. }
  1090. }
  1091. void ClearConsistencyStatusWindow()
  1092. {
  1093. HWND hEdit;
  1094. if (IsWindow(g_wndDlg))
  1095. {
  1096. hEdit = GetDlgItem(g_wndDlg, IDC_EDIT_MESSAGE);
  1097. SetWindowText(hEdit, (LPCTSTR) "");
  1098. }
  1099. }
  1100. HWND GetConsistencyStatusWnd()
  1101. {
  1102. return g_wndDlg;
  1103. }
  1104. // this function should be called once before calling either AddWinsServer
  1105. // or CheckRegisteredNames
  1106. INT
  1107. _stdcall
  1108. InitNameConsistency(HINSTANCE hInstance, HWND hWnd)
  1109. {
  1110. int status = 0;
  1111. // initialize things
  1112. NumWinServers = 0;
  1113. memset(WinServers, 0, sizeof(WinServers));
  1114. CreateConsistencyStatusWindow(hInstance, hWnd);
  1115. InitNameCheckSocket();
  1116. return status;
  1117. }
  1118. INT
  1119. _stdcall
  1120. AddWinsServer(char * szServer, BOOL fVerifyWithPartners)
  1121. {
  1122. if (!InitServers(szServer, fVerifyWithPartners))
  1123. {
  1124. return FALSE;
  1125. }
  1126. return TRUE;
  1127. }
  1128. /*********************************************************************/
  1129. /* M a i n */
  1130. /* */
  1131. /* 27-Dec-1995 CDermody Rather that report 'is not responding' */
  1132. /* for partial response, use multiple */
  1133. /* passes over those that were incomplete */
  1134. /* and report 'never responded' only for */
  1135. /* those that never did. */
  1136. /* Add mechanism to query the purported */
  1137. /* owner of the address to see if the */
  1138. /* service really exists there. */
  1139. /*********************************************************************/
  1140. /*
  1141. _cdecl
  1142. main (argc, argv)
  1143. int argc;
  1144. char *argv[];
  1145. */
  1146. INT
  1147. _stdcall
  1148. CheckNameConsistency(char* szName)
  1149. {
  1150. int status = 0;
  1151. int i;
  1152. int Pass;
  1153. int ServerInx, NameInx, Inx;
  1154. struct in_addr retaddr;
  1155. struct in_addr tempaddr;
  1156. u_long temp;
  1157. WINSERVERS * ServerTemp;
  1158. int retry;
  1159. FILE * nf;
  1160. TCHAR szBuffer[MAX_SIZE] = {0};
  1161. TCHAR szNum[10];
  1162. char lpResults[100] = {0};
  1163. // initialize some things
  1164. memset(NBNames, 0, sizeof(NBNames));
  1165. memset(VerifiedAddress, 0, sizeof(VerifiedAddress));
  1166. for (i = 0; i < MAX_SERVERS; i++)
  1167. {
  1168. WinServers[i].LastResponse = -1;
  1169. WinServers[i].fQueried = FALSE;
  1170. WinServers[i].Valid = 0;
  1171. WinServers[i].Failed = 0;
  1172. WinServers[i].Retries = 0;
  1173. WinServers[i].Completed = 0;
  1174. }
  1175. SetCursor(LoadCursor(0, MAKEINTRESOURCE(IDC_WAIT)));
  1176. // call InitNameConsistency, then AddWinsServer to build the list of servers
  1177. // to verify this name against.
  1178. NumNBNames = 1;
  1179. NameInx = 0;
  1180. NBNames[NameInx] = malloc(NBT_NONCODED_NMSZ);
  1181. if (NBNames[NameInx] == NULL)
  1182. {
  1183. strcat(lpResults, "malloc(17) failed.\r\n");
  1184. //DestroyStatusWindow();
  1185. return FALSE;
  1186. }
  1187. strcpy(NBNames[NameInx], szName);
  1188. for (Pass = 1; Pass < 3; Pass++)
  1189. {
  1190. _tcscpy(szBuffer, L"");
  1191. _tcscat(szBuffer, L"\r\n");
  1192. _tcscat(szBuffer, L"Pass ");
  1193. _itot(Pass, szNum, 10);
  1194. _tcscat(szBuffer, szNum);
  1195. _tcscat(szBuffer, L"\r\n");
  1196. _tcscat(szBuffer, L"\r\n");
  1197. AddStatusMessageW(szBuffer);
  1198. /* We initially have no failed servers */
  1199. for (ServerInx = 0; ServerInx < NumWinServers; ServerInx++)
  1200. {
  1201. ServerTemp = &WinServers[ServerInx];
  1202. ServerTemp->Failed = 0;
  1203. }
  1204. for (NameInx = 0; NameInx < NumNBNames; NameInx++)
  1205. {
  1206. for (ServerInx = 0; ServerInx < NumWinServers; ServerInx++)
  1207. {
  1208. ServerTemp = &WinServers[ServerInx];
  1209. if (ServerTemp->Completed)
  1210. {
  1211. continue;
  1212. }
  1213. retry = 0;
  1214. TranID++;
  1215. RetryLoop:
  1216. strcpy(lpResults, "");
  1217. strcat(lpResults, "Sending NameQuery to the server [");
  1218. strcat(lpResults, inet_ntoa(ServerTemp->Server));
  1219. strcat(lpResults, "] for name " );
  1220. strcat(lpResults, NBNames[NameInx]);
  1221. //AddStatusMessage(lpResults);
  1222. SendNameQuery(NBNames[NameInx],
  1223. ServerTemp->Server.s_addr,
  1224. TranID);
  1225. switch (GetNameResponse(&retaddr.s_addr, TranID))
  1226. {
  1227. case WINSTEST_FOUND: // found
  1228. ServerTemp->RetAddr.s_addr = retaddr.s_addr;
  1229. ServerTemp->Valid = 1;
  1230. ServerTemp->LastResponse = NameInx;
  1231. if (retaddr.s_addr == VerifiedAddress[NameInx])
  1232. {
  1233. // this address has already been verified... don't
  1234. // do the checking again
  1235. strcat(lpResults, "; OK.\r\n");
  1236. AddStatusMessage(lpResults);
  1237. break;
  1238. }
  1239. status = VerifyRemote(inet_ntoa(ServerTemp->RetAddr),
  1240. NBNames[NameInx]);
  1241. if (WINSTEST_VERIFIED == status)
  1242. {
  1243. strcat(lpResults, "; OK.\r\n");
  1244. AddStatusMessage(lpResults);
  1245. VerifiedAddress[NameInx] = retaddr.s_addr;
  1246. }
  1247. else
  1248. {
  1249. strcat(lpResults, "; could not be verified.\r\n");
  1250. AddStatusMessage(lpResults);
  1251. }
  1252. break;
  1253. case WINSTEST_NOT_FOUND: // responded -- name not found
  1254. ServerTemp->RetAddr.s_addr = retaddr.s_addr;
  1255. ServerTemp->Valid = 0;
  1256. ServerTemp->LastResponse = NameInx;
  1257. strcat(lpResults, "; Name not found!\r\n");
  1258. AddStatusMessage(lpResults);
  1259. break;
  1260. case WINSTEST_NO_RESPONSE: // no response
  1261. ServerTemp->RetAddr.s_addr = retaddr.s_addr;
  1262. ServerTemp->Valid = 0;
  1263. ServerTemp->Retries++;
  1264. strcat(lpResults, "; No response.\r\n");
  1265. AddStatusMessage(lpResults);
  1266. retry++;
  1267. if (retry > 2)
  1268. {
  1269. ServerTemp->Failed = 1;
  1270. continue;
  1271. }
  1272. goto RetryLoop;
  1273. } // switch GetNameResponse
  1274. } // for ServerInx
  1275. for (ServerInx = 0; ServerInx < NumWinServers; ServerInx++)
  1276. {
  1277. ServerTemp = &WinServers[ServerInx];
  1278. if (ServerTemp->Completed)
  1279. {
  1280. continue;
  1281. }
  1282. if (ServerTemp->Valid)
  1283. {
  1284. temp = ServerTemp->RetAddr.s_addr;
  1285. break;
  1286. }
  1287. } // for ServerInx
  1288. for (ServerInx = 0; ServerInx < NumWinServers; ServerInx++)
  1289. {
  1290. ServerTemp = &WinServers[ServerInx];
  1291. if (ServerTemp->Completed)
  1292. {
  1293. continue;
  1294. }
  1295. if ( (ServerTemp->Valid) )
  1296. {
  1297. if ((temp != ServerTemp->RetAddr.s_addr)
  1298. || (0 != VerifiedAddress[NameInx]
  1299. && temp != VerifiedAddress[NameInx]) )
  1300. {
  1301. strcpy(lpResults, "");
  1302. strcat(lpResults, "Inconsistency found with WINS for NetBIOS name ");
  1303. strcat(lpResults, NBNames[NameInx]);
  1304. strcat(lpResults, "\r\n");
  1305. AddStatusMessage(lpResults);
  1306. if (0 != VerifiedAddress[NameInx])
  1307. {
  1308. tempaddr.s_addr = VerifiedAddress[NameInx];
  1309. strcpy(lpResults, "");
  1310. strcat(lpResults,"NetBIOS name has verified address (");
  1311. strcat(lpResults,inet_ntoa(tempaddr));
  1312. strcat(lpResults, "). \r\n");
  1313. AddStatusMessage(lpResults);
  1314. }
  1315. for (Inx = 0; Inx < NumWinServers; Inx++)
  1316. {
  1317. if (WinServers[Inx].Valid)
  1318. {
  1319. strcpy(lpResults, "");
  1320. strcat(lpResults," NameQuery(");
  1321. strcat(lpResults,inet_ntoa(WinServers[Inx].Server));
  1322. strcat(lpResults, " \\");
  1323. strcat(lpResults, NBNames[NameInx]);
  1324. strcat(lpResults, ")");
  1325. strcat(lpResults , " = ");
  1326. strcat(lpResults, inet_ntoa(WinServers[Inx].RetAddr));
  1327. strcat(lpResults, " \r\n");
  1328. AddStatusMessage(lpResults);
  1329. }
  1330. }
  1331. break;
  1332. }
  1333. }
  1334. } // for ServerInx
  1335. } // for NameInx
  1336. for (ServerInx = 0; ServerInx < NumWinServers; ServerInx++)
  1337. {
  1338. ServerTemp = &WinServers[ServerInx];
  1339. if (!ServerTemp->Failed)
  1340. {
  1341. ServerTemp->Completed = 1;
  1342. }
  1343. } // for ServerInx
  1344. } // for Pass
  1345. for (ServerInx = 0; ServerInx < NumWinServers; ServerInx++)
  1346. {
  1347. ServerTemp = &WinServers[ServerInx];
  1348. if ((-1) == ServerTemp->LastResponse)
  1349. {
  1350. strcpy(lpResults, "");
  1351. strcat(lpResults,"WINS Server ");
  1352. strcat(lpResults, inet_ntoa(ServerTemp->Server));
  1353. strcat(lpResults, " never responded! \r\n");
  1354. AddStatusMessage(lpResults);
  1355. }
  1356. else if (0 == ServerTemp->Completed)
  1357. {
  1358. strcpy(lpResults, "");
  1359. strcat(lpResults, "WINS Server ");
  1360. strcat(lpResults, inet_ntoa(ServerTemp->Server));
  1361. strcat(lpResults, " incomplete!\r\n");
  1362. AddStatusMessage(lpResults);
  1363. }
  1364. } // for ServerInx
  1365. for (NameInx = 0; NameInx < NumNBNames; NameInx++)
  1366. {
  1367. if (0 == VerifiedAddress[NameInx])
  1368. {
  1369. strcpy(lpResults, "");
  1370. strcat(lpResults,"Could not verify address for name (");
  1371. strcat(lpResults, NBNames[NameInx]);
  1372. strcat(lpResults, ").\r\n\r\n");
  1373. AddStatusMessage(lpResults);
  1374. }
  1375. } // for NameInx
  1376. // exit(0);
  1377. if (NBNames[0])
  1378. free(NBNames[0]);
  1379. return 1; // just to keep the compiler happy -- why do we have to?
  1380. }