如何以编程方式设置SeCreateGlobalPrivilege?

时间:2014-02-25 14:27:57

标签: c# winapi windows-7

我想知道如何以编程方式将SeCreateGlobalPrivilege设置为尝试打开带有session0前缀的MemoryMappedFile的无Global\进程,该进程将用于在两个进程之间共享一些数据,一个运行session0(Windows服务),另一个是通过在用户登录系统时调用CreateProcessAsUser启动的进程。

传递给CreateProcessAsUser函数的访问令牌与sessionIdWTSGetActiveConsoleSessionId()的结果匹配的“资源管理器”进程重复。

我有一个在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)

1 个答案:

答案 0 :(得分:0)

这似乎不可能。我只是猜测,我看到其他博客文章和论坛条目建议打开带有Global \前缀的MemoryMappedFile仅允许具有管理员权限的进程。