權限問題
互斥量對象會一直存活着直到使用它的最後一個程序關閉其句柄,因此它能在初始創建它的應用程序退出後保留相當長的時間。因爲此對象被廣泛地共享,所以它必須被賦予明確的許可以允許任何人使用它。事實上,“缺省”許可幾乎從不適用。 對於 SYNCHRONIZE和MUTEX_ALL_ACCESS 權限,因爲非管理員沒有這些權限(僅有上列的少許)互斥量不能被打開或者獲取,於是CreateMutex() 和OpenMutex() 返回NULL。因此,當對象已經存活於內存中時硬性改變其上的許可配置:(需要調用 SetKernelObjectSecurity(),下列程序片斷展示一個程序如何才能打開互斥量並安裝一個新的 DACL,此 DACL 即使在程序退出後也仍然保持着,只要任一其他程序還維護有它的句柄)
...
// open the mutex that we're going to adjust
HANDLE hMutex = OpenMutex(MUTEX_ALL_ACCESS, FALSE, "DBWinMutex");
// create SECURITY_DESCRIPTOR with an explicit, empty DACL
// that allows full access to everybody
SECURITY_DESCRIPTOR sd;
InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION);
SetSecurityDescriptorDacl(
&sd, // addr of SD
TRUE, // TRUE=DACL present
NULL, // ... but it's empty (wide open)
FALSE); // DACL explicitly set, not defaulted
// plug in the new DACL
SetKernelObjectSecurity(hMutex, DACL_SECURITY_INFORMATION, &sd);
...
例子:
HANDLE hEventQuit = NULL;
hEventQuit = CreateEvent(NULL, FALSE, FALSE, NULL);
DWORD WINAPI ThreadOperation()
{
HANDLE hMutex = NULL;
// Create SECURITY_DESCRIPTOR with an explicit, empty DACL
// that allows full access to everybody
SECURITY_DESCRIPTOR sd;
InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION);
SetSecurityDescriptorDacl(
&sd, // addr of SD
TRUE, // TRUE=DACL present
NULL, // ... but it's empty (wide open)
FALSE); // DACL explicitly set, not defaulted
// Open the mutex that we're going to adjust
hMutex = OpenMutex(MUTEX_ALL_ACCESS, NULL, _T("Global\\MutexName"));
if (NULL == hMutex)
{
SECURITY_ATTRIBUTES sa;
sa.nLength = sizeof(sa);
sa.bInheritHandle = FALSE;
sa.lpSecurityDescriptor = &sd;
hMutex = CreateMutex(&sa, FALSE, _T("Global\\MutexName"));
}
// Plug in the new DACL
SetKernelObjectSecurity(hMutex, DACL_SECURITY_INFORMATION, &sd);
if (NULL != hMutex)
{
HANDLE hMutexHandles[] = {hMutex, hEventQuit};
DWORD dwMutexResult = WaitForMultipleObjects(
_countof(hMutexHandles),
hMutexHandles,
FALSE,
INFINITE);
switch(dwMutexResult)
{
case WAIT_OBJECT_0: //scucess
//Do yourself things
break;
case WAIT_OBJECT_0 + 1: //quit,cancel thread
break;
case WAIT_ABANDONED:
//not release mutex and not response
break;
default: //failure
//decide operation yourself
break;
}
ReleaseMutex(hMutex);
}
else
{
CloseHandle(hMutex);
}
return 0;
}
延伸:
互斥對象
1. 互斥對象(mutex)屬於內核對象,它能夠確保線程擁有對單個資源的互斥訪問權。
2. 互斥對象包含一個使用數量,一個線程ID和一個計數器。
3. ID用於標識系統中的哪個線程當前擁有互斥對象,計數器用於指明該線程擁有互斥對象的次數。
涉及到三個函數:
1. CreateMutex:創建互斥對象,返回互斥對象的句柄,其中第二個參數如果是TRUE,表示調用該函數的線程擁有互斥對象的所有權,即互斥對象處於非空閒狀態。如果是FALSE,則表示當前互斥對象處於空閒狀態,其他線程可以佔用。
2. WaitForSingleObject(WaitForMultipleObject):等待互斥對象的使用權,如果第二個參數設置爲INFINITE,則表示會持續等待下去,直到擁有所有權,纔有權執行該函數下面的語句。一旦擁有了所有權,則會將互斥對象的的線程ID設置爲當前使用的線程ID值。
3. ReleaseMutex:將互斥對象所有權進行釋放,交還給系統。
可以將互斥對象想象成一把鑰匙,CreateMutex創建了這把鑰匙,WaitForSingleObject等待這把鑰匙去訪問一個公共的資源,比如一個房間,如果擁有了鑰匙,則這個房間的所有權就屬於這個進程了,別人是進不去這個房間的,直到進程將這個房間的鑰匙歸還掉,即ReleaseMutex。
訪問控制項 (ACE)
安全描述符 (SD)
隨機訪問控制列表 (DACL)
當允許訪問的 ACE 被添加到文件的隨機訪問控制列表 (DACL) 中時,相應用戶或組帳戶與 ACE 關聯將由提供與該文件允許訪問系統。大多數的情況文件的 DACL 不足夠大,以添加更多的 ACE。因此,就需要創建一個新的訪問控制列表 (ACL) 和從該文件的現有 DACL 按首選順序複製ace。新的 DACL 然後可以替換該文件的安全描述符 (SD) 中舊的 DACL。