使用 Least-Privileged 用户帐户进行游戏

本文介绍了游戏开发人员如何创作适用于最低特权用户帐户的 Microsoft Windows 游戏, (也称为受限用户帐户) 。

简介

Windows使用帐户管理其用户。 如今,超过80%的计算机用户在家庭中与其他家庭成员共享其计算机。 当多个用户共享一台Windows计算机时,将创建多个用户帐户,并且每个用户使用单个帐户登录以访问计算机。 随着安全性意识的提高,越来越多的人使用最低特权用户帐户(也称为受限用户帐户)运行其计算机,这些帐户对系统没有完全控制。 管理员帐户通常对计算机的每个部分具有不受限制的访问权限。 这可能会影响基于Windows的游戏的工作方式。

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

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

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

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

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

路径 文件夹内容 读取 写入 创建/删除
<Drive>:\Windows Windows操作系统 X
<Drive>:\Program Files 可执行的应用程序文件 X
<Drive>:\Documents and 设置\Username* 每个用户的文件 X X X
<Drive>:\Documents and 设置\All Users 所有用户文件 X X X

 

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

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

这意味着,不应将保存游戏放置在 \Program Files 中,而应将其置于 \My Documents 的子文件夹中。 此外,不应将临时应用程序数据放置在 \Program Files 或 \My Documents 中,而应将其放置在应用程序数据文件夹中 (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:用户需要查看或更改的文件

典型的示例是用户的已保存游戏文件。 Microsoft Store用户文档文件夹中的文件,以便用户能够轻松看到这些文件。 应用程序通过调用具有 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 Installer 进行安装和修补。

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

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

通常,最低特权用户无法修改游戏的程序文件。 但是,如果满足上述条件并启用了 LUA 修补,Windows安装程序可以更新游戏的文件,以便用户获取最新版本。

注意

本文中包含的信息与预发行软件产品有关,该产品可能在首次商业发布之前进行大量修改。 因此,在首次商业发布时,这些信息可能无法准确描述或反映软件产品。 本文仅供参考,Microsoft 对本文或其中包含的信息不作任何明示或默示保证。