windows-nt/Source/XPSP1/NT/base/ntsetup/opktools/netcfg/main.cpp
2020-09-26 16:20:57 +08:00

491 lines
11 KiB
C++

//+---------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1997.
//
// File: M A I N . C P P
//
// Contents: Code to provide a simple cmdline interface to
// the sample code functions
//
// Notes: The code in this file is not required to access any
// netcfg functionality. It merely provides a simple cmdline
// interface to the sample code functions provided in
// file netcfg.cpp.
//
// Author: kumarp 28-September-98
//
// vijayj 12-November-2000
// - Adapt it for WinPE network installation
//
//----------------------------------------------------------------------------
#include "pch.h"
#pragma hdrstop
#include "netcfg.h"
#include <string>
#include "msg.h"
#include <libmsg.h>
// ----------------------------------------------------------------------
// Global vars
//
BOOL g_fVerbose=FALSE;
BOOL MiniNTMode = FALSE;
static WCHAR* optarg;
//
// Global variables used to get formatted message for this program.
//
HMODULE ThisModule = NULL;
WCHAR Message[4096];
// ----------------------------------------------------------------------
void ShowUsage();
WCHAR getopt(ULONG Argc, WCHAR* Argv[], WCHAR* Opts);
enum NetClass MapToNetClass(WCHAR ch);
INT
MainEntry(
IN INT argc,
IN WCHAR *argv[]
);
DWORD
InstallWinPENetworkComponents(
IN INT Argc,
IN WCHAR *Argv[]
);
// ----------------------------------------------------------------------
//
// Function: wmain
//
// Purpose: The main function
//
// Arguments: standard main args
//
// Returns: 0 on success, non-zero otherwise
//
// Author: kumarp 25-December-97
//
// Notes:
//
EXTERN_C int __cdecl wmain(int argc, WCHAR* argv[])
{
INT Result = 0;
ThisModule = GetModuleHandle(NULL);
if ((argc > 1) && (argc < 4)) {
Result = (INT)InstallWinPENetworkComponents(argc, argv);
if (Result == ERROR_INVALID_DATA) {
Result = MainEntry(argc, argv);
}
} else {
Result = MainEntry(argc, argv);
}
return Result;
}
INT
MainEntry(
IN INT argc,
IN WCHAR *argv[]
)
{
HRESULT hr=S_OK;
WCHAR ch;
enum NetClass nc=NC_Unknown;
// use simple cmd line parsing to get parameters for actions
// we want to perform. the order of parameters supplied is significant.
static const WCHAR c_szValidOptions[] =
L"hH?c:C:l:L:i:I:u:U:vVp:P:s:S:b:B:q:Q:";
WCHAR szFileFullPath[MAX_PATH+1];
PWSTR szFileComponent;
MiniNTMode = IsMiniNTMode();
while (_istprint(ch = getopt(argc, argv, (WCHAR*) c_szValidOptions)))
{
switch (tolower(ch))
{
case 'q':
FindIfComponentInstalled(optarg);
break;
case 'b':
hr = HrShowBindingPathsOfComponent(optarg);
break;
case 'c':
nc = MapToNetClass(optarg[0]);
break;
case 'l':
wcscpy(szFileFullPath, optarg);
break;
case 'i':
if (nc != NC_Unknown)
{
hr = HrInstallNetComponent(optarg, nc, szFileFullPath);
}
else
{
ShowUsage();
exit(-1);
}
break;
case 'u':
hr = HrUninstallNetComponent(optarg);
break;
case 's':
switch(tolower(optarg[0]))
{
case 'a':
hr = HrShowNetAdapters();
break;
case 'n':
hr = HrShowNetComponents();
break;
default:
ShowUsage();
exit(-1);
break;
}
break;
case 'v':
g_fVerbose = TRUE;
break;
case EOF:
break;
default:
case 'h':
case '?':
ShowUsage();
exit(0);
break;
}
}
return hr;
}
//+---------------------------------------------------------------------------
//
// Function: MapToNetClass
//
// Purpose: Map a character to the corresponding net class enum
//
// Arguments:
// ch [in] char to map
//
// Returns: enum for net class
//
// Author: kumarp 06-October-98
//
// Notes:
//
enum NetClass MapToNetClass(WCHAR ch)
{
switch(tolower(ch))
{
case 'a':
return NC_NetAdapter;
case 'p':
return NC_NetProtocol;
case 's':
return NC_NetService;
case 'c':
return NC_NetClient;
default:
return NC_Unknown;
}
}
// ----------------------------------------------------------------------
//
// Function: ShowUsage
//
// Purpose: Display program usage help
//
// Arguments: None
//
// Returns: None
//
// Author: kumarp 24-December-97
//
// Notes:
//
void ShowUsage()
{
_putts( GetFormattedMessage( ThisModule,
FALSE,
Message,
sizeof(Message)/sizeof(Message[0]),
MSG_PGM_USAGE ) );
}
//+---------------------------------------------------------------------------
//
// Function: getopt
//
// Purpose: Parse cmdline and return one argument each time
// this function is called.
//
// Arguments:
// Argc [in] standard main argc
// Argv [in] standard main argv
// Opts [in] valid options
//
// Returns:
//
// Author: kumarp 06-October-98
//
// Notes:
//
WCHAR getopt (ULONG Argc, WCHAR* Argv[], WCHAR* Opts)
{
static ULONG optind=1;
static ULONG optcharind;
static ULONG hyphen=0;
WCHAR ch;
WCHAR* indx;
do {
if (optind >= Argc) {
return EOF;
}
ch = Argv[optind][optcharind++];
if (ch == '\0') {
optind++; optcharind=0;
hyphen = 0;
continue;
}
if ( hyphen || (ch == '-') || (ch == '/')) {
if (!hyphen) {
ch = Argv[optind][optcharind++];
if (ch == '\0') {
optind++;
return EOF;
}
} else if (ch == '\0') {
optind++;
optcharind = 0;
continue;
}
indx = wcschr(Opts, ch);
if (indx == NULL) {
continue;
}
if (*(indx+1) == ':') {
if (Argv[optind][optcharind] != '\0'){
optarg = &Argv[optind][optcharind];
} else {
if ((optind + 1) >= Argc ||
(Argv[optind+1][0] == '-' ||
Argv[optind+1][0] == '/' )) {
return 0;
}
optarg = Argv[++optind];
}
optind++;
hyphen = optcharind = 0;
return ch;
}
hyphen = 1;
return ch;
} else {
return EOF;
}
} while (1);
}
BOOL
IsMiniNTMode(
VOID
)
/*++
Routine Description:
Finds out if we are running under MiniNT environment
Arguments:
none
Return value:
TRUE if we are running under MiniNT environment
otherwise FALSE
--*/
{
BOOL Result = FALSE;
TCHAR *MiniNTKeyName = TEXT("SYSTEM\\CurrentControlSet\\Control\\MiniNT");
HKEY MiniNTKey = NULL;
LONG RegResult;
RegResult = RegOpenKey(HKEY_LOCAL_MACHINE,
MiniNTKeyName,
&MiniNTKey);
if (RegResult == ERROR_SUCCESS) {
Result = TRUE;
RegCloseKey(MiniNTKey);
}
return Result;
}
DWORD
InstallWinPENetworkComponents(
IN INT Argc,
IN WCHAR *Argv[]
)
/*++
Routine Description:
Installs the required network components for
WinPE environment
- TCP/IP Stack
- NETBIOS Stack
- MS Client
Note : This basically calls into MainEntry(...)
manipulating the arguments as though user had
entered them.
Arguments:
Argc - Argument Count
Argv - Arguments
Return value:
Win32 Error code
--*/
{
DWORD Result = ERROR_INVALID_DATA;
WCHAR *NetArgs[] = {
TEXT("-l"),
TEXT("\\inf\\nettcpip.inf"),
TEXT("-c"),
TEXT("p"),
TEXT("-i"),
TEXT("ms_tcpip"),
TEXT("-l"),
TEXT("\\inf\\netnb.inf"),
TEXT("-c"),
TEXT("s"),
TEXT("-i"),
TEXT("ms_netbios"),
TEXT("-l"),
TEXT("\\inf\\netmscli.inf"),
TEXT("-c"),
TEXT("c"),
TEXT("-i"),
TEXT("ms_msclient") };
ULONG TcpIpInfIdx = 1;
ULONG NetNbInfIdx = 7;
ULONG MsCliInfIdx = 13;
if (Argc && Argv) {
bool IsWinPE = false;
bool VerboseInstall = false;
for (ULONG Index = 1; Argv[Index]; Index++) {
if (!_wcsicmp(Argv[Index], TEXT("-winpe"))) {
IsWinPE = true;
} else if (!_wcsicmp(Argv[Index], TEXT("-v"))) {
VerboseInstall = true;
}
}
if (IsWinPE) {
WCHAR WinDir[MAX_PATH] = {0};
PWSTR VerboseArg = TEXT("-v");
if (GetWindowsDirectory(WinDir, sizeof(WinDir)/sizeof(WinDir[0]))) {
std::wstring TcpIpFullPath = WinDir;
std::wstring NetNbFullPath = WinDir;
std::wstring MsClientFullPath = WinDir;
TcpIpFullPath += NetArgs[TcpIpInfIdx];
NetArgs[TcpIpInfIdx] = (PWSTR)TcpIpFullPath.c_str();
NetNbFullPath += NetArgs[NetNbInfIdx];
NetArgs[NetNbInfIdx] = (PWSTR)NetNbFullPath.c_str();
MsClientFullPath += NetArgs[MsCliInfIdx];
NetArgs[MsCliInfIdx] = (PWSTR)MsClientFullPath.c_str();
ULONG ArgsSize = (sizeof(NetArgs) + (sizeof(PWSTR) * 3));
PWSTR *Args = (PWSTR *)(new char[ArgsSize]);
ULONG NumArgs = ArgsSize / sizeof(PWSTR);
if (Args) {
Index = 0;
Args[Index++] = Argv[0];
if (VerboseInstall) {
Args[Index++] = VerboseArg;
}
for (ULONG TempIndex = 0;
(TempIndex < (sizeof(NetArgs)/sizeof(PWSTR)));
TempIndex++) {
Args[Index++] = NetArgs[TempIndex];
}
ULONG ArgCount = Index;
Args[Index++] = NULL;
Result = MainEntry(ArgCount, Args);
delete [](PSTR)Args;
} else {
Result = GetLastError();
}
} else {
Result = GetLastError();
}
}
}
return Result;
}