Доступ запрещен при вызове DocumentProperties после олицетворения при запуске 32-битного приложения в 64-битной Windows 10

Мне нужно получить структуру DEVMODE для принтеров после того, как мое приложение выдало себя за пользователя. Это прекрасно работает, если моя архитектура соответствует архитектуре Windows, 32-битного приложения, работающего на 32-битной ОС, и наоборот. Однако любой вызов, который я выполняю для DocumentProperties, завершается с ошибкой либо с КОДОМ ОШИБКИ: 5 (доступ запрещен) в Windows 10, либо с ошибкой RPC в Windows 7 после олицетворения в 32-разрядной версии моего приложения, работающего в 64-разрядной ОС. К сожалению, клиент не может запустить 64-битную версию моего приложения из-за других устаревших приложений, с которыми ему нужно взаимодействовать.

Кто-нибудь знает обойти эту проблему?

Вот небольшой пример кода, который продемонстрирует проблему. Вам нужно будет собрать его как приложение x86 и запустить его на 64-битной ОС, чтобы увидеть проблему.

// DocumentPropertiesTest.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"#include <string>
#include <iostream>
#include "Winspool.h"#include "DocumentPropertiesTest.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif// The one and only application object

CWinApp theApp;

using namespace std;

int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
int nRetCode = 0;

HMODULE hModule = ::GetModuleHandle(NULL);

if (hModule != NULL)
{
// initialize MFC and print and error on failure
if (!AfxWinInit(hModule, NULL, ::GetCommandLine(), 0))
{
// TODO: change error code to suit your needs
_tprintf(_T("Fatal Error: MFC initialization failed\n"));
nRetCode = 1;
}
else
{
wstring username;
wstring domainName;
wstring password;
wstring printername;
int lastError;

cout << "Please specify a valid username: ";
wcin >> username;
cout << "Please specify the computer or domain name for the user. Use \".\" for this computer: ";
wcin >> domainName;
cout << "Please specify the users password: ";
wcin >> password;
cout << "Please give the printer name: ";
wcin.ignore();
getline (wcin, printername);

HANDLE pHandle;
HANDLE pPrinter;
if (LogonUser(username.c_str(), domainName.c_str(), password.c_str(), LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, &pHandle) != 0)
{
if (ImpersonateLoggedOnUser(pHandle) != 0)
{
PRINTER_DEFAULTS printerDefaults;

printerDefaults.pDatatype     = NULL;
printerDefaults.pDevMode      = NULL;
printerDefaults.DesiredAccess = PRINTER_ALL_ACCESS;

if (::OpenPrinter((LPWSTR)(printername.c_str()), &pPrinter, NULL))
{
int dSize = ::DocumentPropertiesW(NULL, pPrinter, (LPWSTR)(printername.c_str()), NULL, NULL, 0);
if (dSize > 0)
{
}
else
{
lastError = ::GetLastError();
cout << "Failed DocumentProperties with Error code: " << lastError << endl;
}
::ClosePrinter(pPrinter);
}
else
{
lastError = ::GetLastError();
cout << "Failed OpenPrinter with Error code: " << lastError << endl;
}
RevertToSelf();
}
else
{
lastError = ::GetLastError();
cout << "Failed ImpersonateLogonUser with Error code: " << lastError << endl;
}
}
else
{
lastError = ::GetLastError();
cout << "Failed LogonUser with Error code: " << lastError << endl;
}

system("pause");
}
}
else
{
// TODO: change error code to suit your needs
_tprintf(_T("Fatal Error: GetModuleHandle failed\n"));
nRetCode = 1;
}

return nRetCode;
}

2

Решение

Задача ещё не решена.

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]