////////////////////////////////////////////////////////////////////////////// // // Copyright (c) 1999 Microsoft Corporation // // Module Name: // // utils.c // // Abstract: // // utils functions // // Revision History: // // Thierry Perraut 04/07/1999 // ////////////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include #include "aaaamontr.h" #include "strdefs.h" #include "rmstring.h" #include "aaaamon.h" #include "context.h" #include #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 (-1); continue; } pwszArg = static_cast(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(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(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(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(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; }