权限问题
互斥量对象会一直存活着直到使用它的最后一个程序关闭其句柄,因此它能在初始创建它的应用程序退出后保留相当长的时间。因为此对象被广泛地共享,所以它必须被赋予明确的许可以允许任何人使用它。事实上,“缺省”许可几乎从不适用。 对于 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。