2013-08-05 35 views
4

我正在嘗試使用內存映射文件在Windows(用C#編寫)服務和用C++編寫的屏幕保護程序之間共享數據。無法從登錄屏幕打開內存映射文件

雖然如果屏幕保護程序在登錄用戶的上下文中運行,那麼運行良好,但如果屏幕保護程序在登錄屏幕上運行,則不起作用。而不是OpenFileMapping失敗,出現未經授權的訪問錯誤。似乎很明顯,我錯過了一個訪問規則(或系統設置也許使這項工作),但我無法弄清楚哪一個。

我的C#端代碼:

public CreateMemMappedFile(string fileName) 
    { 
     this.rootName = fileName; 
     var security = new MemoryMappedFileSecurity(); 

     security.AddAccessRule(new System.Security.AccessControl.AccessRule<MemoryMappedFileRights>(
      new SecurityIdentifier(WellKnownSidType.WorldSid, null), 
      MemoryMappedFileRights.FullControl, System.Security.AccessControl.AccessControlType.Allow)); 
     security.AddAccessRule(new System.Security.AccessControl.AccessRule<MemoryMappedFileRights>(
      new SecurityIdentifier(WellKnownSidType.AnonymousSid, null), 
      MemoryMappedFileRights.FullControl, System.Security.AccessControl.AccessControlType.Allow)); 
     security.AddAccessRule(new System.Security.AccessControl.AccessRule<MemoryMappedFileRights>(
      new SecurityIdentifier(WellKnownSidType.NullSid, null), 
      MemoryMappedFileRights.FullControl, System.Security.AccessControl.AccessControlType.Allow)); 

     // printing the SID from the screensaver shows that we are running as Local Service 
     security.AddAccessRule(new System.Security.AccessControl.AccessRule<MemoryMappedFileRights>(
      new SecurityIdentifier(WellKnownSidType.LocalServiceSid, null), 
      MemoryMappedFileRights.FullControl, System.Security.AccessControl.AccessControlType.Allow)); 

     this.handle = MemoryMappedFile.CreateOrOpen(
      "Global\\" + fileName, 1024 * 1024, 
      MemoryMappedFileAccess.ReadWriteExecute 
      ,MemoryMappedFileOptions.DelayAllocatePages, 
      security, System.IO.HandleInheritability.Inheritable 
      ); 
    } 

我的屏幕保護程序代碼:

 TCHAR* myFileName = _T("Global\\myfile"); 
     ipcBufferHandle = OpenFileMapping(FILE_MAP_READ,FALSE,myFileName); 
     if(ipcBufferHandle == NULL) 
     { 
      _tprintf(_T("couldn't open file \"%s\" with error code %d\n"),myFileName,GetLastError()); 
     } 
     else 
     { 
      _tprintf(_T("opened file %s\n"),myFileName); 
     } 

其輸出couldn't open file "Global\myfile" with error code 5

+2

什麼是通過內存映射文件進行通信,也許可能有另一種形式的IPC,可能會更好地工作。 –

+0

@ScottChamberlain我正在移動未壓縮的視頻。使用內存映射文件爲我提供了一個優雅降級的途徑,而套接字需要明確處理屏幕保護程序無法跟上的情況。 – Yaur

回答

0

作爲上msdn OpenFileMapping表示被定義爲

HANDLE WINAPI OpenFileMapping(
    _In_ DWORD dwDesiredAccess, 
    _In_ BOOL bInheritHandle, 
    _In_ LPCTSTR lpName 
); 

因此,當您撥打bInheritHandleFALSE時,句柄不與其他進程共享。嘗試TRUE,就像您在C#中使用System.IO.HandleInheritability.Inheritable一樣。

ipcBufferHandle = OpenFileMapping(FILE_MAP_READ, TRUE, myFileName); 
+0

沒有工作。請記住,如果用戶登錄,一切工作正常。 – Yaur

+0

你好,我看到你有更可能的另一個訪問問題...所以'winlogon'父進程?你是否允許你的服務訪問桌面? – metadings

+0

對[此問題]的評論(http://stackoverflow.com/questions/14345274/memory-mapped-file-access-denied)提到一個LocalService可能無法創建一個MMF。嘗試以SYSTEM身份運行該服務,並嘗試刪除AnonymousSid(爲什麼是NullSid?),因爲這也可能會被拒絕規則覆蓋 – metadings