我想知道如何以编程方式将SeCreateGlobalPrivilege
设置为尝试打开带有session0
前缀的MemoryMappedFile
的无Global\
进程,该进程将用于在两个进程之间共享一些数据,一个运行session0
(Windows服务),另一个是通过在用户登录系统时调用CreateProcessAsUser
启动的进程。
传递给CreateProcessAsUser
函数的访问令牌与sessionId
与WTSGetActiveConsoleSessionId()
的结果匹配的“资源管理器”进程重复。
我有一个在session0
下运行的Owin中间件,它返回由用户进程分配的MemoryMappedFile
内容,该用户进程持续监视映射到用于访问数据的URL的特定本地文件从外面使用HTTP。
我不能让Windows服务进程打开MemoryMappedFile,因为它会创建一些任何sesison0进程都不知道的任意位置。
以下是我试图让它在这种特定情况下工作的代码片段。只有当前面两个进程都使用相同的sessionId运行时,它才有效,无论是否有全局前缀。
public class FileView
{
private readonly AutoResetEvent _run = new AutoResetEvent(false);
private readonly AutoResetEvent _update = new AutoResetEvent(false);
private ILog logger = LogManager.GetLogger("weldR");
private bool IsDisposed { get; set; }
private byte[] Data { get; set; }
private string MapName { get; set; }
private string MutexName { get; set; }
private MemoryMappedFileSecurity Security { get; set; }
public FileView(string url)
{
if (url.StartsWith("/"))
{
url = url.Substring(1);
}
MapName = string.Format("Global\\{0}",String.Concat("pipe://", url));
MutexName = string.Format("Global\\{0}", url.GetHashCode().ToString("x"));
Security = new MemoryMappedFileSecurity();
Security.AddAccessRule(new System.Security.AccessControl.AccessRule<MemoryMappedFileRights>("everyone",
MemoryMappedFileRights.FullControl, System.Security.AccessControl.AccessControlType.Allow));
Task.Factory.StartNew(Run);
}
void Run()
{
while (!IsDisposed)
{
if(Data != null)
{
Process process = Process.GetCurrentProcess();
using (new PrivilegeEnabler(process, Privilege.CreateGlobal))
{
var mutex = new Mutex(true, MutexName);
using (var mmf = MemoryMappedFile.CreateNew(MapName, Data.Length + 8,
MemoryMappedFileAccess.ReadWriteExecute, MemoryMappedFileOptions.None, Security, HandleInheritability.Inheritable))
{
using (var viewAccessor = mmf.CreateViewAccessor())
{
try
{
var size = Data.Length.Bytes();
viewAccessor.WriteArray(0, size, 0, size.Length);
viewAccessor.WriteArray(size.Length + 1, Data, 0, Data.Length);
}
catch (Exception e)
{
logger.ErrorFormat(e.ToString());
}
}
mutex.ReleaseMutex();
_update.Set();
_run.WaitOne();
mutex.WaitOne();
}
}
}
else
{
_run.WaitOne();
}
}
}
public void Update(byte[] data)
{
Data = data;
_run.Set();
_update.WaitOne();
}
public void Dispose()
{
IsDisposed = true;
_run.Set();
_update.Set();
}
}
private static Action<OwinRequest, OwinResponse> Serve(string path)
{
return (request, response) =>
{
//var pipename = String.Concat("pipe://", path);
// var pipemutex = path.GetHashCode().ToString("x");
var pipename = string.Format("Global\\{0}", String.Concat("pipe://", path));
var pipemutex = string.Format("Global\\{0}", path.GetHashCode().ToString("x"));
using (var mmf = MemoryMappedFile.OpenExisting(pipename))
{
using (var mutex = Mutex.OpenExisting(pipemutex))
{
try
{
mutex.WaitOne();
using (var accessor = mmf.CreateViewAccessor())
{
var offset = 0;
var fileLength = new byte[4];
accessor.ReadArray(offset, fileLength, 0, fileLength.Length);
offset += fileLength.Length;
var size = fileLength.Int32();
var buff = new byte[size];
accessor.ReadArray(offset, buff, 0, buff.Length);
var lastWriteTimeUtc = new DateTime();
var etag = string.Concat("\"", lastWriteTimeUtc.Ticks.ToString("x"), "\"");
var lastModified = lastWriteTimeUtc.ToString("R");
if ("HEAD".Equals(request.Method, StringComparison.OrdinalIgnoreCase))
return;
//if (CacheHelpers.ReturnNotModified(etag, lastWriteTimeUtc, context))
//{
// mutex.ReleaseMutex();
// return TaskHelpers.Completed();
//}
response.AddHeader("ETag", etag);
response.AddHeader("Last-Modified", lastModified);
response.AddHeader("Content-Type", Mime.MimeTypeFromExtension(path, "text/plain"));
response.AddHeader("Content-Length", size.ToString(CultureInfo.InvariantCulture));
response.Body.Write(buff, 0, buff.Length);
}
}
finally
{
mutex.ReleaseMutex();
}
}
}
};
}
当Window Service进程尝试打开由用户会话进程创建的MemoryMappedFile时,我得到以下异常。
2014-02-27 11:21:18,677 [1704 | 22 | DEBUG] XXX:System.IO.FileNotFoundException:指定されたファイルが见つかりません。 场所System.IO .__ Error.WinIOError(Int32 errorCode,String maybeFullPath) 场所System.IO.MemoryMappedFiles.MemoryMappedFile.OpenCore(String mapName,HandleInheritability inheritability,Int32 desiredAccessRights,Boolean createOrOpen) 场所System.IO.MemoryMappedFiles.MemoryMappedFile.OpenExisting(String mapName,MemoryMappedFileRights desiredAccessRights,HandleInheritability inheritability) 场所System.IO.MemoryMappedFiles.MemoryMappedFile.OpenExisting(String mapName)
答案 0 :(得分:0)
这似乎不可能。我只是猜测,我看到其他博客文章和论坛条目建议打开带有Global \前缀的MemoryMappedFile仅允许具有管理员权限的进程。