D
Daniel Berger
Hi all,
I'm trying to write a Ruby extension that would make
the Etc module functions, such as getpwnam, work on
Win32 (in roughly the same manner).
The equivalent to the getpwnam call on Win32 is
NetUserGetInfo(). The only problem is that when I
wrap this in an extension, the call always fails. I
*think* I know why.
Take a look at the C program here (scroll down to the
example code):
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/netmgmt/netmgmt/netusergetinfo.asp
When I build this program as-is, it works fine. One
thing to note, however, is that this program uses
"wmain" as an entry point instead of "main",
presumably as a way of handling wide-strings. Any
attempt to change the entry point back to main causes
NetUserGetInfo() to return an unsuccessful result
(error code 2221).
Consequently, trying to wrap this code in an extension
causes a similar error, I'm guessing because of the
main vs wmain issue.
Is there a way around this? Below is a sample
extension.
Regards,
Dan
/* win32etc.c */
#include "ruby.h"
#include <windows.h>
#include <stdio.h>
#include <lm.h>
#ifndef UNICODE
#define UNICODE
#endif
static VALUE win32etc_getpwnam(VALUE mod, VALUE name)
{
DWORD dwLevel = 10;
LPUSER_INFO_10 pBuf = NULL;
NET_API_STATUS nStatus;
char* cname = STR2CSTR(name);
VALUE Passwd =
rb_struct_define("Passwd","name","comment",0);
VALUE pstruct = rb_struct_new(Passwd);
// Call the NetUserGetInfo function; specify level
10.
nStatus = NetUserGetInfo(NULL,(wchar_t
*)cname,dwLevel,(LPBYTE *)&pBuf);
// If the call succeeds, print the user
information.
if (nStatus == NERR_Success)
{
if (pBuf != NULL)
{
rb_struct_aset(pstruct,INT2NUM(0),rb_str_new2((char
*)pBuf->usri10_name));
rb_struct_aset(pstruct,INT2NUM(1),rb_str_new2((char
*)pBuf->usri10_comment));
}
}
else
{
rb_warn("NetUserGetInfo() call failed");
}
/* Free the allocated memory. */
if (pBuf != NULL)
{
NetApiBufferFree(pBuf);
}
return pstruct;
}
void Init_win32etc()
{
VALUE mEtc = rb_define_module("Win32Etc");
rb_define_module_function(mEtc, "getpwnam",
win32etc_getpwnam, 1);
}
/*
# extconf.rb
require "mkmf"
have_library("netapi32")
create_makefile("win32etc")
*/
/*
# test.rb
require "win32etc"
Win32Etc.getpwnam("your userid")
*/
__________________________________
Do you Yahoo!?
Yahoo! SiteBuilder - Free, easy-to-use web site design software
http://sitebuilder.yahoo.com
I'm trying to write a Ruby extension that would make
the Etc module functions, such as getpwnam, work on
Win32 (in roughly the same manner).
The equivalent to the getpwnam call on Win32 is
NetUserGetInfo(). The only problem is that when I
wrap this in an extension, the call always fails. I
*think* I know why.
Take a look at the C program here (scroll down to the
example code):
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/netmgmt/netmgmt/netusergetinfo.asp
When I build this program as-is, it works fine. One
thing to note, however, is that this program uses
"wmain" as an entry point instead of "main",
presumably as a way of handling wide-strings. Any
attempt to change the entry point back to main causes
NetUserGetInfo() to return an unsuccessful result
(error code 2221).
Consequently, trying to wrap this code in an extension
causes a similar error, I'm guessing because of the
main vs wmain issue.
Is there a way around this? Below is a sample
extension.
Regards,
Dan
/* win32etc.c */
#include "ruby.h"
#include <windows.h>
#include <stdio.h>
#include <lm.h>
#ifndef UNICODE
#define UNICODE
#endif
static VALUE win32etc_getpwnam(VALUE mod, VALUE name)
{
DWORD dwLevel = 10;
LPUSER_INFO_10 pBuf = NULL;
NET_API_STATUS nStatus;
char* cname = STR2CSTR(name);
VALUE Passwd =
rb_struct_define("Passwd","name","comment",0);
VALUE pstruct = rb_struct_new(Passwd);
// Call the NetUserGetInfo function; specify level
10.
nStatus = NetUserGetInfo(NULL,(wchar_t
*)cname,dwLevel,(LPBYTE *)&pBuf);
// If the call succeeds, print the user
information.
if (nStatus == NERR_Success)
{
if (pBuf != NULL)
{
rb_struct_aset(pstruct,INT2NUM(0),rb_str_new2((char
*)pBuf->usri10_name));
rb_struct_aset(pstruct,INT2NUM(1),rb_str_new2((char
*)pBuf->usri10_comment));
}
}
else
{
rb_warn("NetUserGetInfo() call failed");
}
/* Free the allocated memory. */
if (pBuf != NULL)
{
NetApiBufferFree(pBuf);
}
return pstruct;
}
void Init_win32etc()
{
VALUE mEtc = rb_define_module("Win32Etc");
rb_define_module_function(mEtc, "getpwnam",
win32etc_getpwnam, 1);
}
/*
# extconf.rb
require "mkmf"
have_library("netapi32")
create_makefile("win32etc")
*/
/*
# test.rb
require "win32etc"
Win32Etc.getpwnam("your userid")
*/
__________________________________
Do you Yahoo!?
Yahoo! SiteBuilder - Free, easy-to-use web site design software
http://sitebuilder.yahoo.com