995 lines
24 KiB
C++
995 lines
24 KiB
C++
//////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Copyright (c) 1999 Microsoft Corporation
|
|
//
|
|
// Module Name:
|
|
//
|
|
// utils.c
|
|
//
|
|
// Abstract:
|
|
//
|
|
// utils functions
|
|
//
|
|
// Revision History:
|
|
//
|
|
// Thierry Perraut 04/07/1999
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
#include "stdafx.h"
|
|
|
|
#include <netsh.h>
|
|
#include "aaaamontr.h"
|
|
#include "strdefs.h"
|
|
#include "rmstring.h"
|
|
#include "aaaamon.h"
|
|
#include "context.h"
|
|
#include <rtutils.h>
|
|
#include "utils.h"
|
|
#include "base64tool.h"
|
|
|
|
const WCHAR c_szCurrentBuildNumber[] = L"CurrentBuildNumber";
|
|
const WCHAR c_szWinVersionPath[] =
|
|
L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion";
|
|
const WCHAR c_szAssignFmt[] = L"%s = %s";
|
|
const WCHAR pszAAAAEngineParamStub[] =
|
|
L"SYSTEM\\CurrentControlSet\\Services\\AAAAEngine\\Parameters\\";
|
|
|
|
AAAA_ALLOC_FN RutlAlloc;
|
|
AAAA_DWORDDUP_FN RutlDwordDup;
|
|
AAAA_CREATE_DUMP_FILE_FN RutlCreateDumpFile;
|
|
AAAA_CLOSE_DUMP_FILE_FN RutlCloseDumpFile;
|
|
AAAA_ASSIGN_FROM_TOKENS_FN RutlAssignmentFromTokens;
|
|
AAAA_STRDUP_FN RutlStrDup;
|
|
AAAA_FREE_FN RutlFree;
|
|
AAAA_GET_OS_VERSION_FN RutlGetOsVersion;
|
|
AAAA_GET_TAG_TOKEN_FN RutlGetTagToken;
|
|
AAAA_IS_HELP_TOKEN_FN RutlIsHelpToken;
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
// RutlGetTagToken
|
|
//
|
|
// Routine Description:
|
|
//
|
|
// Identifies each argument based on its tag. It assumes that each argument
|
|
// has a tag. It also removes tag= from each argument.
|
|
//
|
|
// Arguments:
|
|
//
|
|
// ppwcArguments - The argument array. Each argument has tag=value form
|
|
// dwCurrentIndex - ppwcArguments[dwCurrentIndex] is first arg.
|
|
// dwArgCount - ppwcArguments[dwArgCount - 1] is last arg.
|
|
// pttTagToken - Array of tag token ids that are allowed in the args
|
|
// dwNumTags - Size of pttTagToken
|
|
// pdwOut - Array identifying the type of each argument.
|
|
//
|
|
// Return Value:
|
|
//
|
|
// NO_ERROR, ERROR_INVALID_PARAMETER, ERROR_INVALID_OPTION_TAG
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
DWORD
|
|
WINAPI
|
|
RutlGetTagToken(
|
|
IN HANDLE hModule,
|
|
IN PWCHAR *ppwcArguments,
|
|
IN DWORD dwCurrentIndex,
|
|
IN DWORD dwArgCount,
|
|
IN PTAG_TYPE pttTagToken,
|
|
IN DWORD dwNumTags,
|
|
OUT PDWORD pdwOut
|
|
)
|
|
{
|
|
PWCHAR pwcTag,pwcTagVal,pwszArg = NULL;
|
|
|
|
//
|
|
// This function assumes that every argument has a tag
|
|
// It goes ahead and removes the tag.
|
|
//
|
|
|
|
for ( DWORD i = dwCurrentIndex; i < dwArgCount; ++i )
|
|
{
|
|
DWORD len = wcslen(ppwcArguments[i]);
|
|
|
|
if ( !len )
|
|
{
|
|
//
|
|
// something wrong with arg
|
|
//
|
|
|
|
pdwOut[i] = static_cast<DWORD> (-1);
|
|
continue;
|
|
}
|
|
|
|
pwszArg = static_cast<unsigned short *>(RutlAlloc(
|
|
(len + 1) * sizeof(WCHAR),
|
|
FALSE));
|
|
|
|
if ( !pwszArg )
|
|
{
|
|
DisplayError(NULL, ERROR_NOT_ENOUGH_MEMORY);
|
|
return ERROR_NOT_ENOUGH_MEMORY;
|
|
}
|
|
|
|
wcscpy(pwszArg, ppwcArguments[i]);
|
|
|
|
pwcTag = wcstok(pwszArg, NETSH_ARG_DELIMITER);
|
|
|
|
//
|
|
// Got the first part
|
|
// Now if next call returns NULL then there was no tag
|
|
//
|
|
|
|
pwcTagVal = wcstok((PWCHAR)NULL, NETSH_ARG_DELIMITER);
|
|
|
|
if ( !pwcTagVal )
|
|
{
|
|
DisplayMessage(g_hModule,
|
|
ERROR_NO_TAG,
|
|
ppwcArguments[i]);
|
|
|
|
RutlFree(pwszArg);
|
|
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
//
|
|
// Got the tag. Now try to match it
|
|
//
|
|
|
|
BOOL bFound = FALSE;
|
|
pdwOut[i - dwCurrentIndex] = (DWORD) -1;
|
|
|
|
for ( DWORD j = 0; j < dwNumTags; ++j )
|
|
{
|
|
if ( MatchToken(pwcTag, pttTagToken[j].pwszTag) )
|
|
{
|
|
//
|
|
// Tag matched
|
|
//
|
|
|
|
bFound = TRUE;
|
|
pdwOut[i - dwCurrentIndex] = j;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if ( bFound )
|
|
{
|
|
//
|
|
// Remove tag from the argument
|
|
//
|
|
|
|
wcscpy(ppwcArguments[i], pwcTagVal);
|
|
}
|
|
else
|
|
{
|
|
DisplayError(NULL,
|
|
ERROR_INVALID_OPTION_TAG,
|
|
pwcTag);
|
|
|
|
RutlFree(pwszArg);
|
|
|
|
return ERROR_INVALID_OPTION_TAG;
|
|
}
|
|
|
|
RutlFree(pwszArg);
|
|
}
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
// RutlCreateDumpFile
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
DWORD
|
|
WINAPI
|
|
RutlCreateDumpFile(
|
|
IN PWCHAR pwszName,
|
|
OUT PHANDLE phFile
|
|
)
|
|
{
|
|
HANDLE hFile;
|
|
|
|
*phFile = NULL;
|
|
|
|
// Create/open the file
|
|
hFile = CreateFileW(pwszName,
|
|
GENERIC_WRITE,
|
|
FILE_SHARE_READ | FILE_SHARE_DELETE,
|
|
NULL,
|
|
OPEN_ALWAYS,
|
|
FILE_ATTRIBUTE_NORMAL,
|
|
NULL);
|
|
|
|
if ( hFile == INVALID_HANDLE_VALUE )
|
|
{
|
|
return GetLastError();
|
|
}
|
|
|
|
// Go to the end of the file
|
|
SetFilePointer(hFile, 0, NULL, FILE_END);
|
|
|
|
*phFile = hFile;
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
// RutlCloseDumpFile
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
VOID
|
|
WINAPI
|
|
RutlCloseDumpFile(HANDLE hFile)
|
|
{
|
|
CloseHandle(hFile);
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// RutlAlloc
|
|
//
|
|
// Returns an allocated block of memory conditionally
|
|
// zeroed of the given size.
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
PVOID
|
|
WINAPI
|
|
RutlAlloc(
|
|
IN DWORD dwBytes,
|
|
IN BOOL bZero
|
|
)
|
|
{
|
|
DWORD dwFlags = 0;
|
|
|
|
if ( bZero )
|
|
{
|
|
dwFlags |= HEAP_ZERO_MEMORY;
|
|
}
|
|
|
|
return HeapAlloc(GetProcessHeap(), dwFlags, dwBytes);
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// RutlFree
|
|
//
|
|
// Conditionally free's a pointer if it is non-null
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
VOID
|
|
WINAPI
|
|
RutlFree(
|
|
IN PVOID pvData
|
|
)
|
|
{
|
|
HeapFree(GetProcessHeap(), 0, pvData);
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// RutlStrDup
|
|
//
|
|
// Uses RutlAlloc to copy a string
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
PWCHAR
|
|
WINAPI
|
|
RutlStrDup(
|
|
IN PWCHAR pwszSrc
|
|
)
|
|
{
|
|
PWCHAR pszRet = NULL;
|
|
DWORD dwLen;
|
|
|
|
if (( !pwszSrc ) || ((dwLen = wcslen(pwszSrc)) == 0))
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
pszRet = static_cast<PWCHAR>(RutlAlloc((dwLen + 1) * sizeof(WCHAR),FALSE));
|
|
if ( pszRet )
|
|
{
|
|
wcscpy(pszRet, pwszSrc);
|
|
}
|
|
|
|
return pszRet;
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
// RutlDwordDup
|
|
//
|
|
// Uses RutlAlloc to copy a dword
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
LPDWORD
|
|
WINAPI
|
|
RutlDwordDup(
|
|
IN DWORD dwSrc
|
|
)
|
|
{
|
|
LPDWORD lpdwRet = NULL;
|
|
|
|
lpdwRet = static_cast<LPDWORD>(RutlAlloc(sizeof(DWORD), FALSE));
|
|
if ( lpdwRet )
|
|
{
|
|
*lpdwRet = dwSrc;
|
|
}
|
|
|
|
return lpdwRet;
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// RutlGetOsVersion
|
|
//
|
|
// Returns the build number of operating system
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
DWORD
|
|
WINAPI
|
|
RutlGetOsVersion(
|
|
IN PWCHAR pwszRouter,
|
|
OUT LPDWORD lpdwVersion)
|
|
{
|
|
|
|
DWORD dwErr, dwType = REG_SZ, dwLength;
|
|
HKEY hkMachine = NULL, hkVersion = NULL;
|
|
WCHAR pszBuildNumber[64];
|
|
PWCHAR pszMachine = pwszRouter;
|
|
|
|
//
|
|
// Validate and initialize
|
|
//
|
|
if ( !lpdwVersion )
|
|
{
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
*lpdwVersion = FALSE;
|
|
|
|
do
|
|
{
|
|
//
|
|
// Connect to the remote server
|
|
//
|
|
dwErr = RegConnectRegistry(
|
|
pszMachine,
|
|
HKEY_LOCAL_MACHINE,
|
|
&hkMachine);
|
|
if ( dwErr != ERROR_SUCCESS )
|
|
{
|
|
break;
|
|
}
|
|
|
|
//
|
|
// Open the windows version key
|
|
//
|
|
|
|
dwErr = RegOpenKeyEx(
|
|
hkMachine,
|
|
c_szWinVersionPath,
|
|
0,
|
|
KEY_QUERY_VALUE,
|
|
&hkVersion
|
|
);
|
|
if ( dwErr != NO_ERROR )
|
|
{
|
|
break;
|
|
}
|
|
|
|
//
|
|
// Read in the current version key
|
|
//
|
|
dwLength = sizeof(pszBuildNumber);
|
|
dwErr = RegQueryValueEx (
|
|
hkVersion,
|
|
c_szCurrentBuildNumber,
|
|
NULL,
|
|
&dwType,
|
|
(BYTE*)pszBuildNumber,
|
|
&dwLength
|
|
);
|
|
if ( dwErr != NO_ERROR )
|
|
{
|
|
break;
|
|
}
|
|
|
|
*lpdwVersion = static_cast<DWORD>(wcstol(pszBuildNumber, NULL, 10));
|
|
|
|
} while (FALSE);
|
|
|
|
|
|
// Cleanup
|
|
if ( hkVersion )
|
|
{
|
|
RegCloseKey( hkVersion );
|
|
}
|
|
if ( hkMachine )
|
|
{
|
|
RegCloseKey( hkMachine );
|
|
}
|
|
|
|
return dwErr;
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// RutlParseOptions
|
|
//
|
|
// Routine Description:
|
|
//
|
|
// Based on an array of tag types returns which options are
|
|
// included in the given command line.
|
|
//
|
|
// Arguments:
|
|
//
|
|
// ppwcArguments - Argument array
|
|
// dwCurrentIndex - ppwcArguments[dwCurrentIndex] is the first arg
|
|
// dwArgCount - ppwcArguments[dwArgCount - 1] is the last arg
|
|
//
|
|
// Return Value:
|
|
//
|
|
// NO_ERROR
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
DWORD
|
|
WINAPI
|
|
RutlParseOptions(
|
|
IN PWCHAR* ppwcArguments,
|
|
IN DWORD dwCurrentIndex,
|
|
IN DWORD dwArgCount,
|
|
IN DWORD dwNumArgs,
|
|
IN TAG_TYPE* rgTags,
|
|
IN DWORD dwTagCount,
|
|
OUT LPDWORD* ppdwTagTypes
|
|
)
|
|
{
|
|
LPDWORD pdwTagType;
|
|
DWORD i, dwErr = NO_ERROR;
|
|
|
|
// If there are no arguments, there's nothing to to
|
|
//
|
|
if ( !dwNumArgs )
|
|
{
|
|
return NO_ERROR;
|
|
}
|
|
|
|
// Set up the table of present options
|
|
pdwTagType = static_cast<LPDWORD>(RutlAlloc(
|
|
dwArgCount * sizeof(DWORD),
|
|
TRUE
|
|
));
|
|
if( !pdwTagType )
|
|
{
|
|
DisplayError(NULL, ERROR_NOT_ENOUGH_MEMORY);
|
|
return ERROR_NOT_ENOUGH_MEMORY;
|
|
}
|
|
|
|
do {
|
|
//
|
|
// The argument has a tag. Assume all of them have tags
|
|
//
|
|
if( wcsstr(ppwcArguments[dwCurrentIndex], NETSH_ARG_DELIMITER) )
|
|
{
|
|
dwErr = RutlGetTagToken(
|
|
g_hModule,
|
|
ppwcArguments,
|
|
dwCurrentIndex,
|
|
dwArgCount,
|
|
rgTags,
|
|
dwTagCount,
|
|
pdwTagType);
|
|
|
|
if( dwErr != NO_ERROR )
|
|
{
|
|
if( dwErr == ERROR_INVALID_OPTION_TAG )
|
|
{
|
|
dwErr = ERROR_INVALID_SYNTAX;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// No tags - all args must be in order
|
|
//
|
|
for( i = 0; i < dwNumArgs; ++i )
|
|
{
|
|
pdwTagType[i] = i;
|
|
}
|
|
}
|
|
|
|
} while (FALSE);
|
|
|
|
// Cleanup
|
|
{
|
|
if ( dwErr == NO_ERROR )
|
|
{
|
|
*ppdwTagTypes = pdwTagType;
|
|
}
|
|
else
|
|
{
|
|
RutlFree(pdwTagType);
|
|
}
|
|
}
|
|
|
|
return dwErr;
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// RutlIsHelpToken
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
BOOL
|
|
WINAPI
|
|
RutlIsHelpToken(PWCHAR pwszToken)
|
|
{
|
|
if( MatchToken(pwszToken, CMD_AAAA_HELP1) )
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
if( MatchToken(pwszToken, CMD_AAAA_HELP2) )
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// RutlAssignmentFromTokens
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
PWCHAR
|
|
WINAPI
|
|
RutlAssignmentFromTokens(
|
|
IN HINSTANCE hModule,
|
|
IN PWCHAR pwszToken,
|
|
IN PWCHAR pszString
|
|
)
|
|
{
|
|
PWCHAR pszRet = NULL, pszCmd = NULL;
|
|
DWORD dwErr = NO_ERROR, dwSize;
|
|
|
|
do
|
|
{
|
|
pszCmd = pwszToken;
|
|
|
|
// Compute the string lenghth needed
|
|
//
|
|
dwSize = wcslen(pszString) +
|
|
wcslen(pszCmd) +
|
|
wcslen(c_szAssignFmt) +
|
|
1;
|
|
dwSize *= sizeof(WCHAR);
|
|
|
|
// Allocate the return value
|
|
pszRet = (PWCHAR) RutlAlloc(dwSize, FALSE);
|
|
if (pszRet == NULL)
|
|
{
|
|
dwErr = ERROR_NOT_ENOUGH_MEMORY;
|
|
break;
|
|
}
|
|
|
|
// Copy in the command assignment
|
|
_snwprintf(
|
|
pszRet,
|
|
dwSize,
|
|
c_szAssignFmt,
|
|
pszCmd,
|
|
pszString
|
|
);
|
|
|
|
} while ( FALSE );
|
|
|
|
// Cleanup
|
|
{
|
|
if ( dwErr != NO_ERROR )
|
|
{
|
|
if ( pszRet )
|
|
{
|
|
RutlFree(pszRet);
|
|
}
|
|
pszRet = NULL;
|
|
}
|
|
}
|
|
return pszRet;
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// RutlRegReadDword
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
DWORD
|
|
RutlRegReadDword(
|
|
IN HKEY hKey,
|
|
IN PWCHAR pszValName,
|
|
OUT LPDWORD lpdwValue
|
|
)
|
|
{
|
|
DWORD dwSize = sizeof(DWORD), dwType = REG_DWORD, dwErr;
|
|
|
|
dwErr = RegQueryValueExW(
|
|
hKey,
|
|
pszValName,
|
|
NULL,
|
|
&dwType,
|
|
(LPBYTE)lpdwValue,
|
|
&dwSize);
|
|
if ( dwErr == ERROR_FILE_NOT_FOUND )
|
|
{
|
|
dwErr = NO_ERROR;
|
|
}
|
|
|
|
return dwErr;
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// RutlRegReadString
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
DWORD
|
|
RutlRegReadString(
|
|
IN HKEY hKey,
|
|
IN PWCHAR pszValName,
|
|
OUT PWCHAR* ppszValue
|
|
)
|
|
{
|
|
DWORD dwErr = NO_ERROR, dwSize = 0;
|
|
|
|
*ppszValue = NULL;
|
|
|
|
// Findout how big the buffer should be
|
|
//
|
|
dwErr = RegQueryValueExW(
|
|
hKey,
|
|
pszValName,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
&dwSize);
|
|
if ( dwErr == ERROR_FILE_NOT_FOUND )
|
|
{
|
|
return NO_ERROR;
|
|
}
|
|
if ( dwErr != ERROR_SUCCESS )
|
|
{
|
|
return dwErr;
|
|
}
|
|
|
|
// Allocate the string
|
|
//
|
|
*ppszValue = (PWCHAR) RutlAlloc(dwSize, TRUE);
|
|
if ( ! *ppszValue )
|
|
{
|
|
return ERROR_NOT_ENOUGH_MEMORY;
|
|
}
|
|
|
|
// Read the value in and return
|
|
//
|
|
dwErr = RegQueryValueExW(
|
|
hKey,
|
|
pszValName,
|
|
NULL,
|
|
NULL,
|
|
(LPBYTE)*ppszValue,
|
|
&dwSize);
|
|
|
|
return dwErr;
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// RutlRegReadString
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
DWORD
|
|
RutlRegWriteDword(
|
|
IN HKEY hKey,
|
|
IN PWCHAR pszValName,
|
|
IN DWORD dwValue
|
|
)
|
|
{
|
|
return RegSetValueExW(
|
|
hKey,
|
|
pszValName,
|
|
0,
|
|
REG_DWORD,
|
|
(LPBYTE)&dwValue,
|
|
sizeof(DWORD));
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// RutlRegWriteString
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
DWORD
|
|
RutlRegWriteString(
|
|
IN HKEY hKey,
|
|
IN PWCHAR pszValName,
|
|
IN PWCHAR pszValue
|
|
)
|
|
{
|
|
return RegSetValueExW(
|
|
hKey,
|
|
pszValName,
|
|
0,
|
|
REG_SZ,
|
|
(LPBYTE)pszValue,
|
|
(wcslen(pszValue) + 1) * sizeof(WCHAR));
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//RutlParse
|
|
//
|
|
// Generic parse
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
DWORD
|
|
RutlParse(
|
|
IN PWCHAR* ppwcArguments,
|
|
IN DWORD dwCurrentIndex,
|
|
IN DWORD dwArgCount,
|
|
IN BOOL* pbDone,
|
|
OUT AAAAMON_CMD_ARG* pAaaaArgs,
|
|
IN DWORD dwAaaaArgCount
|
|
)
|
|
{
|
|
DWORD i, dwNumArgs, dwErr, dwLevel = 0;
|
|
LPDWORD pdwTagType = NULL;
|
|
TAG_TYPE* pTags = NULL;
|
|
AAAAMON_CMD_ARG* pArg = NULL;
|
|
|
|
if ( !dwAaaaArgCount )
|
|
{
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
do
|
|
{
|
|
// Initialize
|
|
dwNumArgs = dwArgCount - dwCurrentIndex;
|
|
|
|
// Generate a list of the tags
|
|
//
|
|
pTags = (TAG_TYPE*)
|
|
RutlAlloc(dwAaaaArgCount * sizeof(TAG_TYPE), TRUE);
|
|
if ( !pTags )
|
|
{
|
|
dwErr = ERROR_NOT_ENOUGH_MEMORY;
|
|
break;
|
|
}
|
|
for ( i = 0; i < dwAaaaArgCount; ++i )
|
|
{
|
|
CopyMemory(&pTags[i], &pAaaaArgs[i].rgTag, sizeof(TAG_TYPE));
|
|
}
|
|
|
|
// Get the list of present options
|
|
//
|
|
dwErr = RutlParseOptions(
|
|
ppwcArguments,
|
|
dwCurrentIndex,
|
|
dwArgCount,
|
|
dwNumArgs,
|
|
pTags,
|
|
dwAaaaArgCount,
|
|
&pdwTagType);
|
|
if ( dwErr != NO_ERROR )
|
|
{
|
|
break;
|
|
}
|
|
|
|
// Copy the tag info back
|
|
//
|
|
for ( i = 0; i < dwAaaaArgCount; ++i )
|
|
{
|
|
CopyMemory(&pAaaaArgs[i].rgTag, &pTags[i], sizeof(TAG_TYPE));
|
|
}
|
|
|
|
for( i = 0; i < dwNumArgs; ++i )
|
|
{
|
|
// Validate the current argument
|
|
//
|
|
if ( pdwTagType[i] >= dwAaaaArgCount )
|
|
{
|
|
i = dwNumArgs;
|
|
dwErr = ERROR_INVALID_SYNTAX;
|
|
break;
|
|
}
|
|
pArg = &pAaaaArgs[pdwTagType[i]];
|
|
|
|
// Get the value of the argument
|
|
//
|
|
switch ( pArg->dwType )
|
|
{
|
|
case AAAAMONTR_CMD_TYPE_STRING:
|
|
{
|
|
pArg->Val.pszValue =
|
|
RutlStrDup(ppwcArguments[i + dwCurrentIndex]);
|
|
break;
|
|
}
|
|
|
|
case AAAAMONTR_CMD_TYPE_ENUM:
|
|
{
|
|
dwErr = MatchEnumTag(g_hModule,
|
|
ppwcArguments[i + dwCurrentIndex],
|
|
pArg->dwEnumCount,
|
|
pArg->rgEnums,
|
|
&(pArg->Val.dwValue));
|
|
|
|
if(dwErr != NO_ERROR)
|
|
{
|
|
RutlDispTokenErrMsg(
|
|
g_hModule,
|
|
EMSG_BAD_OPTION_VALUE,
|
|
pArg->rgTag.pwszTag,
|
|
ppwcArguments[i + dwCurrentIndex]);
|
|
i = dwNumArgs;
|
|
dwErr = ERROR_INVALID_PARAMETER;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
if ( dwErr != NO_ERROR )
|
|
{
|
|
break;
|
|
}
|
|
|
|
// Mark the argument as present if needed
|
|
//
|
|
if ( pArg->rgTag.bPresent )
|
|
{
|
|
dwErr = ERROR_TAG_ALREADY_PRESENT;
|
|
i = dwNumArgs;
|
|
break;
|
|
}
|
|
pArg->rgTag.bPresent = TRUE;
|
|
}
|
|
if( dwErr != NO_ERROR )
|
|
{
|
|
break;
|
|
}
|
|
|
|
// Make sure that all of the required parameters have
|
|
// been included.
|
|
//
|
|
for ( i = 0; i < dwAaaaArgCount; ++i )
|
|
{
|
|
if ( (pAaaaArgs[i].rgTag.dwRequired & NS_REQ_PRESENT)
|
|
&& !pAaaaArgs[i].rgTag.bPresent )
|
|
{
|
|
DisplayMessage(g_hModule, EMSG_CANT_FIND_EOPT);
|
|
dwErr = ERROR_INVALID_SYNTAX;
|
|
break;
|
|
}
|
|
}
|
|
if ( dwErr != NO_ERROR )
|
|
{
|
|
break;
|
|
}
|
|
|
|
} while (FALSE);
|
|
|
|
// Cleanup
|
|
{
|
|
if ( pTags )
|
|
{
|
|
RutlFree(pTags);
|
|
}
|
|
if ( pdwTagType )
|
|
{
|
|
RutlFree(pdwTagType);
|
|
}
|
|
}
|
|
|
|
return dwErr;
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
// RefreshIASService
|
|
//
|
|
// Send a control 128 (refresh)to IAS
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
HRESULT RefreshIASService()
|
|
{
|
|
SC_HANDLE hManager = OpenSCManager(
|
|
NULL,
|
|
SERVICES_ACTIVE_DATABASE,
|
|
SC_MANAGER_CONNECT |
|
|
SC_MANAGER_ENUMERATE_SERVICE |
|
|
SC_MANAGER_QUERY_LOCK_STATUS
|
|
);
|
|
if ( !hManager )
|
|
{
|
|
return E_FAIL;
|
|
}
|
|
|
|
|
|
SC_HANDLE hService = OpenServiceW(
|
|
hManager,
|
|
L"IAS",
|
|
SERVICE_USER_DEFINED_CONTROL |
|
|
SERVICE_QUERY_STATUS
|
|
);
|
|
|
|
if ( !hService )
|
|
{
|
|
CloseServiceHandle(hManager);
|
|
return E_FAIL;
|
|
}
|
|
|
|
SERVICE_STATUS ServiceStatus;
|
|
BOOL bResultOk = QueryServiceStatus(
|
|
hService,
|
|
&ServiceStatus
|
|
);
|
|
HRESULT hres;
|
|
if ( bResultOk )
|
|
{
|
|
if ( (SERVICE_STOPPED == ServiceStatus.dwCurrentState) ||
|
|
(SERVICE_STOP_PENDING == ServiceStatus.dwCurrentState))
|
|
{
|
|
//////////////////////////////////////////////////
|
|
// service not running = nothing to do to refresh
|
|
//////////////////////////////////////////////////
|
|
hres = S_OK;
|
|
}
|
|
else
|
|
{
|
|
/////////////////////////////////////////////////////
|
|
// the service is running thus send the refresh code
|
|
/////////////////////////////////////////////////////
|
|
BOOL bControlOk = ControlService(
|
|
hService,
|
|
128,
|
|
&ServiceStatus
|
|
);
|
|
if ( bControlOk == FALSE )
|
|
{
|
|
hres = E_FAIL;
|
|
}
|
|
else
|
|
{
|
|
hres = S_OK;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
hres = E_FAIL;
|
|
}
|
|
|
|
//////////
|
|
// clean
|
|
//////////
|
|
CloseServiceHandle(hService);
|
|
CloseServiceHandle(hManager);
|
|
// hres is always defined here.
|
|
return hres;
|
|
}
|