最近工作中用到共享内存进行进程间通信,客户端在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/