[Win32utils-devel] Service.start arguments failing or causing segfault

Daniel Berger djberg96 at gmail.com
Sat Nov 24 12:53:03 EST 2007


Heesob Park wrote:
> Hi,
> 
> 2007/11/24, Daniel Berger <djberg96 at gmail.com <mailto:djberg96 at gmail.com>>:
> 
>     Heesob Park wrote:
> 
>     <snip>
> 
>      > Don't ask me why, just follow the rule of the microsoft :)
>      >
>      > Acording to http://msdn2.microsoft.com/en-US/library/ms686321.aspx ,
>      > StartService function requires NULL or an argument which the first
>      > element must be service name.
>      > And argument type is not LPCSTR, but LPCTSTR* ( pointer of
>     string), so
>      > it need to be packed.
> 
>     Oops, I did see a mistake with num_args. It should be like this I
>     think:
> 
>     num_args = 0
> 
>     if args.empty?
>        args = nil
>     else
>        args.unshift(service)
>        num_args = args.length
>        args = [args.join("\000")].pack('p*')
>     end
> 
>     I forgot to add 1 for the service name.
> 
>     The only problem is, now it segfaults. :(
> 
>     Dan
> 
>  
> I figured it out finally.
>  
> First, fix argument type. you don't need to put the first element as 
> service name as documented. 
> The code service.rb before StartService should be like this:
>  
>          num_args = 0
>          if args.empty?
>             args = nil
>          else
>             # args.unshift(service)  --> this is optional
>             num_args = args.length
>             args = args.map {|x| [x].pack('p*')}.join
>          end     
> 
> Second, you did'nt send argument from Service_Main C function to 
> service_main ruby methods.
> The code  daemon.c shoud be like this: 
>  
> Before RegisterServiceCtrlHandler of Service_Main function
>  
>    if(dwArgc>1) {
>      int i;
>      Argc = dwArgc-1;                             // declared STATIC 
> int Arg; on top 
>      Argv = malloc(sizeof(VALUE)*Argc);  // declared STATIC VALUE *Argv; 
> on top 
>      for(i=1;i<dwArgc;i++)
>        Argv[i-1]=rb_str_new2(lpszArgv[i]);
>    }
>  
> daemon_mainloop_protect function
>  
> static VALUE daemon_mainloop_protect(VALUE self)
> {
>     if(rb_respond_to(self,rb_intern("service_main")))
>     {
>        if(Argc==0)      
>          rb_funcall(self,rb_intern("service_main"),0);
>        else
>          rb_funcall2(self,rb_intern("service_main"),Argc,Argv);
>     }      
>     return self;
> }

Awesome, that works! Thanks!

I think that was the last thing I wanted to get worked out for 0.6.0. 
I'll get a release out today or tomorrow.

Thanks,

Dan


More information about the win32utils-devel mailing list