function PacketGetAdaptersNPF(): Byte;
var
LinkageKey, AdapKey, OneAdapKey: HKEY;
RegKeySize: DWORD;
Status: Longint;
i: Integer;
dim: DWORD;
RegType: DWORD;
TName: array[..] of AnsiChar;
TAName: array[..] of AnsiChar;
AdapName: array[..] of AnsiChar;
TcpBindingsMultiString: PAnsiChar;
FireWireFlag: UINT;
//
// Old registry based WinPcap names
//
// CHAR npfCompleteDriverPrefix[MAX_WINPCAP_KEY_CHARS];
// UINT RegQueryLen;
npfCompleteDriverPrefix: array[..MAX_WINPCAP_KEY_CHARS - ] of AnsiChar; // = NPF_DRIVER_COMPLETE_DEVICE_PREFIX;
DeviceGuidName: array[..] of AnsiChar;
label tcpip_linkage;
begin
RegKeySize := ;
FillChar(npfCompleteDriverPrefix, sizeof(npfCompleteDriverPrefix), #);
StrCopy(npfCompleteDriverPrefix, NPF_DRIVER_COMPLETE_DEVICE_PREFIX);
//TRACE_ENTER("PacketGetAdaptersNPF");
//
// Old registry based WinPcap names
//
// Get device prefixes from the registry
Status := RegOpenKeyEx(HKEY_LOCAL_MACHINE,
'SYSTEMCurrentControlSetControlClass{4D36E972-E325-11CE-BFC1-08002BE10318}',
,
KEY_READ,
AdapKey);
if (Status <> ERROR_SUCCESS) then
begin
//TRACE_PRINT("PacketGetAdaptersNPF: RegOpenKeyEx ( Class\{networkclassguid} ) Failed");
goto tcpip_linkage;
end;
i := ;
//TRACE_PRINT("PacketGetAdaptersNPF: RegOpenKeyEx ( Class\{networkclassguid} ) was successful");
//TRACE_PRINT("PacketGetAdaptersNPF: Cycling through the adapters in the registry:");
//
// Cycle through the entries inside the {4D36E972-E325-11CE-BFC1-08002BE10318} key
// To get the names of the adapters
//
//while((Result = RegEnumKey(AdapKey, i, AdapName, sizeof(AdapName)/2)) == ERROR_SUCCESS)
while ((RegEnumKey(AdapKey, i, AdapName, sizeof(AdapName) div )) = ERROR_SUCCESS) do
begin
Inc(i);
FireWireFlag := ;
//
// Get the adapter name from the registry key
//
Status := RegOpenKeyEx(AdapKey, AdapName, , KEY_READ, OneAdapKey);
if (Status <> ERROR_SUCCESS) then
begin
//TRACE_PRINT1("%d) RegOpenKey( OneAdapKey ) Failed, skipping the adapter.",i);
continue;
end;
//
//
// Check if this is a FireWire adapter, looking for "1394" in its ComponentId string.
// We prevent listing FireWire adapters because winpcap can open them, but their interface
// with the OS is broken and they can cause blue screens.
//
dim := sizeof(TName);
Status := RegQueryValueEx(OneAdapKey,
'ComponentId',
nil,
nil,
PBYTE(@TName[]),
@dim);
if (Status = ERROR_SUCCESS) then
begin
if (IsFireWire(TName) <> ) then
begin
FireWireFlag := INFO_FLAG_DONT_EXPORT;
end;
end;
Status := RegOpenKeyEx(OneAdapKey, 'Linkage', , KEY_READ, LinkageKey);
if (Status <> ERROR_SUCCESS) then
begin
RegCloseKey(OneAdapKey);
//TRACE_PRINT1("%d) RegOpenKeyEx ( LinkageKey ) Failed, skipping the adapter",i);
continue;
end;
dim := sizeof(DeviceGuidName);
Status := RegQueryValueExA(LinkageKey,
'Export',
nil,
nil,
PBYTE(@DeviceGuidName[]),
@dim);
if (Status <> ERROR_SUCCESS) then
begin
RegCloseKey(OneAdapKey);
RegCloseKey(LinkageKey);
//TRACE_PRINT1("%d) Name = SKIPPED (error reading the key)", i);
continue;
end;
if (strlen(DeviceGuidName) >= strlen('Device')) then
begin
// Put the DeviceNPF_ string at the beginning of the name
StrPCopy(TAName, Format('%s%s', [npfCompleteDriverPrefix,
DeviceGuidName + strlen('Device')]));
end
else
continue;
//terminate the string, just in case
TAName[sizeof(TAName) - ] := #;
//TRACE_PRINT2("%d) Successfully retrieved info for adapter %s, trying to add it to the global list...", i, TAName);
// If the adapter is valid, add it to the list.
PacketAddAdapterNPF(TAName, FireWireFlag);
RegCloseKey(OneAdapKey);
RegCloseKey(LinkageKey);
end; // while enum reg keys
RegCloseKey(AdapKey);
tcpip_linkage:
//
// no adapters were found under {4D36E972-E325-11CE-BFC1-08002BE10318}. This means with great probability
// that we are under Windows NT 4, so we try to look under the tcpip bindings.
//
//TRACE_PRINT("Adapters not found under SYSTEM\CurrentControlSet\Control\Class. Using the TCP/IP bindings.");
Status := RegOpenKeyEx(HKEY_LOCAL_MACHINE,
'SYSTEMCurrentControlSetServicesTcpipLinkage',
,
KEY_READ,
LinkageKey);
if (Status = ERROR_SUCCESS) then
begin
// Retrieve the length of th binde key
// This key contains the name of the devices as devicefoo
//in ASCII, separated by a single '\0'. The list is terminated
//by another '\0'
Status := RegQueryValueExA(LinkageKey,
'bind',
nil,
@RegType,
nil,
@RegKeySize);
// Allocate the buffer
TcpBindingsMultiString := GlobalAllocPtr(GMEM_MOVEABLE or GMEM_ZEROINIT, RegKeySize + );
if (TcpBindingsMultiString = nil) then
begin
//TRACE_PRINT("GlobalAlloc failed allocating memory for the registry key, returning.");
//TRACE_EXIT("PacketGetAdaptersNPF");
Result := ;
Exit;
end;
// Query the key again to get its content
Status := RegQueryValueExA(LinkageKey,
'bind',
nil,
@RegType,
PBYTE(@TcpBindingsMultiString[]),
@RegKeySize);
RegCloseKey(LinkageKey);
// Scan the buffer with the device names
i := ;
while True do
begin
if (TcpBindingsMultiString[i] = #) then
break;
StrPCopy(TAName, Format('%s%s', [npfCompleteDriverPrefix, TcpBindingsMultiString + i + strlen('Device')]));
//
// TODO GV: this cast to avoid a compilation warning is
// actually stupid. We shouls check not to go over the buffer boundary!
//
Inc(i, strlen(PAnsiChar(TcpBindingsMultiString + i)) + );
// If the adapter is valid, add it to the list.
PacketAddAdapterNPF(TAName, );
end;
GlobalFreePtr(TcpBindingsMultiString);
end
else
begin
end;
Result := ;
end;