我怎样才能收到OutputDebugString的从服务? [英] How can I receive OutputDebugString from service?

查看:619
本文介绍了我怎样才能收到OutputDebugString的从服务?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图捕捉所有 OutputDebugString的消息用下面的代码(包括来自服务)。它工作得很好,直到我迁移​​到Windows 7的问题是,由于Windows Vista中服务在低水平会话#0运行某些人说的这是不可能赶上他们有的认为它是。你有什么感想 ?是否有可能通过增加一些权限修改下面的代码能够接收的从会话#0的OutputDebugString 消息?换一种说法;是否有可能与会话#1?



股DBWIN_BUFFER会话#0

我想说这应该是可能的,因为如DebugView中能做到这一点,我看不到任何服务帮助这会发送这些信息(例如,通过命名管道)从会话#0到会话#1,GUI的运行在哪里。



的问题将是国际海事组织在安全设置。任何人都可以建议我如何修改呢?



 键入
TODSThread =类(TThread类)
保护
程序执行;覆盖;
端;

...

程序TODSThread.Execute;
VAR SharedMem:指针;
SharedFile:THandle;
WaitingResult:DWORD;
SharedMessage:字符串;
DataReadyEvent:THandle;
BufferReadyEvent:THandle;
SecurityAttributes:SECURITY_ATTRIBUTES;
SecurityDescriptor:SECURITY_DESCRIPTOR;

开始
SecurityAttributes.nLength:=一下SizeOf(SECURITY_ATTRIBUTES);
SecurityAttributes.bInheritHandle:= TRUE;
SecurityAttributes.lpSecurityDescriptor:= @SecurityDescriptor;

如果不InitializeSecurityDescriptor(@SecurityDescriptor,SECURITY_DESCRIPTOR_REVISION),那么
出口;

如果不SetSecurityDescriptorDacl(@SecurityDescriptor,真,零,假),那么
出口;

BufferReadyEvent:= CreateEvent(@SecurityAttributes,假,真,DBWIN_BUFFER_READY');

如果BufferReadyEvent = 0,那么
出口;

DataReadyEvent:= CreateEvent(@SecurityAttributes,假,假,DBWIN_DATA_READY');

如果DataReadyEvent = 0,那么
出口;

SharedFile:=的CreateFileMapping(THandle(-1),@SecurityAttributes,PAGE_READWRITE,0,4096,DBWIN_BUFFER');

如果SharedFile = 0,那么
出口;

SharedMem:= MapViewOfFile(SharedFile,FILE_MAP_READ,0,0,512);

如果未分配(SharedMem),那么
出口;

,而(没有终止)和(非Application.Terminated)做
开始
SetEvent的(BufferReadyEvent);
WaitingResult:= WaitForSingleObject的(DataReadyEvent,INFINITE);
WAIT_TIMEOUT的

情况下WaitingResult:继续;
WAIT_OBJECT_0:
开始
SharedMessage:=字符串(PAnsiChar(SharedMem)+中SizeOf(DWORD));
//这里我有我需要什么,并在主线程
端处理它;

WAIT_FAILED:继续;
端;
端;

UnmapViewOfFile(SharedMem);
CloseHandle的(SharedFile);
端;



我添加即使代码是在Delphi中,因为安全属性都为常见的C#标签整体的Windows API和C#有众多的追随者:)的任何建议。


解决方案


谢谢>

有人谈到了的Sysinternals论坛同样的问题。他们的解决方案是加上Global\来命名对象



所以使用下面的

  CreateEvent(@SecurityAttributes,假,真, Global\DBWIN_BUFFER_READY'); 
CreateEvent(@SecurityAttributes,假,假,Global\DBWIN_DATA_READY');
的CreateFileMapping(THandle(-1),@SecurityAttributes,PAGE_READWRITE,0,4096,Global\DBWIN_BUFFER');


I'm trying to catch all OutputDebugString messages (including those from services) using the following code. It worked fine until I migrated to Windows 7. The problem is that since Windows Vista services are running in the low level Session #0 some people says that it's impossible to catch them and some that it is. What do you think ? Is it possible to modify the following code by increasing some rights to be able to receive OutputDebugString messages from the Session #0 ? In other words; is it possible to share DBWIN_BUFFER in the session #0 with Session #1 ?

I would say it should be possible because e.g. DebugView can do that and I can't see any service helper which would send those messages (e.g. through the named pipes) from the Session #0 to Session #1, where the GUI's running.

The problem will be IMO in the security settings. Can anyone suggest me how to modify them ?

type
  TODSThread = class(TThread)
  protected
    procedure Execute; override;
  end;

...

procedure TODSThread.Execute;
var SharedMem: Pointer;
    SharedFile: THandle;
    WaitingResult: DWORD;
    SharedMessage: string;
    DataReadyEvent: THandle;
    BufferReadyEvent: THandle;
    SecurityAttributes: SECURITY_ATTRIBUTES;
    SecurityDescriptor: SECURITY_DESCRIPTOR;

begin
  SecurityAttributes.nLength := SizeOf(SECURITY_ATTRIBUTES);
  SecurityAttributes.bInheritHandle := True;
  SecurityAttributes.lpSecurityDescriptor := @SecurityDescriptor;

  if not InitializeSecurityDescriptor(@SecurityDescriptor, SECURITY_DESCRIPTOR_REVISION) then
    Exit;

  if not SetSecurityDescriptorDacl(@SecurityDescriptor, True, nil, False) then
    Exit;

  BufferReadyEvent := CreateEvent(@SecurityAttributes, False, True, 'DBWIN_BUFFER_READY');

  if BufferReadyEvent = 0 then
    Exit;

  DataReadyEvent := CreateEvent(@SecurityAttributes, False, False, 'DBWIN_DATA_READY');

  if DataReadyEvent = 0 then
    Exit;

  SharedFile := CreateFileMapping(THandle(-1), @SecurityAttributes, PAGE_READWRITE, 0, 4096, 'DBWIN_BUFFER');

  if SharedFile = 0 then
    Exit;

  SharedMem := MapViewOfFile(SharedFile, FILE_MAP_READ, 0, 0, 512);

  if not Assigned(SharedMem) then
    Exit;

  while (not Terminated) and (not Application.Terminated) do
    begin
      SetEvent(BufferReadyEvent);
      WaitingResult := WaitForSingleObject(DataReadyEvent, INFINITE);

      case WaitingResult of
        WAIT_TIMEOUT: Continue;
        WAIT_OBJECT_0:
          begin
            SharedMessage := String(PAnsiChar(SharedMem) + SizeOf(DWORD));
            // here I have what I need and process it in the main thread
          end;

       WAIT_FAILED: Continue;
     end;
   end;

   UnmapViewOfFile(SharedMem);
   CloseHandle(SharedFile);
end;

I've added C# tag even if the code is in Delphi because the security attributes are common for the whole Windows API and C# has many followers :)

Thanks for any suggestions

解决方案

Someone talked about the same issue in the SysInternals forums. Their solution was to add "Global\" to the named objects.

So use the following

CreateEvent(@SecurityAttributes, False, True, 'Global\DBWIN_BUFFER_READY');
CreateEvent(@SecurityAttributes, False, False, 'Global\DBWIN_DATA_READY');
CreateFileMapping(THandle(-1), @SecurityAttributes, PAGE_READWRITE, 0, 4096, 'Global\DBWIN_BUFFER');

这篇关于我怎样才能收到OutputDebugString的从服务?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆