Abstract
This chapter offers a utility written in C by Steve
Scoggins that demonstrates remote registry administration. The
chapter also contains practical examples you can use to make
the registry do what you want, including C source code showing
you how to read registry keys and techniques that let you
change registry keys on your users' machines remotely and when
they log on.
REMOTE REGISTRY
ADMINISTRATION
Windows NT and Windows 95 both let you administer the registry
from remote locations. A simple way to change values on a
system is to use Regedt32.exe to connect to a remote computer
and modify the registry. This procedure works fine for small
numbers of modifications or queries, but what if you have 20,
50, or 100 workstations to change?
You may decide that you want a way to automatically perform
registry administration tasks on a remote computer. REGREM is
a utility written in C that demonstrates remote registry
administration; it queries the registry of a remote Windows NT
computer. The program prints to the screen a copy of the
network configuration settings for a remote Windows NT
computer.
// regrem.c
// Steve Scoggins 1997
#include <stdio.h>
#include <time.h>
#include <conio.h>
#include <ctype.h>
#include <windows.h>
#define OK ERROR_SUCCESS
main(int argc, char *argv[])
{
static char lpszNIC_Description[80];
static char lpszNIC_Manufacturer[80];
static char lpszNIC_ProductName[80];
static char lpszNIC_ServiceName[80];
static char lpszTcpip_DefaultGateway[20];
static char lpszTcpip_IPAddress[20];
static char lpszTcpip_SubnetMask[20];
static char lpszTcpip_Domain[80];
static char lpszTcpip_Hostname[80];
static char lpszTcpip_NameServer[80];
static char lpszTcpip_SearchList[128];
static char lpszComputerName[80];
static char lpszDefaultDomainName[80];
char szKeyPart1[] = "SYSTEM\\CurrentControlSet\\Services\\";
char szKeyPart2[] = "\\Parameters";
char szServiceKey[128];
long InterruptNumber, IoBaseAddress;
HKEY hkey, hNetKey ;
DWORD lenKeyValue;
unsigned long DataType;
int err;
char *name = argv[1];
if ((err = RegConnectRegistry(name, HKEY_LOCAL_MACHINE,
&hkey)) == OK)
{
// Open the Registry Key for the first instance of a
Network Adapter
// in the Registry
// Read the Description, Manufacturer, Product Name, and
Service Name
// for this instance of an installed Network Adapter.
if(RegOpenKey(hkey, "SOFTWARE\\Microsoft\\Windows
NT\\CurrentVersion\\
NetworkCards\\1",&hNetKey) == ERROR_SUCCESS)
{
RegQueryValueEx(hNetKey, "Description", 0,
&DataType, NULL,
&lenKeyValue);
RegQueryValueEx(hNetKey, "Description", 0,
&DataType,(LPTSTR)
lpszNIC_Description, &lenKeyValue);
printf("Windows NT Network Adapter:\n");
printf("Description: %s\n",lpszNIC_Description);
RegQueryValueEx(hNetKey, "Manufacturer", 0,
&DataType, NULL,
&lenKeyValue);
RegQueryValueEx(hNetKey, "Manufacturer", 0,
&DataType,
(LPTSTR)lpszNIC_Manufacturer, &lenKeyValue);
printf("Manufacturer: %s\n",lpszNIC_Manufacturer);
RegQueryValueEx(hNetKey, "ProductName", 0,
&DataType, NULL,
&lenKeyValue);
RegQueryValueEx(hNetKey, "ProductName", 0,
&DataType,
(LPTSTR)lpszNIC_ProductName, &lenKeyValue);
printf("Product Name: %s\n",lpszNIC_ProductName);
RegQueryValueEx(hNetKey, "ServiceName", 0,
&DataType, NULL,
&lenKeyValue);
RegQueryValueEx(hNetKey, "ServiceName", 0,
&DataType,
(LPTSTR)lpszNIC_ServiceName, &lenKeyValue);
printf("Service Name: %s\n",lpszNIC_ServiceName);
RegCloseKey(hNetKey);
}
// Now that we have the ServiceName for the Network
Adapter from the
// NetworkCards key we will reconstruct the correct
ServiceKey path
// based on the Service Name for this network adapter.
strcpy(szServiceKey, szKeyPart1);
strcat(szServiceKey, lpszNIC_ServiceName);
strcat(szServiceKey, szKeyPart2);
if(RegOpenKey(hkey, (LPCTSTR) szServiceKey, &hNetKey)
== ERROR_SUCCESS)
{
RegQueryValueEx(hNetKey, "InterruptNumber", 0,
&DataType, NULL,
&lenKeyValue);
RegQueryValueEx(hNetKey, "InterruptNumber", 0,
&DataType, (LPBYTE)
&InterruptNumber, &lenKeyValue);
printf("Interrupt Number: %x\n",InterruptNumber);
RegQueryValueEx(hNetKey, "IoBaseAddress", 0,
&DataType, NULL,
&lenKeyValue);
RegQueryValueEx(hNetKey, "IoBaseAddress", 0,
&DataType, (LPBYTE)
&IoBaseAddress, &lenKeyValue);
printf("IO Base Address: %x\n",IoBaseAddress);
RegCloseKey(hNetKey);
}
// Open the TCP/IP Key for this Network Adapter
// Read some of the key TCP/IP parameters for this Network
Adapter
strcat(szServiceKey, "\\Tcpip");
if(RegOpenKey(hkey, (LPCTSTR) szServiceKey ,&hNetKey)
== ERROR_SUCCESS)
{
RegQueryValueEx(hNetKey, "DefaultGateway", 0,
&DataType, NULL,
&lenKeyValue);
RegQueryValueEx(hNetKey, "DefaultGateway", 0,
&DataType,(LPTSTR)
lpszTcpip_DefaultGateway, &lenKeyValue);
printf("TCP/IP DefaultGateway :
%s\n",lpszTcpip_DefaultGateway);
RegQueryValueEx(hNetKey, "IPAddress", 0, &DataType,
NULL,
&lenKeyValue);
RegQueryValueEx(hNetKey, "IPAddress", 0, &DataType,
(LPTSTR)lpszTcpip_IPAddress, &lenKeyValue);
printf("TCP/IP IPAddress : %s\n",lpszTcpip_IPAddress);
RegQueryValueEx(hNetKey, "SubnetMask", 0, &DataType,
NULL,
&lenKeyValue);
RegQueryValueEx(hNetKey, "SubnetMask", 0, &DataType,
(LPTSTR)lpszTcpip_SubnetMask, &lenKeyValue);
printf("TCP/IP Subnet Mask :
%s\n",lpszTcpip_SubnetMask);
RegCloseKey(hNetKey);
}
// Read the global TCP/IP paramters
if(RegOpenKey(hkey,
"SYSTEM\\CurrentControlSet\\Services\\Tcpip\\
Parameters",&hNetKey) == ERROR_SUCCESS)
{
RegQueryValueEx(hNetKey, "Domain", 0, &DataType,
NULL,
&lenKeyValue);
RegQueryValueEx(hNetKey, "Domain", 0, &DataType,
(LPTSTR)lpszTcpip_Domain, &lenKeyValue);
printf("TCP/IP Domain Name: %s\n",lpszTcpip_Domain);
RegQueryValueEx(hNetKey, "Hostname", 0, &DataType,
NULL,
&lenKeyValue);
RegQueryValueEx(hNetKey, "Hostname", 0, &DataType,
(LPTSTR)lpszTcpip_Hostname, &lenKeyValue);
printf("TCP/IP Hostname: %s\n",lpszTcpip_Hostname);
RegQueryValueEx(hNetKey, "NameServer", 0, &DataType,
NULL,
&lenKeyValue);
RegQueryValueEx(hNetKey, "NameServer", 0, &DataType,
(LPTSTR)lpszTcpip_NameServer, &lenKeyValue);
printf("TCP/IP DNS Name Servers:
%s\n",lpszTcpip_NameServer);
RegQueryValueEx(hNetKey, "SearchList", 0, &DataType,
NULL,
&lenKeyValue);
RegQueryValueEx(hNetKey, "SearchList", 0, &DataType,
(LPTSTR)lpszTcpip_SearchList, &lenKeyValue);
printf("TCP/IP Domain Name Search List:
%s\n",lpszTcpip_SearchList);
RegCloseKey(hNetKey);
}
// Read the Computer Name and Domain Name for this Windows
NT Computer
if(RegOpenKey(hkey,
"SYSTEM\\CurrentControlSet\\Control\\ComputerName\\
ActiveComputerName", &hNetKey) == ERROR_SUCCESS)
{
RegQueryValueEx(hNetKey, "ComputerName", 0,
&DataType,
NULL, &lenKeyValue);
RegQueryValueEx(hNetKey, "ComputerName", 0,
&DataType,
(LPTSTR)lpszComputerName, &lenKeyValue);
printf("Windows NT Computer Name:
%s\n",lpszComputerName);
RegCloseKey(hNetKey);
}
if(RegOpenKey(hkey, "SOFTWARE\\Microsoft\\Windows
NT\\CurrentVersion\\
Winlogon", &hNetKey) == ERROR_SUCCESS)
{
RegQueryValueEx(hNetKey, "DefaultDomainName", 0,
&DataType,
NULL, &lenKeyValue);
RegQueryValueEx(hNetKey, "DefaultDomainName", 0,
&DataType,
(LPTSTR)lpszDefaultDomainName, &lenKeyValue);
printf("Windows NT DomainName:
%s\n",lpszDefaultDomainName);
RegCloseKey(hNetKey);
}
RegCloseKey(hkey);
}
else
{
switch (err)
{
#define MSG(x) case x : printf("%s\t\t\t\n", #x)
MSG(ERROR_OPERATION_ABORTED); break;
MSG(ERROR_BAD_NETPATH); break;
MSG(ERROR_ACCESS_DENIED); break;
default: printf("Error #%u (look in
WINERROR.H)\n", err);
break;
}
printf("failed to connect to remote registry");
}
printf("bye!\n");
return 0;
}
The source and the compiled executable are available on the
CD-ROM that comes with this book. To run REGREM, you must be
logged on as an administrator of the Windows NT Domain for the
remote computer.
A network administrator could use this type of software
utility to query the network configuration for all the Windows
NT computers on the local network. The results are printed to
the screen. If you want a file containing this information,
you can redirect the screen printout to a file using the
following form of the command:
REGREM ComputerName > FileName
Sample output from REGREM is shown below.
Windows NT Network Adapter:
Description: 3Com Etherlink III PCI Bus-Master Adapter (3C590)
Manufacturer: 3Com
Product Name: El59x
Service Name: El59x1
Interrupt Number: 12ff8c
IO Base Address: 3
TCP/IP DefaultGateway : 200.200.200.254
TCP/IP IPAddress : 200.200.200.200
TCP/IP Subnet Mask : 255.255.255.0
TCP/IP Domain Name: test.com
TCP/IP Hostname: bigdog
TCP/IP DNS Name Servers:
TCP/IP Domain Name Search List:
Windows NT Computer Name: BIGDOG
Windows NT DomainName: BIGDOG
bye!
You can also run the Regrem.exe client on any Windows 95 or
Windows NT workstation that is logged on to your Windows NT
Domain. To run this utility on a Windows 95 computer, install
the Microsoft Remote Registry Services. The REGREM client
utility uses Winreg.dll as an RPC client that communicates
with the RPC server on the remote Windows NT computer. The RPC
service on the remote computer uses Regserv.exe.
You must enable user-level access before you can run remote
registry software on a Windows 95 computer. You also must be
authenticated by the Windows NT Domain server before you are
allowed to connect to a remote registry on a Windows NT
computer in the Windows NT Domain.
INSTALLING REMOTE REGISTRY SERVICES ON A
WINDOWS 95 COMPUTER
- Open My Computer.
- Open Control Panel.
- Open the Network applet.
- Click Add.
- Double-click Service.
- Click Have Disk.
- When the install dialog box opens, type
Admin\NetTools\RemoteReg for the directory
path.
- Click OK.
- When the network service dialog box opens, select the
Microsoft Remote Registry service.
- Click OK.
- Click the Access Control Tab in the Network setup dialog
box.
- Check the User-level access control
option.
- Click OK.
- Type your Windows NT Domain name in the Obtain list
of users and groups from box and click OK.
ENABLING REMOTE ADMINISTRATION FOR A
WINDOWS 95 COMPUTER
Note: for remote registry administration to work, you must
enable remote registration on the remote Windows 95
computers.
- Open My Computer.
- Open the Control Panel.
- Open the Passwords applet.
- Click the Remote Administration tab.
- Check Enable Remote Administration of this
server.
- The Domain Administrators are listed in the list box of
users allowed to use Remote Administration. Click the Add
button to add other NT Domain users authorized to use Remote
Administration.
- Click OK to finish.
This program is meant as a demonstration of what is possible.
USING
WINDOWS 95-STYLE INF FILES TO MODIFY REGISTRY
SETTINGS
Another way to modify the Windows NT registry automatically
without writing code is to use .inf files. You can change
multiple workstations and servers remotely and automatically.
To avoid having to fire up Regedt32.exe for each change, you
can simply tell the Logon.bat file to run your .inf file,
which can perform any sort command or registry
modification.
The following command line runs an .inf file on a Windows NT
computer:
RUNDLL32 syssetup,SetupInfObjectInstallAction DefaultInstall
128 E:\NT
Registry\cdautoff.inf
It is very important that you provide the fully qualified path
to the .inf file. If you just supply the filename, this
procedure will not work. You can place this command line in a
logon batch file if you want to make this modification for
multiple users. You can then edit the users profiles and
specify this batch file.
Listed below is an INF file that turns off CD-ROM Autorun via
the registry.
; CDAUTOFF.INF
;
; This is an example INF setup information file to turn OFF
CD-ROM Autorun
[Version]
Signature="$Windows NT$"
Provider=%Provider%
[Strings]
Provider="Steve Scoggins"
[DefaultInstall]
AddReg = add.reg
[add.reg]
HKLM,SYSTEM\CurrentControlSet\Services\Cdrom,"Autorun",0x10001
,0
You can automatically roll out any number of modifications to
the registry using this technique. The trick is learning what
the bit fields for each key does.
For more information about using INF files to automate
installing applications or making registry changes, I
recommend the references cited below:
- Microsoft Windows NT Workstation Resource Kit,
Microsoft Press ISBN 1-57231-343-9, Chapter 2, Customizing
Setup; Creating .inf files, page 59
- Microsoft Visual C++ 5.0 Professional
Edition, Microsoft Developer Studio Infoviewer
|