设置系统时间 @ Win7

安全的代价就是会带来一些麻烦。

直接 SetSystemTime 肯定是不行了,先是从网上看到应该用 AdjustTokenPrivileges 来得到设置系统时间的权限(相关文章一般是说 XP 系统)。但实际用下来,设置失败,错误号 1300,也就是 ERROR_NOT_ALL_ASSIGNED,当时没怎么理解这个错误的具体含义。

然后也看到可以通过本地策略的用户权限分配中设置一下,奇怪,不是已经有管理员用户组了吗?不管 3×7=21,先把自己的用户账号加了进去,结果还是没用:(

然后在 stackoverflow 上无意看到可以用 Process Explorer 来查看进程的权限,单步跟踪一下,AdjustTokenPrivileges 之后还是没有出现相关权限(seSystemtimePriviledge)。

开始怀疑是 AdjustTokenPrivileges  是没用对,然后对 MSDN 上这个 API 的说明中关于 PreviousState 的一段说明又理解错误,还以为是调用 API 时参数处理不对。。。反正又捣鼓了半天没搞定。

再然后将程序运行为系统服务,呼呼,竟然就能设置系统时间了。。。再到 procexp 去看一下,果然权限也已经有了。

其实 MSDN 文档里已经写得很清楚了(The AdjustTokenPrivileges function cannot add new privileges to the access token. It can only enable or disable the token’s existing privileges. ),这个 API 只能启用或禁用已有的权限种类!

回到 procexp,情况也很清楚了,程序以命令行方式运行时(继承当前登录用户的权限),根本就没有时间设置的权限,所以再 Adjust 也不顶用(前面说的 1300 错误就是这个意思),而以系统服务方式运行时,是有这个权限的,虽然默认是 Disabled,但 Adjust 一下之后就是 Enabled 了。

嗯,文档还是认真读才行,另外,看来很有必要把放下很久的《Windows Internals》捡起来继续读一读。

遗留问题:本地策略中的那个设置项倒底是起什么作用?

后记:

如果程序不作为系统服务运行,运行过程中又需要修改系统时间,只能在启动时就选择“以管理员身份运行”。据了解,程序运行过程中是不能动态地从非管理员权限提升到管理员权限的,即使愿意看到一个弹出的 UAC 对话框也不行。(By design UAC can only elevate code at process level and only at process’ startup.

所以如果程序中只有小部分功能是需要管理员权限的,可以考虑把程序拆分成两个,程序正常启动时不需要管理员权限,而当碰到需要的时候,通过 ShellExecute 之类的来启动另一个程序就行了。// 更好的实现方式应该不是这种 EXE Elevation,而是 COM Elevation,据说从编程模式来说更方便,用户体验也更好。这里先记下来吧,以后有空再研究:)

This entry was posted in 软件开发 and tagged , , . Bookmark the permalink.

2 条 设置系统时间 @ Win7 的回复

  1. ++说道:

    重走前辈走过的路,此文很有帮助,多谢!

    •Enable or disable privileges by using the AdjustTokenPrivileges function.
    •Restrict or remove privileges by using the CreateRestrictedToken function.

    AdjustTokenPrivileges行不通的话,
    一起尝试下CreateRestrictedToken如何?

发表评论

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / 更改 )

Twitter picture

You are commenting using your Twitter account. Log Out / 更改 )

Facebook photo

You are commenting using your Facebook account. Log Out / 更改 )

Google+ photo

You are commenting using your Google+ account. Log Out / 更改 )

Connecting to %s