[Win32utils-devel] Some thoughts on win32-changenotify

win32utils-devel at rubyforge.org win32utils-devel at rubyforge.org
Thu Jan 6 12:00:57 EST 2005


Hi all,

As things stand now, you can do something like this with
win32-changenotify:

require "win32/changenotify"
include Win32

filter = ChangeNotify::FILE_NAME | ChangeNotify::DIR_NAME |
ChangeNotify::LAST_WRITE
cn = ChangeNotify.new("c:\\",false,filter){
	puts "Something changed"
}
cn.wait

You can pass a block that's executed when a change occurs, but you can't
get any details about the change.  I would like to alter that behavior
so that a ChangeNotifyStruct is yielded to the block that contains two
bits of information - the file or directory that was changed and what
that change would be.  So, that example would look something like this:

filter = ChangeNotify::FILE_NAME | ChangeNotify::DIR_NAME |
ChangeNotify::LAST_WRITE
cn = ChangeNotify.new("c:\\",false,filter){ |cns|
	puts "File changed: " + cns.file_name
	puts "Action: " + cns.action
}
cn.wait

That means altering changenotify.c to use ReadDirectoryChangesW()
instead of FindFirstChangeNotification().  Our Ruby ChangeNotifyStruct
would contain two members, "action" and "file_name" that would be the
Action and FileName members of the FILE_NOTIFY_INFORMATION structure.

I've tinkered around with this but I'm having a couple issues.  I can
open a directory and call ReadDirectoryChangesW() successfully, but I
can't figure out how to read back out of the buffer (nor am I exactly
sure what to pass as a buffer in the first place).

Here's the basic approach.

   // Get a handle to the directory.
   hDir = CreateFile(
	lpPathName,
      FILE_LIST_DIRECTORY,
      FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
      NULL,
      OPEN_EXISTING,
      FILE_FLAG_BACKUP_SEMANTICS,
      NULL
   );
   
   if(hDir == INVALID_HANDLE_VALUE) {
      rb_raise(cChangeNotifyError,ErrorDescription(GetLastError()));
   }
   
   if(!ReadDirectoryChangesW(
      hDir,
      Buf,
      sizeof(Buf),
      bWatchSubtree,
      dwNotifyFilter,
      &dwBytesReturned,
      NULL,
      NULL
   )){
      rb_raise(cChangeNotifyError,ErrorDescription(GetLastError()));
   }

So, the question is, what exactly should "Buf" be and how do I read a
single record back out of it?

Any takers?

Regards,

Dan



More information about the win32utils-devel mailing list