使用用户帐户Least-Privileged游戏

本文介绍游戏开发人员如何创作 Microsoft Windows游戏,这些游戏可以很好地使用最低特权用户帐户 (也称为受限用户帐户) 。

简介

Windows帐户管理其用户。 如今,80% 以上的家庭计算机用户与其他家庭成员共享其计算机。 当多个用户共享Windows,将创建多个用户帐户,每个用户使用单个帐户登录以访问计算机。 随着对安全性的不断增强,越来越多的用户使用特权最低用户帐户(也称为受限用户帐户)来操作其计算机,这些帐户无法完全控制系统。 管理员帐户通常可以不受限制地访问计算机的每一部分。 这可能会影响基于Windows游戏的工作。

对于编写游戏以使用最低特权用户帐户的游戏开发人员来说,还有一些好处。 在 Windows Vista 及更高版本中,将强制实施最低特权用户帐户,这意味着系统上的每个帐户(本地管理员除外)都是最低特权用户帐户。 这将影响未遵循旧版应用程序规则 (在 Vista) 更高版本Windows运行。 例如,当应用程序尝试写入文件夹或没有权限的注册表值时,文件写入将重定向到用户的虚拟文件存储。 此虚拟文件存储将驻留在用户具有写入访问权限的文件夹中。 此行为可能看起来不像完全失败写入尝试一样灾难性;但是,创建虚拟化文件的应用程序可能会让用户感到困惑,因为文件不会写入用户期望的位置。 例如,将高分文件写入可执行文件夹的同一文件夹中的游戏将改为将这些文件写入虚拟化文件夹。 因此,一个用户看不到其他用户实现的高分,因为每个用户都有单独的虚拟化文件存储。

遵循本文中准则的游戏将使用最低特权用户帐户运行,因此将保持与 Windows Vista 及更高版本的兼容性。

Least-Privileged用户帐户的文件访问

Windows支持两个文件系统:FAT32 和 NTFS。 FAT32 是仅支持向后兼容性的旧文件系统;NTFS 支持功能更强大的文件权限。 NTFS 的使用正在扩展,因为零售商正在寄送新计算机,Windows在 NTFS 分区的硬盘驱动器上预装了新计算机。 在基于 NTFS 的 Windows XP 系统中,具有最低特权用户帐户的用户对多个文件夹的访问权限有限。 但是,他们可以完全访问基于 FAT32 的 WINDOWS XP 系统。

下表列出了这些文件夹的默认位置及其权限。

路径 文件夹内容 读取 写入 创建/删除
<驱动器 > \ :Windows Windows操作系统 X
<驱动器 > : \ 程序文件 可执行应用程序文件 X
<驱动器 > : \ 文档设置 \ 用户名* 每个用户的文件 X X X
<驱动器 > : \ 文档设置 \ 所有用户 所有用户文件 X X X

* 用户名是用户的登录名。

在最低特权用户帐户中,可以读取、写入、创建和删除任一文件夹中的文件:文档和设置 \ 用户名或文档设置 \ 所有用户。

这意味着,不应将保存游戏放在"程序文件"中,而应将其放在"程序文件"中的子 \ \ 我的文档。 此外,不应将临时应用程序数据放在 Program Files 或 我的文档中,而应将其放置在"应用程序数据"文件夹中 (\ \ CSIDL _ LOCAL _ APPDATA) 。

更具体地说,每个游戏应处理两种方案:

方案 1:用户无需查看或更改的文件

典型的示例是游戏的配置文件、临时文件和游戏缓存文件。 这些文件通常保存在"应用程序数据"文件夹中。 若要获取此文件夹路径,请通过 CSIDL APPDATA 或 CSIDL LOCAL APPDATA 调用 SHGetFolderPath 函数 _ _ _ ,如以下代码示例所示。

#include <shlobj.h>
#include <strsafe.h>

#define APPNAME L"MyApp"

WCHAR wszPath[MAX_PATH];

// Local Application Data
SHGetFolderPath( hWnd, CSIDL_LOCAL_APPDATA, NULL, SHGFP_TYPE_CURRENT, wszPath );
StringCchCatW( wszPath, MAX_PATH, L"\\" );
StringCchCatW( wszPath, MAX_PATH, APPNAME );

// Create the folder wszPath
// Then create files in wszPath
// Roaming Application Data
SHGetFolderPath( hWnd, CSIDL_APPDATA, NULL, SHGFP_TYPE_CURRENT, wszPath );
StringCchCatW( wszPath, MAX_PATH, L"\\" );
StringCchCatW( wszPath, MAX_PATH, APPNAME );

// Create the folder wszPath
// Then create files in wszPath

本地和漫游应用程序数据文件夹之间的区别在于,在 Windows 2000 和 Windows XP 上,漫游内容在登录/注销过程中与服务器之间复制,而本地内容不是。 对于大多数游戏,本地应用程序数据已足够。

方案 2:需要由用户查看或更改的文件

典型的示例是用户保存的游戏文件。 将文件存储在用户的文档文件夹中,以便用户可以轻松看到这些文件。 应用程序通过使用 CSIDL PERSONAL 调用 SHGetFolderPath 获取用户的文档文件夹 _ 路径,如下面的代码示例所示:

#include <shlobj.h>
#include <strsafe.h>

#define APPNAME L"MyApp"

WCHAR wszPath[MAX_PATH];

SHGetFolderPath( hWnd, CSIDL_PERSONAL, NULL, SHGFP_TYPE_CURRENT, wszPath );
StringCchCatW( wszPath, MAX_PATH, L"\\" );
StringCchCatW( wszPath, MAX_PATH, APPNAME );

// Create the folder wszPath
// Then create files in wszPath

有时,游戏可能需要存储所有用户都能看到和使用的文件。 一个示例是高分数记录,其中所有用户都写入同一记录文件,以便系统范围内维护高分,而不是为每个用户单独保留高分。 其他示例包括下载的地图、任务和游戏修改。 如果这些共享,则只有一个用户需要下载它们,而不是每个用户。 在此方案中,使用共享配置文件文件夹下的文档文件夹,如以下代码所示。

#include <shlobj.h>
#include <strsafe.h>

#define APPNAME L"MyApp"

WCHAR wszPath[MAX_PATH];

SHGetFolderPath( hWnd, CSIDL_COMMON_DOCUMENTS, NULL, SHGFP_TYPE_CURRENT, wszPath );
StringCchCatW( wszPath, MAX_PATH, L"\\" );
StringCchCatW( wszPath, MAX_PATH, APPNAME );

// Create the folder wszPath
// Then create files in wszPath

Least-Privileged用户帐户的注册表访问

应用程序通常使用 Windows注册表来存储信息。 与文件访问类似,管理员和最低特权用户帐户对注册表的权限不同。 对于最低特权用户帐户,整个 HKEY LOCAL _ _ MACHINE 节点是只读的。 例如,游戏可以读取默认配置信息,但不能向此节点写入任何新信息。 因此,在最低特权用户模式下运行、需要写入注册表的游戏将需要使用 HKEY CURRENT USER 节点来存储每 _ 用户 _ 信息,如以下代码所示。

#define APP_REGISTRY_KEY_PATH L"Software\\MyCompany\\MyApp"

LONG lRetVal;
HKEY hKey;

lRetVal = RegCreateKeyExW( HKEY_CURRENT_USER,
                           APP_REGISTRY_KEY_PATH,
                           0,
                           NULL,
                           REG_OPTION_NON_VOLATILE,
                           KEY_WRITE|KEY_READ,
                           NULL,
                           &hKey,
                           NULL );

if( ERROR_SUCCESS == lRetVal )
{
    // Store information in hKey
}

值得注意的是,在安装过程中,注册表信息应写入 HKEY _ LOCAL _ MACHINE,而不是 HKEY _ CURRENT _ USER。 这是因为运行安装的人通常是管理员,并且可能并不是使用该程序的唯一人员。 在这种情况下,写入 HKEY _ CURRENT _ USER 会使该信息对其他用户不可用。 这通常不是问题,因为在安装过程中写入注册表的信息是应用于程序的每个用户的配置和默认设置。

卸载游戏时,需要额外努力删除游戏写入注册表的每一个值。 由于卸载程序由一个人(通常是管理员)运行,因此直接删除 HKEY LOCAL MACHINE 和 HKEY CURRENT USER 中的相关信息不会删除 _ _ _ _ 其他用户的值。 删除注册表中每用户信息的一种方式是枚举 HKEY _ USERS 注册表配置单元根。 HKEY USERS 下 _ 的每个子项对应于系统特定用户的 HKEY _ CURRENT USER _ 配置单元。 通过枚举 HKEY USERS 并删除每个子项下特定于游戏的信息,卸载程序可以确保 _ 没有留下任何信息。

使用用户帐户Least-Privileged修补

修补游戏涉及更新游戏的文件。 因此,通常需要对游戏的程序文件夹进行写入访问。 修补游戏是管理员完成游戏的一个简单过程,因为他们可以不受限制地访问游戏的程序文件夹。 相反,由于访问限制,最低特权用户通常很难修补游戏(如果不是不可能)。 现在,Windows安装程序已增强,使最低特权用户帐户修补成为可能。 若要利用此功能,建议游戏利用Windows安装程序进行安装和修补。

从 Windows安装程序 3.0 开始,当满足某些条件时,最低特权用户可以应用应用程序修补程序。 这些条件包括:

  • 该应用程序是使用安装程序 3.0 Windows安装的。
  • 该应用程序最初是每台计算机安装的。
  • 该应用程序是从可移动媒体(如 cd-rom 或数字视频光盘 (DVD) 上安装的。
  • 修补程序由原始安装程序包标识的证书进行数字签名 (.msi 文件) 。
  • 可以针对数字签名对修补程序进行验证。
  • 原始安装程序包未禁用最小特权用户帐户修补。
  • 系统管理员未禁用通过系统策略修补最低特权的用户帐户。

通常,特权最少的用户不能修改游戏的程序文件。 但是,在满足上述条件并启用了 LUA 修补后,Windows Installer 可以更新游戏的文件,以便用户获取最新版本。

备注

本文中包含的信息与预发行版软件产品相关,该产品在其首次发布之前可能会进行重大修改。 相应地,在首次发布产品时,此信息可能不能准确描述或反映软件产品。 本文仅供参考,Microsoft 对本文章或其中包含的信息不作任何明示或默示的保证。)