1

サービスからリモート (共有) プリンターの印刷ジョブを監視したい。プリンターに接続するユーザー (例: \PC-PRINTER\Canon Printer) の偽装アクセス トークンがあります。

ユーザーとして偽装した後、OpenPrinter をプリンターに呼び出し、次に FindFirstPrinterChangeNotification を呼び出します。OpenPrinter は成功しましたが、FindFirstPrinterChangeNotification は ERROR_INVALID_HANDLE エラーで失敗しました。

通常のユーザー(サービスではなくプリンターの所有者)として試してみると、すべて成功し、通知が機能します。また、Windows XP で試してみると成功しましたが、Windows 7 とおそらく Windows Vista でのみ失敗しました。

偽装トークンのセキュリティ属性を設定するか、他の属性を OpenPrinter に渡す必要があると思います。私は多くのことを試しましたが、解決策が見つかりませんでした。

私のコード例:

PRINTER_NOTIFY_OPTIONS_TYPE optionsType;
unsigned short jobFields[] = {JOB_NOTIFY_FIELD_PRINTER_NAME};
optionsType.Type = JOB_NOTIFY_TYPE;
optionsType.Count = 1;
optionsType.pFields = &jobFields[0];

PRINTER_NOTIFY_OPTIONS options;
options.Version = 2; 
options.Count = 1;
options.pTypes = &optionsType;
options.Flags = 0;

DWORD dwFilter = PRINTER_CHANGE_DELETE_JOB | PRINTER_CHANGE_SET_JOB ;
HANDLE hPrinterHandle = NULL;

ImpersonateLoggedOnUser(hUserToken); //I retrieve token from printer owner's process (I try every process for this user)

OpenPrinter(L"\\\\PC-PRINTER\\Canon Printer", &hPrinterHandle, NULL); \\it succeeded and I try many other parameters as well

HANDLE hNotification = FindFirstPrinterChangeNotification(hPrinterHandle, dwFilter, 0, (LPVOID) &options);

if (hNotification == INVALID_HANDLE_VALUE)
{//it comes here, GetLastError() == ERROR_INVALID_HANDLE (Windows 7, process runs as service)
 //it succeded on Windows XP or when process runs in printer owner context
}

RevertToSelf();

解決策をありがとう!

4

0 に答える 0