|
|
// Util.cpp : Implementation of ds routines and classes
//+-------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1992 - 1999
//
// File: Util.cpp
//
// Contents: Utility functions
//
// History: 02-Oct-96 WayneSc Created
//
//
//--------------------------------------------------------------------------
#include "stdafx.h"
#include "util.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__; #endif
#define MAX_STRING 1024
//+----------------------------------------------------------------------------
//
// Function: LoadStringToTchar
//
// Sysnopsis: Loads the given string into an allocated buffer that must be
// caller freed using delete.
//
//-----------------------------------------------------------------------------
BOOL LoadStringToTchar(int ids, PTSTR * pptstr) { TCHAR szBuf[MAX_STRING];
if (!LoadString(_Module.GetModuleInstance(), ids, szBuf, MAX_STRING - 1)) { return FALSE; }
*pptstr = new TCHAR[_tcslen(szBuf) + 1];
if (*pptstr == NULL) { return FALSE; };
_tcscpy(*pptstr, szBuf);
return TRUE; }
//
// These routines courtesy of Felix Wong -- JonN 2/24/98
//
// just guessing at what Felix meant by these -- JonN 2/24/98
#define RRETURN(hr) { ASSERT( SUCCEEDED(hr) ); return hr; }
#define BAIL_ON_FAILURE if ( FAILED(hr) ) { ASSERT(FALSE); goto error; }
//////////////////////////////////////////////////////////////////////////
// Variant Utilitites
//
HRESULT BinaryToVariant(DWORD Length, BYTE* pByte, VARIANT* lpVarDestObject) { HRESULT hr = S_OK; SAFEARRAY *aList = NULL; SAFEARRAYBOUND aBound; CHAR HUGEP *pArray = NULL;
aBound.lLbound = 0; aBound.cElements = Length; aList = SafeArrayCreate( VT_UI1, 1, &aBound );
if ( aList == NULL ) { hr = E_OUTOFMEMORY; BAIL_ON_FAILURE(hr); }
hr = SafeArrayAccessData( aList, (void HUGEP * FAR *) &pArray ); BAIL_ON_FAILURE(hr);
memcpy( pArray, pByte, aBound.cElements ); SafeArrayUnaccessData( aList );
V_VT(lpVarDestObject) = VT_ARRAY | VT_UI1; V_ARRAY(lpVarDestObject) = aList;
RRETURN(hr);
error:
if ( aList ) { SafeArrayDestroy( aList ); } RRETURN(hr); }
HRESULT HrVariantToStringList(const CComVariant& refvar, CStringList& refstringlist) { HRESULT hr = S_OK; long start, end, current;
if (V_VT(&refvar) == VT_BSTR) { refstringlist.AddHead( V_BSTR(&refvar) ); return S_OK; }
//
// Check the VARIANT to make sure we have
// an array of variants.
//
if ( V_VT(&refvar) != ( VT_ARRAY | VT_VARIANT ) ) { ASSERT(FALSE); return E_UNEXPECTED; } SAFEARRAY *saAttributes = V_ARRAY( &refvar );
//
// Figure out the dimensions of the array.
//
hr = SafeArrayGetLBound( saAttributes, 1, &start ); if( FAILED(hr) ) return hr;
hr = SafeArrayGetUBound( saAttributes, 1, &end ); if( FAILED(hr) ) return hr;
CComVariant SingleResult;
//
// Process the array elements.
//
for ( current = start; current <= end; current++) { hr = SafeArrayGetElement( saAttributes, ¤t, &SingleResult ); if( FAILED(hr) ) return hr; if ( V_VT(&SingleResult) != VT_BSTR ) return E_UNEXPECTED;
refstringlist.AddHead( V_BSTR(&SingleResult) ); }
return S_OK; } // VariantToStringList()
HRESULT HrStringListToVariant(CComVariant& refvar, const CStringList& refstringlist) { HRESULT hr = S_OK; int cCount = (int)refstringlist.GetCount();
SAFEARRAYBOUND rgsabound[1]; rgsabound[0].lLbound = 0; rgsabound[0].cElements = cCount;
SAFEARRAY* psa = SafeArrayCreate(VT_VARIANT, 1, rgsabound); if (NULL == psa) return E_OUTOFMEMORY;
V_VT(&refvar) = VT_VARIANT|VT_ARRAY; V_ARRAY(&refvar) = psa;
POSITION pos = refstringlist.GetHeadPosition(); long i;
for (i = 0; i < cCount, pos != NULL; i++) { CComVariant SingleResult; // declare inside loop. Otherwise, throws
// exception in destructor if nothing added.
V_VT(&SingleResult) = VT_BSTR; V_BSTR(&SingleResult) = T2BSTR((LPCTSTR)refstringlist.GetNext(pos)); hr = SafeArrayPutElement(psa, &i, &SingleResult); if( FAILED(hr) ) return hr; } if (i != cCount || pos != NULL) return E_UNEXPECTED;
return hr; } // StringListToVariant()
//////////////////////////////////////////////////////////
// streaming helper functions
HRESULT SaveStringHelper(LPCWSTR pwsz, IStream* pStm) { ASSERT(pStm); ULONG nBytesWritten; HRESULT hr;
//
// wcslen returns a size_t and to make that consoles work the same
// on any platform we always convert to a DWORD
//
DWORD nLen = static_cast<DWORD>(wcslen(pwsz)+1); // WCHAR including NULL
hr = pStm->Write((void*)&nLen, sizeof(DWORD),&nBytesWritten); ASSERT(nBytesWritten == sizeof(DWORD)); if (FAILED(hr)) return hr; hr = pStm->Write((void*)pwsz, sizeof(WCHAR)*nLen,&nBytesWritten); ASSERT(nBytesWritten == sizeof(WCHAR)*nLen); TRACE(_T("SaveStringHelper(<%s> nLen = %d\n"),pwsz,nLen); return hr; }
HRESULT LoadStringHelper(CString& sz, IStream* pStm) { ASSERT(pStm); HRESULT hr; ULONG nBytesRead; DWORD nLen = 0;
hr = pStm->Read((void*)&nLen,sizeof(DWORD), &nBytesRead); ASSERT(nBytesRead == sizeof(DWORD)); if (FAILED(hr) || (nBytesRead != sizeof(DWORD))) return hr;
hr = pStm->Read((void*)sz.GetBuffer(nLen),sizeof(WCHAR)*nLen, &nBytesRead); ASSERT(nBytesRead == sizeof(WCHAR)*nLen); sz.ReleaseBuffer(); TRACE(_T("LoadStringHelper(<%s> nLen = %d\n"),(LPCTSTR)sz,nLen); return hr; }
HRESULT SaveDWordHelper(IStream* pStm, DWORD dw) { ULONG nBytesWritten; HRESULT hr = pStm->Write((void*)&dw, sizeof(DWORD),&nBytesWritten); if (nBytesWritten < sizeof(DWORD)) hr = STG_E_CANTSAVE; return hr; }
HRESULT LoadDWordHelper(IStream* pStm, DWORD* pdw) { ULONG nBytesRead; HRESULT hr = pStm->Read((void*)pdw,sizeof(DWORD), &nBytesRead); ASSERT(nBytesRead == sizeof(DWORD)); return hr; }
void GetCurrentTimeStampMinusInterval(DWORD dwDays, LARGE_INTEGER* pLI) { ASSERT(pLI);
FILETIME ftCurrent; GetSystemTimeAsFileTime(&ftCurrent);
pLI->LowPart = ftCurrent.dwLowDateTime; pLI->HighPart = ftCurrent.dwHighDateTime; pLI->QuadPart -= ((((ULONGLONG)dwDays * 24) * 60) * 60) * 10000000; }
/////////////////////////////////////////////////////////////////////
// CCommandLineOptions
//
// helper function to parse a single command and match it with a given switch
//
BOOL _LoadCommandLineValue(IN LPCWSTR lpszSwitch, IN LPCWSTR lpszArg, OUT CString* pszValue) { ASSERT(lpszSwitch != NULL); ASSERT(lpszArg != NULL); int nSwitchLen = lstrlen(lpszSwitch); // not counting NULL
// check if the arg is the one we look for
if (_wcsnicmp(lpszSwitch, lpszArg, nSwitchLen) == 0) { // got it, copy the value
if (pszValue != NULL) (*pszValue) = lpszArg+nSwitchLen; return TRUE; } // not found, empty string
if (pszValue != NULL) pszValue->Empty(); return FALSE; }
void CCommandLineOptions::Initialize() { // command line overrides the snapin understands,
// not subject to localization
static LPCWSTR lpszOverrideDomainCommandLine = L"/Domain="; static LPCWSTR lpszOverrideServerCommandLine = L"/Server="; static LPCWSTR lpszOverrideRDNCommandLine = L"/RDN="; static LPCWSTR lpszOverrideSavedQueriesCommandLine = L"/Queries="; #ifdef DBG
static LPCWSTR lpszOverrideNoNameCommandLine = L"/NoName"; #endif
// do it only once
if (m_bInit) { return; } m_bInit = TRUE;
//
// see if we have command line arguments
//
LPCWSTR * lpServiceArgVectors; // Array of pointers to string
int cArgs = 0; // Count of arguments
lpServiceArgVectors = (LPCWSTR *)CommandLineToArgvW(GetCommandLineW(), OUT &cArgs); if (lpServiceArgVectors == NULL) { // none, just return
return; }
// loop and search for pertinent strings
for (int i = 1; i < cArgs; i++) { ASSERT(lpServiceArgVectors[i] != NULL); TRACE (_T("command line arg: %s\n"), lpServiceArgVectors[i]);
if (_LoadCommandLineValue(lpszOverrideDomainCommandLine, lpServiceArgVectors[i], &m_szOverrideDomainName)) { continue; } if (_LoadCommandLineValue(lpszOverrideServerCommandLine, lpServiceArgVectors[i], &m_szOverrideServerName)) { continue; } if (_LoadCommandLineValue(lpszOverrideRDNCommandLine, lpServiceArgVectors[i], &m_szOverrideRDN)) { continue; } if (_LoadCommandLineValue(lpszOverrideSavedQueriesCommandLine, lpServiceArgVectors[i], &m_szSavedQueriesXMLFile)) { continue; } #ifdef DBG
if (_LoadCommandLineValue(lpszOverrideNoNameCommandLine, lpServiceArgVectors[i], NULL)) { continue; } #endif
} LocalFree(lpServiceArgVectors); }
////////////////////////////////////////////////////////////////
// Type conversions for LARGE_INTEGERs
void wtoli(LPCWSTR p, LARGE_INTEGER& liOut) { liOut.QuadPart = 0; BOOL bNeg = FALSE; if (*p == L'-') { bNeg = TRUE; p++; } while (*p != L'\0') { liOut.QuadPart = 10 * liOut.QuadPart + (*p-L'0'); p++; } if (bNeg) { liOut.QuadPart *= -1; } }
void litow(LARGE_INTEGER& li, CString& sResult) { LARGE_INTEGER n; n.QuadPart = li.QuadPart;
if (n.QuadPart == 0) { sResult = L"0"; } else { CString sNeg; sResult = L""; if (n.QuadPart < 0) { sNeg = CString(L'-'); n.QuadPart *= -1; } while (n.QuadPart > 0) { sResult += CString(L'0' + static_cast<WCHAR>(n.QuadPart % 10)); n.QuadPart = n.QuadPart / 10; } sResult = sResult + sNeg; } sResult.MakeReverse(); }
// This wrapper function required to make prefast shut up when we are
// initializing a critical section in a constructor.
void ExceptionPropagatingInitializeCriticalSection(LPCRITICAL_SECTION critsec) { __try { ::InitializeCriticalSection(critsec); }
//
// propagate the exception to our caller.
//
__except (EXCEPTION_CONTINUE_SEARCH) { } }
|