2025-11-28 00:35:46 +09:00

345 lines
10 KiB
C++

/******************************************************************************
* <copyright file="ParamsParser.cpp" company="Microsoft">
* Copyright (c) Microsoft Corporation. All rights reserved.
* </copyright>
*****************************************************************************/
#include "ParamsParser.h"
// Constructor.
CParamsParser::CParamsParser()
{
this->connection = NULL;
this->authentication = NULL;
this->username = NULL;
this->password = NULL;
this->resourceUri = NULL;
this->commandLine = NULL;
this->sendData = NULL;
this->countStr = NULL;
authenticationMechanism = WSMAN_FLAG_AUTH_KERBEROS;
count = 1;
}
// Destructor.
CParamsParser::~CParamsParser()
{
delete [] this->connection;
delete [] this->authentication;
delete [] this->username;
delete [] this->password;
delete [] this->resourceUri;
delete [] this->commandLine;
delete [] this->sendData;
delete [] this->countStr;
}
bool CParamsParser::ParseCommandLine(int argc, __in_ecount(argc) wchar_t * argv[])
{
// parse commandline args
for (int i = 1; i < argc; i++)
{
PWSTR argName = new wchar_t[wcslen(argv[i])+1];
if (NULL == argName)
{
wprintf(L"Could not allocate argName\n");
return false;
}
ZeroMemory(argName, (wcslen(argv[i])+1)*sizeof(wchar_t));
StringCchCopy(argName, wcslen(argv[i])+1, argv[i]);
PWSTR argValue = NULL;
if (argValue = wcsstr(argName, L":"))
{
// put terminator where colon is
*argValue = L'\0';
argValue++; // move past colon
}
if (!argValue)
{
wprintf(L"Value missing for switch: %s\n", argName);
PrintUsage(argv[0]);
delete [] argName;
return 1;
}
if (0 == _wcsicmp(argName,L"/remote") ||
0 == _wcsicmp(argName,L"-remote"))
{
if (NULL == this->connection)
{
this->connection = new wchar_t[wcslen(argValue)+1];
if (NULL == this->connection)
{
wprintf(L"Could not allocate connection\n");
delete [] argName;
return false;
}
ZeroMemory(this->connection, (wcslen(argValue)+1)*sizeof(wchar_t));
StringCchCopy(this->connection, wcslen(argValue)+1, argValue);
}
else
{
wprintf(L"Error: more than one remote specified\n");
CParamsParser::PrintUsage(argv[0]);
delete [] argName;
return false;
}
}
else if (0 == _wcsicmp(argName,L"/authentication") ||
0 == _wcsicmp(argName,L"-authentication"))
{
if (NULL == this->authentication)
{
this->authentication = new wchar_t[wcslen(argValue)+1];
if (NULL == this->authentication)
{
wprintf(L"Could not allocate authentication\n");
delete [] argName;
return false;
}
ZeroMemory(this->authentication, (wcslen(argValue)+1)*sizeof(wchar_t));
StringCchCopy(this->authentication, wcslen(argValue)+1, argValue);
if (0 == _wcsicmp(this->authentication,L"Negotiate"))
{
authenticationMechanism = WSMAN_FLAG_AUTH_NEGOTIATE;
}
else if (0 == _wcsicmp(this->authentication,L"Basic"))
{
authenticationMechanism = WSMAN_FLAG_AUTH_BASIC;
}
else if (0 == _wcsicmp(this->authentication,L"Kerberos"))
{
authenticationMechanism = WSMAN_FLAG_AUTH_KERBEROS;
}
else
{
// you can add more, here only allows the above for short demo
wprintf(L"Error: unsupported authentication mechanism specified\n");
CParamsParser::PrintUsage(argv[0]);
delete [] argName;
return false;
}
}
else
{
wprintf(L"Error: more than one authentication specified\n");
CParamsParser::PrintUsage(argv[0]);
delete [] argName;
return false;
}
}
else if (0 == _wcsicmp(argName,L"/username") ||
0 == _wcsicmp(argName,L"-username"))
{
if (NULL == this->username)
{
this->username = new wchar_t[wcslen(argValue)+1];
if (NULL == this->username)
{
wprintf(L"Could not allocate username\n");
delete [] argName;
return false;
}
ZeroMemory(this->username, (wcslen(argValue)+1)*sizeof(wchar_t));
StringCchCopy(this->username, wcslen(argValue)+1, argValue);
}
else
{
wprintf(L"Error: more than one username specified\n");
CParamsParser::PrintUsage(argv[0]);
delete [] argName;
return false;
}
}
else if (0 == _wcsicmp(argName,L"/password") ||
0 == _wcsicmp(argName,L"-password"))
{
if (NULL == this->password)
{
this->password = new wchar_t[wcslen(argValue)+1];
if (NULL == this->password)
{
wprintf(L"Could not allocate password\n");
delete [] argName;
return false;
}
ZeroMemory(this->password, (wcslen(argValue)+1)*sizeof(wchar_t));
StringCchCopy(this->password, wcslen(argValue)+1, argValue);
}
else
{
wprintf(L"Error: more than one password specified\n");
CParamsParser::PrintUsage(argv[0]);
delete [] argName;
return false;
}
}
else if (0 == _wcsicmp(argName,L"/resourceUri") ||
0 == _wcsicmp(argName,L"-resourceUri"))
{
if (NULL == this->resourceUri)
{
this->resourceUri = new wchar_t[wcslen(argValue)+1];
if (NULL == this->resourceUri)
{
wprintf(L"Could not allocate resourceUri\n");
delete [] argName;
return false;
}
ZeroMemory(this->resourceUri, (wcslen(argValue)+1)*sizeof(wchar_t));
StringCchCopy(this->resourceUri, wcslen(argValue)+1, argValue);
}
else
{
wprintf(L"Error: more than one resourceUri specified\n");
CParamsParser::PrintUsage(argv[0]);
delete [] argName;
return false;
}
}
else if (0 == _wcsicmp(argName,L"/commandLine") ||
0 == _wcsicmp(argName,L"-commandLine"))
{
if (NULL == this->commandLine)
{
this->commandLine = new wchar_t[wcslen(argValue)+1];
if (NULL == this->commandLine)
{
wprintf(L"Could not allocate commandLine\n");
delete [] argName;
return false;
}
ZeroMemory(this->commandLine, (wcslen(argValue)+1)*sizeof(wchar_t));
StringCchCopy(this->commandLine, wcslen(argValue)+1, argValue);
}
else
{
wprintf(L"Error: more than one commandLine specified\n");
CParamsParser::PrintUsage(argv[0]);
delete [] argName;
return false;
}
}
else if (0 == _wcsicmp(argName,L"/sendData") ||
0 == _wcsicmp(argName,L"-sendData"))
{
if (NULL == this->sendData)
{
this->sendData = new char[wcslen(argValue)+1];
if (NULL == this->sendData)
{
wprintf(L"Could not allocate sendData\n");
delete [] argName;
return false;
}
ZeroMemory(this->sendData, (wcslen(argValue)+1)*sizeof(char));
if (!WideCharToMultiByte(
CP_ACP,
WC_NO_BEST_FIT_CHARS,
argValue,
-1,
sendData,
wcslen(argValue)+1,
NULL,
NULL))
{
wprintf(L"Failed to convert %s to ansi\n", argValue);
delete [] argName;
return false;
}
}
else
{
wprintf(L"Error: more than one sendData specified\n");
CParamsParser::PrintUsage(argv[0]);
delete [] argName;
return false;
}
}
else if (0 == _wcsicmp(argName,L"/count") ||
0 == _wcsicmp(argName,L"-count"))
{
if (NULL == this->countStr)
{
this->countStr = new wchar_t[wcslen(argValue)+1];
if (NULL == this->countStr)
{
wprintf(L"Could not allocate countStr\n");
delete [] argName;
return false;
}
ZeroMemory(this->countStr, (wcslen(argValue)+1)*sizeof(wchar_t));
StringCchCopy(this->countStr, wcslen(argValue)+1, argValue);
count = _wtoi(this->countStr);
if (count < 1)
{
wprintf(L"count should not be less than 1\n");
delete [] argName;
return false;
}
}
else
{
wprintf(L"Error: more than one count specified\n");
CParamsParser::PrintUsage(argv[0]);
delete [] argName;
return false;
}
}
else
{
wprintf(L"Unknown switch: %s\n", argv[i]);
CParamsParser::PrintUsage(argv[0]);
delete [] argName;
return false;
}
delete [] argName;
}
if (!this->connection || !this->authentication ||
!this->username || !this->password || !this->resourceUri ||
!this->commandLine || !this->sendData || !this->countStr)
{
printf("Error: missing required parameter\n");
CParamsParser::PrintUsage(argv[0]);
return false;
}
return true;
}
void CParamsParser::PrintUsage(PCWSTR program)
{
wprintf(L"Usage: %s /<SWITCH>:<VALUE> ... \n\n", program);
wprintf(L"Valid switches: \n");
wprintf(L"\tremote\\ttSpecifies identifier of remote system.\n");
wprintf(L"\tauthentication\tSpecifies authentication basic, negotiate, kerberos.\n");
wprintf(L"\tusername\tSpecifies username on remote machine.\n");
wprintf(L"\tpassword\tSpecifies password.\n");
wprintf(L"\tresourceUri\tspecify management resources to be used for operations.\n");
wprintf(L"\tcommandLine\tSpecifies command string.\n");
wprintf(L"\tsendData\tSpecifies data to be sent.\n");
wprintf(L"\tcount\\ttSpecifies how many times data will be sent.\n\n");
wprintf(L"For example: \n\n");
wprintf(L"1) execute 'cmd dir': \n");
wprintf(L"\t%s -remote:http://fqdn.domain.com "
L"-authentication:negotiate -username:domain\\username -password:dummyPassword "
L"-resourceUri:http://schemas.microsoft.com/wbem/wsman/1/windows/shell/cmd "
L"-commandLine:dir -sendData: /count:1 \n\n", program);
wprintf(L"2) receive back whatever user has sent: \n");
wprintf(L"\t%s -remote:https://fqdn.domain.com:444/WSManSDKSamples "
L"-authentication:negotiate -username:domain\\username -password:dummyPassword "
L"-resourceUri:http://microsoft.wsman.sdksample/shellresource "
L"-commandLine:dir -sendData:dummy /count:3 \n\n", program);
wprintf(L"3) operation failure 'exceeding the authz quota' due to many send operations: \n");
wprintf(L"\t%s -remote:https://fqdn.domain.com:444/WSManSDKSamples "
L"-authentication:negotiate -username:domain\\username -password:dummyPassword "
L"-resourceUri:http://microsoft.wsman.sdksample/shellresource "
L"-commandLine:dir -sendData:dummy /count:10 \n", program);
}