+typedef struct _NAME_SERVER_LIST_PRIVATE {
+ UINT NumServers;
+ UINT CurrentName;
+ PIP_ADDRESS_STRING AddrString;
+} NAME_SERVER_LIST_PRIVATE, *PNAME_SERVER_LIST_PRIVATE;
+
+PVOID STDCALL
+RtlAllocateHeap (
+ HANDLE Heap,
+ ULONG Flags,
+ ULONG Size
+ );
+
+BOOLEAN
+STDCALL
+RtlFreeHeap (
+ HANDLE Heap,
+ ULONG Flags,
+ PVOID Address
+ );
+
+NTSTATUS
+STDCALL
+RtlUnicodeToMultiByteN (
+ PCHAR MbString,
+ ULONG MbSize,
+ PULONG ResultSize,
+ PWCHAR UnicodeString,
+ ULONG UnicodeSize
+ );
+
+typedef VOID (*EnumNameServersFunc)( PWCHAR Interface,
+ PWCHAR NameServer,
+ PVOID Data );
+typedef VOID (*EnumInterfacesFunc)( HKEY ChildKeyHandle,
+ PWCHAR ChildKeyName,
+ PVOID Data );
+
+/*
+ * EnumInterfaces
+ *
+ * Call the enumeration function for each name server.
+ */
+
+static void EnumInterfaces( PVOID Data, EnumInterfacesFunc cb ) {
+ HKEY RegHandle, TcpipHandle;
+ HKEY ChildKeyHandle = 0;
+ PWCHAR RegKeyToEnumerate =
+ L"SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces";
+ PWCHAR RegKeyForTcpip =
+ L"SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters";
+ PWCHAR ChildKeyName = 0;
+ DWORD CurrentInterface;
+
+ if (OpenChildKeyRead(HKEY_LOCAL_MACHINE,RegKeyToEnumerate,&RegHandle)) {
+ return;
+ }
+
+ for (CurrentInterface = 0; TRUE; CurrentInterface++) {
+ ChildKeyName = GetNthChildKeyName( RegHandle, CurrentInterface );
+ if (!ChildKeyName) break;
+ if (OpenChildKeyRead(RegHandle,ChildKeyName,
+ &ChildKeyHandle) == 0) {
+ cb( ChildKeyHandle, ChildKeyName, Data );
+ RegCloseKey( ChildKeyHandle );
+ }
+ ConsumeChildKeyName( ChildKeyName );
+ }
+}
+
+/*
+ * EnumNameServers
+ */
+
+static void EnumNameServers( HANDLE RegHandle, PWCHAR Interface,
+ PVOID Data, EnumNameServersFunc cb ) {
+ PWCHAR NameServerString =
+ QueryRegistryValueString(RegHandle, L"NameServer");
+ /* Now, count the non-empty comma separated */
+ if (NameServerString) {
+ DWORD ch;
+ DWORD LastNameStart = 0;
+ for (ch = 0; NameServerString[ch]; ch++) {
+ if (NameServerString[ch] == ',') {
+ if (ch - LastNameStart > 0) { /* Skip empty entries */
+ PWCHAR NameServer =
+ malloc(ch - LastNameStart + 1);
+ if (NameServer) {
+ memcpy(NameServer,NameServerString + LastNameStart,
+ (ch - LastNameStart));
+ NameServer[ch - LastNameStart] = 0;
+ cb( Interface, NameServer, Data );
+ free(NameServer);
+ }
+ }
+ LastNameStart = ch + 1; /* The first one after the comma */
+ }
+ }
+ if (ch - LastNameStart > 0) { /* A last name? */
+ PWCHAR NameServer = malloc(ch - LastNameStart + 1);
+ memcpy(NameServer,NameServerString + LastNameStart,
+ (ch - LastNameStart));
+ NameServer[ch - LastNameStart] = 0;
+ cb( Interface, NameServer, Data );
+ free(NameServer);
+ }
+ ConsumeRegValueString(NameServerString);
+ }
+}
+
+static void CreateNameServerListEnumNamesFuncCount( PWCHAR Interface,
+ PWCHAR Server,
+ PVOID _Data ) {
+ PNAME_SERVER_LIST_PRIVATE Data = (PNAME_SERVER_LIST_PRIVATE)_Data;
+ Data->NumServers++;
+}
+
+static void CreateNameServerListEnumIfFuncCount( HKEY RegHandle,
+ PWCHAR InterfaceName,
+ PVOID _Data ) {
+ PNAME_SERVER_LIST_PRIVATE Data = (PNAME_SERVER_LIST_PRIVATE)_Data;
+ EnumNameServers(RegHandle,InterfaceName,Data,
+ CreateNameServerListEnumNamesFuncCount);
+}
+
+static void CreateNameServerListEnumNamesFunc( PWCHAR Interface,
+ PWCHAR Server,
+ PVOID _Data ) {
+ PNAME_SERVER_LIST_PRIVATE Data = (PNAME_SERVER_LIST_PRIVATE)_Data;
+ RtlUnicodeToMultiByteN((PCHAR)&Data->AddrString[Data->CurrentName],
+ sizeof(Data->AddrString[0]),
+ NULL,
+ Server,
+ wcslen(Server));
+ Data->CurrentName++;
+}
+
+static void CreateNameServerListEnumIfFunc( HKEY RegHandle,
+ PWCHAR InterfaceName,
+ PVOID _Data ) {
+ PNAME_SERVER_LIST_PRIVATE Data = (PNAME_SERVER_LIST_PRIVATE)_Data;
+ EnumNameServers(RegHandle,InterfaceName,Data,
+ CreateNameServerListEnumNamesFunc);
+}
+
+static int CountNameServers( PNAME_SERVER_LIST_PRIVATE PrivateData ) {
+ EnumInterfaces(PrivateData,CreateNameServerListEnumIfFuncCount);
+ return PrivateData->NumServers;
+}
+
+static void MakeNameServerList( PNAME_SERVER_LIST_PRIVATE PrivateData ) {
+ EnumInterfaces(PrivateData,CreateNameServerListEnumIfFunc);
+}