2014-02-25 290 views
0

我想知道我如何通過編程設定SeCreateGlobalPrivilege到無session0的過程,正試圖打開一個MemoryMappedFileGlobal\前綴,將用於2個進程之間共享一些數據,與session0(Windows服務)運行一個等通過在用戶登錄到系統時調用CreateProcessAsUser來啓動該進程。如何以編程方式設置SeCreateGlobalPrivilege?

傳遞給CreateProcessAsUser函數的訪問令牌從「explorer」進程複製而來,該進程的sessionIdWTSGetActiveConsoleSessionId()的結果匹配。

我有session0,它返回一個連續監測其被映射到用於從使用HTTP外部訪問數據的URL的特定本地文件一個用戶進程分配的MemoryMappedFile內容下運行本Owin中間件。

我不能讓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(); 
         } 
        } 
       } 
      }; 
    } 

我得到以下異常時,窗口服務過程中嘗試打開由用戶會話過程中創建的MemoryMappedFile。

2014年2月27日11:21:18677 [1704 | 22 | DEBUG] XXX:System.IO.FileNotFoundException:找不到指定されたファイルが見つかりません 場所System.IO .__ Error.WinIOError(的Int32的errorCode ,字符串maybeFullPath) 場所System.IO.MemoryMappedFiles.MemoryMappedFile.OpenCore(字符串MAPNAME,HandleInheritability可繼承,的Int32 desiredAccessRights,布爾createOrOpen) 場所System.IO.MemoryMappedFiles.MemoryMappedFile.OpenExisting(字符串MAPNAME,MemoryMappedFileRights desiredAccessRights,HandleInheritability可繼承) 場所System.IO.MemoryMappedFiles.MemoryMappedFile.OpenExisting(String mapName)

+0

我正試圖在Windows 7環境中執行此操作。 – hanishi

回答

0

這似乎是施加IBLE。然而,我只是在猜測,我看到其他博客文章和論壇條目都建議使用Global \ prefix打開MemoryMappedFile只能由具有管理員權限的進程訪問。

相關問題