|
|
/*++
Copyright (c) 2000 Microsoft Corporation
Module Name:
cliparse.cpp
Abstract:
Implements CLI parsing engine
Author:
Ravisankar Pudipeddi [ravisp] 3-March-2000
Revision History:
--*/
//
// Throughout this parse module, we return E_NOINTERFACE
// to indicate invalid command line syntax/parameters.
// This is to explicitly distinguish from E_INVALIDARG that may
// be returned by the CLI dll: we wish to distinguish a syntax error
// detected by the parser from a syntax error detected by the CLI dll
// because in the latter case we do not print the usage for the interface.
// Whereas for errors detected by the parser, we *do* print the usage.
// This rule needs to be strictly adhered to
//
#include "stdafx.h"
#include "stdlib.h"
#include "cliparse.h"
#include "string.h"
#include "locale.h"
#include "winnlsp.h"
#pragma warning( disable : 4100 )
CComModule _Module; CComPtr<IWsbTrace> g_pTrace;
#define MAX_ARGS 40
#define MAX_SWITCHES 20
//
// List of all CLI keywords
// TBD: Sort them!
//
RSS_KEYWORD RssInterfaceStrings[] = { {L"ADMIN", L"AD", ADMIN_IF}, {L"VOLUME", L"VL", VOLUME_IF}, {L"MEDIA", L"MD", MEDIA_IF}, {L"FILE", L"FL", FILE_IF}, {L"SHOW", L"SH", SHOW_IF}, {L"SET", L"ST", SET_IF}, {L"MANAGE", L"MG", MANAGE_IF}, {L"UNMANAGE", L"UM", UNMANAGE_IF}, {L"DELETE", L"DL", DELETE_IF}, {L"JOB", L"JB", JOB_IF}, {L"RECALL", L"RC", RECALL_IF}, {L"SYNCHRONIZE", L"SN", SYNCHRONIZE_IF}, {L"RECREATEMASTER", L"RM", RECREATEMASTER_IF}, {L"HELP", L"/?", HELP_IF}, //
// Duplicate entry for HELP to recognize -? also as a help
// interface
//
{L"HELP", L"-?", HELP_IF}, {NULL, NULL, UNKNOWN_IF} };
//
// Rss option strings - listed here without the preceding
// '/' or '-' (or whatever that distinguishes a switch from
// an argument)
// TBD: Sort them!
//
RSS_SWITCH_DEFINITION RssSwitchStrings[] = { {L"RECALLLIMIT", L"LM", RECALLLIMIT_SW, RSS_ARG_DWORD}, {L"MEDIACOPIES", L"MC", MEDIACOPIES_SW, RSS_ARG_DWORD}, {L"SCHEDULE", L"SC", SCHEDULE_SW, RSS_ARG_STRING}, {L"CONCURRENCY", L"CN", CONCURRENCY_SW, RSS_ARG_DWORD}, {L"ADMINEXEMPT", L"AE", ADMINEXEMPT_SW, RSS_ARG_DWORD}, {L"GENERAL", L"GN", GENERAL_SW, RSS_NO_ARG}, {L"MANAGEABLES", L"MS", MANAGEABLES_SW, RSS_NO_ARG}, {L"MANAGED", L"MN", MANAGED_SW, RSS_NO_ARG}, {L"MEDIA", L"MD", MEDIA_SW, RSS_NO_ARG}, {L"DFS", L"DF", DFS_SW, RSS_ARG_DWORD}, {L"SIZE", L"SZ", SIZE_SW, RSS_ARG_DWORD}, {L"ACCESS", L"AC", ACCESS_SW, RSS_ARG_DWORD}, {L"INCLUDE", L"IN", INCLUDE_SW, RSS_ARG_STRING}, {L"EXCLUDE", L"EX", EXCLUDE_SW, RSS_ARG_STRING}, {L"RECURSIVE", L"RC", RECURSIVE_SW, RSS_NO_ARG}, {L"QUICK", L"QK", QUICK_SW, RSS_NO_ARG}, {L"FULL", L"FL", FULL_SW, RSS_NO_ARG}, {L"RULE", L"RL", RULE_SW, RSS_ARG_STRING}, {L"STATISTICS", L"ST", STATISTICS_SW, RSS_NO_ARG}, {L"TYPE", L"TY", TYPE_SW, RSS_ARG_STRING}, {L"RUN", L"RN", RUN_SW, RSS_NO_ARG}, {L"CANCEL", L"CX", CANCEL_SW, RSS_NO_ARG}, {L"WAIT", L"WT", WAIT_SW, RSS_NO_ARG}, {L"COPYSET", L"CS", COPYSET_SW, RSS_ARG_DWORD}, {L"NAME", L"NM", NAME_SW, RSS_ARG_STRING}, {L"STATUS", L"SS", STATUS_SW, RSS_NO_ARG}, {L"CAPACITY", L"CP", CAPACITY_SW, RSS_NO_ARG}, {L"FREESPACE", L"FS", FREESPACE_SW, RSS_NO_ARG}, {L"VERSION", L"VR", VERSION_SW, RSS_NO_ARG}, {L"COPIES", L"CP", COPIES_SW, RSS_NO_ARG}, {L"HELP", L"?", HELP_SW, RSS_NO_ARG}, {NULL, NULL, UNKNOWN_SW, RSS_NO_ARG} };
RSS_JOB_DEFINITION RssJobTypeStrings[] = { {L"CREATEFREESPACE", L"F", CreateFreeSpace}, {L"COPYFILES", L"C", CopyFiles}, {L"VALIDATE", L"V", Validate}, {NULL, NULL, InvalidJobType} };
//
// Global arrays of arguments and switches
// These will be used as 'known' entities by all
// the interface implementations instead of passing
// them around as parameters
//
LPWSTR Args[MAX_ARGS]; RSS_SWITCHES Switches[MAX_SWITCHES]; DWORD NumberOfArguments = 0; DWORD NumberOfSwitches = 0;
//
// Useful macros
//
#define CLIP_ARGS_REQUIRED() { \
if (NumberOfArguments <= 0) { \ WsbThrow(E_NOINTERFACE); \ } \ }
#define CLIP_ARGS_NOT_REQUIRED() { \
if (NumberOfArguments > 0) { \ WsbThrow(E_NOINTERFACE); \ } \ }
#define CLIP_SWITCHES_REQUIRED() { \
if (NumberOfSwitches <= 0) { \ WsbThrow(E_NOINTERFACE); \ } \ }
#define CLIP_SWITCHES_NOT_REQUIRED() { \
if (NumberOfSwitches > 0) { \ WsbThrow(E_NOINTERFACE); \ } \ }
#define CLIP_TRANSLATE_HR_AND_RETURN(__HR) { \
if (__HR == S_OK) { \ return CLIP_ERROR_SUCCESS; \ } else if ((__HR == E_NOINTERFACE) || \ (__HR == E_INVALIDARG)) { \ return CLIP_ERROR_INVALID_PARAMETER; \ } else if (__HR == E_OUTOFMEMORY) { \ return CLIP_ERROR_INSUFFICIENT_MEMORY; \ } else { \ return CLIP_ERROR_UNKNOWN; \ } \ }
#define CLIP_GET_DWORD_ARG(__VAL, __STRING, __STOPSTRING) { \
__VAL = wcstol(__STRING, &(__STOPSTRING), 10); \ if (*(__STOPSTRING) != L'\0') { \ WsbThrow(E_NOINTERFACE); \ } \ }
#define CLIP_VALIDATE_DUPLICATE_DWORD_ARG(__ARG) { \
if ((__ARG) != INVALID_DWORD_ARG) { \ WsbThrow(E_NOINTERFACE); \ } \ }
#define CLIP_VALIDATE_DUPLICATE_POINTER_ARG(__ARG) { \
if ((__ARG) != INVALID_POINTER_ARG) { \ WsbThrow(E_NOINTERFACE); \ } \ }
//
// Local function prototypes
//
RSS_INTERFACE ClipGetInterface( IN LPWSTR InterfaceString );
DWORD ClipGetSwitchTypeIndex( IN LPWSTR SwitchString );
HSM_JOB_TYPE ClipGetJobType( IN LPWSTR JobTypeString );
HRESULT ClipCompileSwitchesAndArgs( IN LPWSTR CommandLine, IN RSS_INTERFACE Interface, IN RSS_INTERFACE SubInterface );
VOID ClipCleanup( VOID );
HRESULT ClipAdminShow( VOID );
HRESULT ClipAdminSet( VOID );
HRESULT ClipVolumeShow( VOID );
HRESULT ClipVolumeUnmanage( VOID );
HRESULT ClipVolumeSetManage( IN BOOL Set );
HRESULT ClipVolumeDelete( VOID );
HRESULT ClipVolumeJob( VOID );
HRESULT ClipMediaShow( VOID );
HRESULT ClipMediaSynchronize( VOID );
HRESULT ClipMediaRecreateMaster( VOID );
HRESULT ClipMediaDelete( VOID );
HRESULT ClipFileRecall( VOID );
VOID ClipHelp( IN RSS_INTERFACE Interface, IN RSS_INTERFACE SubInterface );
HRESULT ClipParseTime( IN LPWSTR TimeString, OUT PSYSTEMTIME ScheduledTime );
HRESULT ClipParseSchedule( IN LPWSTR ScheduleString, OUT PHSM_JOB_SCHEDULE Schedule ); BOOL ClipInitializeTrace( VOID );
VOID ClipUninitializeTrace( VOID );
VOID ClipHandleErrors( IN HRESULT RetCode, IN RSS_INTERFACE Interface, IN RSS_INTERFACE SubInterface ); //
// Function bodies start here
//
RSS_INTERFACE ClipGetInterface( IN LPWSTR InterfaceString ) /*++
Routine Description:
Maps the interface string that is supplied to an enum
Arguments InterfaceString - Pointer to the interface string TBD: implement a binary search
Return Value
UNKNOWN_IF - if the interface string is not recognized An RSS_INTERFACE value if it is.
--*/ { DWORD i; RSS_INTERFACE ret = UNKNOWN_IF;
WsbTraceIn(OLESTR("ClipHandleErrors"), OLESTR(""));
for (i=0 ; TRUE ; i++) { if (RssInterfaceStrings[i].Long == NULL) { //
// Reached end of table.
//
break;
} else if ((_wcsicmp(RssInterfaceStrings[i].Short, InterfaceString) == 0) || (_wcsicmp(RssInterfaceStrings[i].Long, InterfaceString) == 0)) { ret = RssInterfaceStrings[i].Interface; break;
} }
WsbTraceOut(OLESTR("ClipGetInterface"), OLESTR("Interface = <%ls>"), WsbLongAsString((LONG) ret)); return ret; }
DWORD ClipGetSwitchTypeIndex( IN LPWSTR SwitchString ) /*++
Routine Description
Maps the Switch to an entry in the global list of switches and returns the index
Arguments
SwitchString - Pointer to switch string TBD: implement a binary search
Return Value
-1 - If the switch is not recognized A positive value (index to the entry) if it is --*/ { DWORD i;
WsbTraceIn(OLESTR("ClipGetSwitchTypeIndex"), OLESTR(""));
for (i = 0; TRUE; i++) { if (RssSwitchStrings[i].Long == NULL) { //
// Reached end of table.
//
i = -1; break; } else if ((_wcsicmp(RssSwitchStrings[i].Short, SwitchString) == 0) || (_wcsicmp(RssSwitchStrings[i].Long, SwitchString) == 0)) {
break; } }
WsbTraceOut(OLESTR("ClipGetSwitchTypeIndex"), OLESTR("index = <%ls>"), WsbLongAsString((LONG) i)); return i; }
HSM_JOB_TYPE ClipGetJobType( IN LPWSTR JobTypeString ) /*++
Routine Description
Maps the job string to an enum
Arguments
JobTypeString - Pointer to JobType string TBD: implement a binary search
Return Value
InvalidJobType - If the job type is not recognized HSM_JOB_TYPE value if it is --*/ { DWORD i; HSM_JOB_TYPE jobType = InvalidJobType;
WsbTraceIn(OLESTR("ClipGetJobType"), OLESTR(""));
for (i = 0; TRUE; i++) { if (RssJobTypeStrings[i].Long == NULL) { //
// Reached end of table.
//
break; } if ((_wcsicmp(RssJobTypeStrings[i].Short, JobTypeString) == 0) || (_wcsicmp(RssJobTypeStrings[i].Long, JobTypeString) == 0)) { jobType = RssJobTypeStrings[i].JobType; break; } }
WsbTraceOut(OLESTR("ClipGetJobType"), OLESTR("JobType = <%ls>"), WsbLongAsString((LONG) jobType));
return jobType; }
HRESULT ClipCompileSwitchesAndArgs( IN LPWSTR CommandLine, IN RSS_INTERFACE Interface, IN RSS_INTERFACE SubInterface ) /*++
Routine Description
Parses the passed in string and compiles all switches (a switch is identified by an appropriate delimiter preceding it, such as a '/') into a global switches array (along with the arguments to the switch) and the rest of the parameters into an Args array
Arguments
CommandLine - String to be parsed
Return Value
S_OK if success --*/ { HRESULT hr = S_OK; WCHAR token[MAX_PATH+1]; LPWSTR p = CommandLine, pToken = token, switchArg = NULL, switchString = NULL; int cToken = 0; RSS_SWITCH_TYPE switchType; DWORD index; BOOL isSwitch, skipSpace;
WsbTraceIn(OLESTR("ClipCompileSwitchesAndArgs"), OLESTR(""));
try { if (p == NULL) { WsbThrow(S_OK); }
while (*p != L'\0') {
if (wcschr(SEPARATORS, *p) != NULL) { //
// Skip white space
//
p++; continue; } if (wcschr(SWITCH_DELIMITERS, *p) != NULL) { isSwitch = TRUE; p++; if (*p == L'\0') { //
// Badly formed - a SWITCH_DELIMITER with no switch
//
WsbThrow(E_NOINTERFACE); } } else { isSwitch = FALSE; } //
// Get the rest of the word
//
skipSpace = FALSE; while (*p != L'\0' && *p != L'\n') { //
// We wish to consider stuff enclosed entirely in
// quotes as a single token. As a result
// we won't consider white space to be a delimiter
// for tokens when they are in quotes.
//
if (*p == QUOTE) { if (skipSpace) { //
// A quote was encountered previously.
// This signifies - hence - the end of the token
//
p++; break; } else { //
// Start of quoted string..don't treat whitespace
// as a delimiter anymore, only a quote will end the token
//
skipSpace = TRUE; p++; continue; } }
if (!skipSpace && (wcschr(SEPARATORS, *p) != NULL)) { //
// This is not quoted and white space was encountered..
//
break; } cToken++; if (cToken > MAX_PATH) { // Token is too large
WsbThrow(E_NOINTERFACE); } *pToken++ = *p++; }
*pToken = L'\0';
if (isSwitch) { //
// For a switch, we will have to further split it into
// the switch part and the argument part
//
switchString = wcstok(token, SWITCH_ARG_DELIMITERS);
index = ClipGetSwitchTypeIndex(switchString); if (index == -1) { //
// Invalid switch. Get out.
//
WsbThrow(E_NOINTERFACE); } switchType = RssSwitchStrings[index].SwitchType;
switchArg = wcstok(NULL, L""); //
// Validation - badly formed commandline if either:
// 1. An argument was supplied and the switch definition indicated
// no argument was required
// OR
// 2. This is a non-SHOW interface (by default show interface
// don't require arguments for options), and an argument was not
// supplied even though the switch definition indicated one is
// required.
//
// 3. This is a SHOW interface and an argument was supplied
//
if ( ((switchArg != NULL) && (RssSwitchStrings[index].ArgRequired == RSS_NO_ARG)) ||
((SubInterface != SHOW_IF) && (switchArg == NULL) && (RssSwitchStrings[index].ArgRequired != RSS_NO_ARG)) || ((SubInterface == SHOW_IF) && (switchArg != NULL))) { WsbThrow(E_NOINTERFACE); }
Switches[NumberOfSwitches].SwitchType = switchType;
if (switchArg != NULL) { Switches[NumberOfSwitches].Arg = new WCHAR [wcslen(switchArg)+1];
if (Switches[NumberOfSwitches].Arg == NULL) { WsbThrow(E_OUTOFMEMORY); }
wcscpy(Switches[NumberOfSwitches].Arg, switchArg);
} else { //
// No arg for this switch
//
Switches[NumberOfSwitches].Arg = NULL; }
NumberOfSwitches++; } else { //
// This is an argument..
//
Args[NumberOfArguments] = new WCHAR [wcslen(token)+1];
if (Args[NumberOfArguments] == NULL) { WsbThrow(E_OUTOFMEMORY); }
wcscpy(Args[NumberOfArguments], token); NumberOfArguments++; } pToken = token; cToken = 0; } }WsbCatch(hr);
WsbTraceOut(OLESTR("ClipCompileSwitchesAndArgs"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
return hr; }
VOID ClipCleanup(VOID) /*++
Routine Description
Performs global cleanup for CLI parse module. Mainly - frees up all allocated arguments and switches
Arguments
None
Return Value
None --*/ { DWORD i;
WsbTraceIn(OLESTR("ClipCleanup"), OLESTR(""));
for (i = 0; i < NumberOfArguments; i++) { delete [] Args[i]; } for (i = 0; i < NumberOfSwitches; i++) { if (Switches[i].Arg != NULL) { delete [] Switches[i].Arg; } }
WsbTraceOut(OLESTR("ClipCleanup"), OLESTR("")); }
HRESULT ClipAdminShow(VOID) /*++
Routine Description
Implements RSS ADMIN SHOW interface. Arguments are in global arrays: Args - containing list of arguments Switches - containing list of switches
Arguments None
Return Value
S_OK if everything's ok E_NOINTERFACE if args/switches are bad --*/ { DWORD i; HRESULT hr; BOOL recallLimit = FALSE; BOOL adminExempt = FALSE; BOOL mediaCopies = FALSE; BOOL concurrency = FALSE; BOOL schedule = FALSE; BOOL general = FALSE; BOOL manageables = FALSE; BOOL managed = FALSE; BOOL media = FALSE;
WsbTraceIn(OLESTR("ClipAdminShow"), OLESTR("")); try { //
// No arguments needed for this interface
//
CLIP_ARGS_NOT_REQUIRED();
if (NumberOfSwitches) { for (i = 0; i < NumberOfSwitches; i++) { switch (Switches[i].SwitchType) { case RECALLLIMIT_SW: { recallLimit = TRUE; break; } case ADMINEXEMPT_SW: { adminExempt = TRUE; break; } case MEDIACOPIES_SW: { mediaCopies = TRUE; break; } case CONCURRENCY_SW: { concurrency = TRUE; break; } case SCHEDULE_SW: { schedule = TRUE; break; } case GENERAL_SW: { general = TRUE; break; } case MANAGEABLES_SW: { manageables = TRUE; break; } case MANAGED_SW: { managed = TRUE; break; } case MEDIA_SW: { media = TRUE; break; } default: { // Unknown switch - get out
WsbThrow(E_NOINTERFACE); } } } hr = AdminShow(recallLimit, adminExempt, mediaCopies, concurrency, schedule, general, manageables, managed, media);
} else { hr = AdminShow(TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE); } }WsbCatch(hr);
WsbTraceOut(OLESTR("ClipAdminShow"), OLESTR("hr = <%ls>"), WsbHrAsString(hr)); return hr; }
HRESULT ClipAdminSet(VOID) /*++
Routine Description
Implements RSS ADMIN SET interface. Arguments are in global arrays: Args - containing list of arguments Switches - containing list of switches
Arguments None
Return Value
S_OK if everything's ok E_NOINTERFACE if arguments are invalid
--*/ { DWORD i; HRESULT hr; LPWSTR stopString = NULL; DWORD recallLimit = INVALID_DWORD_ARG; DWORD adminExempt = INVALID_DWORD_ARG; DWORD mediaCopies = INVALID_DWORD_ARG; DWORD concurrency = INVALID_DWORD_ARG; PHSM_JOB_SCHEDULE schedule = INVALID_POINTER_ARG; HSM_JOB_SCHEDULE schedAllocated;
WsbTraceIn(OLESTR("ClipAdminSet"), OLESTR("")); try { //
// No arguments needed for this interface
//
CLIP_ARGS_NOT_REQUIRED();
if (NumberOfSwitches) { for (i = 0; i < NumberOfSwitches; i++) { switch (Switches[i].SwitchType) { case RECALLLIMIT_SW: { CLIP_VALIDATE_DUPLICATE_DWORD_ARG(recallLimit); CLIP_GET_DWORD_ARG(recallLimit, Switches[i].Arg, stopString); break; }
case ADMINEXEMPT_SW: { CLIP_VALIDATE_DUPLICATE_DWORD_ARG(adminExempt); CLIP_GET_DWORD_ARG(adminExempt, Switches[i].Arg, stopString); break; }
case MEDIACOPIES_SW: { CLIP_VALIDATE_DUPLICATE_DWORD_ARG(mediaCopies); CLIP_GET_DWORD_ARG(mediaCopies, Switches[i].Arg, stopString); break; }
case CONCURRENCY_SW: { CLIP_VALIDATE_DUPLICATE_DWORD_ARG(concurrency); CLIP_GET_DWORD_ARG(concurrency, Switches[i].Arg, stopString); break; }
case SCHEDULE_SW: { CLIP_VALIDATE_DUPLICATE_POINTER_ARG(schedule); hr = ClipParseSchedule(Switches[i].Arg, &schedAllocated); if (!SUCCEEDED(hr)) { WsbThrow(E_NOINTERFACE); } else { //
// schedAllocated has the schedule
//
schedule = &schedAllocated; } break; }
default: { // Unknown switch - get out
WsbThrow(E_NOINTERFACE); } } } } hr = AdminSet(recallLimit, adminExempt, mediaCopies, concurrency, schedule); }WsbCatch(hr);
WsbTraceOut(OLESTR("ClipAdminSet"), OLESTR("hr = <%ls>"), WsbHrAsString(hr)); return hr; }
HRESULT ClipVolumeShow(VOID) /*++
Routine Description
Implements RSS VOLUME SHOW interface. Arguments are in global arrays: Args - containing list of arguments Switches - containing list of switches
Arguments None
Return Value
S_OK if everything's ok E_NOINTERFACE if arguments are invalid
--*/ { DWORD i; HRESULT hr; LPWSTR stopString = NULL; BOOL dfs = FALSE; BOOL size = FALSE; BOOL access = FALSE; BOOL rules = FALSE; BOOL statistics = FALSE;
WsbTraceIn(OLESTR("ClipVolumeShow"), OLESTR("")); try { //
// Atleast one arg. required for this interface
//
CLIP_ARGS_REQUIRED();
if (NumberOfSwitches == 0) { dfs = size = access = rules = statistics = TRUE; } else { for (i = 0; i < NumberOfSwitches; i++) { switch (Switches[i].SwitchType) { case DFS_SW: { dfs = TRUE; break; } case SIZE_SW: { size = TRUE; break; } case ACCESS_SW: { access = TRUE; break; } case RULE_SW: { rules = TRUE; break; } case STATISTICS_SW: { statistics = TRUE; break; } default: { //
// Invalid option
//
WsbThrow(E_NOINTERFACE); } } } } hr = VolumeShow(Args, NumberOfArguments, dfs, size, access, rules, statistics); }WsbCatch(hr);
WsbTraceOut(OLESTR("ClipVolumeShow"), OLESTR("hr = <%ls>"), WsbHrAsString(hr)); return hr; }
HRESULT ClipVolumeUnmanage(VOID) /*++
Routine Description
Implements RSS VOLUME UNMANAGE interface. Arguments are in global arrays: Args - containing list of arguments Switches - containing list of switches
Arguments None
Return Value
S_OK if everything's ok E_NOINTERFACE if arguments are invalid
--*/ { DWORD i = 0; HRESULT hr;
#define QUICK_UNMANAGE 0
#define FULL_UNMANAGE 1
DWORD fullOrQuick = INVALID_DWORD_ARG;
WsbTraceIn(OLESTR("ClipVolumeUnmanage"), OLESTR(""));
try { //
// Atleast one arg. required for this interface
//
CLIP_ARGS_REQUIRED();
if (NumberOfSwitches) { for (i = 0; i < NumberOfSwitches; i++) { switch (Switches[i].SwitchType) { case FULL_SW: { CLIP_VALIDATE_DUPLICATE_DWORD_ARG(fullOrQuick); fullOrQuick = FULL_UNMANAGE; break; } case QUICK_SW: { CLIP_VALIDATE_DUPLICATE_DWORD_ARG(fullOrQuick); fullOrQuick = QUICK_UNMANAGE; break; } default: { //
// Invalid option
//
WsbThrow(E_NOINTERFACE); } } } } //
// The default for UNMANAGE is quick. So if fullOrQuick is either
// QUICK_UNMANAGE or INVALID_DWORD_ARG, we call unmanage of the quick
// variety
//
hr = VolumeUnmanage(Args, NumberOfArguments, (fullOrQuick == FULL_UNMANAGE)? TRUE : FALSE); }WsbCatch(hr);
WsbTraceOut(OLESTR("ClipVolumeUnmanage"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
return hr;
}
HRESULT ClipVolumeSetManage(IN BOOL Set) /*++
Routine Description
Implements RSS VOLUME MANAGE & RSS VOLUME SET interfaces. Arguments are in global arrays: Args - containing list of arguments Switches - containing list of switches
Arguments None
Return Value
CLIP_ERROR_SUCCESS if everything's ok CLIP_ERROR_INVALID_PARAMETER if args/switches are bad CLIP_ERROR_UNKNOWN any other error
--*/ { DWORD i = 0; HRESULT hr; LPWSTR stopString = NULL; DWORD dfs = INVALID_DWORD_ARG; DWORD size = INVALID_DWORD_ARG; DWORD access = INVALID_DWORD_ARG; LPWSTR rulePath = INVALID_POINTER_ARG; LPWSTR ruleFileSpec = INVALID_POINTER_ARG; BOOL include = FALSE; BOOL recursive = FALSE;
WsbTraceIn(OLESTR("ClipVolumeSetManage"), OLESTR(""));
try { //
// Atleast one arg. required for this interface
//
CLIP_ARGS_REQUIRED();
if (NumberOfSwitches) { for (i = 0; i < NumberOfSwitches; i++) { switch (Switches[i].SwitchType) { case DFS_SW: { CLIP_VALIDATE_DUPLICATE_DWORD_ARG(dfs); CLIP_GET_DWORD_ARG(dfs, Switches[i].Arg, stopString); break; }
case SIZE_SW: { CLIP_VALIDATE_DUPLICATE_DWORD_ARG(size); CLIP_GET_DWORD_ARG(size, Switches[i].Arg, stopString); break; }
case ACCESS_SW: { CLIP_VALIDATE_DUPLICATE_DWORD_ARG(access); CLIP_GET_DWORD_ARG(access, Switches[i].Arg, stopString); break; } case INCLUDE_SW: { include = TRUE; //
// Deliberately fall down to the EXCLUDE case
// (break intentionally omitted)
//
} case EXCLUDE_SW: {
CLIP_VALIDATE_DUPLICATE_POINTER_ARG(rulePath);
rulePath = wcstok(Switches[i].Arg, RULE_DELIMITERS); ruleFileSpec = wcstok(NULL, L""); if (ruleFileSpec == NULL) { //
// Omission of this indicates all files
//
ruleFileSpec = CLI_ALL_STR; } break; } case RECURSIVE_SW: { recursive = TRUE; break; } default: { WsbThrow(E_NOINTERFACE); } } } } //
// Validate the rule arguments
//
if ((rulePath == INVALID_POINTER_ARG) && recursive) { //
// The recursive flag is valid only if a rule was specified
//
WsbThrow(E_NOINTERFACE); }
if (Set) { hr = VolumeSet(Args, NumberOfArguments, dfs, size, access, rulePath, ruleFileSpec, include, recursive); } else { hr = VolumeManage(Args, NumberOfArguments, dfs, size, access, rulePath, ruleFileSpec, include, recursive); } }WsbCatch(hr);
WsbTraceOut(OLESTR("ClipVolumeSetManage"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
return hr; }
HRESULT ClipVolumeDelete(VOID) /*++
Routine Description
Implements RSS VOLUME DELETE interface. Arguments are in global arrays: Args - containing list of arguments Switches - containing list of switches
Arguments None
Return Value
S_OK if everything's ok E_NOINTERFACE if arguments are invalid
--*/ { DWORD i; HRESULT hr; BOOL rule = FALSE; LPWSTR rulePath = INVALID_POINTER_ARG; LPWSTR ruleFileSpec = INVALID_POINTER_ARG;
WsbTraceIn(OLESTR("ClipVolumeDelete"), OLESTR(""));
try { //
// Atleast one arg. required for this interface
//
CLIP_ARGS_REQUIRED();
for (i = 0; i < NumberOfSwitches; i++) { switch (Switches[i].SwitchType) { case RULE_SW: { CLIP_VALIDATE_DUPLICATE_POINTER_ARG(rulePath); rule = TRUE; rulePath = wcstok(Switches[i].Arg, RULE_DELIMITERS); ruleFileSpec = wcstok(NULL, L""); if (ruleFileSpec == NULL) { //
// Omission of this indicates all files
//
ruleFileSpec = CLI_ALL_STR; } break; } default: { //
// Invalid option
//
WsbThrow(E_NOINTERFACE); } } } //
// Only deleting rules is supported now
//
if (rule) { hr = VolumeDeleteRule(Args, NumberOfArguments, rulePath, ruleFileSpec); } else { hr = E_NOINTERFACE; } }WsbCatch(hr);
WsbTraceOut(OLESTR("ClipVolumeDelete"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
return hr; }
HRESULT ClipVolumeJob(VOID) /*++
Routine Description
Implements RSS VOLUME JOB interface. Arguments are in global arrays: Args - containing list of arguments Switches - containing list of switches
Arguments None
Return Value
S_OK if everything's ok E_NOINTERFACE if arguments are invalid --*/ { DWORD i; HRESULT hr; HSM_JOB_TYPE jobType = InvalidJobType;
#define CANCEL_JOB 0
#define RUN_JOB 1
DWORD runOrCancel = INVALID_DWORD_ARG; BOOL synchronous = FALSE;
WsbTraceIn(OLESTR("ClipVolumeJob"), OLESTR(""));
try { //
// Atleast one arg. required for this interface
//
CLIP_ARGS_REQUIRED();
for (i = 0; i < NumberOfSwitches; i++) { switch (Switches[i].SwitchType) { case RUN_SW: { CLIP_VALIDATE_DUPLICATE_DWORD_ARG(runOrCancel); runOrCancel = RUN_JOB; break; } case CANCEL_SW: { CLIP_VALIDATE_DUPLICATE_DWORD_ARG(runOrCancel); runOrCancel = CANCEL_JOB; break; } case WAIT_SW: { synchronous = TRUE; break; } case TYPE_SW: { if (jobType != InvalidJobType) { //
// Duplicate switch. Bail
//
WsbThrow(E_NOINTERFACE); } jobType = ClipGetJobType(Switches[i].Arg); if (jobType == InvalidJobType) { //
// Invalid job type supplied..
//
WsbThrow(E_NOINTERFACE); } break; } default: { WsbThrow(E_NOINTERFACE); } } }
//
// More validation:
// job type should be valid i.e., specified
//
if (jobType == InvalidJobType) { WsbThrow(E_NOINTERFACE); }
//
// Run is the default.. (i.e. TRUE). So if runOrCancel is either
// INVALID_DWORD_ARG or RUN_JOB, we pass TRUE
//
hr = VolumeJob(Args, NumberOfArguments, jobType, (runOrCancel == CANCEL_JOB)? FALSE: TRUE, synchronous);
}WsbCatch(hr);
WsbTraceOut(OLESTR("ClipVolumeJob"), OLESTR("hr = <%ls>"), WsbHrAsString(hr)); return hr; }
HRESULT ClipMediaShow(VOID) /*++
Routine Description
Implements RSS MEDIA SHOW interface. Arguments are in global arrays: Args - containing list of arguments Switches - containing list of switches
Arguments None
Return Value
S_OK if everything's ok E_NOINTERFACE if arguments are invalid --*/ { DWORD i; HRESULT hr; BOOL name = FALSE; BOOL status = FALSE; BOOL capacity = FALSE; BOOL freeSpace = FALSE; BOOL version = FALSE; BOOL copies = FALSE;
WsbTraceIn(OLESTR("ClipMediaShow"), OLESTR(""));
try { //
// Atleast one arg. required for this interface
//
CLIP_ARGS_REQUIRED();
if (NumberOfSwitches == 0) { name = status = capacity = freeSpace = version = copies = TRUE; } else { for (i = 0; i < NumberOfSwitches; i++) { switch (Switches[i].SwitchType) { case NAME_SW: { name = TRUE; break; } case STATUS_SW: { status = TRUE; break; } case CAPACITY_SW: { capacity = TRUE; break; } case FREESPACE_SW: { freeSpace = TRUE; break; } case VERSION_SW: { version = TRUE; break; } case COPIES_SW: { copies = TRUE; break; } default: { //
// Invalid option
//
WsbThrow(E_NOINTERFACE); } } } }
hr = MediaShow(Args, NumberOfArguments, name, status, capacity, freeSpace, version, copies); }WsbCatch(hr);
WsbTraceOut(OLESTR("ClipMediaShow"), OLESTR("hr = <%ls>"), WsbHrAsString(hr)); return hr;
}
HRESULT ClipMediaSynchronize(VOID) /*++
Routine Description
Implements RSS MEDIA SYNCHRONIZE interface. Arguments are in global arrays: Args - containing list of arguments Switches - containing list of switches
Arguments None
Return Value
S_OK if everything's ok E_NOINTERFACE if arguments are invalid --*/ { DWORD i; HRESULT hr; DWORD copySetNumber = INVALID_DWORD_ARG; BOOL synchronous = FALSE; LPWSTR stopString = NULL;
WsbTraceIn(OLESTR("ClipMediaSynchronize"), OLESTR(""));
try { //
// No arguments needed
//
CLIP_ARGS_NOT_REQUIRED();
for (i = 0; i < NumberOfSwitches; i++) { switch (Switches[i].SwitchType) { case COPYSET_SW: { CLIP_VALIDATE_DUPLICATE_DWORD_ARG(copySetNumber); CLIP_GET_DWORD_ARG(copySetNumber, Switches[i].Arg, stopString); break; } case WAIT_SW: { synchronous = TRUE; break; } default: { //
// Invalid option
//
WsbThrow(E_NOINTERFACE); } } } //
// Need copy set number..
//
if (copySetNumber == INVALID_DWORD_ARG) { //
// None was specified
//
WsbThrow(E_NOINTERFACE); } hr = MediaSynchronize(copySetNumber, synchronous); }WsbCatch(hr);
WsbTraceOut(OLESTR("ClipMediaRecreateMaster"), OLESTR("hr = <%ls>"), WsbHrAsString(hr)); return hr; }
HRESULT ClipMediaRecreateMaster(VOID) /*++
Routine Description
Implements RSS MEDIA RECREATEMASTER interface. Arguments are in global arrays: Args - containing list of arguments Switches - containing list of switches
Arguments None
Return Value
S_OK if everything's ok E_NOINTERFACE if arguments are invalid
--*/ {
DWORD i; HRESULT hr; DWORD copySetNumber = INVALID_DWORD_ARG; LPWSTR stopString = NULL; BOOL synchronous = FALSE;
WsbTraceIn(OLESTR("ClipMediaRecreateMaster"), OLESTR(""));
try {
//
// Atleast one arg required
//
CLIP_ARGS_REQUIRED();
if (NumberOfArguments > 1) { //
// Only one argument supported...
//
WsbThrow(E_NOINTERFACE); }
for (i = 0; i < NumberOfSwitches; i++) { switch (Switches[i].SwitchType) { case COPYSET_SW: { CLIP_VALIDATE_DUPLICATE_DWORD_ARG(copySetNumber); CLIP_GET_DWORD_ARG(copySetNumber, Switches[i].Arg, stopString); break; }
case WAIT_SW: { synchronous = TRUE; break; }
default: { //
// Invalid option
//
WsbThrow(E_NOINTERFACE); } } } //
// Need copy set number..
//
if (copySetNumber == INVALID_DWORD_ARG) { //
// None was specified
//
WsbThrow(E_NOINTERFACE); }
hr = MediaRecreateMaster(Args[0], copySetNumber, synchronous); }WsbCatch(hr);
WsbTraceOut(OLESTR("ClipRecreateMaster"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
return hr; }
HRESULT ClipMediaDelete(VOID) /*++
Routine Description
Implements RSS MEDIA DELETE interface. Arguments are in global arrays: Args - containing list of arguments Switches - containing list of switches
Arguments None
Return Value
S_OK if everything's ok E_NOINTERFACE if arguments are invalid
--*/ { DWORD i; HRESULT hr; DWORD copySetNumber = INVALID_DWORD_ARG; LPWSTR stopString = NULL;
WsbTraceIn(OLESTR("ClipMediaDelete"), OLESTR(""));
try { //
// Atleast one arg required
//
CLIP_ARGS_REQUIRED();
for (i = 0; i < NumberOfSwitches; i++) { switch (Switches[i].SwitchType) { case COPYSET_SW: { CLIP_VALIDATE_DUPLICATE_DWORD_ARG(copySetNumber); CLIP_GET_DWORD_ARG(copySetNumber, Switches[i].Arg, stopString); break; } default: { //
// Invalid option
//
WsbThrow(E_NOINTERFACE); } } } //
// Need copy set number..
//
if (copySetNumber == INVALID_DWORD_ARG) { //
// None was specified
//
WsbThrow(E_NOINTERFACE); } hr = MediaDelete(Args, NumberOfArguments, copySetNumber); }WsbCatch(hr);
WsbTraceOut(OLESTR("ClipMediaDelete"), OLESTR("hr = <%ls>"), WsbHrAsString(hr)); return hr; }
HRESULT ClipFileRecall(VOID) /*++
Routine Description
Implements RSS FILE RECALL interface. Arguments are in global arrays: Args - containing list of arguments Switches - containing list of switches
Arguments None
Return Value
S_OK if everything's ok E_NOINTERFACE if arguments are invalid
--*/ { HRESULT hr;
WsbTraceIn(OLESTR("ClipFileRecall"), OLESTR(""));
try { //
// Atleast one arg. required for this interface
//
CLIP_ARGS_REQUIRED(); //
// No switches supported
//
CLIP_SWITCHES_NOT_REQUIRED();
hr = FileRecall(Args, NumberOfArguments);
}WsbCatch(hr);
WsbTraceOut(OLESTR("ClipFileRecall"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
return hr; }
VOID ClipHelp( IN RSS_INTERFACE Interface, IN RSS_INTERFACE SubInterface ) /*++
Routine Description
Prints appropriate help message depending on the interface Arguments
Interface - Specifies interface for which help has to be displayed SubInterface - Specifies sub-interface for which help has to be displayed
Return Value: NONE
--*/ {
#define BREAK_IF_NOT_UNKNOWN_IF(__INTERFACE) { \
if (((__INTERFACE) != UNKNOWN_IF) && \ ((__INTERFACE) != HELP_IF)) { \ break; \ } \ }
WsbTraceIn(OLESTR("ClipHelp"), OLESTR(""));
switch (Interface) { case HELP_IF: case UNKNOWN_IF: { WsbTraceAndPrint(CLI_MESSAGE_MAIN_HELP, NULL); BREAK_IF_NOT_UNKNOWN_IF(SubInterface); }
case ADMIN_IF: { switch (SubInterface) { case HELP_IF: case UNKNOWN_IF: case SHOW_IF: { WsbTraceAndPrint(CLI_MESSAGE_ADMIN_SHOW_HELP, NULL); BREAK_IF_NOT_UNKNOWN_IF(SubInterface); } case SET_IF: { WsbTraceAndPrint(CLI_MESSAGE_ADMIN_SET_HELP, NULL); BREAK_IF_NOT_UNKNOWN_IF(SubInterface); } } BREAK_IF_NOT_UNKNOWN_IF(Interface); } case VOLUME_IF: { switch (SubInterface) { case HELP_IF: case UNKNOWN_IF: case SHOW_IF: { WsbTraceAndPrint(CLI_MESSAGE_VOLUME_SHOW_HELP, NULL); BREAK_IF_NOT_UNKNOWN_IF(SubInterface); } case SET_IF: { WsbTraceAndPrint(CLI_MESSAGE_VOLUME_SET_HELP, NULL); BREAK_IF_NOT_UNKNOWN_IF(SubInterface); } case MANAGE_IF: { WsbTraceAndPrint(CLI_MESSAGE_VOLUME_MANAGE_HELP, NULL); BREAK_IF_NOT_UNKNOWN_IF(SubInterface); } case UNMANAGE_IF: { WsbTraceAndPrint(CLI_MESSAGE_VOLUME_UNMANAGE_HELP, NULL); BREAK_IF_NOT_UNKNOWN_IF(SubInterface); } case JOB_IF: { WsbTraceAndPrint(CLI_MESSAGE_VOLUME_JOB_HELP, NULL); BREAK_IF_NOT_UNKNOWN_IF(SubInterface); } case DELETE_IF: { WsbTraceAndPrint(CLI_MESSAGE_VOLUME_DELETE_HELP, NULL); BREAK_IF_NOT_UNKNOWN_IF(SubInterface); } } BREAK_IF_NOT_UNKNOWN_IF(Interface); }
case MEDIA_IF: { switch (SubInterface) { case HELP_IF: case UNKNOWN_IF: case SHOW_IF: { WsbTraceAndPrint(CLI_MESSAGE_MEDIA_SHOW_HELP, NULL); BREAK_IF_NOT_UNKNOWN_IF(SubInterface); } case DELETE_IF: { WsbTraceAndPrint(CLI_MESSAGE_MEDIA_DELETE_HELP, NULL); BREAK_IF_NOT_UNKNOWN_IF(SubInterface); } case SYNCHRONIZE_IF: { WsbTraceAndPrint(CLI_MESSAGE_MEDIA_SYNCHRONIZE_HELP, NULL); BREAK_IF_NOT_UNKNOWN_IF(SubInterface); } case RECREATEMASTER_IF: { WsbTraceAndPrint(CLI_MESSAGE_MEDIA_RECREATEMASTER_HELP, NULL); BREAK_IF_NOT_UNKNOWN_IF(SubInterface); } } BREAK_IF_NOT_UNKNOWN_IF(Interface); } case FILE_IF: { switch (SubInterface) { case HELP_IF: case UNKNOWN_IF: case RECALL_IF: { WsbTraceAndPrint(CLI_MESSAGE_FILE_RECALL_HELP, NULL); BREAK_IF_NOT_UNKNOWN_IF(SubInterface); } } BREAK_IF_NOT_UNKNOWN_IF(Interface); } } WsbTraceOut(OLESTR("ClipHelp"), OLESTR("")); }
HRESULT ClipParseTime( IN LPWSTR TimeString, OUT PSYSTEMTIME ScheduledTime) /*++
Routine Description
Parses the passed in TimeString as a 24 hour format (hh:mm:ss) and sets hour/minute/sec/millisec in the passed in SYSTEMTIME structure Arguments
TimeString - String in the format "hh:mm:ss" ScheduledTime - Pointer to SYSTEMTIME structure. Time parsed from TimeString (if ok) will be used to set hour/min/sec/millisec fields in this struc.
Return Value
S_OK - TimeString is valid and time was successfully parsed Any other - Syntax error in TimeString
--*/ { LPWSTR stopString = NULL, hourString = NULL, minuteString = NULL, secondString = NULL; DWORD hour, minute, second = 0; HRESULT hr = S_OK;
WsbTraceIn(OLESTR("ClipParseTime"), OLESTR(""));
try { hourString = wcstok(TimeString, HSM_SCHED_TIME_SEPARATORS); WsbAssert(hourString != NULL, E_NOINTERFACE); CLIP_GET_DWORD_ARG(hour, hourString, stopString);
if (hour > 23) { WsbThrow(E_NOINTERFACE); }
minuteString = wcstok(NULL, HSM_SCHED_TIME_SEPARATORS); WsbAssert(minuteString != NULL, E_NOINTERFACE); CLIP_GET_DWORD_ARG(minute, minuteString, stopString);
if (minute > 59) { WsbThrow(E_NOINTERFACE); }
secondString = wcstok(NULL, HSM_SCHED_TIME_SEPARATORS); if (secondString != NULL) { CLIP_GET_DWORD_ARG(second, secondString, stopString); if (second > 59) { WsbThrow(E_NOINTERFACE); } }
ScheduledTime->wHour = (WORD) hour; ScheduledTime->wMinute = (WORD) minute; ScheduledTime->wSecond = (WORD) second; ScheduledTime->wMilliseconds = 0;
}WsbCatch(hr);
WsbTraceOut(OLESTR("ClipParseTime"), OLESTR(""));
return hr; }
HRESULT ClipParseSchedule( IN LPWSTR ScheduleString, OUT PHSM_JOB_SCHEDULE Schedule ) /*++
Routine Description
Parses the passed in schedule string, and constructs the canonical schedule form (of type HSM_JOB_SCHEDULE) Examples of schedule parameter: "At 21:03:00" "At Startup" "At Login" "At Idle" "Every 1 Week 1 21:03:00" "Every 2 Day 21:03:00" "Every 1 Month 2 21:03:00" Arguments
ScheduleString - String specifying the schedule in user-readable syntax Schedule - Pointer to canonical schedule form will be returned in this var. Return Value
S_OK - Successful, Schedule contains a pointer to the constructed schedule. E_OUTOFMEMORY - Lack of sufficient system resources Any other error: incorrect schedule specification --*/ { LPWSTR token; DWORD occurrence; HSM_JOB_FREQUENCY frequency; SYSTEMTIME scheduledTime; DWORD day; HRESULT hr = S_OK;
WsbTraceIn(OLESTR("ClipParseSchedule"), OLESTR(""));
try { token = wcstok(ScheduleString, SEPARATORS);
WsbAssert(token != NULL, E_NOINTERFACE);
if (!_wcsicmp(token, HSM_SCHED_AT)) {
token = wcstok(NULL, SEPARATORS);
if (token == NULL) { //
// Bad arguments
//
WsbThrow(E_NOINTERFACE); } else if (!_wcsicmp(token, HSM_SCHED_SYSTEMSTARTUP)) { //
// Once at system startup
//
Schedule->Frequency = SystemStartup; WsbThrow(S_OK); } else if (!_wcsicmp(token, HSM_SCHED_LOGIN)) { //
// Once at login time
//
Schedule->Frequency = Login; WsbThrow(S_OK); } else if (!_wcsicmp(token, HSM_SCHED_IDLE)) { //
// Whenever system's idle
//
Schedule->Frequency = WhenIdle; WsbThrow(S_OK); } else {
GetSystemTime(&scheduledTime); //
// Once at specified time.
// Parse the time string and obtain it
// TBD - Add provision to specify date as well as time
//
hr = ClipParseTime(token, &scheduledTime); WsbAssertHr(hr);
Schedule->Frequency = Once; Schedule->Parameters.Once.Time = scheduledTime; WsbThrow(S_OK); } } else if (!_wcsicmp(token, HSM_SCHED_EVERY)) { LPWSTR stopString = NULL;
//
// Get the occurrence
//
token = wcstok(NULL, SEPARATORS); WsbAssert(token != NULL, E_NOINTERFACE); CLIP_GET_DWORD_ARG(occurrence, token, stopString);
//
// Get the qualifier: Daily/Weekly/Monthly
//
token = wcstok(NULL, SEPARATORS); WsbAssert(token != NULL, E_NOINTERFACE); if (!_wcsicmp(token, HSM_SCHED_DAILY)) { frequency = Daily; } else if (!_wcsicmp(token, HSM_SCHED_WEEKLY)) { frequency = Weekly; } else if (!_wcsicmp(token, HSM_SCHED_MONTHLY)) { frequency = Monthly; } else { //
// Badly constructed argument
//
WsbThrow(E_NOINTERFACE); } //
// Get current time
//
GetSystemTime(&scheduledTime); //
// For weekly/monthly we also need to get the day of the week/month
// Monday = 1, Sunday = 7 for weekly
//
if ((frequency == Weekly) || (frequency == Monthly)) { token = wcstok(NULL, SEPARATORS); WsbAssert(token != NULL, E_NOINTERFACE);
CLIP_GET_DWORD_ARG(day, token, stopString);
//
// Validate & update the parameters
//
if (frequency == Weekly) { if (day > 6) { WsbThrow(E_NOINTERFACE); } scheduledTime.wDayOfWeek = (WORD) day; } if (frequency == Monthly) { if ((day > 31) || (day < 1)) { WsbThrow(E_NOINTERFACE); } scheduledTime.wDay = (WORD) day; } } //
// Fetch the time
//
token = wcstok(NULL, SEPARATORS); WsbAssert(token != NULL, E_NOINTERFACE); hr = ClipParseTime(token, &scheduledTime);
WsbAssertHr(hr);
Schedule->Frequency = frequency; Schedule->Parameters.Daily.Occurrence = occurrence; Schedule->Parameters.Daily.Time = scheduledTime; } else { WsbThrow(E_NOINTERFACE); } }WsbCatch(hr);
WsbTraceOut(OLESTR("ClipParseSchedule"), OLESTR(""));
return hr; }
BOOL ClipInitializeTrace( VOID ) /*++
Routine Description Initializes the trace/printing mechanism for CLI
Arguments
NONE
Return Value
TRUE if successful, FALSE otherwise
--*/ { BOOL ret = TRUE;
if (S_OK == CoCreateInstance(CLSID_CWsbTrace, 0, CLSCTX_SERVER, IID_IWsbTrace, (void **)&g_pTrace)) { CWsbStringPtr tracePath; CWsbStringPtr regPath; CWsbStringPtr outString;
// Registry path for CLI settings
// If those expand beyond Trace settings, this path should go to a header file
regPath = L"SOFTWARE\\Microsoft\\RemoteStorage\\CLI";
// Check if tracing path already exists, if not - set it (this should happen only once)
WsbAffirmHr(outString.Alloc(WSB_TRACE_BUFF_SIZE)); if ( WsbGetRegistryValueString(NULL, regPath, L"WsbTraceFileName", outString, WSB_TRACE_BUFF_SIZE, 0) != S_OK) { // No trace settings yet
WCHAR *systemPath; systemPath = _wgetenv(L"SystemRoot"); WsbAffirmHr(tracePath.Printf( L"%ls\\System32\\RemoteStorage\\Trace\\RsCli.Trc", systemPath));
// Set default settings in the Registry
WsbEnsureRegistryKeyExists(0, regPath); WsbSetRegistryValueString(0, regPath, L"WsbTraceFileName", tracePath);
// Make sure the trace directory exists.
WsbAffirmHr(tracePath.Printf( L"%ls\\System32\\RemoteStorage", systemPath)); CreateDirectory(tracePath, 0); WsbAffirmHr(tracePath.Printf( L"%ls\\System32\\RemoteStorage\\Trace", systemPath)); CreateDirectory(tracePath, 0); }
g_pTrace->SetRegistryEntry(regPath); g_pTrace->LoadFromRegistry(); }
return ret; }
VOID ClipUninitializeTrace( VOID ) /*++
Routine Description Uninitializes the trace/print mechansim Paired with ClipInitializeTrace
Arguments
NONE
Return Value
NONE
--*/ { g_pTrace = 0; }
VOID ClipHandleErrors( IN HRESULT RetCode, IN RSS_INTERFACE Interface, IN RSS_INTERFACE SubInterface ) /*++
Routine Description
Translates the main return value & displays any appropriate error messages and returns
Arguments
RetCode - Error to handle Interface - RSS interface specified in the command SubInterface - RSS sub-interface specified in the command
Return Value
None
--*/ { WsbTraceIn(OLESTR("ClipHandleErrors"), OLESTR(""));
switch (RetCode) { case E_INVALIDARG: case S_OK:{ //
// Nothing to print
//
break;}
case E_NOINTERFACE:{ WsbTraceAndPrint(CLI_MESSAGE_VALUE_DISPLAY, WsbHrAsString(E_INVALIDARG)); ClipHelp(Interface, SubInterface); break;} default:{ WsbTraceAndPrint(CLI_MESSAGE_VALUE_DISPLAY, WsbHrAsString(RetCode)); break;} }
WsbTraceOut(OLESTR("ClipHandleErrors"), OLESTR("")); }
extern "C" int __cdecl wmain() { LPWSTR commandLine, token; HRESULT hr = E_NOINTERFACE; RSS_INTERFACE intrface = HELP_IF, subInterface = UNKNOWN_IF;
try { WsbAffirmHr(CoInitialize(NULL));
//
// Set to OEM page locale
//
_wsetlocale(LC_ALL, L".OCP");
//
// Set to console UI langauge
//
SetThreadUILanguage(0);
ClipInitializeTrace();
commandLine = GetCommandLine(); //
// Get argv[0] out of the way
//
token = wcstok(commandLine, SEPARATORS);
//
// Get the interface string
//
token = wcstok(NULL, SEPARATORS);
if (token == NULL) { ClipHelp(HELP_IF, UNKNOWN_IF); hr = S_OK; goto exit; }
intrface = ClipGetInterface(token);
if (intrface == UNKNOWN_IF) { hr = E_NOINTERFACE; intrface = HELP_IF; goto exit; }
if (intrface == HELP_IF) { ClipHelp(HELP_IF, UNKNOWN_IF); hr = S_OK; goto exit; }
//
// Get sub interface string
//
token = wcstok(NULL, SEPARATORS);
if (token == NULL) { hr = E_NOINTERFACE; goto exit; } subInterface = ClipGetInterface(token);
if (subInterface == UNKNOWN_IF) { hr = E_NOINTERFACE; goto exit; }
if (subInterface == HELP_IF) { ClipHelp(intrface, UNKNOWN_IF); hr = S_OK; goto exit; } //
// Now compile the switches & arguments into separate arrays
// First, get the rest of line ..
//
token = wcstok(NULL, L""); hr = ClipCompileSwitchesAndArgs(token, intrface, subInterface);
if (hr != S_OK) { goto exit; }
switch (intrface) { case ADMIN_IF:{ if (subInterface == SHOW_IF) { hr = ClipAdminShow(); } else if (subInterface == SET_IF) { hr = ClipAdminSet(); } else { hr = E_NOINTERFACE; } break; }
case VOLUME_IF:{ if (subInterface == MANAGE_IF) { hr = ClipVolumeSetManage(FALSE); } else if (subInterface == UNMANAGE_IF) { hr = ClipVolumeUnmanage(); } else if (subInterface == SET_IF) { hr = ClipVolumeSetManage(TRUE); } else if (subInterface == SHOW_IF) { hr = ClipVolumeShow(); } else if (subInterface == DELETE_IF) { hr = ClipVolumeDelete(); } else if (subInterface == JOB_IF) { hr = ClipVolumeJob(); } else { hr = E_NOINTERFACE; } break; }
case FILE_IF:{ if (subInterface == RECALL_IF) { hr = ClipFileRecall(); } else { hr = E_NOINTERFACE; } break; }
case MEDIA_IF:{ if (subInterface == SYNCHRONIZE_IF) { hr = ClipMediaSynchronize(); } else if (subInterface == RECREATEMASTER_IF) { hr = ClipMediaRecreateMaster(); } else if (subInterface == DELETE_IF) { hr = ClipMediaDelete(); } else if (subInterface == SHOW_IF) { hr = ClipMediaShow(); } else { hr = E_NOINTERFACE; } break; }
default:{ hr = E_NOINTERFACE; break; } }
exit:
ClipHandleErrors(hr, intrface, subInterface);
ClipCleanup(); ClipUninitializeTrace(); CoUninitialize();
}WsbCatchAndDo(hr, WsbTraceAndPrint(CLI_MESSAGE_GENERIC_ERROR, WsbHrAsString(hr)); );
CLIP_TRANSLATE_HR_AND_RETURN(hr); }
|