使用 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 系統上會有完整的存取權。

下表列出這些資料夾的預設位置及其許可權。

路徑 資料夾內容 讀取 Write 建立/刪除
<磁片磁碟機 > :\Windows Windows 作業系統 X
<磁片磁碟機 > :\Program Files 可執行檔應用程式檔 X
<磁片磁碟機 > :\檔和設定\使用者名稱* 每個使用者的檔案 X X X
<磁片磁碟機 > :\檔和設定\所有使用者 所有使用者檔案 X X X

 

* 使用者名稱是使用者的登入名稱。

在最低許可權的使用者帳戶中,您可以讀取、寫入、建立和刪除任一資料夾中的檔案:Documents and Settings\Username 或 Documents and Settings\All Users。

這表示您不應該在 \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:使用者必須檢視或修改的檔案

典型的範例是使用者的已儲存遊戲檔案。 將檔案儲存在使用者的文檔資料夾中,讓使用者可以輕鬆地看到這些檔案。 應用程式會呼叫具有 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 Hive。 藉由列舉HKEY_USERS並移除每個子機碼下的遊戲特定資訊,卸載程式可以確保不會留下任何資訊。

使用 Least-Privileged 使用者帳戶修補

修補遊戲牽涉到更新遊戲的檔案。 因此,通常需要對遊戲的程式資料夾進行寫入存取。 當遊戲由系統管理員完成時,修補遊戲是一個直接的程式,因為它們無法存取遊戲的程式資料夾。 相反地,由於存取限制,對於最低特殊許可權使用者而言,傳統上很難修補遊戲。 現在, Windows Installer 已增強,讓最低許可權的使用者帳戶能夠修補。 為了利用這項功能,建議使用 Windows Installer 來安裝和修補遊戲。

從 Windows Installer 3.0 開始,符合特定條件時,應用程式修補程式可由最低許可權的使用者套用。 這些條件包括:

  • 應用程式是使用 Windows Installer 3.0 安裝。
  • 應用程式最初是每部電腦安裝。
  • 應用程式會從抽取式媒體安裝,例如 CD-ROM 或數位視訊磁片 (DVD) 。
  • 修補程式是由原始安裝程式套件 (.msi 檔案) 所識別的憑證進行數位簽署。
  • 您可以根據數位簽章驗證修補程式。
  • 原始安裝程式套件尚未停用最低許可權的使用者帳戶修補。
  • 系統管理員未透過系統原則停用最低許可權使用者帳戶修補。

一般而言,最低許可權的使用者無法修改遊戲的程式檔。 不過,當符合上述條件並啟用 LUA 修補時,Windows Installer 可以更新遊戲的檔案,讓使用者取得最新版本。

注意

本文中包含的資訊與發行前版本軟體產品有關,在發行前版本第一個商業版本之前可能會大幅修改。 因此,資訊可能無法在首次商業發行時正確描述或反映軟體產品。 本文僅供參考之用,且 Microsoft 不會針對本文或其所包含的資訊提出任何明示或隱含擔保。