Hi, ----- Original Message ----- From: "Daniel Berger" <djberg96 / yahoo.com> To: "ruby-talk ML" <ruby-talk / ruby-lang.org> Sent: Friday, August 08, 2003 12:29 PM Subject: Ruby, MS Windows, extensions and entry points > 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. > It's due to the Unicode Conversion problem. Try with following code. Regards, Park Heesob /* 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); char dest[256]; wchar_t wszUserName[UNLEN+1]; VALUE Passwd = rb_struct_define("Passwd","name","comment",0); VALUE pstruct = rb_struct_new(Passwd); MultiByteToWideChar( CP_ACP, 0, cname, strlen(cname)+1, wszUserName, sizeof(wszUserName)/sizeof(wszUserName[0]) ); // Call the NetUserGetInfo function; specify level 10. nStatus = NetUserGetInfo(NULL,wszUserName,dwLevel,(LPBYTE *)&pBuf); // If the call succeeds, print the user information. if (nStatus == NERR_Success) { if (pBuf != NULL) { WideCharToMultiByte( CP_ACP, 0, pBuf->usri10_name, -1, dest, 256, NULL, NULL ); rb_struct_aset(pstruct,INT2NUM(0),rb_str_new2(dest)); WideCharToMultiByte( CP_ACP, 0, pBuf->usri10_comment, -1, dest, 256, NULL, NULL ); rb_struct_aset(pstruct,INT2NUM(1),rb_str_new2(dest)); } } 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); }