|
|
/////////////////////////////////////////////////////////////////////
//
// StdUtils.cpp
//
// Utilities routines for any snapin.
//
// HISTORY
// t-danmo 96.10.10 Creation.
//
/////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "stdutils.h"
/////////////////////////////////////////////////////////////////////
// CompareMachineNames()
//
// Compare if the strings refer to the same machine (computer).
//
// Return 0 if both strings map to the same machine, otherwise
// return -1 or +1 if machine name differs.
//
// INTERFACE NOTES:
// An empty string means the local machine.
//
// HISTORY
// 02-Jun-97 t-danm Creation.
// 14-Jul-97 t-danm Comment update.
// 29-Jul-97 t-danm Renamed from FCompareMachineNames().
//
int CompareMachineNames( LPCTSTR pszMachineName1, LPCTSTR pszMachineName2) { TCHAR szThisMachineName[MAX_COMPUTERNAME_LENGTH + 4]; ZeroMemory( szThisMachineName, sizeof(szThisMachineName) ); // JonN 3/28/02
BOOL fMachine1IsLocal = (pszMachineName1 == NULL || *pszMachineName1 == '\0'); BOOL fMachine2IsLocal = (pszMachineName2 == NULL || *pszMachineName2 == '\0'); if (fMachine1IsLocal) pszMachineName1 = szThisMachineName; if (fMachine2IsLocal) pszMachineName2 = szThisMachineName; if (pszMachineName1 == pszMachineName2) return 0; if (fMachine1IsLocal || fMachine2IsLocal) { // Get the computer name
szThisMachineName[0] = _T('\\'); szThisMachineName[1] = _T('\\'); DWORD cchBuffer = MAX_COMPUTERNAME_LENGTH + 1; VERIFY(::GetComputerName(OUT &szThisMachineName[2], &cchBuffer)); ASSERT(szThisMachineName[2] != _T('\\') && "Machine name has too many backslashes"); } return lstrcmpi(pszMachineName1, pszMachineName2); } // CompareMachineNames()
/////////////////////////////////////////////////////////////////////
// HrLoadOleString()
//
// Load a string from the resource and return pointer to allocated
// OLE string.
//
// HISTORY
// 29-Jul-97 t-danm Creation.
//
HRESULT HrLoadOleString( UINT uStringId, // IN: String Id to load from the resource
OUT LPOLESTR * ppaszOleString) // OUT: Pointer to pointer to allocated OLE string
{ if (ppaszOleString == NULL) { TRACE0("HrLoadOleString() - ppaszOleString is NULL.\n"); return E_POINTER; } CString strT; // Temporary string
// ISSUE-2002/03/28-JonN should call HrCopyToOleString
AFX_MANAGE_STATE(AfxGetStaticModuleState()); // Needed for LoadString()
VERIFY( strT.LoadString(uStringId) ); *ppaszOleString = reinterpret_cast<LPOLESTR> (CoTaskMemAlloc((strT.GetLength() + 1)* sizeof(wchar_t))); if (*ppaszOleString == NULL) return E_OUTOFMEMORY; // ISSUE-2002/03/28-JonN I don't entirely trust this USES_CONVERSION stuff
USES_CONVERSION; wcscpy(OUT *ppaszOleString, T2OLE((LPTSTR)(LPCTSTR)strT)); return S_OK; } // HrLoadOleString()
/////////////////////////////////////////////////////////////////////
// HrCopyToOleString()
//
// Copies a CString into an allocated
// OLE string.
//
// HISTORY
// 05-Jun-2001 jeffjon Creation.
//
HRESULT HrCopyToOleString( const CString& strT, // IN: String Id to load from the resource
OUT LPOLESTR * ppaszOleString) // OUT: Pointer to pointer to allocated OLE string
{ if (ppaszOleString == NULL) { TRACE0("HrLoadOleString() - ppaszOleString is NULL.\n"); return E_POINTER; } AFX_MANAGE_STATE(AfxGetStaticModuleState()); // Needed for LoadString()
*ppaszOleString = reinterpret_cast<LPOLESTR> (CoTaskMemAlloc((strT.GetLength() + 1)* sizeof(wchar_t))); if (*ppaszOleString == NULL) { return E_OUTOFMEMORY; }
USES_CONVERSION; wcscpy(OUT *ppaszOleString, T2OLE((LPTSTR)(LPCTSTR)strT)); return S_OK; } // HrCopyToOleString()
//
// Nodetype utility routines
// aNodetypeGuids must be defined by the subclass
//
int CheckObjectTypeGUID( const BSTR lpszObjectTypeGUID ) { ASSERT(NULL != lpszObjectTypeGUID); if (NULL == lpszObjectTypeGUID) // JonN 2002/03/28
return 0; for ( int objecttype = 0; objecttype < g_cNumNodetypeGuids; objecttype += 1 ) { if ( !::lstrcmpiW(lpszObjectTypeGUID,g_aNodetypeGuids[objecttype].bstr) ) return objecttype; } ASSERT( FALSE ); return 0; }
int CheckObjectTypeGUID( const GUID* pguid ) { ASSERT(NULL != pguid); if (NULL == pguid) // JonN 2002/03/28
return 0; for ( int objecttype = 0; objecttype < g_cNumNodetypeGuids; objecttype += 1 ) { if ( g_aNodetypeGuids[objecttype].guid == *pguid ) return objecttype; } ASSERT( FALSE ); return 0; }
/////////////////////////////////////////////////////////////////////
// FilemgmtCheckObjectTypeGUID()
//
// Compare the GUID and return the objecttype associated with
// the guid.
// If no match found, return -1.
//
// HISTORY
// 14-Jul-97 t-danm Creation. Inspired from CheckObjectTypeGUID()
// but does not assert if the GUID is not found.
//
int FilemgmtCheckObjectTypeGUID(const GUID* pguid ) { ASSERT(NULL != pguid); if (NULL == pguid) // JonN 2002/03/28
return -1; for ( int objecttype = 0; objecttype < g_cNumNodetypeGuids; objecttype += 1 ) { if ( g_aNodetypeGuids[objecttype].guid == *pguid ) return objecttype; } return -1; } // FilemgmtCheckObjectTypeGUID()
const BSTR GetObjectTypeString( int objecttype ) { if (objecttype < 0 || objecttype >= g_cNumNodetypeGuids) { ASSERT( FALSE ); objecttype = 0; } return g_aNodetypeGuids[objecttype].bstr; }
const GUID* GetObjectTypeGUID( int objecttype ) { if (objecttype < 0 || objecttype >= g_cNumNodetypeGuids) { ASSERT( FALSE ); objecttype = 0; } return &(g_aNodetypeGuids[objecttype].guid); }
//+---------------------------------------------------------------------------
//
// Function: SynchronousCreateProcess
//
// Synopsis: Invoke a separate UI process as a modal window.
//
//----------------------------------------------------------------------------
HRESULT SynchronousCreateProcess( HWND hWnd, LPCTSTR pszAppName, LPCTSTR pszCommandLine, LPDWORD lpdwExitCode ) { HRESULT hr = S_OK; BOOL bReturn = FALSE; STARTUPINFO si; PROCESS_INFORMATION pi;
//
// disable the MMC main frame window to prevent it from
// being shut down. The process we're going to create must
// display a UI, such that, it behaves like a modal window.
//
::EnableWindow(hWnd, FALSE);
*lpdwExitCode = 0;
ZeroMemory(&si, sizeof(STARTUPINFO)); si.cb = sizeof(STARTUPINFO); bReturn = CreateProcess( pszAppName, //LPCTSTR lpApplicationName
const_cast<LPTSTR>(pszCommandLine), //LPTSTR lpCommandLine
NULL, //LPSECURITY_ATTRIBUTES lpProcessAttributes
NULL, //LPSECURITY_ATTRIBUTES lpThreadAttributes
FALSE, //BOOL bInheritHandles
NORMAL_PRIORITY_CLASS, //DWORD dwCreationFlags
NULL, //LPVOID lpEnvironment
NULL, //lpCurrentDirectory
&si, //LPSTARTUPINFO lpStartupInfo
&pi //LPPROCESS_INFORMATION lpProcessInformation
);
if (!bReturn) { hr = HRESULT_FROM_WIN32(GetLastError()); } else { //
// while process is still running, pump message to MMC main window,
// such that it will repaint itself
//
while (TRUE) { MSG tempMSG; DWORD dwWait;
while(::PeekMessage(&tempMSG,NULL, 0, 0, PM_REMOVE)) DispatchMessage(&tempMSG);
dwWait = MsgWaitForMultipleObjects(1, &(pi.hProcess), FALSE, INFINITE, QS_ALLINPUT); if ( 0 == (dwWait - WAIT_OBJECT_0)) break; // process is done
};
bReturn = GetExitCodeProcess(pi.hProcess, lpdwExitCode); if (!bReturn) hr = HRESULT_FROM_WIN32(GetLastError());
CloseHandle(pi.hThread); CloseHandle(pi.hProcess); }
//
// enable MMC main frame window before return
//
::EnableWindow(hWnd, TRUE);
return hr; }
/*
This code is not working yet. The problem is that it hangs the message loop, preventing redraw. One possible approach is to disable the top-level window and spin off a thread which waits for the process to stop, then the thread reenables the top-level window and calls UpdateAllViews.
DWORD WINAPI ProcessMonitor(LPVOID pv) { }
class CSyncThread : public CThread { };
HRESULT SynchronousCreateProcess(LPCTSTR cpszCommandLine, SynchronousProcessCompletionRoutine pfunc, PVOID pvFuncParams) // does not handle completion routine
{ PROCESS_INFORMATION piProcInfo; (void) ::memset(&piProcInfo,0,sizeof(piProcInfo)); STARTUPINFO si; (void) ::memset(&si,0,sizeof(si)); ::GetStartupInfo( &si );
//
// MarkL 1/30/97: Is pszCommandLine a static string?
// It can not be read only. It is modified temporarily by the call
// if you do not specify lpszImageName. There is no query to see
// if a process is running. You can test to see if it has exited
// using waitforsingleobject to see if the process object is signaled.
//
// MarkL also confirms that the handle should absolutely always
// be signalled when the process dies.
//
LPTSTR pszCommandLine = (LPTSTR) ::alloca(sizeof(TCHAR)*(::_tcslen(cpszCommandLine)+1)); ::_tcscpy(pszCommandLine,cpszCommandLine); if ( !::CreateProcess( NULL, // LPCTSTR lpszImageName
pszCommandLine, // LPTSTR lpszCommandLine
NULL, // LPSECURITY_ATTRIBUTES lpsaProcess
NULL, // LPSECURITY_ATTRIBUTES lpsaThread
FALSE, // BOOL fInheritHandles
0L, // DWORD fdwCreate
NULL, // LPVOID lpvEnvironment
NULL, // LPTSTR lpszCurDir
&si, // LPSTARTUPINFO lpsiStartInfo
&piProcInfo // LPPROCESS_INFORMATION lppiProcInfo
) ) { DWORD dwErr = ::GetLastError(); ASSERT( ERROR_SUCCESS != dwErr ); return HRESULT_FROM_WIN32(dwErr); } ASSERT( NULL != piProcInfo.hProcess );
VERIFY( WAIT_OBJECT_0 == ::WaitForSingleObject( piProcInfo.hProcess, INFINITE ) );
VERIFY( ::CloseHandle( piProcInfo.hProcess ) ); VERIFY( ::CloseHandle( piProcInfo.hThread ) ); return S_OK; } */
// ISSUE-2002/03/28-JonN duplicates HrCopyToOleString
LPOLESTR CoTaskAllocString( LPCOLESTR psz ) { if (NULL == psz) return NULL; LPOLESTR pszReturn = (LPOLESTR)CoTaskMemAlloc( (lstrlen(psz)+1)*sizeof(OLECHAR) ); if (NULL != pszReturn) lstrcpy( pszReturn, psz ); ASSERT( NULL != pszReturn ); return pszReturn; }
// ISSUE-2002/03/28-JonN duplicates HrLoadOleString
LPOLESTR CoTaskLoadString( UINT nResourceID ) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); // load the resource
CString strText; strText.LoadString( nResourceID ); ASSERT( !strText.IsEmpty() ); return CoTaskAllocString( const_cast<BSTR>((LPCTSTR)strText) ); }
|