windows-nt/Source/XPSP1/NT/admin/snapin/framewrk/stdutils.cpp
2020-09-26 16:20:57 +08:00

339 lines
9.3 KiB
C++

/////////////////////////////////////////////////////////////////////
//
// 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];
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
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;
USES_CONVERSION;
wcscpy(OUT *ppaszOleString, T2OLE((LPTSTR)(LPCTSTR)strT));
return S_OK;
} // HrLoadOleString()
//
// Nodetype utility routines
// aNodetypeGuids must be defined by the subclass
//
int CheckObjectTypeGUID( const BSTR lpszObjectTypeGUID )
{
ASSERT(NULL != lpszObjectTypeGUID);
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);
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);
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;
}
*/
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;
}
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) );
}