621 lines
13 KiB
C++
621 lines
13 KiB
C++
/*++
|
||
|
||
Microsoft Windows
|
||
|
||
Copyright (C) Microsoft Corporation, 1998 - 2001
|
||
|
||
Module Name:
|
||
|
||
netdom5.cxx
|
||
|
||
Abstract:
|
||
|
||
Command line utility for taking care of all the desired net operations
|
||
|
||
--*/
|
||
#include "pch.h"
|
||
#pragma hdrstop
|
||
#include "netdom.h"
|
||
#include "CompName.h"
|
||
|
||
HINSTANCE g_hInstance = NULL;
|
||
|
||
BOOL Verbose = FALSE;
|
||
|
||
//+----------------------------------------------------------------------------
|
||
//
|
||
// Function: GetPrimaryArg
|
||
//
|
||
// Synopsis: The second argument of the command line should be the primary
|
||
// command (the first is the program name).
|
||
//
|
||
// Arguments: [rgNetDomArgs] - The command line argument array.
|
||
// [pTokens] - the token array.
|
||
// [PriCmd] - the out parameter reference.
|
||
//
|
||
// Returns: Success or error.
|
||
//
|
||
//-----------------------------------------------------------------------------
|
||
DWORD
|
||
GetPrimaryArg(ARG_RECORD * rgNetDomArgs, CToken * pTokens,
|
||
NETDOM_ARG_ENUM & PriCmd)
|
||
{
|
||
PWSTR str = (pTokens + 1)->GetToken();
|
||
|
||
if (!str) return ERROR_INVALID_PARAMETER;
|
||
|
||
if ((pTokens + 1)->IsSwitch())
|
||
{
|
||
str++;
|
||
}
|
||
|
||
for (int i = eArgBegin; i < ePriEnd; i += 1)
|
||
{
|
||
if (rgNetDomArgs[i].strArg1 && !_wcsicmp(str, rgNetDomArgs[i].strArg1) ||
|
||
rgNetDomArgs[i].strArg2 && !_wcsicmp(str, rgNetDomArgs[i].strArg2))
|
||
{
|
||
PriCmd = (NETDOM_ARG_ENUM)i;
|
||
return ERROR_SUCCESS;
|
||
}
|
||
}
|
||
|
||
return ERROR_INVALID_PARAMETER;
|
||
}
|
||
|
||
//+----------------------------------------------------------------------------
|
||
//
|
||
// Function: GetHelpTarget
|
||
//
|
||
// Synopsis: If the second argument of the command line is help, the next
|
||
// arg can be either SYNTAX or a primary command.
|
||
//
|
||
// Arguments: [rgNetDomArgs] - The command line argument array.
|
||
// [pTokens] - the token array.
|
||
// [argc] - the count of arguments.
|
||
//
|
||
//-----------------------------------------------------------------------------
|
||
void
|
||
GetHelpTarget(ARG_RECORD * rgNetDomArgs, CToken * pTokens, int argc)
|
||
{
|
||
if (argc < 3)
|
||
{
|
||
DisplayHelp(ePriHelp);
|
||
return;
|
||
}
|
||
|
||
PWSTR str = (pTokens + 2)->GetToken();
|
||
|
||
if (!str)
|
||
{
|
||
DisplayHelp(ePriHelp);
|
||
return;
|
||
}
|
||
|
||
if ((pTokens + 2)->IsSwitch())
|
||
{
|
||
str++;
|
||
}
|
||
|
||
if (rgNetDomArgs[eHelpSyntax].strArg1 &&
|
||
!_wcsicmp(str, rgNetDomArgs[eHelpSyntax].strArg1))
|
||
{
|
||
DisplayHelp(eHelpSyntax);
|
||
}
|
||
|
||
for (int i = eArgBegin; i < ePriEnd; i += 1)
|
||
{
|
||
if (rgNetDomPriArgs[i].strArg1 && !_wcsicmp(str, rgNetDomPriArgs[i].strArg1))
|
||
{
|
||
DisplayHelp((NETDOM_ARG_ENUM)i);
|
||
return;
|
||
}
|
||
}
|
||
|
||
DisplayHelp(ePriHelp);
|
||
}
|
||
|
||
|
||
VOID
|
||
NetDompDisplayMessage(
|
||
IN DWORD MessageId,
|
||
...
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Loads the resource out of the executable and displays it.
|
||
|
||
Arguments:
|
||
|
||
MessageId - Id of the message to load
|
||
... - Optional list of parameters
|
||
|
||
Return Value:
|
||
|
||
VOID
|
||
|
||
--*/
|
||
{
|
||
PWSTR MessageDisplayString;
|
||
va_list ArgList;
|
||
ULONG Length;
|
||
|
||
va_start( ArgList, MessageId );
|
||
|
||
Length = FormatMessage( FORMAT_MESSAGE_FROM_HMODULE | FORMAT_MESSAGE_ALLOCATE_BUFFER,
|
||
NULL,
|
||
MessageId,
|
||
0,
|
||
( PWSTR )&MessageDisplayString,
|
||
0,
|
||
&ArgList );
|
||
|
||
if ( Length != 0 ) {
|
||
|
||
printf( "%ws", MessageDisplayString );
|
||
LocalFree( MessageDisplayString );
|
||
|
||
#if DBG
|
||
} else {
|
||
|
||
printf( "Failed to format buffer for %lu: %lu\n", MessageId, GetLastError() );
|
||
#endif
|
||
}
|
||
|
||
va_end( ArgList );
|
||
}
|
||
|
||
|
||
VOID
|
||
NetDompDisplayMessageAndError(
|
||
IN DWORD MessageId,
|
||
IN DWORD Error,
|
||
IN PWSTR String OPTIONAL
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Loads the resource out of the executable and displays it.
|
||
|
||
Arguments:
|
||
|
||
MessageId - Id of the message to load
|
||
Error - Error message to display
|
||
|
||
Return Value:
|
||
|
||
VOID
|
||
|
||
--*/
|
||
{
|
||
#if DBG
|
||
DWORD Win32Err = ERROR_SUCCESS;
|
||
#endif
|
||
PWSTR ErrorString, Lop;
|
||
ULONG Length;
|
||
|
||
|
||
|
||
Length = FormatMessageW( FORMAT_MESSAGE_FROM_SYSTEM |
|
||
FORMAT_MESSAGE_ALLOCATE_BUFFER,
|
||
NULL,
|
||
Error,
|
||
0,
|
||
( PWSTR )&ErrorString,
|
||
0,
|
||
NULL );
|
||
if ( Length == 0 ) {
|
||
|
||
#if DBG
|
||
Win32Err = GetLastError();
|
||
#endif
|
||
|
||
} else {
|
||
|
||
Lop = wcsrchr( ErrorString, L'\n' );
|
||
if ( Lop ) {
|
||
|
||
*Lop = UNICODE_NULL;
|
||
|
||
if ( Lop != ErrorString ) {
|
||
|
||
*(Lop - 1 ) = UNICODE_NULL;
|
||
}
|
||
}
|
||
NetDompDisplayMessage( MessageId, String, ErrorString );
|
||
LocalFree( ErrorString );
|
||
}
|
||
}
|
||
|
||
|
||
|
||
VOID
|
||
NetDompDisplayErrorMessage(
|
||
IN DWORD Error
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This function display the error string for the given error status
|
||
|
||
Arguments:
|
||
|
||
Error - Status to display the message for
|
||
|
||
Return Value:
|
||
|
||
VOID
|
||
|
||
--*/
|
||
{
|
||
HMODULE NetMsgHandle = NULL;
|
||
ULONG Size = 0;
|
||
PWSTR DisplayString = NULL;
|
||
ULONG Options = FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM;
|
||
|
||
//
|
||
// Load and display the net errors, if that is what we were given
|
||
//
|
||
if ( Error >= 2100 && Error <= 3000 ) {
|
||
|
||
//
|
||
// If it fails to load, it's not the end of the world. We just won't be able
|
||
// to map the message
|
||
//
|
||
NetMsgHandle = LoadLibraryEx( L"netmsg.dll", NULL, LOAD_LIBRARY_AS_DATAFILE );
|
||
if ( NetMsgHandle ) {
|
||
|
||
Options |= FORMAT_MESSAGE_FROM_HMODULE;
|
||
}
|
||
}
|
||
|
||
Size = FormatMessage( Options,
|
||
( LPCVOID )NetMsgHandle,
|
||
Error,
|
||
MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ),
|
||
( LPTSTR )&DisplayString,
|
||
0,
|
||
NULL );
|
||
|
||
if ( Size != 0 ) {
|
||
|
||
printf( "%ws\n", DisplayString );
|
||
LocalFree( DisplayString );
|
||
|
||
#if DBG
|
||
} else {
|
||
|
||
printf( "Failed to map %lu: %lu\n", Error, GetLastError() );
|
||
#endif
|
||
}
|
||
|
||
if ( NetMsgHandle ) {
|
||
|
||
FreeLibrary( NetMsgHandle );
|
||
}
|
||
}
|
||
|
||
|
||
VOID
|
||
NetDompDisplayUnexpectedParameter(
|
||
IN PWSTR UnexpectedParameter
|
||
)
|
||
{
|
||
NetDompDisplayMessage(MSG_NETDOM5_UNEXPECTED, UnexpectedParameter);
|
||
}
|
||
|
||
|
||
VOID
|
||
DisplayHelp(NETDOM_ARG_ENUM HelpOp)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This function displays the help associated with a given operation
|
||
|
||
--*/
|
||
{
|
||
NetDompDisplayMessage( MSG_NETDOM5_SYNTAX );
|
||
|
||
switch (HelpOp)
|
||
{
|
||
case ePriHelp:
|
||
NetDompDisplayMessage( MSG_NETDOM5_COMMAND_USAGE );
|
||
break;
|
||
|
||
case eHelpSyntax:
|
||
NetDompDisplayMessage( MSG_NETDOM5_HELP_SYNTAX );
|
||
break;
|
||
|
||
case ePriAdd:
|
||
NetDompDisplayMessage( MSG_NETDOM5_HELP_ADD );
|
||
NetDompDisplayMessage( MSG_NETDOM5_HELP_MORE );
|
||
break;
|
||
|
||
case ePriCompName:
|
||
NetDompDisplayMessage( MSG_NETDOM5_HELP_COMPUERNAME );
|
||
NetDompDisplayMessage( MSG_NETDOM5_HELP_MORE );
|
||
break;
|
||
|
||
case ePriJoin:
|
||
NetDompDisplayMessage( MSG_NETDOM5_HELP_JOIN );
|
||
NetDompDisplayMessage( MSG_NETDOM5_HELP_MORE );
|
||
break;
|
||
|
||
case ePriMove:
|
||
NetDompDisplayMessage( MSG_NETDOM5_HELP_MOVE );
|
||
NetDompDisplayMessage( MSG_NETDOM5_HELP_MORE );
|
||
break;
|
||
|
||
case ePriQuery:
|
||
NetDompDisplayMessage( MSG_NETDOM5_HELP_QUERY );
|
||
NetDompDisplayMessage( MSG_NETDOM5_HELP_MORE );
|
||
break;
|
||
|
||
case ePriRemove:
|
||
NetDompDisplayMessage( MSG_NETDOM5_HELP_REMOVE );
|
||
NetDompDisplayMessage( MSG_NETDOM5_HELP_MORE );
|
||
break;
|
||
|
||
case ePriRename:
|
||
NetDompDisplayMessage( MSG_NETDOM5_HELP_RENAME );
|
||
NetDompDisplayMessage( MSG_NETDOM5_HELP_MORE );
|
||
break;
|
||
|
||
case ePriRenameComputer:
|
||
NetDompDisplayMessage( MSG_NETDOM5_HELP_RENAMECOMPUTER );
|
||
NetDompDisplayMessage( MSG_NETDOM5_HELP_MORE );
|
||
break;
|
||
|
||
case ePriReset:
|
||
NetDompDisplayMessage( MSG_NETDOM5_HELP_RESET );
|
||
NetDompDisplayMessage( MSG_NETDOM5_HELP_MORE );
|
||
break;
|
||
|
||
case ePriResetPwd:
|
||
NetDompDisplayMessage( MSG_NETDOM5_HELP_RESETPWD );
|
||
NetDompDisplayMessage( MSG_NETDOM5_HELP_MORE );
|
||
break;
|
||
|
||
case ePriTrust:
|
||
NetDompDisplayMessage( MSG_NETDOM5_HELP_TRUST );
|
||
NetDompDisplayMessage( MSG_NETDOM5_HELP_MORE );
|
||
break;
|
||
|
||
case ePriVerify:
|
||
NetDompDisplayMessage( MSG_NETDOM5_HELP_VERIFY );
|
||
NetDompDisplayMessage( MSG_NETDOM5_HELP_MORE );
|
||
break;
|
||
|
||
// case ePriTime:
|
||
// NetDompDisplayMessage( MSG_NETDOM5_HELP_TIME );
|
||
// NetDompDisplayMessage( MSG_NETDOM5_HELP_MORE );
|
||
// break;
|
||
|
||
default:
|
||
NetDompDisplayMessage( MSG_NETDOM5_COMMAND_USAGE );
|
||
break;
|
||
}
|
||
|
||
}
|
||
|
||
int __cdecl _tmain(VOID)
|
||
{
|
||
DWORD Win32Err = ERROR_SUCCESS;
|
||
|
||
g_hInstance = GetModuleHandle(NULL);
|
||
|
||
setlocale(LC_CTYPE, "");
|
||
|
||
//
|
||
// Parse the command line
|
||
//
|
||
int argc = 0;
|
||
CToken * pTokens = NULL;
|
||
PARSE_ERROR Error = {0};
|
||
|
||
Win32Err = GetCommandInput(&argc, &pTokens);
|
||
|
||
if (ERROR_SUCCESS != Win32Err)
|
||
{
|
||
NetDompDisplayErrorMessage(Win32Err);
|
||
goto Netdom5Exit;
|
||
}
|
||
|
||
//
|
||
// Display the help.
|
||
//
|
||
if (argc < 2)
|
||
{
|
||
NetDompDisplayMessage(MSG_NETDOM5_SYNTAX);
|
||
NetDompDisplayMessage(MSG_NETDOM5_USAGE);
|
||
goto Netdom5Exit;
|
||
}
|
||
|
||
NETDOM_ARG_ENUM ePrimaryCmd = ePriHelp;
|
||
|
||
if (!LoadCmd(rgNetDomArgs) || !LoadCmd(rgNetDomPriArgs))
|
||
{
|
||
Win32Err = ERROR_NOT_ENOUGH_MEMORY;
|
||
goto Netdom5Exit;
|
||
}
|
||
|
||
Win32Err = GetPrimaryArg(rgNetDomPriArgs, pTokens, ePrimaryCmd);
|
||
|
||
if (ERROR_SUCCESS != Win32Err)
|
||
{
|
||
PWSTR wzTok = (pTokens + 1)->GetToken();
|
||
if (wzTok)
|
||
{
|
||
NetDompDisplayUnexpectedParameter(wzTok);
|
||
}
|
||
goto Netdom5Exit;
|
||
}
|
||
|
||
//
|
||
// Handle the help case
|
||
//
|
||
if (ePriHelp == ePrimaryCmd || ePriHelp2 == ePrimaryCmd)
|
||
{
|
||
GetHelpTarget(rgNetDomArgs, pTokens, argc);
|
||
goto Netdom5Exit;
|
||
}
|
||
|
||
if (argc < 3)
|
||
{
|
||
// All commands require at least one argument after the primary command.
|
||
//
|
||
DisplayHelp(ePrimaryCmd);
|
||
goto Netdom5Exit;
|
||
}
|
||
|
||
bool fSkipObject = false;
|
||
//
|
||
// The QUERY and RESETPWD commands don't take an "object" parameter.
|
||
//
|
||
if (ePriQuery == ePrimaryCmd || ePriResetPwd == ePrimaryCmd)
|
||
{
|
||
fSkipObject = true;
|
||
}
|
||
|
||
if (!ParseCmd(rgNetDomArgs,
|
||
argc - 2, // skip the program name and primary arg.
|
||
pTokens + 2,
|
||
fSkipObject,
|
||
&Error))
|
||
{
|
||
if (Error.Error == PARSE_ERROR_HELP_SWITCH)
|
||
{
|
||
DisplayHelp(ePrimaryCmd);
|
||
}
|
||
else
|
||
{
|
||
//
|
||
// Display the usage text
|
||
//
|
||
NetDompDisplayMessage(MSG_NETDOM5_SYNTAX);
|
||
NetDompDisplayMessage(MSG_NETDOM5_USAGE);
|
||
Win32Err = ERROR_INVALID_PARAMETER;
|
||
}
|
||
goto Netdom5Exit;
|
||
}
|
||
|
||
if (CmdFlagOn(rgNetDomArgs, eCommHelp) || CmdFlagOn(rgNetDomArgs, eCommQHelp))
|
||
{
|
||
DisplayHelp(ePrimaryCmd);
|
||
goto Netdom5Exit;
|
||
}
|
||
|
||
//
|
||
// Make sure the object name followed the primary command. The query and
|
||
// ResetPwd primary operations don't use the object param.
|
||
//
|
||
if (!fSkipObject && !rgNetDomArgs[eObject].strValue)
|
||
{
|
||
if (argc > 2)
|
||
{
|
||
PWSTR wzTok = (pTokens + 2)->GetToken();
|
||
if (wzTok)
|
||
{
|
||
NetDompDisplayUnexpectedParameter(wzTok);
|
||
}
|
||
}
|
||
NetDompDisplayMessage(MSG_NETDOM5_SYNTAX);
|
||
NetDompDisplayMessage(MSG_NETDOM5_USAGE);
|
||
Win32Err = ERROR_INVALID_PARAMETER;
|
||
goto Netdom5Exit;
|
||
}
|
||
|
||
Verbose = CmdFlagOn(rgNetDomArgs, eCommVerbose);
|
||
|
||
switch (ePrimaryCmd)
|
||
{
|
||
case ePriAdd:
|
||
Win32Err = NetDompHandleAdd(rgNetDomArgs);
|
||
break;
|
||
|
||
case ePriCompName:
|
||
Win32Err = NetDomComputerNames(rgNetDomArgs);
|
||
break;
|
||
|
||
case ePriJoin:
|
||
Win32Err = NetDompHandleJoin(rgNetDomArgs, FALSE);
|
||
break;
|
||
|
||
case ePriMove:
|
||
Win32Err = NetDompHandleMove(rgNetDomArgs);
|
||
break;
|
||
|
||
case ePriQuery:
|
||
Win32Err = NetDompHandleQuery(rgNetDomArgs);
|
||
break;
|
||
|
||
case ePriRemove:
|
||
Win32Err = NetDompHandleRemove(rgNetDomArgs);
|
||
break;
|
||
|
||
// case ePriTime:
|
||
// Win32Err = NetDompHandleTime(rgNetDomArgs);
|
||
// break;
|
||
|
||
case ePriRename:
|
||
Win32Err = NetDompHandleRename(rgNetDomArgs);
|
||
break;
|
||
|
||
case ePriRenameComputer:
|
||
Win32Err = NetDompHandleRenameComputer(rgNetDomArgs);
|
||
break;
|
||
|
||
case ePriReset:
|
||
Win32Err = NetDompHandleReset(rgNetDomArgs);
|
||
break;
|
||
|
||
case ePriResetPwd:
|
||
Win32Err = NetDompHandleResetPwd(rgNetDomArgs);
|
||
break;
|
||
|
||
case ePriTrust:
|
||
Win32Err = NetDompHandleTrust(rgNetDomArgs);
|
||
break;
|
||
|
||
case ePriVerify:
|
||
Win32Err = NetDompHandleVerify(rgNetDomArgs);
|
||
break;
|
||
|
||
default:
|
||
Win32Err = ERROR_INVALID_PARAMETER;
|
||
break;
|
||
}
|
||
|
||
Netdom5Exit:
|
||
|
||
if (pTokens)
|
||
{
|
||
delete [] pTokens;
|
||
}
|
||
|
||
FreeCmd(rgNetDomArgs);
|
||
FreeCmd(rgNetDomPriArgs);
|
||
|
||
if (Win32Err == ERROR_SUCCESS)
|
||
{
|
||
NetDompDisplayMessage( MSG_NETDOM5_SUCCESS );
|
||
}
|
||
else
|
||
{
|
||
if (ERROR_INVALID_PARAMETER == Win32Err)
|
||
{
|
||
NetDompDisplayMessage(MSG_NETDOM5_HELPHINT);
|
||
}
|
||
else
|
||
{
|
||
NetDompDisplayMessage(MSG_NETDOM5_FAILURE);
|
||
}
|
||
}
|
||
|
||
return(Win32Err);
|
||
}
|