|
|
/*****************************************************************************\
* MODULE: util.cpp * * PURPOSE: Tools for OlePrn project * * Copyright (C) 1997-1998 Microsoft Corporation * * History: * * 08/16/97 paulmo Created * 09/12/97 weihaic Added more functions * 10/28/97 keithst Added SetScriptingError * 11/06/97 keithst Removed Win2ComErr * \*****************************************************************************/ #include "stdafx.h"
//---------------------------------------------
// Put an ANSI string into a SAFEARRAY
//
//
// Convert the string into UNICODE
// Make a BSTR out of it
// Add it to the array
//
HRESULT PutString(SAFEARRAY *psa, long *ix, LPSTR sz) { LPWSTR lpWstr; VARIANT var; HRESULT hr;
VariantInit(&var); var.vt = VT_BSTR;
if (sz == NULL) lpWstr = MakeWide(""); else lpWstr = MakeWide(sz);
if (lpWstr == NULL) return E_OUTOFMEMORY;
var.bstrVal = SysAllocString(lpWstr); LocalFree(lpWstr);
if (var.bstrVal == NULL) return E_OUTOFMEMORY;
hr = SafeArrayPutElement(psa, ix, &var); VariantClear(&var); return hr; }
// ---------------------------------------------
// Convert an ANSI string to UNICODE
//
// Note - you must LocalFree the returned string
//
LPWSTR MakeWide(LPSTR psz) { LPWSTR buff; int i; i = MultiByteToWideChar(CP_ACP, 0, psz, -1, NULL, 0); buff = (LPWSTR)LocalAlloc(LPTR, i * 2); if (buff == NULL) return NULL; i = MultiByteToWideChar(CP_ACP, 0, psz, -1, buff, i); return buff; }
//-------------------------------------------------
// Convert a UNICODE string to ANSI
//
// Note - you must LocalFree the returned string
//
LPSTR MakeNarrow(LPWSTR str) { LPSTR buff; int i;
i = WideCharToMultiByte(CP_ACP, 0, str, -1, NULL, 0, NULL, NULL); buff = (LPSTR )LocalAlloc(LPTR, i); if (buff == NULL) return NULL; i = WideCharToMultiByte(CP_ACP, 0, str, -1, buff, i, NULL, NULL); return buff; }
//-------------------------------------------------
// SetScriptingError
// Takes a Win32 error code and sets the associated string as
// the scripting language error description
//
// Parameters:
// CLSID *pclsid: pointer to Class ID (CLSID) for the class which
// generated the error; passed to AtlReportError
//
// IID *piid: pointer to interface ID (IID) for the interface
// which generated the error; passed to AtlReportError
//
// DWORD dwError: the error code retrieved from GetLastError by
// the caller of this function
//
// Return Value:
// This function uses the HRESULT_FROM_WIN32 macro, which translates
// the Win32 dwError code to a COM error code. This COM error code
// should be returned out as the return value of the failed method.
//
HRESULT SetScriptingError(const CLSID& rclsid, const IID& riid, DWORD dwError) { LPTSTR lpMsgBuf = NULL; DWORD dwRet = 0;
dwRet = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, dwError, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf, 0, NULL);
if (dwRet == 0 || !lpMsgBuf) { //
// If FormatMessage fails, it returns 0, but since we can not call
// GetLastError again, we return OUTOFMEMORY instead.
//
return E_OUTOFMEMORY; }
AtlReportError(rclsid, lpMsgBuf, riid, HRESULT_FROM_WIN32(dwError));
LocalFree(lpMsgBuf);
return (HRESULT_FROM_WIN32(dwError)); }
HANDLE RevertToPrinterSelf( VOID) { HANDLE NewToken, OldToken; NTSTATUS Status;
NewToken = NULL;
Status = NtOpenThreadToken( NtCurrentThread(), TOKEN_IMPERSONATE, TRUE, &OldToken );
if ( !NT_SUCCESS(Status) ) { SetLastError(Status); return FALSE; }
Status = NtSetInformationThread( NtCurrentThread(), ThreadImpersonationToken, (PVOID)&NewToken, (ULONG)sizeof(HANDLE) );
if ( !NT_SUCCESS(Status) ) { SetLastError(Status); return FALSE; }
return OldToken;
}
BOOL ImpersonatePrinterClient( HANDLE hToken) { NTSTATUS Status;
Status = NtSetInformationThread( NtCurrentThread(), ThreadImpersonationToken, (PVOID)&hToken, (ULONG)sizeof(HANDLE) );
if ( !NT_SUCCESS(Status) ) { SetLastError(Status); return FALSE; }
NtClose(hToken);
return TRUE; }
DWORD MyDeviceCapabilities( LPCTSTR pDevice, // pointer to a printer-name string
LPCTSTR pPort, // pointer to a port-name string
WORD fwCapability, // device capability to query
LPTSTR pOutput, // pointer to the output
CONST DEVMODE *pDevMode // pointer to structure with device data
) { DWORD dwRet = DWERROR; HANDLE hToken = NULL;
dwRet = DeviceCapabilities(pDevice, pPort, fwCapability, pOutput, pDevMode);
if (dwRet == DWERROR && GetLastError () == ERROR_ACCESS_DENIED) { // In a cluster machine, we need to get the local admin previlige to get
// the device capabilities.
if (hToken = RevertToPrinterSelf()) { dwRet = DeviceCapabilities(pDevice, pPort, fwCapability, pOutput, pDevMode); ImpersonatePrinterClient(hToken); } } return dwRet; }
|