windows-nt/Source/XPSP1/NT/printscan/lib/psutil/fusutils.cpp
2020-09-26 16:20:57 +08:00

210 lines
6 KiB
C++

/*****************************************************************************
*
* (C) COPYRIGHT MICROSOFT CORPORATION, 2000
*
* TITLE: fusutils.cpp
*
* VERSION: 1.0
*
* AUTHOR: LazarI
*
* DATE: 14-Feb-2001
*
* DESCRIPTION: Fusion utilities
*
*****************************************************************************/
#include "precomp.h"
#pragma hdrstop
#include "fusutils.h"
#include "coredefs.h"
// open C code brace
#ifdef __cplusplus
extern "C" {
#endif
//
// Win32Error2HRESULT: converts Win32 error to HRESULT
//
inline HRESULT Win32Error2HRESULT(DWORD dwError = GetLastError())
{
return (ERROR_SUCCESS == dwError) ? E_FAIL : HRESULT_FROM_WIN32(dwError);
}
//
// SearchExecutableWrap: HRESULT wrapper around SearchPath
//
// searches for an executable and returns its full path in lpBuffer.
// returns E_INVALIDARG if the executable cannot be found and
// Win32Error2HRESULT(ERROR_INSUFFICIENT_BUFFER) if the
// passed in buffer is too small to hold the full path.
//
inline HRESULT SearchExecutableWrap(LPCTSTR lpszExecutableName, UINT nBufferLength, LPTSTR lpBuffer, LPTSTR *lppFilePart)
{
DWORD cch = SearchPath(NULL, lpszExecutableName, NULL, nBufferLength, lpBuffer, lppFilePart);
return (0 == cch) ? Win32Error2HRESULT() :
(cch >= nBufferLength) ? Win32Error2HRESULT(ERROR_INSUFFICIENT_BUFFER) : S_OK;
}
//
// GetExecutableNameWrap: HRESULT wrapper around GetModuleFileName
//
//
// returns the full path of the current process executable (EXE)
// or Win32Error2HRESULT(ERROR_INSUFFICIENT_BUFFER) if the
// passed in buffer is too small to hold the full path.
//
inline HRESULT GetExecutableNameWrap(HMODULE hModule, UINT nBufferLength, LPTSTR lpBuffer)
{
DWORD cch = GetModuleFileName(hModule, lpBuffer, nBufferLength);
return (0 == cch) ? Win32Error2HRESULT() :
(cch >= nBufferLength) ? Win32Error2HRESULT(ERROR_INSUFFICIENT_BUFFER) : S_OK;
}
//
// FileExists: checks if the passed in file name exists.
//
inline HRESULT FileExists(LPCTSTR pszFileName, BOOL *pbExists)
{
HRESULT hr = E_INVALIDARG;
if (pszFileName && pbExists)
{
hr = S_OK;
*pbExists = FALSE;
WIN32_FIND_DATA findFileData;
HANDLE hFind = FindFirstFile(pszFileName, &findFileData);
if (hFind != INVALID_HANDLE_VALUE)
{
*pbExists = TRUE;
FindClose(hFind);
}
}
return hr;
}
static TCHAR g_szManifestExt[] = TEXT(".manifest");
//
// CreateActivationContextFromExecutableEx:
//
// check the passed in executable name for a manifest (if any)
// and creates an activation context from it.
//
HRESULT CreateActivationContextFromExecutableEx(LPCTSTR lpszExecutableName, UINT uResourceID, BOOL bMakeProcessDefault, HANDLE *phActCtx)
{
HRESULT hr = E_INVALIDARG;
if (phActCtx)
{
TCHAR szModule[MAX_PATH];
TCHAR szManifest[MAX_PATH];
BOOL bManifestFileFound = FALSE;
// let's try to figure out whether this executable has a manifest file or not
if (lpszExecutableName)
{
// search the passed in name in the path
hr = SearchExecutableWrap(lpszExecutableName, ARRAYSIZE(szModule), szModule, NULL);
}
else
{
// if lpszExecutableName is NULL we assume the current module name
hr = GetExecutableNameWrap(GetModuleHandle(NULL), ARRAYSIZE(szModule), szModule);
}
if (SUCCEEDED(hr))
{
if ((lstrlen(szModule) + lstrlen(g_szManifestExt)) < ARRAYSIZE(szManifest))
{
// create the manifest file name by appending ".manifest" to the executable name
lstrcpy(szManifest, szModule);
lstrcat(szManifest, g_szManifestExt);
}
else
{
// buffer is too small to hold the manifest file name
hr = Win32Error2HRESULT(ERROR_BUFFER_OVERFLOW);
}
if (SUCCEEDED(hr))
{
BOOL bFileExists = FALSE;
hr = FileExists(szManifest, &bFileExists);
if (SUCCEEDED(hr) && bFileExists)
{
// an external manifest file found!
bManifestFileFound = TRUE;
}
}
}
// now let's try to create an activation context
ACTCTX act;
::ZeroMemory(&act, sizeof(act));
act.cbSize = sizeof(act);
if (bManifestFileFound)
{
// the executable has an external manifest file
act.lpSource = szManifest;
}
else
{
// if the executable doesn't have an external manifest file,
// so we assume that the it may have a manifest in its resources.
act.dwFlags |= ACTCTX_FLAG_RESOURCE_NAME_VALID;
act.lpResourceName = MAKEINTRESOURCE(uResourceID);
act.lpSource = szModule;
}
if (bMakeProcessDefault)
{
// the caller has requested to set this activation context as
// sefault for the current process. watch out!
act.dwFlags |= ACTCTX_FLAG_SET_PROCESS_DEFAULT;
}
// now let's ask kernel32 to create an activation context
HANDLE hActCtx = CreateActCtx(&act);
if (INVALID_HANDLE_VALUE == hActCtx)
{
// something failed. create proper HRESULT to return.
hr = Win32Error2HRESULT();
}
else
{
// wow, success!
*phActCtx = hActCtx;
hr = S_OK;
}
}
return hr;
}
//
// CreateActivationContextFromExecutable:
//
// check the passed in executable name for a manifest (if any)
// and creates an activation context from it using the defaults
// (i.e. bMakeProcessDefault=FALSE & uResourceID=123)
//
HRESULT CreateActivationContextFromExecutable(LPCTSTR lpszExecutableName, HANDLE *phActCtx)
{
return CreateActivationContextFromExecutableEx(lpszExecutableName, 123, FALSE, phActCtx);
}
// close C code brace
#ifdef __cplusplus
}
#endif