# Re: win32api: how to access NetFileEnum results?

**URL:** <https://www.ruby-forum.com/t/re-win32api-how-to-access-netfileenum-results/76988>\
**Category:** Ruby\
**Created:** [November 23, 2006, 4:18am UTC](https://www.ruby-forum.com/t/re-win32api-how-to-access-netfileenum-results/76988 "2006-11-23T04:18:38Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![Robert\_Chastain](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/f14d63/32.png) [@Robert\_Chastain](https://www.ruby-forum.com/u/Robert_Chastain)\
**Post date:** [November 23, 2006, 4:18am UTC](https://www.ruby-forum.com/t/re-win32api-how-to-access-netfileenum-results/76988/1 "2006-11-23T04:18:38Z")

</div>

Trying to modify the below script to allow me to query remote  
machines. The first parameter to NetFileEnum needs to be a char \* to  
the machine name. Can’t seem to work out how to do that in ruby.

Thanks,  
RC

Subject: Re: win32api: how to access NetFileEnum results?  
From: Jos B.   
Date: Wed, 14 Jul 2004 09:28:13 +0900  
References: 106163 106180 106240 106266  
In-reply-to: 106266

–YiEDa0DAkWCtVeE4  
Content-Type: text/plain; charset=us-ascii  
Content-Disposition: inline

On Wed, Jul 14, 2004 at 04:57:21AM +0900, daz wrote:

> Re-reading the API suggests a change of tack.  
> I think that memcpy isn’t required.  
> [snip]  
> p rbuf  
> #----------------------------------
> 
> Good or bad ?

This yields 10k worth of zeroes on my screen 🙂 I think I understand  
what you  
are trying to do (have win32api follow the pointer automagically) but I  
can’t  
seem to get it to work. bufptr does have the right value in this case  
too, so  
that part works fine, but I opted to use the simpler initialization  
instead.  
So I ended up doing some memcpy’s which I need anyway to access the  
pathname  
and username fields in the returned FILE\_INFO\_3 structs. The attached  
code  
works for me; cleanup suggestions welcomed!

Thanks for your help guys.

## Cheers,

Jos B. _/ //_/ Sunnyvale, CA  
\_/ \_/ \_/  
_/ //_/  
\_/ \_/ \_/ _/  
jos at [catnook.com](http://catnook.com)// //_/ require  
‘std/disclaimer’

–YiEDa0DAkWCtVeE4  
Content-Type: text/plain; charset=us-ascii  
Content-Disposition: attachment; filename=“openfiles.rb”

#!/usr/bin/env ruby

# LMSTR =

# LPBYTE\* = P

# DWORD = L

# LPDWORD = P

# PDWORD\_PTR = L

# NET\_API\_STATUS NetFileEnum(

# LMSTR servername,

# LMSTR basepath,

# LMSTR username,

# DWORD level,

# LPBYTE\* bufptr,

# DWORD prefmaxlen,

# LPDWORD entriesread,

# LPDWORD totalentries,

# PDWORD\_PTR resume\_handle

#);

# typedef struct \_FILE\_INFO\_3 {

# DWORD fi3\_id;

# DWORD fi3\_permissions;

# DWORD fi3\_num\_locks;

# LMSTR fi3\_pathname;

# LMSTR fi3\_username;

# } FILE\_INFO\_3;

require “Win32API”

NetFileEnum = Win32API.new(‘netapi32’, ‘NetFileEnum’, ‘PPPNPNPPP’,‘I’)  
Memcpy = Win32API.new(‘msvcrt’, ‘memcpy’, ‘PPL’, ‘P’)  
Pmemcpy1 = Win32API.new(‘msvcrt’, ‘memcpy’, ‘PLL’, ‘L’)  
Pmemcpy2 = Win32API.new(‘msvcrt’, ‘memcpy’, ‘LPL’, ‘L’)  
Wcslen = Win32API.new(‘msvcrt’, ‘wcslen’, ‘P’, ‘L’)

class OpenFile  
attr\_reader :id, :permissions, :num\_locks, :pathname, :username  
def initialize(id, permissions, num\_locks, p\_pathname, p\_username)  
@id, @permissions, @num\_locks = id, permissions, num\_locks  
pathlen = Wcslen.call(p\_pathname) \* 2  
userlen = Wcslen.call(p\_username) \* 2  
pname = “\0” \* pathlen  
uname = “\0” \* userlen  
Pmemcpy1.call(pname, p\_pathname, pathlen)  
Pmemcpy1.call(uname, p\_username, userlen)  
@pathname = pname.delete(“\0”)  
@username = uname.delete(“\0”)  
end  
def inspect  
“File #{@pathname} opened by #{@username} (id #{@id},  
#{@num\_locks} lock(s))”  
end  
end

MAX\_PREFERRED\_LENGTH = -1  
FILE\_INFO\_3\_SIZE = 20  
LEVEL = 3

bufptr = “\0” \* 4  
entriesread = “\0” \* 4  
totalentries = “\0” \* 4  
resume\_handle = “\0” \* 4

ret = NetFileEnum.call(nil, nil, nil, LEVEL, bufptr,  
MAX\_PREFERRED\_LENGTH,  
entriesread, totalentries, resume\_handle)

if 0 != ret  
puts “Failed: #{ret}”  
exit  
end

entriesread = entriesread.unpack(“S”)[0]  
totalentries = totalentries.unpack(“S”)[0]

rbuf = “\0” \* entriesread \* FILE\_INFO\_3\_SIZE

# bufptr now contains a ptr to a ptr

Pmemcpy1.call(rbuf, bufptr.unpack(“L”)[0], entriesread \*  
FILE\_INFO\_3\_SIZE)

open\_files = []  
entriesread.times do |i|  
open\_files \<\< OpenFile.new(\*rbuf[i \* FILE\_INFO\_3\_SIZE, FILE\_INFO\_3\_SIZE].unpack(“LLLLL”))  
end

open\_files.each do |file|  
p file  
end

exit
