private unsafe HashSet <string> BuildCache() { var size = 1024; lock (sync) { while (true) { var buffer = resizeableBuffer.Get(ref size, false); fixed(byte *b = buffer) { var result = IPHlpApi.GetAdaptersAddresses( AddressFamily.AF_UNSPEC, GetAdaptersAddressesFlags.GAA_FLAG_INCLUDE_WINS_INFO | GetAdaptersAddressesFlags.GAA_FLAG_INCLUDE_GATEWAYS | GetAdaptersAddressesFlags.GAA_FLAG_INCLUDE_ALL_INTERFACES, IntPtr.Zero, b, ref size); if (result == (int)ErrorCodes.ERROR_BUFFER_OVERFLOW) { continue; } if (result == (int)ErrorCodes.ERROR_NO_DATA) { return(new HashSet <string>(StringComparer.OrdinalIgnoreCase)); } if (result != (int)ErrorCodes.ERROR_SUCCESS) { Win32ExceptionUtility.Throw(result); } var upInterfaces = new HashSet <string>(StringComparer.OrdinalIgnoreCase); for (var ptr = (IP_ADAPTER_ADDRESSES *)b; ptr != null; ptr = ptr->Next) { UnsafeHelper.CheckBounds(b, size, ptr, sizeof(IP_ADAPTER_ADDRESSES)); if (ptr->OperStatus == OperationalStatus.Up && ptr->IfType != NetworkInterfaceType.Loopback) { upInterfaces.Add(GetAdapterIdentity(new string(ptr->Description))); } } return(upInterfaces); } } } }
private static unsafe void VisitProcesses(byte *ptr, byte[] buffer, SystemProcInfoVisitor visit) { while (true) { UnsafeHelper.CheckBounds(ptr, buffer.Length, ptr, sizeof(SystemProcessInformation)); var processInfo = (SystemProcessInformation *)ptr; // don't visit processes which maybe suspended zombies // (which may appear in NtQuerySystemInformation output) // to avoid survival of zombie processes due to opened handles // TODO rewrite this comment if (!IsZombie(processInfo)) { visit(processInfo); } if (processInfo->NextEntryOffset == 0) { return; } ptr += processInfo->NextEntryOffset; } }