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.

1709 lines
47 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[BUFF_SIZE];
  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. pInterfaceInfo = NULL;
  381. InterfaceInfoSize *= 2;
  382. if (InterfaceInfoSize != 0xFFFF)
  383. {
  384. pInterfaceInfo = LocalAlloc(LMEM_FIXED,InterfaceInfoSize);
  385. }
  386. if (!pInterfaceInfo)
  387. {
  388. NtClose(StreamHandle);
  389. //NlsPerror(COMMON_UNABLE_TO_ALLOCATE_PACKET,0);
  390. return(STATUS_INSUFFICIENT_RESOURCES);
  391. }
  392. }
  393. else if (!NT_SUCCESS (status))
  394. {
  395. LocalFree(pInterfaceInfo);
  396. NtClose(StreamHandle);
  397. return(status);
  398. }
  399. } while (status == STATUS_BUFFER_OVERFLOW);
  400. NtClose (StreamHandle);
  401. for (i = 0; i<pInterfaceInfo->NumAdapters; i++)
  402. {
  403. RtlInitString(&name_string, NULL);
  404. RtlInitUnicodeString(&uc_name_string, pInterfaceInfo->Adapter[i].Name);
  405. if (NT_SUCCESS(RtlUnicodeStringToAnsiString(&name_string, &uc_name_string, TRUE)))
  406. {
  407. size = (name_string.Length > MAX_NAME) ? MAX_NAME : name_string.Length;
  408. strncpy(pDeviceName[index], name_string.Buffer, size);
  409. pDeviceName[index][size] = '\0';
  410. RtlFreeAnsiString (&name_string);
  411. index++;
  412. }
  413. }
  414. //
  415. // NULL out the next device string ptr
  416. //
  417. if (index < NBT_MAXIMUM_BINDINGS)
  418. {
  419. pDeviceName[index][0] = '\0';
  420. }
  421. //
  422. // Read the ScopeId key!
  423. //
  424. size = BUFF_SIZE;
  425. *pScope = '\0'; // By default
  426. status = RegOpenKeyExA(HKEY_LOCAL_MACHINE,
  427. SubKeyParms,
  428. 0,
  429. KEY_READ,
  430. &Key);
  431. if (status == ERROR_SUCCESS)
  432. {
  433. // now read the Scope key
  434. status = RegQueryValueExA(Key, Scope, NULL, &Type, pScopeBuffer, &size);
  435. if (status == ERROR_SUCCESS)
  436. {
  437. strcpy(pScope,pScopeBuffer);
  438. }
  439. status = RegCloseKey(Key);
  440. }
  441. status = STATUS_SUCCESS;
  442. }
  443. if (pInterfaceInfo != NULL)
  444. LocalFree(pInterfaceInfo);
  445. return status;
  446. }
  447. //------------------------------------------------------------------------
  448. NTSTATUS
  449. OpenNbt(
  450. IN char path[][MAX_NAME+1],
  451. OUT PHANDLE pHandle,
  452. int max_paths
  453. )
  454. {
  455. HANDLE StreamHandle;
  456. OBJECT_ATTRIBUTES ObjectAttributes;
  457. IO_STATUS_BLOCK IoStatusBlock;
  458. STRING name_string;
  459. UNICODE_STRING uc_name_string;
  460. NTSTATUS status;
  461. LONG index=0;
  462. ASSERT ( max_paths <= NBT_MAXIMUM_BINDINGS );
  463. while ((path[index][0] != '\0') && (index < max_paths))
  464. {
  465. RtlInitString(&name_string, path[index]);
  466. RtlAnsiStringToUnicodeString(&uc_name_string, &name_string, TRUE);
  467. InitializeObjectAttributes(
  468. &ObjectAttributes,
  469. &uc_name_string,
  470. OBJ_CASE_INSENSITIVE,
  471. (HANDLE) NULL,
  472. (PSECURITY_DESCRIPTOR) NULL
  473. );
  474. status =
  475. NtCreateFile(
  476. &StreamHandle,
  477. SYNCHRONIZE | FILE_READ_DATA | FILE_WRITE_DATA,
  478. &ObjectAttributes,
  479. &IoStatusBlock,
  480. NULL,
  481. FILE_ATTRIBUTE_NORMAL,
  482. FILE_SHARE_READ | FILE_SHARE_WRITE,
  483. FILE_OPEN_IF,
  484. 0,
  485. NULL,
  486. 0);
  487. RtlFreeUnicodeString(&uc_name_string);
  488. if (NT_SUCCESS(status))
  489. {
  490. *pHandle = StreamHandle;
  491. return(status);
  492. }
  493. ++index;
  494. }
  495. return (status);
  496. } // s_open
  497. //------------------------------------------------------------------------
  498. NTSTATUS
  499. DeviceIoCtrl(
  500. IN HANDLE fd,
  501. IN PVOID ReturnBuffer,
  502. IN ULONG BufferSize,
  503. IN ULONG Ioctl,
  504. IN PVOID pInput,
  505. IN ULONG SizeInput
  506. )
  507. /*++
  508. Routine Description:
  509. This procedure performs an ioctl(I_STR) on a stream.
  510. Arguments:
  511. fd - NT file handle
  512. iocp - pointer to a strioctl structure
  513. Return Value:
  514. 0 if successful, non-zero otherwise.
  515. History:
  516. 27-Dec-1995 CDermody copied from nbtstat.c
  517. --*/
  518. {
  519. NTSTATUS status;
  520. int retval;
  521. ULONG QueryType;
  522. IO_STATUS_BLOCK iosb;
  523. status = NtDeviceIoControlFile(
  524. fd, // Handle
  525. NULL, // Event
  526. NULL, // ApcRoutine
  527. NULL, // ApcContext
  528. &iosb, // IoStatusBlock
  529. Ioctl, // IoControlCode
  530. pInput, // InputBuffer
  531. SizeInput, // InputBufferSize
  532. (PVOID) ReturnBuffer, // OutputBuffer
  533. BufferSize); // OutputBufferSize
  534. if (status == STATUS_PENDING)
  535. {
  536. status = NtWaitForSingleObject(
  537. fd, // Handle
  538. TRUE, // Alertable
  539. NULL); // Timeout
  540. if (NT_SUCCESS(status))
  541. {
  542. status = iosb.Status;
  543. }
  544. }
  545. return(status);
  546. }
  547. /****************************************************************************/
  548. /* CheckRemoteTable */
  549. /* */
  550. /* This routine does an adapter status query to get the remote name table */
  551. /* then checks to see if a netbios name is contained in it. */
  552. /* */
  553. /* Parameters: */
  554. /* RemoteName, the IP address (asci nn.nn.nn.nn format) of a server to */
  555. /* query. */
  556. /* SearchName, a net bios name. */
  557. /* */
  558. /* Return: */
  559. /* WINSTEST_VERIFIED The name exists in the remote name table */
  560. /* WINSTEST_NOT_VERIFIED The name does not exist in the remote table */
  561. /* WINSTEST_BAD_IP_ADDRESS inet_addr could not convert the ip address */
  562. /* character string. */
  563. /* WINSTEST_HOST_NOT_FOUND Could not reach ip address */
  564. /* WINSTEST_OUT_OF_MEMORY Out of memory */
  565. /* History: */
  566. /* 27-Dec-1995 CDermody created following example of nbtstat.c */
  567. /****************************************************************************/
  568. int
  569. CheckRemoteTable(
  570. IN HANDLE fd,
  571. IN PCHAR RemoteName,
  572. IN PCHAR SearchName
  573. )
  574. {
  575. LONG Count;
  576. LONG i;
  577. PVOID pBuffer;
  578. ULONG BufferSize=600;
  579. NTSTATUS status;
  580. tADAPTERSTATUS *pAdapterStatus;
  581. NAME_BUFFER *pNames;
  582. CHAR MacAddress[20];
  583. tIPANDNAMEINFO *pIpAndNameInfo;
  584. ULONG SizeInput;
  585. ULONG IpAddress;
  586. USHORT BytesToCopy;
  587. pBuffer = LocalAlloc(LMEM_FIXED,BufferSize);
  588. if (!pBuffer)
  589. {
  590. return(WINSTEST_OUT_OF_MEMORY);
  591. }
  592. status = STATUS_BUFFER_OVERFLOW;
  593. pIpAndNameInfo = LocalAlloc(LMEM_FIXED,sizeof(tIPANDNAMEINFO));
  594. if (!pIpAndNameInfo)
  595. {
  596. LocalFree(pBuffer);
  597. return(WINSTEST_OUT_OF_MEMORY);
  598. }
  599. RtlZeroMemory((PVOID)pIpAndNameInfo,sizeof(tIPANDNAMEINFO));
  600. //
  601. // Convert the remote name which is really a dotted decimal ip address
  602. // into a ulong
  603. //
  604. IpAddress = inet_addr(RemoteName);
  605. //
  606. // Don't allow zero for the address since it sends a broadcast and
  607. // every one responds
  608. //
  609. if ((IpAddress == INADDR_NONE) || (IpAddress == 0))
  610. {
  611. LocalFree(pBuffer);
  612. LocalFree(pIpAndNameInfo);
  613. return(WINSTEST_BAD_IP_ADDRESS);
  614. }
  615. pIpAndNameInfo->IpAddress = ntohl(IpAddress);
  616. pIpAndNameInfo->NetbiosAddress.Address[0].Address[0].NetbiosName[0] = '*';
  617. pIpAndNameInfo->NetbiosAddress.TAAddressCount = 1;
  618. pIpAndNameInfo->NetbiosAddress.Address[0].AddressLength
  619. = sizeof(TDI_ADDRESS_NETBIOS);
  620. pIpAndNameInfo->NetbiosAddress.Address[0].AddressType
  621. = TDI_ADDRESS_TYPE_NETBIOS;
  622. pIpAndNameInfo->NetbiosAddress.Address[0].Address[0].NetbiosNameType
  623. = TDI_ADDRESS_NETBIOS_TYPE_UNIQUE;
  624. SizeInput = sizeof(tIPANDNAMEINFO);
  625. while (status == STATUS_BUFFER_OVERFLOW)
  626. {
  627. status = DeviceIoCtrl(fd,
  628. pBuffer,
  629. BufferSize,
  630. IOCTL_NETBT_ADAPTER_STATUS,
  631. pIpAndNameInfo,
  632. SizeInput);
  633. if (status == STATUS_BUFFER_OVERFLOW)
  634. {
  635. LocalFree(pBuffer);
  636. BufferSize *=2;
  637. pBuffer = LocalAlloc(LMEM_FIXED,BufferSize);
  638. if (!pBuffer || (BufferSize == 0xFFFF))
  639. {
  640. LocalFree(pIpAndNameInfo);
  641. return(WINSTEST_OUT_OF_MEMORY);
  642. }
  643. }
  644. }
  645. pAdapterStatus = (tADAPTERSTATUS *)pBuffer;
  646. if ((pAdapterStatus->AdapterInfo.name_count == 0) ||
  647. (status != STATUS_SUCCESS))
  648. {
  649. LocalFree(pIpAndNameInfo);
  650. LocalFree(pBuffer);
  651. return(WINSTEST_HOST_NOT_FOUND);
  652. }
  653. pNames = pAdapterStatus->Names;
  654. Count = pAdapterStatus->AdapterInfo.name_count;
  655. status = 1;
  656. while (Count--)
  657. {
  658. if (0 == _strnicmp(SearchName, pNames->name, strlen(SearchName)))
  659. {
  660. LocalFree(pIpAndNameInfo);
  661. LocalFree(pBuffer);
  662. return WINSTEST_VERIFIED; // found
  663. }
  664. pNames++;
  665. }
  666. LocalFree(pIpAndNameInfo);
  667. LocalFree(pBuffer);
  668. return WINSTEST_NOT_VERIFIED;
  669. }
  670. /****************************************************************************/
  671. /* VerifyRemote */
  672. /* */
  673. /* This routine checks to see if a netbios name is contained in the remote */
  674. /* name table at a given IP address. */
  675. /* */
  676. /* Parameters: */
  677. /* RemoteName, the IP address (asci nn.nn.nn.nn format) of a server to */
  678. /* query. */
  679. /* NBName, a net bios name. */
  680. /* */
  681. /* Return: */
  682. /* WINSTEST_VERIFIED The name exists in the remote name table */
  683. /* WINSTEST_NOT_VERIFIED The name does not exist in the remote table */
  684. /* WINSTEST_BAD_IP_ADDRESS inet_addr could not convert the ip address */
  685. /* character string. */
  686. /* WINSTEST_OPEN_FAILED Could not open NBT driver or could not read */
  687. /* the NBT driver info from the registry. */
  688. /* WINSTEST_HOST_NOT_FOUND Could not reach ip address */
  689. /* WINSTEST_OUT_OF_MEMORY Out of memory */
  690. /* History: */
  691. /* 27-Dec-1995 CDermody created following example of nbtstat.c */
  692. /****************************************************************************/
  693. int VerifyRemote(IN PCHAR RemoteName, IN PCHAR NBName)
  694. {
  695. NTSTATUS status;
  696. LONG interval=-1;
  697. HANDLE nbt = 0;
  698. int nStatus;
  699. int index;
  700. CHAR pDeviceName[NBT_MAXIMUM_BINDINGS+1][MAX_NAME+1];
  701. status = GetInterfaceList(pDeviceName);
  702. if (!NT_SUCCESS(status))
  703. {
  704. return WINSTEST_OPEN_FAILED;
  705. }
  706. for (index = 0; index < NBT_MAXIMUM_BINDINGS && pDeviceName[index][0]; index++)
  707. {
  708. //
  709. // Open the device of the appropriate streams module to start with.
  710. //
  711. status = OpenNbt(&pDeviceName[index], &nbt, NBT_MAXIMUM_BINDINGS-index);
  712. if (!NT_SUCCESS(status))
  713. {
  714. //
  715. // Try the next binding!
  716. //
  717. continue;
  718. }
  719. GetIpAddress(nbt, &NetbtIpAddress);
  720. if (RemoteName[0] == '\0')
  721. return WINSTEST_INVALID_ARG;
  722. nStatus = CheckRemoteTable(nbt,RemoteName,NBName);
  723. if (nStatus == WINSTEST_VERIFIED)
  724. break;
  725. }
  726. return nStatus;
  727. }
  728. /*************************************************************/
  729. /* NBDecode(name,name2) */
  730. /* */
  731. /* This routine decodes a netbios name from level2 to leve1. */
  732. /* name is 16 bytes long, remember that. */
  733. /* */
  734. /*************************************************************/
  735. void
  736. NBDecode(
  737. unsigned char *name,
  738. unsigned char *name2
  739. )
  740. {
  741. int i;
  742. for (i = 0; i < NBT_NONCODED_NMSZ - 1; i++)
  743. {
  744. name[i] = (name2[2*i+1] - 0x41)*(NBT_NONCODED_NMSZ-1) +
  745. (name2[2*i+2] - 0x41);
  746. }
  747. }
  748. /*************************************************************/
  749. /* NBEncode(name2,name) */
  750. /* */
  751. /* This routine code a netbios name from level1 to level2. */
  752. /* name2 has to be NBT_NAMESIZE bytes long, remember that. */
  753. /*************************************************************/
  754. void
  755. NBEncode(
  756. unsigned char *name2,
  757. unsigned char *name
  758. )
  759. {
  760. int i;
  761. name2[0] = 0x20; /* length of first block */
  762. for (i = 0; i < NBT_NONCODED_NMSZ - 1; i++)
  763. {
  764. name2[ 2*i+1 ] = ((name[ i ] >> 4) & 0x0f) + 0x41;
  765. name2[ 2*i+2 ] = (name[ i ] & 0x0f) + 0x41;
  766. }
  767. name2[ NBT_NAMESIZE-1 ] = 0; /* length of next block */
  768. }
  769. ULONG
  770. AddWins(
  771. IN ULONG IPAddr
  772. )
  773. {
  774. INT i;
  775. for (i = 0; i < MAX_SERVERS; i++)
  776. {
  777. if (WinServers[i].Server.s_addr == IPAddr)
  778. {
  779. return 0;
  780. }
  781. if (WinServers[i].Server.s_addr == 0)
  782. {
  783. WinServers[i].Server.s_addr = IPAddr;
  784. NumWinServers++;
  785. return i;
  786. }
  787. }
  788. return 0;
  789. }
  790. VOID
  791. PurgeWinsAddr(
  792. IN ULONG IPAddr
  793. )
  794. {
  795. INT i;
  796. for (i = 0; i < MAX_SERVERS; i++)
  797. {
  798. if (WinServers[i].Server.s_addr == IPAddr)
  799. {
  800. INT j = i + 1;
  801. while (WinServers[j].Server.s_addr)
  802. {
  803. WinServers[j - 1] = WinServers[j];
  804. j++;
  805. }
  806. //
  807. // Zap the last entry
  808. //
  809. WinServers[j - 1].Server.s_addr = 0;
  810. break;
  811. }
  812. }
  813. }
  814. /*******************************************************************/
  815. /* */
  816. /* Initialize the WinServers table and set NumWinServers to count */
  817. /* */
  818. /*******************************************************************/
  819. BOOLEAN
  820. InitServers(char *szServer, BOOL fVerifyWithPartners)
  821. {
  822. FILE * sf = NULL;
  823. int i = 0;
  824. ULONG j = 0;
  825. u_char buffer[100] = {0};
  826. WINSINTF_RESULTS_NEW_T ResultsN;
  827. struct in_addr InAddr;
  828. char szNum[10] = {0};
  829. char lpResults[MAX_SIZE] = {0};
  830. strcpy(buffer, szServer);
  831. //WinServers[i].Server.s_addr = inet_addr(buffer);
  832. InAddr.s_addr = inet_addr(buffer);
  833. AddWins(InAddr.s_addr);
  834. if (fVerifyWithPartners)
  835. {
  836. if (GetStatus(TRUE, &ResultsN, TRUE, FALSE, inet_ntoa(InAddr)))
  837. {
  838. strcpy(lpResults, "");
  839. strcat(lpResults, "Unable to verify against the WINS server: ");
  840. strcat(lpResults, inet_ntoa(InAddr));
  841. strcat(lpResults, "\r\n\r\n");
  842. AddStatusMessage(lpResults);
  843. return FALSE;
  844. }
  845. //
  846. // Enter all the WINS server names into the server table
  847. //
  848. for (j = 0; j < ResultsN.NoOfOwners; j++)
  849. {
  850. //
  851. // Add addresses; check for duplicates
  852. //
  853. struct in_addr InAddr;
  854. InAddr.s_addr = htonl(ResultsN.pAddVersMaps[j].Add.IPAdd);
  855. (VOID)AddWins(htonl(ResultsN.pAddVersMaps[j].Add.IPAdd));
  856. }
  857. //NumWinServers = ResultsN.NoOfOwners;
  858. strcpy(lpResults, "");
  859. _itoa(NumWinServers, szNum, 10);
  860. strcat(lpResults, szNum);
  861. strcat(lpResults, " Wins servers will be Queried:\r\n");
  862. AddStatusMessage(lpResults);
  863. for (i = 0; i < NumWinServers; i++)
  864. {
  865. struct in_addr InAddr;
  866. InAddr.s_addr = WinServers[i].Server.s_addr;
  867. strcpy(lpResults, "");
  868. strcat(lpResults, inet_ntoa(InAddr));
  869. strcat(lpResults,"\r\n");
  870. AddStatusMessage(lpResults);
  871. }
  872. }
  873. return TRUE;
  874. }
  875. /*******************************************************************/
  876. /* */
  877. /* Send a Name Query to a WINS Server */
  878. /* */
  879. /* name is the name to query */
  880. /* winsaddr is the ip address of the wins server to query */
  881. /* TransID is the transaction ID to use for the query */
  882. /* */
  883. /*******************************************************************/
  884. void
  885. _stdcall
  886. SendNameQuery(
  887. unsigned char *name,
  888. u_long winsaddr,
  889. u_short TransID
  890. )
  891. {
  892. struct sockaddr_in destad;
  893. char lpResults[MAX_SIZE] = {0};
  894. char paddedname[NBT_NONCODED_NMSZ];
  895. struct
  896. {
  897. u_short TransactionID;
  898. u_short Flags;
  899. u_short QuestionCount;
  900. u_short AnswerCount;
  901. u_short NSCount;
  902. u_short AdditionalRec;
  903. u_char QuestionName[NBT_NAMESIZE];
  904. u_short QuestionType;
  905. u_short QuestionClass;
  906. } NameQuery;
  907. memset(paddedname, 0x20, sizeof(paddedname));
  908. memcpy(paddedname, name, strlen(name));
  909. NBEncode(NameQuery.QuestionName, paddedname);
  910. NameQuery.TransactionID = htons(TransID);
  911. NameQuery.Flags = htons(0x0100);
  912. NameQuery.QuestionCount = htons(1);
  913. NameQuery.AnswerCount = 0;
  914. NameQuery.NSCount = 0;
  915. NameQuery.AdditionalRec = 0;
  916. NameQuery.QuestionType = htons(0x0020);
  917. NameQuery.QuestionClass = htons(1);
  918. destad.sin_family = AF_INET;
  919. destad.sin_port = htons(137);
  920. destad.sin_addr.s_addr = winsaddr;
  921. if (sendto(sd, (char *)&NameQuery, sizeof(NameQuery), 0,
  922. (struct sockaddr *)&destad, sizeof(destad)) == SOCKET_ERROR)
  923. {
  924. wsprintfA(lpResults, "sendto() failed. Error %d. \r\n", WSAGetLastError());
  925. AddStatusMessage(lpResults);
  926. // exit(1);
  927. return;
  928. }
  929. }
  930. /*******************************************************************/
  931. /* */
  932. /* Wait for a Name Response which matches the Transaction ID */
  933. /* */
  934. /* recvaddr is the ip address returned by the wins server */
  935. /* */
  936. /*******************************************************************/
  937. int
  938. _stdcall
  939. GetNameResponse(
  940. u_long * recvaddr,
  941. u_short TransactionID
  942. )
  943. {
  944. char lpResults[100] = {0};
  945. int i;
  946. int len;
  947. int rslt;
  948. u_long AnswerAddr;
  949. struct sockaddr_in addr;
  950. NameResponse * pNameResponse = NULL;
  951. BYTE Buf[NAME_RESPONSE_BUFFER_SIZE] = {0};
  952. i = 0;
  953. while (i < 15)
  954. {
  955. addrlen = sizeof(addr);
  956. if ((len=recvfrom(sd, (char *) Buf, sizeof(Buf), 0,
  957. (struct sockaddr *)&addr, &addrlen)) < 0)
  958. {
  959. rslt = WSAGetLastError();
  960. if (rslt == WSAEWOULDBLOCK)
  961. {
  962. Sleep(100);
  963. i++;
  964. continue;
  965. }
  966. else
  967. {
  968. wsprintfA(lpResults, "recvfrom() failed. Error %d. \r\n", rslt);
  969. AddStatusMessage(lpResults);
  970. return WINSTEST_NO_RESPONSE;
  971. }
  972. }
  973. pNameResponse = (NameResponse *) Buf;
  974. if (TransactionID == htons(pNameResponse->TransactionID))
  975. {
  976. if (htons(pNameResponse->AnswerCount) == 0)
  977. {
  978. *recvaddr = 0;
  979. return(WINSTEST_NOT_FOUND);
  980. }
  981. AnswerAddr = (pNameResponse->AnswerAddr2 << 16) | pNameResponse->AnswerAddr1;
  982. *recvaddr = AnswerAddr;
  983. return(WINSTEST_FOUND);
  984. }
  985. }
  986. *recvaddr = 0;
  987. return(WINSTEST_NO_RESPONSE);
  988. }
  989. INT
  990. _stdcall
  991. InitNameCheckSocket()
  992. {
  993. char lpResults[MAX_SIZE];
  994. /* Set up a socket to use for querys and responses */
  995. WSAStartup( 0x0101, &WsaData ); // make sure winsock is happy - noop for now
  996. if ((sd = socket( AF_INET, SOCK_DGRAM, 0)) == INVALID_SOCKET)
  997. {
  998. //wsprintfA(lpResults, "socket() failed. Error %d. \r\n", WSAGetLastError());
  999. //AddStatusMessage(lpResults);
  1000. return WSAGetLastError();
  1001. }
  1002. myad.sin_family = AF_INET;
  1003. myad.sin_addr.s_addr = INADDR_ANY;
  1004. myad.sin_port = htons(0);
  1005. if (bind( sd, (struct sockaddr *)&myad, sizeof(myad) ) < 0)
  1006. {
  1007. //wsprintfA(lpResults, "bind() failed. Error %d. \r\n", WSAGetLastError());
  1008. //AddStatusMessage(lpResults);
  1009. closesocket( sd );
  1010. return WSAGetLastError();
  1011. }
  1012. if (ioctlsocket(sd, FIONBIO, &NonBlocking) < 0)
  1013. {
  1014. //wsprintfA(lpResults, "ioctlsocket() failed. Error %d. \r\n", WSAGetLastError());
  1015. //AddStatusMessage(lpResults);
  1016. return WSAGetLastError();
  1017. }
  1018. return 0;
  1019. }
  1020. INT
  1021. _stdcall
  1022. CloseNameCheckSocket()
  1023. {
  1024. closesocket(sd);
  1025. WSACleanup();
  1026. return 0;
  1027. }
  1028. DWORD WINAPI ThreadProc(LPVOID pData)
  1029. {
  1030. DialogBox(g_hInstance,
  1031. MAKEINTRESOURCE(IDD_VERSION_CONSIS),
  1032. g_hwndParent,
  1033. dlgProc);
  1034. return 29;
  1035. }
  1036. void CreateConsistencyStatusWindow(HINSTANCE hInstance, HWND hWndParent)
  1037. {
  1038. // dialog creation
  1039. // create a new window if we don't have one or it possibly went away
  1040. DWORD dwId;
  1041. MSG msg;
  1042. g_hInstance = hInstance;
  1043. g_hwndParent = hWndParent;
  1044. if (g_wndDlg && !IsWindow(g_wndDlg))
  1045. {
  1046. CloseHandle(g_hThread);
  1047. g_wndDlg = NULL;
  1048. }
  1049. if (!g_wndDlg)
  1050. {
  1051. g_hThread = CreateThread(NULL, 0, ThreadProc, NULL, 0, &dwId);
  1052. while (g_wndDlg == NULL)
  1053. {
  1054. // give the thread a chance to run
  1055. Sleep(0);
  1056. // since we are all on the same message pump, we need to
  1057. // give the system a chance to handle messages
  1058. while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
  1059. {
  1060. TranslateMessage(&msg);
  1061. DispatchMessage(&msg);
  1062. }
  1063. }
  1064. }
  1065. }
  1066. void DestroyConsistencyStatusWindow()
  1067. {
  1068. BOOL bResult;
  1069. if (IsWindow(g_wndDlg))
  1070. {
  1071. bResult = PostMessage(g_wndDlg, WM_COMMAND, MAKEWPARAM(0, IDCANCEL), 0);
  1072. }
  1073. if (g_wndDlg)
  1074. {
  1075. WaitForSingleObject(g_hThread, 5000);
  1076. CloseHandle(g_hThread);
  1077. g_hThread = NULL;
  1078. g_wndDlg = NULL;
  1079. }
  1080. }
  1081. void EnableConsistencyCloseButton(BOOL bEnable)
  1082. {
  1083. HWND hButton;
  1084. HMENU hSysMenu;
  1085. RECT rect;
  1086. if (IsWindow(g_wndDlg))
  1087. {
  1088. // enable/disable the button
  1089. hButton = GetDlgItem(g_wndDlg, IDCANCEL);
  1090. EnableWindow(hButton, bEnable);
  1091. // now the system menu
  1092. hSysMenu = GetSystemMenu(GetConsistencyStatusWnd(), FALSE);
  1093. EnableMenuItem(hSysMenu, SC_CLOSE, bEnable ? MF_ENABLED : MF_DISABLED);
  1094. GetWindowRect(GetConsistencyStatusWnd(), &rect);
  1095. InvalidateRect(GetConsistencyStatusWnd(), &rect, TRUE);
  1096. }
  1097. }
  1098. void ClearConsistencyStatusWindow()
  1099. {
  1100. HWND hEdit;
  1101. if (IsWindow(g_wndDlg))
  1102. {
  1103. hEdit = GetDlgItem(g_wndDlg, IDC_EDIT_MESSAGE);
  1104. SetWindowText(hEdit, TEXT(""));
  1105. }
  1106. }
  1107. HWND GetConsistencyStatusWnd()
  1108. {
  1109. return g_wndDlg;
  1110. }
  1111. // this function should be called once before calling either AddWinsServer
  1112. // or CheckRegisteredNames
  1113. INT
  1114. _stdcall
  1115. InitNameConsistency(HINSTANCE hInstance, HWND hWnd)
  1116. {
  1117. int status = 0;
  1118. // initialize things
  1119. NumWinServers = 0;
  1120. memset(WinServers, 0, sizeof(WinServers));
  1121. CreateConsistencyStatusWindow(hInstance, hWnd);
  1122. InitNameCheckSocket();
  1123. return status;
  1124. }
  1125. INT
  1126. _stdcall
  1127. AddWinsServer(char * szServer, BOOL fVerifyWithPartners)
  1128. {
  1129. if (!InitServers(szServer, fVerifyWithPartners))
  1130. {
  1131. return FALSE;
  1132. }
  1133. return TRUE;
  1134. }
  1135. /*********************************************************************/
  1136. /* M a i n */
  1137. /* */
  1138. /* 27-Dec-1995 CDermody Rather that report 'is not responding' */
  1139. /* for partial response, use multiple */
  1140. /* passes over those that were incomplete */
  1141. /* and report 'never responded' only for */
  1142. /* those that never did. */
  1143. /* Add mechanism to query the purported */
  1144. /* owner of the address to see if the */
  1145. /* service really exists there. */
  1146. /*********************************************************************/
  1147. /*
  1148. _cdecl
  1149. main (argc, argv)
  1150. int argc;
  1151. char *argv[];
  1152. */
  1153. INT
  1154. _stdcall
  1155. CheckNameConsistency(char* szName)
  1156. {
  1157. int status = 0;
  1158. int i;
  1159. int Pass;
  1160. int ServerInx, NameInx, Inx;
  1161. struct in_addr retaddr;
  1162. struct in_addr tempaddr;
  1163. u_long temp;
  1164. WINSERVERS * ServerTemp;
  1165. int retry;
  1166. FILE * nf;
  1167. TCHAR szBuffer[MAX_SIZE] = {0};
  1168. TCHAR szNum[10];
  1169. char lpResults[100] = {0};
  1170. // initialize some things
  1171. memset(NBNames, 0, sizeof(NBNames));
  1172. memset(VerifiedAddress, 0, sizeof(VerifiedAddress));
  1173. for (i = 0; i < MAX_SERVERS; i++)
  1174. {
  1175. WinServers[i].LastResponse = -1;
  1176. WinServers[i].fQueried = FALSE;
  1177. WinServers[i].Valid = 0;
  1178. WinServers[i].Failed = 0;
  1179. WinServers[i].Retries = 0;
  1180. WinServers[i].Completed = 0;
  1181. }
  1182. SetCursor(LoadCursor(0, MAKEINTRESOURCE(IDC_WAIT)));
  1183. // call InitNameConsistency, then AddWinsServer to build the list of servers
  1184. // to verify this name against.
  1185. NumNBNames = 1;
  1186. NameInx = 0;
  1187. NBNames[NameInx] = malloc(NBT_NONCODED_NMSZ);
  1188. if (NBNames[NameInx] == NULL)
  1189. {
  1190. strcat(lpResults, "malloc(17) failed.\r\n");
  1191. //DestroyStatusWindow();
  1192. return FALSE;
  1193. }
  1194. strcpy(NBNames[NameInx], szName);
  1195. for (Pass = 1; Pass < 3; Pass++)
  1196. {
  1197. _tcscpy(szBuffer, L"");
  1198. _tcscat(szBuffer, L"\r\n");
  1199. _tcscat(szBuffer, L"Pass ");
  1200. _itot(Pass, szNum, 10);
  1201. _tcscat(szBuffer, szNum);
  1202. _tcscat(szBuffer, L"\r\n");
  1203. _tcscat(szBuffer, L"\r\n");
  1204. AddStatusMessageW(szBuffer);
  1205. /* We initially have no failed servers */
  1206. for (ServerInx = 0; ServerInx < NumWinServers; ServerInx++)
  1207. {
  1208. ServerTemp = &WinServers[ServerInx];
  1209. ServerTemp->Failed = 0;
  1210. }
  1211. for (NameInx = 0; NameInx < NumNBNames; NameInx++)
  1212. {
  1213. for (ServerInx = 0; ServerInx < NumWinServers; ServerInx++)
  1214. {
  1215. ServerTemp = &WinServers[ServerInx];
  1216. if (ServerTemp->Completed)
  1217. {
  1218. continue;
  1219. }
  1220. retry = 0;
  1221. TranID++;
  1222. RetryLoop:
  1223. strcpy(lpResults, "");
  1224. strcat(lpResults, "Sending NameQuery to the server [");
  1225. strcat(lpResults, inet_ntoa(ServerTemp->Server));
  1226. strcat(lpResults, "] for name " );
  1227. strcat(lpResults, NBNames[NameInx]);
  1228. //AddStatusMessage(lpResults);
  1229. SendNameQuery(NBNames[NameInx],
  1230. ServerTemp->Server.s_addr,
  1231. TranID);
  1232. switch (GetNameResponse(&retaddr.s_addr, TranID))
  1233. {
  1234. case WINSTEST_FOUND: // found
  1235. ServerTemp->RetAddr.s_addr = retaddr.s_addr;
  1236. ServerTemp->Valid = 1;
  1237. ServerTemp->LastResponse = NameInx;
  1238. if (retaddr.s_addr == VerifiedAddress[NameInx])
  1239. {
  1240. // this address has already been verified... don't
  1241. // do the checking again
  1242. strcat(lpResults, "; OK.\r\n");
  1243. AddStatusMessage(lpResults);
  1244. break;
  1245. }
  1246. status = VerifyRemote(inet_ntoa(ServerTemp->RetAddr),
  1247. NBNames[NameInx]);
  1248. if (WINSTEST_VERIFIED == status)
  1249. {
  1250. strcat(lpResults, "; OK.\r\n");
  1251. AddStatusMessage(lpResults);
  1252. VerifiedAddress[NameInx] = retaddr.s_addr;
  1253. }
  1254. else
  1255. {
  1256. strcat(lpResults, "; could not be verified.\r\n");
  1257. AddStatusMessage(lpResults);
  1258. }
  1259. break;
  1260. case WINSTEST_NOT_FOUND: // responded -- name not found
  1261. ServerTemp->RetAddr.s_addr = retaddr.s_addr;
  1262. ServerTemp->Valid = 0;
  1263. ServerTemp->LastResponse = NameInx;
  1264. strcat(lpResults, "; Name not found!\r\n");
  1265. AddStatusMessage(lpResults);
  1266. break;
  1267. case WINSTEST_NO_RESPONSE: // no response
  1268. ServerTemp->RetAddr.s_addr = retaddr.s_addr;
  1269. ServerTemp->Valid = 0;
  1270. ServerTemp->Retries++;
  1271. strcat(lpResults, "; No response.\r\n");
  1272. AddStatusMessage(lpResults);
  1273. retry++;
  1274. if (retry > 2)
  1275. {
  1276. ServerTemp->Failed = 1;
  1277. continue;
  1278. }
  1279. goto RetryLoop;
  1280. } // switch GetNameResponse
  1281. } // for ServerInx
  1282. for (ServerInx = 0; ServerInx < NumWinServers; ServerInx++)
  1283. {
  1284. ServerTemp = &WinServers[ServerInx];
  1285. if (ServerTemp->Completed)
  1286. {
  1287. continue;
  1288. }
  1289. if (ServerTemp->Valid)
  1290. {
  1291. temp = ServerTemp->RetAddr.s_addr;
  1292. break;
  1293. }
  1294. } // for ServerInx
  1295. for (ServerInx = 0; ServerInx < NumWinServers; ServerInx++)
  1296. {
  1297. ServerTemp = &WinServers[ServerInx];
  1298. if (ServerTemp->Completed)
  1299. {
  1300. continue;
  1301. }
  1302. if ( (ServerTemp->Valid) )
  1303. {
  1304. if ((temp != ServerTemp->RetAddr.s_addr)
  1305. || (0 != VerifiedAddress[NameInx]
  1306. && temp != VerifiedAddress[NameInx]) )
  1307. {
  1308. strcpy(lpResults, "");
  1309. strcat(lpResults, "Inconsistency found with WINS for NetBIOS name ");
  1310. strcat(lpResults, NBNames[NameInx]);
  1311. strcat(lpResults, "\r\n");
  1312. AddStatusMessage(lpResults);
  1313. if (0 != VerifiedAddress[NameInx])
  1314. {
  1315. tempaddr.s_addr = VerifiedAddress[NameInx];
  1316. strcpy(lpResults, "");
  1317. strcat(lpResults,"NetBIOS name has verified address (");
  1318. strcat(lpResults,inet_ntoa(tempaddr));
  1319. strcat(lpResults, "). \r\n");
  1320. AddStatusMessage(lpResults);
  1321. }
  1322. for (Inx = 0; Inx < NumWinServers; Inx++)
  1323. {
  1324. if (WinServers[Inx].Valid)
  1325. {
  1326. strcpy(lpResults, "");
  1327. strcat(lpResults," NameQuery(");
  1328. strcat(lpResults,inet_ntoa(WinServers[Inx].Server));
  1329. strcat(lpResults, " \\");
  1330. strcat(lpResults, NBNames[NameInx]);
  1331. strcat(lpResults, ")");
  1332. strcat(lpResults , " = ");
  1333. strcat(lpResults, inet_ntoa(WinServers[Inx].RetAddr));
  1334. strcat(lpResults, " \r\n");
  1335. AddStatusMessage(lpResults);
  1336. }
  1337. }
  1338. break;
  1339. }
  1340. }
  1341. } // for ServerInx
  1342. } // for NameInx
  1343. for (ServerInx = 0; ServerInx < NumWinServers; ServerInx++)
  1344. {
  1345. ServerTemp = &WinServers[ServerInx];
  1346. if (!ServerTemp->Failed)
  1347. {
  1348. ServerTemp->Completed = 1;
  1349. }
  1350. } // for ServerInx
  1351. } // for Pass
  1352. for (ServerInx = 0; ServerInx < NumWinServers; ServerInx++)
  1353. {
  1354. ServerTemp = &WinServers[ServerInx];
  1355. if ((-1) == ServerTemp->LastResponse)
  1356. {
  1357. strcpy(lpResults, "");
  1358. strcat(lpResults,"WINS Server ");
  1359. strcat(lpResults, inet_ntoa(ServerTemp->Server));
  1360. strcat(lpResults, " never responded! \r\n");
  1361. AddStatusMessage(lpResults);
  1362. }
  1363. else if (0 == ServerTemp->Completed)
  1364. {
  1365. strcpy(lpResults, "");
  1366. strcat(lpResults, "WINS Server ");
  1367. strcat(lpResults, inet_ntoa(ServerTemp->Server));
  1368. strcat(lpResults, " incomplete!\r\n");
  1369. AddStatusMessage(lpResults);
  1370. }
  1371. } // for ServerInx
  1372. for (NameInx = 0; NameInx < NumNBNames; NameInx++)
  1373. {
  1374. if (0 == VerifiedAddress[NameInx])
  1375. {
  1376. strcpy(lpResults, "");
  1377. strcat(lpResults,"Could not verify address for name (");
  1378. strcat(lpResults, NBNames[NameInx]);
  1379. strcat(lpResults, ").\r\n\r\n");
  1380. AddStatusMessage(lpResults);
  1381. }
  1382. } // for NameInx
  1383. // exit(0);
  1384. if (NBNames[0])
  1385. free(NBNames[0]);
  1386. return 1; // just to keep the compiler happy -- why do we have to?
  1387. }