windows-nt/Source/XPSP1/NT/admin/wmi/wbem/tools/wmic/wcmain.cpp
2020-09-26 16:20:57 +08:00

506 lines
14 KiB
C++

/****************************************************************************
Copyright information : Copyright (c) 1998-1999 Microsoft Corporation
File Name : wcmain.cpp
Project Name : WMI Command Line
Author Name : Ch. Sriramachandramurthy
Date of Creation (dd/mm/yy) : 27th-September-2000
Version Number : 1.0
Brief Description : The _tmain function is the entry point of the
WMICli program.
Revision History :
Last Modified by :Biplab Mistry
Last Modified date :4/11/00
****************************************************************************/
// wcmain.cpp :main function implementation file
#include "Precomp.h"
#include "CommandSwitches.h"
#include "GlobalSwitches.h"
#include "HelpInfo.h"
#include "ErrorLog.h"
#include "ParsedInfo.h"
#include "CmdTokenizer.h"
#include "CmdAlias.h"
#include "ParserEngine.h"
#include "ExecEngine.h"
#include "ErrorInfo.h"
#include "WmiCliXMLLog.h"
#include "FormatEngine.h"
#include "WmiCmdLn.h"
CWMICommandLine g_wmiCmd;
_TCHAR* g_pszBuffer = NULL;
/*------------------------------------------------------------------------
Name :_tmain
Synopsis :This function takes the error code as input and return
an error string
Type :Member Function
Input parameters :
argc :argument count
argv :Pointer to string array storing command line arguments
Output parameters :None
Return Type :Integer
Global Variables :None
Calling Syntax :
Calls :CWMICommandLine::Initialize,
CWMICommandLine::UnInitialize,
CFormatEngine::DisplayResults,
CWMICommandLine::ProcessCommandAndDisplayResults
Called by :None
Notes :None
------------------------------------------------------------------------*/
__cdecl _tmain(WMICLIINT argc, _TCHAR **argv)
{
SESSIONRETCODE ssnRetCode = SESSION_SUCCESS;
BOOL bFileEmpty = FALSE;
BOOL bIndirectionInput = FALSE;
FILE *fpInputFile = NULL;
WMICLIUINT uErrLevel = 0;
try
{
_bstr_t bstrBuf;
// Initailize the CWMICommandLine object.
if (g_wmiCmd.Initialize())
{
HANDLE hStd=GetStdHandle(STD_INPUT_HANDLE);
if(hStd != (HANDLE)0x00000003 && hStd != INVALID_HANDLE_VALUE &&
hStd != (HANDLE)0x0000000f)
{
if (!(g_wmiCmd.ReadXMLOrBatchFile(hStd)) ||
(fpInputFile = _tfopen(TEMP_BATCH_FILE, _T("r"))) == NULL)
{
g_wmiCmd.SetSessionErrorLevel(SESSION_ERROR);
uErrLevel = g_wmiCmd.GetSessionErrorLevel();
g_wmiCmd.Uninitialize();
return uErrLevel;
}
bIndirectionInput = TRUE;
}
// If no command line arguments are specified.
if (argc == 1)
{
// Allocate memory for the g_pszBuffer
g_pszBuffer = new _TCHAR[MAX_BUFFER];
// If memory allocation successfull
if (g_pszBuffer)
{
while (TRUE)
{
OUTPUTSPEC opsOutOpt = g_wmiCmd.GetParsedInfoObject().
GetGlblSwitchesObject().
GetOutputOrAppendOption(TRUE);
OUTPUTSPEC opsSavedOutOpt = opsOutOpt;
CHString chsSavedOutFileName;
if ( opsSavedOutOpt == FILEOUTPUT )
chsSavedOutFileName =
g_wmiCmd.GetParsedInfoObject().
GetGlblSwitchesObject().
GetOutputOrAppendFileName(TRUE);
// Make propmt to be diplayed to stdout.
if ( opsOutOpt != STDOUT )
{
g_wmiCmd.GetParsedInfoObject().
GetGlblSwitchesObject().
SetOutputOrAppendOption(STDOUT, TRUE);
}
// Preserve append file pointer.
FILE* fpAppend =
g_wmiCmd.GetParsedInfoObject().
GetGlblSwitchesObject().
GetOutputOrAppendFilePointer(FALSE);
// Set append file pointer = null.
g_wmiCmd.GetParsedInfoObject().
GetGlblSwitchesObject().
SetOutputOrAppendFilePointer(NULL, FALSE);
// Display the prompt;
bstrBuf = _bstr_t(EXEC_NAME);
bstrBuf += _bstr_t(":");
bstrBuf += _bstr_t(g_wmiCmd.GetParsedInfoObject().
GetGlblSwitchesObject().GetRole());
bstrBuf += _bstr_t(">");
DisplayMessage(bstrBuf, CP_OEMCP, FALSE, FALSE);
// To handle Ctrl+C at propmt, Start accepting command
g_wmiCmd.SetAcceptCommand(TRUE);
// To handle batch input from file.
_TCHAR *pBuf = NULL;
while(TRUE)
{
if ( bIndirectionInput == TRUE )
pBuf = _fgetts(g_pszBuffer, MAX_BUFFER-1,
fpInputFile);
else
pBuf = _fgetts(g_pszBuffer, MAX_BUFFER-1, stdin);
if(pBuf != NULL)
{
if ( bIndirectionInput == TRUE )
{
DisplayMessage(g_pszBuffer, CP_OEMCP,
FALSE, FALSE);
}
LONG lInStrLen = lstrlen(g_pszBuffer);
if(g_pszBuffer[lInStrLen - 1] == _T('\n'))
g_pszBuffer[lInStrLen - 1] = _T('\0');
break;
}
// Indicates end of file
if (pBuf == NULL)
{
// Set the bFileEmpty flag to TRUE
bFileEmpty = TRUE;
break;
}
}
// To handle Ctrl+C at propmt, End accepting command
// and start of executing command
g_wmiCmd.SetAcceptCommand(FALSE);
// Set append file pointer = saved.
g_wmiCmd.GetParsedInfoObject().
GetGlblSwitchesObject().
SetOutputOrAppendFilePointer(fpAppend, FALSE);
// Redirect the output back to file specified.
if ( opsOutOpt != STDOUT )
{
g_wmiCmd.GetParsedInfoObject().
GetGlblSwitchesObject().
SetOutputOrAppendOption(opsOutOpt, TRUE);
}
// Set the error level to success.
g_wmiCmd.SetSessionErrorLevel(SESSION_SUCCESS);
// If all the commands in the batch file got executed.
if (bFileEmpty)
{
SAFEDELETE(g_pszBuffer);
break;
}
// Set Break Event to False
g_wmiCmd.SetBreakEvent(FALSE);
// Clear the clipboard.
g_wmiCmd.EmptyClipBoardBuffer();
// Process the command and display results.
ssnRetCode = g_wmiCmd.ProcessCommandAndDisplayResults
(g_pszBuffer);
uErrLevel = g_wmiCmd.GetSessionErrorLevel();
// Break the loop if "QUIT" keyword is keyed-in.
if(ssnRetCode == SESSION_QUIT)
{
SAFEDELETE(g_pszBuffer);
break;
}
opsOutOpt = g_wmiCmd.GetParsedInfoObject().
GetGlblSwitchesObject().
GetOutputOrAppendOption(TRUE);
if ( opsOutOpt == CLIPBOARD )
CopyToClipBoard(g_wmiCmd.GetClipBoardBuffer());
if ( ( opsOutOpt != FILEOUTPUT &&
CloseOutputFile() == FALSE ) ||
CloseAppendFile() == FALSE )
{
SAFEDELETE(g_pszBuffer);
break;
}
if ( g_wmiCmd.GetParsedInfoObject().
GetCmdSwitchesObject().
GetOutputSwitchFlag() == TRUE )
{
if ( opsOutOpt == FILEOUTPUT &&
CloseOutputFile() == FALSE )
{
SAFEDELETE(g_pszBuffer);
break;
}
g_wmiCmd.GetParsedInfoObject().
GetCmdSwitchesObject().
SetOutputSwitchFlag(FALSE);
if ( opsOutOpt == FILEOUTPUT )
g_wmiCmd.GetParsedInfoObject().
GetGlblSwitchesObject().
SetOutputOrAppendFileName(NULL, TRUE);
g_wmiCmd.GetParsedInfoObject().
GetGlblSwitchesObject().
SetOutputOrAppendOption(opsSavedOutOpt
, TRUE);
if ( opsSavedOutOpt == FILEOUTPUT )
g_wmiCmd.GetParsedInfoObject().
GetGlblSwitchesObject().
SetOutputOrAppendFileName(
_bstr_t((LPCWSTR)chsSavedOutFileName),
TRUE);
}
}
}
else
{
ssnRetCode = SESSION_ERROR;
g_wmiCmd.GetParsedInfoObject().GetCmdSwitchesObject().
SetErrataCode(OUT_OF_MEMORY);
g_wmiCmd.SetSessionErrorLevel(ssnRetCode);
uErrLevel = g_wmiCmd.GetSessionErrorLevel();
}
}
// If command line arguments are specified.
else
{
// Obtain the command line string
g_pszBuffer = GetCommandLine();
if (g_pszBuffer != NULL)
{
// Set the error level to success.
g_wmiCmd.SetSessionErrorLevel(SESSION_SUCCESS);
// Process the command and display results.
while( *(++g_pszBuffer) != _T(' '));
ssnRetCode = g_wmiCmd.ProcessCommandAndDisplayResults(g_pszBuffer);
uErrLevel = g_wmiCmd.GetSessionErrorLevel();
}
}
// Call the uninitialize function of the CWMICommandLine object.
g_wmiCmd.Uninitialize();
if ( bIndirectionInput == TRUE )
{
fclose(fpInputFile);
DeleteFile(TEMP_BATCH_FILE);
}
}
else
{
ssnRetCode = SESSION_ERROR;
// If COM error.
if (g_wmiCmd.GetParsedInfoObject().
GetCmdSwitchesObject().GetCOMError())
{
g_wmiCmd.GetFormatObject().
DisplayResults(g_wmiCmd.GetParsedInfoObject());
}
g_wmiCmd.SetSessionErrorLevel(ssnRetCode);
uErrLevel = g_wmiCmd.GetSessionErrorLevel();
g_wmiCmd.Uninitialize();
}
}
catch(...)
{
ssnRetCode = SESSION_ERROR;
g_wmiCmd.GetParsedInfoObject().GetCmdSwitchesObject().
SetErrataCode(UNKNOWN_ERROR);
g_wmiCmd.SetSessionErrorLevel(ssnRetCode);
DisplayString(IDS_E_WMIC_UNKNOWN_ERROR, CP_OEMCP,
NULL, TRUE, TRUE);
uErrLevel = g_wmiCmd.GetSessionErrorLevel();
g_wmiCmd.Uninitialize();
SAFEDELETE(g_pszBuffer);
if ( bIndirectionInput == TRUE )
{
fclose(fpInputFile);
DeleteFile(TEMP_BATCH_FILE);
}
}
return uErrLevel;
}
/*------------------------------------------------------------------------
Name :CtrlHandler
Synopsis :Handler routine to handle CTRL + C so as free
the memory allocated during the program execution.
Type :Global Function
Input parameters :
fdwCtrlType - control handler type
Output parameters :None
Return Type :BOOL
Global Variables :
g_pszBuffer - command buffer
g_wmiCmd - wmi command line object
Notes :None
------------------------------------------------------------------------*/
BOOL CtrlHandler(DWORD fdwCtrlType)
{
BOOL bRet = FALSE;
switch (fdwCtrlType)
{
case CTRL_C_EVENT:
// if at command propmt
if ( g_wmiCmd.GetAcceptCommand() == TRUE )
{
SAFEDELETE(g_pszBuffer);
g_wmiCmd.Uninitialize();
bRet = FALSE;
}
else // executing command
{
g_wmiCmd.SetBreakEvent(TRUE);
bRet = TRUE;
}
break;
case CTRL_CLOSE_EVENT:
default:
SAFEDELETE(g_pszBuffer);
g_wmiCmd.Uninitialize();
bRet = FALSE;
break;
}
return bRet;
}
/*------------------------------------------------------------------------
Name :CloseOutputFile
Synopsis :Close the output file.
Type :Global Function
Input parameters :None
Output parameters :None
Return Type :BOOL
Global Variables :
g_wmiCmd - wmi command line object
Calling Syntax :CloseOutputFile()
Notes :None
------------------------------------------------------------------------*/
BOOL CloseOutputFile()
{
BOOL bRet = TRUE;
// TRUE for getting output file pointer.
FILE* fpOutputFile =
g_wmiCmd.GetParsedInfoObject().GetGlblSwitchesObject().
GetOutputOrAppendFilePointer(TRUE);
// If currently output is going to file close the file.
if ( fpOutputFile != NULL )
{
if ( fclose(fpOutputFile) == EOF )
{
DisplayString(IDS_E_CLOSE_OUT_FILE_ERROR, CP_OEMCP,
NULL, TRUE, TRUE);
bRet = FALSE;
}
else // TRUE for setting output file pointer.
g_wmiCmd.GetParsedInfoObject().GetGlblSwitchesObject().
SetOutputOrAppendFilePointer(NULL, TRUE);
}
return bRet;
}
/*------------------------------------------------------------------------
Name :CloseAppendFile
Synopsis :Close the append file.
Type :Global Function
Input parameters :None
Output parameters :None
Return Type :BOOL
Global Variables :
g_wmiCmd - wmi command line object
Calling Syntax :CloseAppendFile()
Notes :None
------------------------------------------------------------------------*/
BOOL CloseAppendFile()
{
BOOL bRet = TRUE;
// FALSE for getting append file pointer.
FILE* fpAppendFile =
g_wmiCmd.GetParsedInfoObject().GetGlblSwitchesObject().
GetOutputOrAppendFilePointer(FALSE);
if ( fpAppendFile != NULL )
{
if ( fclose(fpAppendFile) == EOF )
{
DisplayString(IDS_E_CLOSE_APPEND_FILE_ERROR, CP_OEMCP,
NULL, TRUE, TRUE);
bRet = FALSE;
}
else // FASLE for setting output file pointer.
g_wmiCmd.GetParsedInfoObject().GetGlblSwitchesObject().
SetOutputOrAppendFilePointer(NULL, FALSE);
}
return bRet;
}
/*------------------------------------------------------------------------
Name :CopyToClipBoard
Synopsis :Copy data to clip board.
Type :Global Function
Input parameters :
bstrClipBoardBuffer - reference to object of type _bstr_t.
Output parameters :None
Return Type :void
Global Variables :None
Calling Syntax :CopyToClipBoard(bstrClipBoardBuffer)
Notes :None
------------------------------------------------------------------------*/
void CopyToClipBoard(_bstr_t& bstrClipBoardBuffer)
{
HGLOBAL hMem = CopyStringToHGlobal(bstrClipBoardBuffer);
if (hMem != NULL)
{
if (OpenClipboard(NULL))
{
EmptyClipboard();
SetClipboardData(CF_UNICODETEXT, hMem);
CloseClipboard();
}
else
GlobalFree(hMem); //We must clean up.
}
}
/*------------------------------------------------------------------------
Name :CopyStringToHGlobal
Synopsis :Copy string to global memory.
Type :Global Function
Input parameters :
psz - LPTSTR type, specifying string to get memory allocated.
Output parameters :None
Return Type :HGLOBAL
Global Variables :None
Calling Syntax :CopyStringToHGlobal(psz)
Notes :None
------------------------------------------------------------------------*/
HGLOBAL CopyStringToHGlobal(LPTSTR psz)
{
HGLOBAL hMem;
LPTSTR pszDst;
hMem = GlobalAlloc(GHND, (DWORD) (lstrlen(psz)+1) * sizeof(TCHAR));
if (hMem != NULL)
{
pszDst = (LPTSTR) GlobalLock(hMem);
lstrcpy(pszDst, psz);
GlobalUnlock(hMem);
}
return hMem;
}