Windows 从 Vista 开始重新修改了其系统的权限管理机制,于是现在就会碰到一些 xp 能过而 win7 不能过的代码。比如 Service 程序和一般应用程序用共享内存的方式来通讯,CreateFileMapping 的第二个参数我们往往都是填 NULL 使用默认权限(Service 的默认权限自然是 Service 级别的啦),于是在 Vista 以上的系统中运行于 user 权限应用程序打不开这一段共享内存。
网上很多帖子都说在遇到这种问题的时候让应用程序请求管理员权限,这个办法是能解决问题的,但是,我们很多时候是不希望程序获得管理员权限的,比如一台公用的PC,我们可能希望除了真正的管理员以外的用户都不知道管理员密码,以方便管理。于是在运行时会请求管理员权限的程序,都不能够使用了,只有管理员自己能用,这样的程序。。。挺二的,于是我们必须让程序在 user 权限下就完成所有工作。解决这个问题的办法之一,就是在 user 权限下打通与 Service 的通讯,借助 Service 来完成对权限有要求的操作。CreateFileMapping 就是其中的一个突破口,而 Service 必须以较低的权限来创建共享内存,应用程序才能直接打开。以下是 Service 端的代码
- HANDLE hMapFile;
- unsigned char *pBuf;
- SECURITY_ATTRIBUTES SecAttr;
- SECURITY_DESCRIPTOR SecDesc;
- SecAttr.nLength = sizeof(SecAttr);
- SecAttr.bInheritHandle = FALSE;
- SecAttr.lpSecurityDescriptor = &SecDesc;
- InitializeSecurityDescriptor(&SecDesc, SECURITY_DESCRIPTOR_REVISION);
- SetSecurityDescriptorDacl(&SecDesc, TRUE, 0, FALSE);
- hMapFile = CreateFileMapping(INVALID_HANDLE_VALUE, &SecAttr, PAGE_READWRITE, 0, BUF_SIZE, MAPPING_NAME);
- if(hMapFile == NULL)
- {
- return GetLastError();
- }
HANDLE hMapFile;
unsigned char *pBuf;
SECURITY_ATTRIBUTES SecAttr;
SECURITY_DESCRIPTOR SecDesc;
SecAttr.nLength = sizeof(SecAttr);
SecAttr.bInheritHandle = FALSE;
SecAttr.lpSecurityDescriptor = &SecDesc;
InitializeSecurityDescriptor(&SecDesc, SECURITY_DESCRIPTOR_REVISION);
SetSecurityDescriptorDacl(&SecDesc, TRUE, 0, FALSE);
hMapFile = CreateFileMapping(INVALID_HANDLE_VALUE, &SecAttr, PAGE_READWRITE, 0, BUF_SIZE, MAPPING_NAME);
if(hMapFile == NULL)
{
return GetLastError();
}
而应用程序端可以使用 OpenFileMapping 或 CreateFileMapping 打开共享内存。