[IPHLPAPI] Implement NhpAllocateAndGetInterfaceInfoFromStack

NhpAllocateAndGetInterfaceInfoFromStack is used by WinXPs ifmon.dll.
This commit is contained in:
Eric Kohl
2025-10-14 09:59:10 +02:00
parent 21fc5cd20f
commit 7715046ae3
2 changed files with 137 additions and 0 deletions

View File

@@ -1001,4 +1001,139 @@ Error:
NtClose(TcpFile);
return RtlNtStatusToDosError(Status);
}
DWORD
WINAPI
NhpAllocateAndGetInterfaceInfoFromStack(
_Inout_ IP_INTERFACE_NAME_INFO **ppTable,
_Inout_ PDWORD pdwCount,
_In_ BOOL bOrder,
_In_ HANDLE hHeap,
_In_ DWORD dwFlags)
{
NTSTATUS Status;
HANDLE TcpFile;
TDIEntityID* InterfacesList;
ULONG InterfacesCount;
ULONG AdaptersCount = 0;
ULONG i, j;
IP_INTERFACE_NAME_INFO *pTable = NULL;
UNICODE_STRING UnicodeGuidString;
ANSI_STRING AnsiGuidString;
TRACE("ppTable %p, pdwCount %p, bOrder %u, hHeap %p, dwFlags %lu\n",
ppTable, pdwCount, bOrder, hHeap, dwFlags);
/* open the tcpip driver */
Status = openTcpFile(&TcpFile, FILE_READ_DATA);
if (!NT_SUCCESS(Status))
{
ERR("Could not open handle to tcpip.sys. Status %08x\n", Status);
return RtlNtStatusToDosError(Status);
}
/* Get the interfaces list */
Status = GetInterfacesList(TcpFile, &InterfacesList, &InterfacesCount);
if (!NT_SUCCESS(Status))
{
ERR("Could not get adapters list. Status %08x\n", Status);
NtClose(TcpFile);
return RtlNtStatusToDosError(Status);
}
for (i = 0; i < InterfacesCount; i++)
{
if (InterfacesList[i].tei_entity == IF_ENTITY)
{
BYTE EntryBuffer[FIELD_OFFSET(IFEntry, if_descr) +
RTL_FIELD_SIZE(IFEntry, if_descr[0]) * (MAX_ADAPTER_DESCRIPTION_LENGTH + 1)];
IFEntry* Entry = (IFEntry*)EntryBuffer;
/* Get the entry */
Status = GetInterfaceEntry(TcpFile, InterfacesList[i], Entry);
if (!NT_SUCCESS(Status))
goto Error;
if (Entry->if_type != IF_TYPE_SOFTWARE_LOOPBACK)
AdaptersCount++;
}
}
TRACE("InterfacesCount %lu AdaptersCount %lu\n", InterfacesCount, AdaptersCount);
pTable = HeapAlloc(hHeap, dwFlags, AdaptersCount * sizeof(IP_INTERFACE_NAME_INFO));
if (pTable == NULL)
{
Status = STATUS_NO_MEMORY;
goto Error;
}
for (i = 0, j = 0; i < InterfacesCount; i++)
{
if (InterfacesList[i].tei_entity == IF_ENTITY)
{
BYTE EntryBuffer[FIELD_OFFSET(IFEntry, if_descr) +
RTL_FIELD_SIZE(IFEntry, if_descr[0]) * (MAX_ADAPTER_DESCRIPTION_LENGTH + 1)];
IFEntry* Entry = (IFEntry*)EntryBuffer;
/* Get the entry */
Status = GetInterfaceEntry(TcpFile, InterfacesList[i], Entry);
if (!NT_SUCCESS(Status))
goto Error;
TRACE("Got entity %*s, index %u.\n",
Entry->if_descrlen, &Entry->if_descr[0], Entry->if_index);
if (Entry->if_type != IF_TYPE_SOFTWARE_LOOPBACK)
{
pTable[j].Index = Entry->if_index;
pTable[j].MediaType = Entry->if_type;
pTable[j].ConnectionType = 1; //IF_CONNECTION_DEDICATED;
pTable[j].AccessType = 2; //IF_ACCESS_BROADCAST;
AnsiGuidString.Length = Entry->if_descrlen;
AnsiGuidString.MaximumLength = Entry->if_descrlen;
AnsiGuidString.Buffer = (PCHAR)Entry->if_descr;
Status = RtlAnsiStringToUnicodeString(&UnicodeGuidString,
&AnsiGuidString, TRUE);
if (!NT_SUCCESS(Status))
{
ERR("Status %lx\n", Status);
goto Error;
}
Status = RtlGUIDFromString(&UnicodeGuidString, &pTable[j].DeviceGuid);
RtlFreeUnicodeString(&UnicodeGuidString);
if (!NT_SUCCESS(Status))
{
ERR("Status %lx\n", Status);
goto Error;
}
memset(&pTable[j].InterfaceGuid, 0, sizeof(GUID));
j++;
}
}
}
/* We're done */
HeapFree(GetProcessHeap(), 0, InterfacesList);
NtClose(TcpFile);
*ppTable = pTable;
*pdwCount = AdaptersCount;
return ERROR_SUCCESS;
Error:
ERR("Failed! Status 0x%08x\n", Status);
if (pTable)
HeapFree(hHeap, 0, pTable);
*ppTable = NULL;
*pdwCount = 0;
HeapFree(GetProcessHeap(), 0, InterfacesList);
NtClose(TcpFile);
return RtlNtStatusToDosError(Status);
}
#endif

View File

@@ -3221,6 +3221,7 @@ DWORD WINAPI GetBestInterfaceEx(struct sockaddr *pDestAddr,PDWORD pdwBestIfIndex
return 0L;
}
#ifdef GetAdaptersAddressesV1
/*
* @unimplemented
*/
@@ -3229,6 +3230,7 @@ DWORD WINAPI NhpAllocateAndGetInterfaceInfoFromStack(IP_INTERFACE_NAME_INFO **pp
FIXME(":stub\n");
return 0L;
}
#endif
/*
* @unimplemented