【问题标题】:Access denied calling EnumJobs访问被拒绝调用 EnumJobs
【发布时间】:2019-07-24 02:26:55
【问题描述】:

我正在尝试在 Windows Server 2012 R2 Standard 上的打印机队列中获取作业的域用户名。下面的代码 sn-p 在 Delphi 中。 OpenPrinter 和 EnumJobs 是 Windows 后台处理程序 API 的一部分。

更新! 将 maxJobs 设置为 4 的更高倍数允许枚举队列中的更多作业。例如。设置 maxJobs=8 允许两个作业,但不是三个。 maxJobs=12 允许三个作业。

已解决! 看来我可以忽略 EnumJobs 的返回值,只需查看它返回的作业数是否 > 0(调用时的最后一个参数)。这似乎适用于下面列出的所有实例,包括通过共享的打印机。

const
  maxJobs = 4;
var
  h : THandle;
  jia : array [1..maxJobs] of JOB_INFO_1;
  jiz, jic : DWord;  // size of jia, count of jia
begin
  if OpenPrinter('DocTest', h, nil) then
  begin
    if EnumJobs(h, 0, maxJobs, 1, @jia, SizeOf(jia), jiz, jic) then  
[...]

EnumJobs 根据下面列出的不同条件返回 true 或 false。如果它在以下任何一种情况下返回 false,我正在检索的错误消息是“系统错误。代码:5。访问被拒绝”。

显然是权限问题。我已在打印机安全设置中将打印、管理此打印机和管理文档分配给每个人。分配这些设置后,所有作业均已提交。我的程序正在以域管理员身份登录的会话中运行。

  • 如果我从运行此程序的同一会话中打印作业,并且队列中只有一个作业,则 EnumJobs 将返回 TRUE。 (有关更改,请参阅上面的更新)
  • 如果我以任何用户身份从服务器上的另一个会话(它安装了终端服务)打印,并且队列中只有一个作业,则 EnumJobs 返回 TRUE。 (有关更改,请参阅上面的更新)
  • 如果队列中有多个作业,EnumJobs 将返回 FALSE。作业是否针对同一用户并不重要。 (有关更改,请参阅上面的更新)
  • 如果我将作业从另一台服务器打印到打印机共享,EnumJobs 将返回 FALSE。两台服务器都在同一个域中。哪个用户打印作业都没有关系,包括域管理员。

这里发生了什么,特别是在一次枚举超过 (maxJobs / 4) 个作业时访问被拒绝?

【问题讨论】:

  • 程序是否有权访问C:\Windows\System32\spool目录?
  • @Drake 确实如此,毕竟它是以域管理员身份运行的。获取上述作业信息后,它会扫描 spool 文件夹的 *.spl 文件中的作业内容以获取更多信息,然后再删除作业。

标签: windows winapi printers


【解决方案1】:

忽略 EnumJobs 的返回值,检查 out 参数 pcReturned 是否大于 0。这表示找到的打印作业数。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-12-21
    • 1970-01-01
    • 1970-01-01
    • 2020-02-23
    • 2010-11-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多