windows中以最低权限(SECURITY_ATTRIBUTES)创建内核对象

最近工作中用到共享内存进行进程间通信,客户端在win8的IE10中老是报无法打开服务端以默认权限创建的共享内存等内核对象,环境是:1. 使用win8的默认等级的用户帐户控制,2. IE10的安全属性中开启了“启用保护模式”。开始是想办法提升客户端的权限,尝试了好多方法,最终都无法达到效果,最后转换思路,尝试以低权限来创建内核对象,又进行了好长时间的搜索,最终在Writing to Global Shared memory from an Application in Vista中找到相关信息,并整理如下。


BOOL createLowSecurityDescriptor(SECURITY_ATTRIBUTES& secAttr)
{
	BOOL succ = FALSE;
	DWORD lassErr = 0;
	PACL pSacl = NULL;                  // not allocated


	PSECURITY_DESCRIPTOR pSD = NULL;

	//OSVERSIONINFO osvi;
	//osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
	//succ = GetVersionEx (&osvi);
	bool bIsWindowsXPOrLater = ( (osvi.dwMajorVersion > 5) || ( (osvi.dwMajorVersion == 5) && (osvi.dwMinorVersion >= 1) ));
	//bool bIsVistaOrLater = ( osvi.dwMajorVersion > 5);
	//if (bIsVistaOrLater)
	//{
		succ = ConvertStringSecurityDescriptorToSecurityDescriptor(
			_T("S:(ML;;NW;;;LW)"), // this means "low integrity"
			SDDL_REVISION_1,
			&pSD,
			NULL);
		lassErr = GetLastError();
		srlog_func_return_ret(succ,
			(_T("::createLowSecurityDescriptor | ConvertStringSecurityDescriptorToSecurityDescriptor return:%d, lassErr:%lu"), succ, lassErr),
			NULL
			);

		BOOL fSaclPresent = FALSE;
		BOOL fSaclDefaulted = FALSE;
		succ = GetSecurityDescriptorSacl(
			pSD,
			&fSaclPresent,
			&pSacl,
			&fSaclDefaulted);
		lassErr = GetLastError();
		srlog_func_return_ret(succ,
			(_T("::createLowSecurityDescriptor | GetSecurityDescriptorSacl return:%d, lassErr:%lu"), succ, lassErr),
			NULL
			);
	//}
	

	succ = InitializeSecurityDescriptor(secAttr.lpSecurityDescriptor, SECURITY_DESCRIPTOR_REVISION);
	lassErr = GetLastError();
	srlog_func_return_ret(succ,
		(_T("::createLowSecurityDescriptor | InitializeSecurityDescriptor return:%d, lassErr:%lu"), succ, lassErr),
		NULL
		);

	succ = SetSecurityDescriptorSacl(secAttr.lpSecurityDescriptor, TRUE, pSacl, FALSE);
	lassErr = GetLastError();
	srlog_func_return_ret(succ,
		(_T("::createLowSecurityDescriptor | SetSecurityDescriptorSacl return:%d, lassErr:%lu"), succ, lassErr),
		NULL
		);

	return TRUE;
}

HANDLE openMutex(const TCHAR* gMutexName)
{
	HANDLE hMutex = NULL;
	hMutex = OpenMutex(SYNCHRONIZE | MUTEX_MODIFY_STATE, FALSE, gMutexName);
	if (hMutex == NULL)
	{
		srlog_warn(TEXT("createOrOpenMutex::Could not open mutex object (%d).\n"), 
			GetLastError());
		hMutex = NULL;
	}
	return hMutex;

}
HANDLE createOrOpenMutex(const TCHAR* gMutexName)
{
	srlog_tracer(::createOrOpenMutex);

	HANDLE hMutex = NULL;


	BOOL succ  = FALSE;
	DWORD lassErr = 0;
	SECURITY_ATTRIBUTES secAttr;	
	SECURITY_DESCRIPTOR secDesc;

	OSVERSIONINFO osvi;
	osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
	succ = GetVersionEx (&osvi);
	//bool bIsWindowsXPOrLater = ( (osvi.dwMajorVersion > 5) || ( (osvi.dwMajorVersion == 5) && (osvi.dwMinorVersion >= 1) ));
	bool bIsVistaOrLater = ( osvi.dwMajorVersion > 5);
	if (bIsVistaOrLater)
	{
		secAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
		secAttr.bInheritHandle = FALSE;
		secAttr.lpSecurityDescriptor = &secDesc;

		succ = createLowSecurityDescriptor(secAttr);
		srlog_info(_T("::createOrOpenMutex | createLowSecurityDescriptor return:%d"), succ);		
	}
	else
	{
		
		if(InitializeSecurityDescriptor(&secDesc, SECURITY_DESCRIPTOR_REVISION)) //Revision level
		{
			if(SetSecurityDescriptorDacl(&secDesc,
				TRUE, // DACL presence
				NULL, // DACL (NULL DACL means all access granted)
				FALSE)) // default DACL
			{
				secAttr.nLength = sizeof(SECURITY_DESCRIPTOR);
				secAttr.lpSecurityDescriptor = (LPVOID)&secDesc;
				secAttr.bInheritHandle = FALSE;
				// now you can fill param LPSECURITY_ATTRIBUTES while &secAttr
			}
		}
	}

	hMutex = CreateMutex(&secAttr, FALSE, gMutexName);
	if (hMutex == NULL)
	{
		srlog_warn(TEXT("createOrOpenMutex::Could not create mutex object (%d).\n"), 
			GetLastError());
		hMutex = openMutex(gMutexName);
	}
	return hMutex;
}


HANDLE openEvent(const TCHAR* gEventName)
{
	srlog_tracer(::openEvent);
	HANDLE hMutex = NULL;
	hMutex = OpenEvent(SYNCHRONIZE | EVENT_MODIFY_STATE, FALSE, gEventName);
	if (hMutex == NULL)
	{
		srlog_warn(TEXT("createOrOpenMutex::Could not open mutex object (%d).\n"), 
			GetLastError());
		hMutex = NULL;
	}	
	return hMutex;
}

HANDLE createOrOpenEvent(const TCHAR* gEventName, BOOL bManualReset, BOOL bInitialState)
{
	srlog_tracer(::createOrOpenEvent);
	HANDLE hEvent = openEvent(gEventName);
	DWORD lastErr = GetLastError();
	if (hEvent == NULL)
	{
		srlog_warn(TEXT("createOrOpenMutex::Could not open mutex object (%d).\n"), 
			lastErr);

		BOOL succ  = FALSE;
		DWORD lassErr = 0;
		SECURITY_ATTRIBUTES secAttr;	
		SECURITY_DESCRIPTOR secDesc;

		OSVERSIONINFO osvi;
		osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
		succ = GetVersionEx (&osvi);
		//bool bIsWindowsXPOrLater = ( (osvi.dwMajorVersion > 5) || ( (osvi.dwMajorVersion == 5) && (osvi.dwMinorVersion >= 1) ));
		bool bIsVistaOrLater = ( osvi.dwMajorVersion > 5);
		if (bIsVistaOrLater)
		{
			secAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
			secAttr.bInheritHandle = FALSE;
			secAttr.lpSecurityDescriptor = &secDesc;

			succ = createLowSecurityDescriptor(secAttr);
			srlog_info(_T("::createOrOpenEvent | createLowSecurityDescriptor return:%d"), succ);		
		}
		else
		{

			if(InitializeSecurityDescriptor(&secDesc, SECURITY_DESCRIPTOR_REVISION)) //Revision level
			{
				if(SetSecurityDescriptorDacl(&secDesc,
					TRUE, // DACL presence
					NULL, // DACL (NULL DACL means all access granted)
					FALSE)) // default DACL
				{
					secAttr.nLength = sizeof(SECURITY_DESCRIPTOR);
					secAttr.lpSecurityDescriptor = (LPVOID)&secDesc;
					secAttr.bInheritHandle = FALSE;
					// now you can fill param LPSECURITY_ATTRIBUTES while &secAttr
				}
			}
		}

		hEvent = CreateEvent(&secAttr, bManualReset, bInitialState, gEventName);
		lastErr = GetLastError();
		if (hEvent == NULL)
		{
			srlog_warn(TEXT("createOrOpenMutex::Could not create mutex object (%d).\n"), 
				lastErr);
		}
	}
	return hEvent;
}

HANDLE openFileMapping(const TCHAR* gFileMappingName)
{
	HANDLE hMapFile = OpenFileMapping(
		FILE_MAP_WRITE | FILE_MAP_READ,   // read/write access
		FALSE,                 // do not inherit the name
		gFileMappingName);               // name of mapping object 
	if (hMapFile == NULL) 
	{ 
		_tprintf(TEXT("Could not open file mapping object (%d).\n"), 
			GetLastError());		
	}
	return hMapFile;
}

HANDLE createOrOpenFileMapping(const TCHAR* gFileMappingName, int size)
{
	BOOL succ  = FALSE;
	DWORD lassErr = 0;
	SECURITY_ATTRIBUTES secAttr;	
	SECURITY_DESCRIPTOR secDesc;

	OSVERSIONINFO osvi;
	osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
	succ = GetVersionEx (&osvi);
	//bool bIsWindowsXPOrLater = ( (osvi.dwMajorVersion > 5) || ( (osvi.dwMajorVersion == 5) && (osvi.dwMinorVersion >= 1) ));
	bool bIsVistaOrLater = ( osvi.dwMajorVersion > 5);
	if (bIsVistaOrLater)
	{
		secAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
		secAttr.bInheritHandle = FALSE;
		secAttr.lpSecurityDescriptor = &secDesc;

		succ = createLowSecurityDescriptor(secAttr);
		srlog_info(_T("::createOrOpenFileMapping | createLowSecurityDescriptor return:%d"), succ);		
	}
	else
	{

		if(InitializeSecurityDescriptor(&secDesc, SECURITY_DESCRIPTOR_REVISION)) //Revision level
		{
			if(SetSecurityDescriptorDacl(&secDesc,
				TRUE, // DACL presence
				NULL, // DACL (NULL DACL means all access granted)
				FALSE)) // default DACL
			{
				secAttr.nLength = sizeof(SECURITY_DESCRIPTOR);
				secAttr.lpSecurityDescriptor = (LPVOID)&secDesc;
				secAttr.bInheritHandle = FALSE;
				// now you can fill param LPSECURITY_ATTRIBUTES while &secAttr
			}
		}
	}

	HANDLE hMapFile = CreateFileMapping(
		INVALID_HANDLE_VALUE,    // use paging file
		&secAttr,          // default security 
		PAGE_READWRITE,          // read/write access
		0,                       // maximum object size (high-order DWORD) 
		size,					// maximum object size (low-order DWORD)  
		gFileMappingName);                 // name of mapping object
	lassErr = GetLastError();
	srlog_func_ret(hMapFile != NULL,
		(_T("::createLowSecurityDescriptor | CreateFileMapping return:%d, lassErr:%lu"), succ, lassErr)
		);

	if (hMapFile == NULL)
	{ 
		_tprintf(TEXT("Could not create file mapping object (%d).\n"), 
			GetLastError());
		hMapFile = openFileMapping(gFileMappingName);
	}
	return hMapFile;
}




参考资料:

http://blogs.msdn.com/b/ieinternals/archive/2012/03/23/understanding-ie10-enhanced-protected-mode-network-security-addons-cookies-metro-desktop.aspx?PageIndex=2

http://social.msdn.microsoft.com/forums/en-US/windowssecurity/thread/08e18474-5f8c-4294-a9cf-7ede1ff8ae1f/

你可能感兴趣的:(C/C++,win8,ie10,Protected,Mode,CreateMutex)