mirror of
https://github.com/solemnwarning/ipxwrapper
synced 2024-12-30 16:45:37 +01:00
Support Windows 98 Resource Kit REG.EXE in test suite.
This commit is contained in:
parent
623d2c3df4
commit
f20261dfa5
2
Makefile
2
Makefile
@ -51,7 +51,7 @@ TESTS := tests/addr.exe tests/addrcache.exe tests/ethernet.exe tools/fionread.ex
|
|||||||
# Tools to compile before running the test suite.
|
# Tools to compile before running the test suite.
|
||||||
TOOLS := tools/socket.exe tools/list-interfaces.exe tools/bind.exe tools/ipx-send.exe \
|
TOOLS := tools/socket.exe tools/list-interfaces.exe tools/bind.exe tools/ipx-send.exe \
|
||||||
tools/ipx-recv.exe tools/spx-server.exe tools/spx-client.exe tools/ipx-isr.exe \
|
tools/ipx-recv.exe tools/spx-server.exe tools/spx-client.exe tools/ipx-isr.exe \
|
||||||
tools/dptool.exe
|
tools/dptool.exe tools/osversion.exe tools/reg-set-bin.exe
|
||||||
|
|
||||||
# DLLs to copy to the tools/ directory before running the test suite.
|
# DLLs to copy to the tools/ directory before running the test suite.
|
||||||
TOOL_DLLS := tools/ipxwrapper.dll tools/wsock32.dll tools/mswsock.dll tools/dpwsockx.dll
|
TOOL_DLLS := tools/ipxwrapper.dll tools/wsock32.dll tools/mswsock.dll tools/dpwsockx.dll
|
||||||
|
103
tests/lib/IPXWrapper/Tool/OSVersion.pm
Normal file
103
tests/lib/IPXWrapper/Tool/OSVersion.pm
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
# IPXWrapper test suite
|
||||||
|
# Copyright (C) 2024 Daniel Collins <solemnwarning@solemnwarning.net>
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or modify it
|
||||||
|
# under the terms of the GNU General Public License version 2 as published by
|
||||||
|
# the Free Software Foundation.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
# more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License along with
|
||||||
|
# this program; if not, write to the Free Software Foundation, Inc., 51
|
||||||
|
# Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
use strict;
|
||||||
|
use warnings;
|
||||||
|
|
||||||
|
package IPXWrapper::Tool::OSVersion;
|
||||||
|
|
||||||
|
use IPC::Open3;
|
||||||
|
use Test::Spec;
|
||||||
|
|
||||||
|
my %os_version_cache = ();
|
||||||
|
|
||||||
|
sub get
|
||||||
|
{
|
||||||
|
my ($class, $host) = @_;
|
||||||
|
|
||||||
|
if(defined $os_version_cache{$host})
|
||||||
|
{
|
||||||
|
return $os_version_cache{$host};
|
||||||
|
}
|
||||||
|
|
||||||
|
my @command = ("ssh", $host, "Z:\\tools\\osversion.exe");
|
||||||
|
|
||||||
|
note(join(" ", @command));
|
||||||
|
|
||||||
|
# No need for error checking here - open3 throws on failure.
|
||||||
|
my $pid = open3(my $in, my $out, undef, @command);
|
||||||
|
|
||||||
|
my $output = do {
|
||||||
|
local $/;
|
||||||
|
<$out>;
|
||||||
|
};
|
||||||
|
|
||||||
|
if($output =~ m/^(\d+).(\d+)\r?\n(\d+)\r?\n(\w+)\r?\n(.*)\r?\n$/)
|
||||||
|
{
|
||||||
|
my $self = bless({
|
||||||
|
major => $1,
|
||||||
|
minor => $2,
|
||||||
|
build => $3,
|
||||||
|
platform => $4,
|
||||||
|
extra => $5,
|
||||||
|
}, $class);
|
||||||
|
|
||||||
|
$os_version_cache{$host} = $self;
|
||||||
|
|
||||||
|
return $self;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
die("Didn't get expected output from osversion.exe:\n$output");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sub major
|
||||||
|
{
|
||||||
|
my ($self) = @_;
|
||||||
|
return $self->{major};
|
||||||
|
}
|
||||||
|
|
||||||
|
sub minor
|
||||||
|
{
|
||||||
|
my ($self) = @_;
|
||||||
|
return $self->{minor};
|
||||||
|
}
|
||||||
|
|
||||||
|
sub build
|
||||||
|
{
|
||||||
|
my ($self) = @_;
|
||||||
|
return $self->{build};
|
||||||
|
}
|
||||||
|
|
||||||
|
sub platform
|
||||||
|
{
|
||||||
|
my ($self) = @_;
|
||||||
|
return $self->{platform};
|
||||||
|
}
|
||||||
|
|
||||||
|
sub platform_is_win9x
|
||||||
|
{
|
||||||
|
my ($self) = @_;
|
||||||
|
return $self->{platform} eq "VER_PLATFORM_WIN32_WINDOWS";
|
||||||
|
}
|
||||||
|
|
||||||
|
sub platform_is_winnt
|
||||||
|
{
|
||||||
|
my ($self) = @_;
|
||||||
|
return $self->{platform} eq "VER_PLATFORM_WIN32_NT";
|
||||||
|
}
|
||||||
|
|
||||||
|
1;
|
@ -1,5 +1,5 @@
|
|||||||
# IPXWrapper test suite
|
# IPXWrapper test suite
|
||||||
# Copyright (C) 2014-2017 Daniel Collins <solemnwarning@solemnwarning.net>
|
# Copyright (C) 2014-2024 Daniel Collins <solemnwarning@solemnwarning.net>
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify it
|
# This program is free software; you can redistribute it and/or modify it
|
||||||
# under the terms of the GNU General Public License version 2 as published by
|
# under the terms of the GNU General Public License version 2 as published by
|
||||||
@ -55,6 +55,8 @@ use Net::Libdnet::Eth;
|
|||||||
use NetPacket::IPX;
|
use NetPacket::IPX;
|
||||||
use NetPacket::IPXWrapper;
|
use NetPacket::IPXWrapper;
|
||||||
|
|
||||||
|
use IPXWrapper::Tool::OSVersion;
|
||||||
|
|
||||||
sub run_remote_cmd
|
sub run_remote_cmd
|
||||||
{
|
{
|
||||||
my ($host_ip, $exe_name, @exe_args) = @_;
|
my ($host_ip, $exe_name, @exe_args) = @_;
|
||||||
@ -78,7 +80,21 @@ sub reg_set_dword
|
|||||||
{
|
{
|
||||||
my ($host_ip, $key, $value, $data) = @_;
|
my ($host_ip, $key, $value, $data) = @_;
|
||||||
|
|
||||||
run_remote_cmd($host_ip, "REG", "ADD", $key, "/v", $value, "/t", "REG_DWORD", "/d", $data, "/f");
|
if(IPXWrapper::Tool::OSVersion->get($host_ip)->platform_is_winnt())
|
||||||
|
{
|
||||||
|
run_remote_cmd($host_ip, "REG", "ADD", $key, "/v", $value, "/t", "REG_DWORD", "/d", $data, "/f");
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
eval { run_remote_cmd($host_ip, "REG", "QUERY", "$key\\$value"); };
|
||||||
|
|
||||||
|
if($@)
|
||||||
|
{
|
||||||
|
run_remote_cmd($host_ip, "REG", "ADD", "$key\\$value=$data", "REG_DWORD");
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
run_remote_cmd($host_ip, "REG", "UPDATE", "$key\\$value=$data");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sub reg_set_addr
|
sub reg_set_addr
|
||||||
@ -86,33 +102,71 @@ sub reg_set_addr
|
|||||||
my ($host_ip, $key, $value, $data) = @_;
|
my ($host_ip, $key, $value, $data) = @_;
|
||||||
|
|
||||||
$data =~ s/://g;
|
$data =~ s/://g;
|
||||||
run_remote_cmd($host_ip, "REG", "ADD", $key, "/v", $value, "/t", "REG_BINARY", "/d", $data, "/f");
|
|
||||||
|
if(IPXWrapper::Tool::OSVersion->get($host_ip)->platform_is_winnt())
|
||||||
|
{
|
||||||
|
run_remote_cmd($host_ip, "REG", "ADD", $key, "/v", $value, "/t", "REG_BINARY", "/d", $data, "/f");
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
run_remote_cmd($host_ip, "Z:\\tools\\reg-set-bin.exe", $key, $value, $data);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sub reg_set_string
|
sub reg_set_string
|
||||||
{
|
{
|
||||||
my ($host_ip, $key, $value, $data) = @_;
|
my ($host_ip, $key, $value, $data) = @_;
|
||||||
|
|
||||||
run_remote_cmd($host_ip, "REG", "ADD", $key, "/v", $value, "/t", "REG_SZ", "/d", $data, "/f");
|
if(IPXWrapper::Tool::OSVersion->get($host_ip)->platform_is_winnt())
|
||||||
|
{
|
||||||
|
run_remote_cmd($host_ip, "REG", "ADD", $key, "/v", $value, "/t", "REG_SZ", "/d", $data, "/f");
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
eval { run_remote_cmd($host_ip, "REG", "QUERY", "$key\\$value"); };
|
||||||
|
|
||||||
|
if($@)
|
||||||
|
{
|
||||||
|
run_remote_cmd($host_ip, "REG", "ADD", "$key\\$value=$data", "REG_SZ");
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
run_remote_cmd($host_ip, "REG", "UPDATE", "$key\\$value=$data");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sub reg_delete_key
|
sub reg_delete_key
|
||||||
{
|
{
|
||||||
my ($host_ip, $key) = @_;
|
my ($host_ip, $key) = @_;
|
||||||
|
|
||||||
# Attempting to delete a key which doesn't exist is considered to be an
|
eval { run_remote_cmd($host_ip, "REG", "QUERY", $key); };
|
||||||
# error, so we touch the key beforehand.
|
|
||||||
|
|
||||||
run_remote_cmd($host_ip, "REG", "ADD", $key, "/f");
|
unless($@)
|
||||||
run_remote_cmd($host_ip, "REG", "DELETE", $key, "/f");
|
{
|
||||||
|
if(IPXWrapper::Tool::OSVersion->get($host_ip)->platform_is_winnt())
|
||||||
|
{
|
||||||
|
run_remote_cmd($host_ip, "REG", "DELETE", $key, "/f");
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
run_remote_cmd($host_ip, "REG", "DELETE", $key, "/FORCE");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sub reg_delete_value
|
sub reg_delete_value
|
||||||
{
|
{
|
||||||
my ($host_ip, $key, $value) = @_;
|
my ($host_ip, $key, $value) = @_;
|
||||||
|
|
||||||
run_remote_cmd($host_ip, "REG", "ADD", $key, "/v", $value, "/t", "REG_SZ", "/f");
|
eval { run_remote_cmd($host_ip, "REG", "QUERY", "$key\\$value"); };
|
||||||
run_remote_cmd($host_ip, "REG", "DELETE", $key, "/v", $value, "/f");
|
|
||||||
|
unless($@)
|
||||||
|
{
|
||||||
|
if(IPXWrapper::Tool::OSVersion->get($host_ip)->platform_is_winnt())
|
||||||
|
{
|
||||||
|
run_remote_cmd($host_ip, "REG", "DELETE", $key, "/v", $value, "/f");
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
run_remote_cmd($host_ip, "REG", "DELETE", "$key\\$value", "/FORCE");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sub send_ipx_over_udp
|
sub send_ipx_over_udp
|
||||||
|
61
tools/osversion.c
Normal file
61
tools/osversion.c
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
/* IPXWrapper test tools
|
||||||
|
* Copyright (C) 2024 Daniel Collins <solemnwarning@solemnwarning.net>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 as published by
|
||||||
|
* the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
* more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along with
|
||||||
|
* this program; if not, write to the Free Software Foundation, Inc., 51
|
||||||
|
* Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
OSVERSIONINFO osver;
|
||||||
|
osver.dwOSVersionInfoSize = sizeof(osver);
|
||||||
|
|
||||||
|
if(!GetVersionEx(&osver))
|
||||||
|
{
|
||||||
|
fprintf(stderr, "GetVersionEx: %u\n", (unsigned)(GetLastError()));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *platform;
|
||||||
|
|
||||||
|
switch(osver.dwPlatformId)
|
||||||
|
{
|
||||||
|
case VER_PLATFORM_WIN32s:
|
||||||
|
platform = "VER_PLATFORM_WIN32s";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case VER_PLATFORM_WIN32_WINDOWS:
|
||||||
|
platform = "VER_PLATFORM_WIN32_WINDOWS";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case VER_PLATFORM_WIN32_NT:
|
||||||
|
platform = "VER_PLATFORM_WIN32_NT";
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
platform = "VER_PLATFORM_UNKNOWN";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("%u.%u\n%u\n%s\n%s\n",
|
||||||
|
(unsigned)(osver.dwMajorVersion),
|
||||||
|
(unsigned)(osver.dwMinorVersion),
|
||||||
|
(unsigned)(osver.dwBuildNumber),
|
||||||
|
platform,
|
||||||
|
osver.szCSDVersion);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
140
tools/reg-set-bin.c
Normal file
140
tools/reg-set-bin.c
Normal file
@ -0,0 +1,140 @@
|
|||||||
|
/* IPXWrapper test tools
|
||||||
|
* Copyright (C) 2024 Daniel Collins <solemnwarning@solemnwarning.net>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 as published by
|
||||||
|
* the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
* more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along with
|
||||||
|
* this program; if not, write to the Free Software Foundation, Inc., 51
|
||||||
|
* Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* "Why do you have a standalone program specifically for storing binary
|
||||||
|
* registry values rather than using REG.EXE like you do for everything else?"
|
||||||
|
*
|
||||||
|
* "I'm so glad you asked that, hypothetical voice in my head, BEHOLD."
|
||||||
|
*
|
||||||
|
* > REG ADD HKCU\Software\IPXWrapper\08:00:27:C3:6A:E6\net=00000001 REG_BINARY
|
||||||
|
* > Adding Binary Format Data is not Supported.
|
||||||
|
* > The operation completed successfully.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
static unsigned char hex_nibble_to_bin(char hex)
|
||||||
|
{
|
||||||
|
if(hex >= '0' && hex <= '9')
|
||||||
|
{
|
||||||
|
return 0x0 + (hex - '0');
|
||||||
|
}
|
||||||
|
else if(hex >= 'A' && hex <= 'F')
|
||||||
|
{
|
||||||
|
return 0xA + (hex - 'A');
|
||||||
|
}
|
||||||
|
else if(hex >= 'a' && hex <= 'f')
|
||||||
|
{
|
||||||
|
return 0xA + (hex - 'a');
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
if(argc != 4)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Usage: %s <key path> <value name> <hex string>\n", argv[0]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *key_path = argv[1];
|
||||||
|
const char *value_name = argv[2];
|
||||||
|
const char *value_hex = argv[3];
|
||||||
|
|
||||||
|
HKEY root_key;
|
||||||
|
|
||||||
|
if(strncmp(key_path, "HKLM", 4) == 0 && (key_path[4] == '\\' || key_path[4] == '\0'))
|
||||||
|
{
|
||||||
|
root_key = HKEY_LOCAL_MACHINE;
|
||||||
|
key_path += 4;
|
||||||
|
}
|
||||||
|
else if(strncmp(key_path, "HKCU", 4) == 0 && (key_path[4] == '\\' || key_path[4] == '\0'))
|
||||||
|
{
|
||||||
|
root_key = HKEY_CURRENT_USER;
|
||||||
|
key_path += 4;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
fprintf(stderr, "Key path must begin with HKLM or HKCU\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(key_path[0] == '\\')
|
||||||
|
{
|
||||||
|
++key_path;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t hex_len = strlen(value_hex);
|
||||||
|
|
||||||
|
if((hex_len % 2) != 0)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Invalid byte string\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char *data = malloc(hex_len / 2);
|
||||||
|
if(hex_len > 0 && data == NULL)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Error allocating memory\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t data_len = hex_len / 2;
|
||||||
|
|
||||||
|
for(size_t i = 0; i < hex_len; i += 2)
|
||||||
|
{
|
||||||
|
char hex1 = value_hex[i];
|
||||||
|
char hex2 = value_hex[i + 1];
|
||||||
|
|
||||||
|
if(isxdigit(hex1) && isxdigit(hex2))
|
||||||
|
{
|
||||||
|
data[i / 2] = (hex_nibble_to_bin(hex1) << 4) | hex_nibble_to_bin(hex2);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
fprintf(stderr, "Invalid byte string\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
HKEY key;
|
||||||
|
DWORD error = RegCreateKeyEx(root_key, key_path, 0, NULL, 0, KEY_READ | KEY_WRITE, NULL, &key, NULL);
|
||||||
|
if(error != ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Error opening/creating registry key (error code %u)\n", (unsigned)(error));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
error = RegSetValueEx(key, value_name, 0, REG_BINARY, (BYTE*)(data), data_len);
|
||||||
|
|
||||||
|
RegCloseKey(key);
|
||||||
|
free(data);
|
||||||
|
|
||||||
|
if(error == ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
fprintf(stderr, "Error code %u when writing registry value\n", (unsigned)(error));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user