2013-05-06 47 views
0

我目前正試圖讓我的內核過濾器與我的c#應用程序進行通信。內核應用程序在我的結構中發送一個UNICODE_STRING,其中包含文件的路徑。所有其他變量似乎罰款和緩衝的位置似乎相同的用戶和內核的應用程序,但是當我把我的ToString方法,我得到Marshal.PtrToStringUni(s)返回類名稱而不是消息

usermodeFilter.MinifilterWrapper + NativeMethods + COMMAND_MESSAGE

我的C#代碼看起來是這樣

private NativeMethods.USERCOMMAND_MESSAGE data = new NativeMethods.USERCOMMAND_MESSAGE(); 

    [SecurityPermission(SecurityAction.Demand)] 
    public void FilterGetMessage() 
    { 

     UInt32 result = NativeMethods.FilterGetMessage(_handle, ref data, (UInt32)Marshal.SizeOf(typeof(NativeMethods.USERCOMMAND_MESSAGE)), IntPtr.Zero); 
     if (result == NativeMethods.S_OK) 
     { 
      Console.WriteLine("message recived"); 
      Console.WriteLine(this.getProcessNameFromId((int)this.data.cmdMessage.procesID)); 
      Console.WriteLine(this.data.cmdMessage.ToString()); 
     } 
     else 
     { 
      throw new InvalidOperationException("Unknown error, number " +result); 
     } 

    } 

     [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] 
     public struct COMMAND_MESSAGE { 
      public UInt32 procesID; 
      public UNICODE_STRING fileName; 
     } 

     [StructLayout(LayoutKind.Sequential)] 
     public struct UNICODE_STRING : IDisposable 
     { 
      public ushort Length; 
      public ushort MaximumLength; 
      private IntPtr buffer; 

      public UNICODE_STRING(string s) 
      { 
       Length = (ushort)(s.Length * 2); 
       MaximumLength = (ushort)(Length + 2); 
       buffer = Marshal.StringToHGlobalUni(s); 
      } 

      public void Dispose() 
      { 
       Marshal.FreeHGlobal(buffer); 
       buffer = IntPtr.Zero; 
      } 

      public override string ToString() 
      { 
       return Marshal.PtrToStringUni(buffer); 
      } 
      } 

C++代碼的一部分看起來

  WCHAR parametersKeyBuffer[255]; 
      gCmdMessageSend.name.Buffer = parametersKeyBuffer; 
      gCmdMessageSend.name.MaximumLength = sizeof(parametersKeyBuffer); 
      gCmdMessageSend.name.Length = 0; 
      RtlCopyUnicodeString(&gCmdMessageSend.name, &fileInfo->Name); 
      if (FsClientPort) 
       { 
        ulReplayLength = sizeof(gCmdMessageSend); 
        status = FltSendMessage(gFilterHandle, &FsClientPort, &gCmdMessageSend, sizeof(gCmdMessageSend), NULL, &ulReplayLength, &timeout); 
       } 

btw即時通訊也獲取內存位置無效的訪問。 Marshal.FreeHGlobal(緩衝區)時出錯;所以我猜我即使做錯了

+0

如果您要更改'buffer'指向的位置,您可能會遇到'無效的內存位置訪問錯誤'錯誤。你只應該操縱本地土地上的緩衝區,而不是改變它指向的地方。 – Romoku 2013-05-06 15:25:04

+0

即時執行錯誤的緩衝區,現在'Marshal.PtrToStringUni'我得到'試圖讀取或寫入受保護的內存。這通常表明其他內存已損壞 – sinofis 2013-05-06 20:52:24

回答

2

Console.WriteLine(this.data.cmdMessage.ToString());

您沒有覆蓋ToString()方法,所以它將默認爲類型名稱。您需要覆蓋此類中的ToString()方法(COMMAND_MESSAGE)。

相關問題