Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

237 lines
6.2 KiB

  1. /*****************************************************************************\
  2. * MODULE: util.cpp
  3. *
  4. * PURPOSE: Tools for OlePrn project
  5. *
  6. * Copyright (C) 1997-1998 Microsoft Corporation
  7. *
  8. * History:
  9. *
  10. * 08/16/97 paulmo Created
  11. * 09/12/97 weihaic Added more functions
  12. * 10/28/97 keithst Added SetScriptingError
  13. * 11/06/97 keithst Removed Win2ComErr
  14. *
  15. \*****************************************************************************/
  16. #include "stdafx.h"
  17. #include <strsafe.h>
  18. //---------------------------------------------
  19. // Put an ANSI string into a SAFEARRAY
  20. //
  21. //
  22. // Convert the string into UNICODE
  23. // Make a BSTR out of it
  24. // Add it to the array
  25. //
  26. HRESULT PutString(SAFEARRAY *psa, long *ix, LPSTR sz)
  27. {
  28. LPWSTR lpWstr;
  29. VARIANT var;
  30. HRESULT hr;
  31. VariantInit(&var);
  32. var.vt = VT_BSTR;
  33. if (sz == NULL)
  34. lpWstr = MakeWide("");
  35. else
  36. lpWstr = MakeWide(sz);
  37. if (lpWstr == NULL) return E_OUTOFMEMORY;
  38. var.bstrVal = SysAllocString(lpWstr);
  39. LocalFree(lpWstr);
  40. if (var.bstrVal == NULL)
  41. return E_OUTOFMEMORY;
  42. hr = SafeArrayPutElement(psa, ix, &var);
  43. VariantClear(&var);
  44. return hr;
  45. }
  46. // ---------------------------------------------
  47. // Convert an ANSI string to UNICODE
  48. //
  49. // Note - you must LocalFree the returned string
  50. //
  51. LPWSTR MakeWide(LPSTR psz)
  52. {
  53. LPWSTR buff;
  54. int i;
  55. if (!(i = MultiByteToWideChar(CP_ACP, 0, psz, -1, NULL, 0)))
  56. return NULL;
  57. buff = (LPWSTR)LocalAlloc(LPTR, i * sizeof(WCHAR));
  58. if (buff == NULL)
  59. return NULL;
  60. if (!(i = MultiByteToWideChar(CP_ACP, 0, psz, -1, buff, i)))
  61. {
  62. LocalFree(buff);
  63. return NULL;
  64. }
  65. return buff;
  66. }
  67. //-------------------------------------------------
  68. // Convert a UNICODE string to ANSI
  69. //
  70. // Note - you must LocalFree the returned string
  71. //
  72. LPSTR MakeNarrow(LPWSTR str)
  73. {
  74. LPSTR buff;
  75. int i;
  76. if (!(i = WideCharToMultiByte(CP_ACP, 0, str, -1, NULL, 0, NULL, NULL)))
  77. return NULL;
  78. buff = (LPSTR )LocalAlloc(LPTR, i * sizeof(CHAR));
  79. if (buff == NULL)
  80. return NULL;
  81. if (!(i = WideCharToMultiByte(CP_ACP, 0, str, -1, buff, i, NULL, NULL)))
  82. {
  83. LocalFree(buff);
  84. return NULL;
  85. }
  86. return buff;
  87. }
  88. //-------------------------------------------------
  89. // SetScriptingError
  90. // Takes a Win32 error code and sets the associated string as
  91. // the scripting language error description
  92. //
  93. // Parameters:
  94. // CLSID *pclsid: pointer to Class ID (CLSID) for the class which
  95. // generated the error; passed to AtlReportError
  96. //
  97. // IID *piid: pointer to interface ID (IID) for the interface
  98. // which generated the error; passed to AtlReportError
  99. //
  100. // DWORD dwError: the error code retrieved from GetLastError by
  101. // the caller of this function
  102. //
  103. // Return Value:
  104. // This function uses the HRESULT_FROM_WIN32 macro, which translates
  105. // the Win32 dwError code to a COM error code. This COM error code
  106. // should be returned out as the return value of the failed method.
  107. //
  108. HRESULT SetScriptingError(const CLSID& rclsid, const IID& riid, DWORD dwError)
  109. {
  110. LPTSTR lpMsgBuf = NULL;
  111. DWORD dwRet = 0;
  112. dwRet = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
  113. FORMAT_MESSAGE_FROM_SYSTEM |
  114. FORMAT_MESSAGE_IGNORE_INSERTS,
  115. NULL,
  116. dwError,
  117. MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
  118. (LPTSTR) &lpMsgBuf,
  119. 0,
  120. NULL);
  121. if (dwRet == 0 || !lpMsgBuf)
  122. {
  123. //
  124. // If FormatMessage fails, it returns 0, but since we can not call
  125. // GetLastError again, we return OUTOFMEMORY instead.
  126. //
  127. return E_OUTOFMEMORY;
  128. }
  129. AtlReportError(rclsid, lpMsgBuf, riid, HRESULT_FROM_WIN32(dwError));
  130. LocalFree(lpMsgBuf);
  131. return (HRESULT_FROM_WIN32(dwError));
  132. }
  133. HANDLE
  134. RevertToPrinterSelf(
  135. VOID)
  136. {
  137. HANDLE NewToken, OldToken;
  138. NTSTATUS Status;
  139. NewToken = NULL;
  140. Status = NtOpenThreadToken(
  141. NtCurrentThread(),
  142. TOKEN_IMPERSONATE,
  143. TRUE,
  144. &OldToken
  145. );
  146. if ( !NT_SUCCESS(Status) ) {
  147. SetLastError(Status);
  148. return FALSE;
  149. }
  150. Status = NtSetInformationThread(
  151. NtCurrentThread(),
  152. ThreadImpersonationToken,
  153. (PVOID)&NewToken,
  154. (ULONG)sizeof(HANDLE)
  155. );
  156. if ( !NT_SUCCESS(Status) ) {
  157. SetLastError(Status);
  158. return FALSE;
  159. }
  160. return OldToken;
  161. }
  162. BOOL
  163. ImpersonatePrinterClient(
  164. HANDLE hToken)
  165. {
  166. NTSTATUS Status;
  167. Status = NtSetInformationThread(
  168. NtCurrentThread(),
  169. ThreadImpersonationToken,
  170. (PVOID)&hToken,
  171. (ULONG)sizeof(HANDLE)
  172. );
  173. if ( !NT_SUCCESS(Status) ) {
  174. SetLastError(Status);
  175. return FALSE;
  176. }
  177. NtClose(hToken);
  178. return TRUE;
  179. }
  180. DWORD MyDeviceCapabilities(
  181. LPCTSTR pDevice, // pointer to a printer-name string
  182. LPCTSTR pPort, // pointer to a port-name string
  183. WORD fwCapability, // device capability to query
  184. LPTSTR pOutput, // pointer to the output
  185. CONST DEVMODE *pDevMode
  186. // pointer to structure with device data
  187. )
  188. {
  189. DWORD dwRet = DWERROR;
  190. HANDLE hToken = NULL;
  191. dwRet = DeviceCapabilities(pDevice, pPort, fwCapability, pOutput, pDevMode);
  192. if (dwRet == DWERROR && GetLastError () == ERROR_ACCESS_DENIED) {
  193. // In a cluster machine, we need to get the local admin previlige to get
  194. // the device capabilities.
  195. if (hToken = RevertToPrinterSelf()) {
  196. dwRet = DeviceCapabilities(pDevice, pPort, fwCapability, pOutput, pDevMode);
  197. ImpersonatePrinterClient(hToken);
  198. }
  199. }
  200. return dwRet;
  201. }