[Win32utils-devel] ChangeNotify help wanted

win32utils-devel@rubyforge.org
Fri, 21 Jan 2005 21:02:15 -0000

Hi Dan,

> Hi all,
>
> I''ve checked in some code to win32-changenotify.  Unfortunately,
it
> doesn''t work right.  I need some help.  I don''t
understand what,
> exactly, I''m supposed to pass to ReadDirectoryChangesW() for the
2nd
> argument, nor how to read the data back out.
>
> There''s also a WCHAR issue that needs to be worked out with
regards to
> the FileName FILE_NOTIFY_INFORMATION struct member.
>
> Please see the changenotify_init() function in changenotify.c.
>
> HELP!
>
> Regards,
>
> Dan

You should have read carefully the document
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/fileio/base/readdirectorychangesw.asp
:-)
Upon successful synchronous completion, the lpBuffer parameter is a formatted
buffer and the number of bytes written to the buffer is available in
lpBytesReturned. If the number of bytes transferred is zero (0), the buffer was
too small to provide detailed information on all the changes that occurred in
the directory or subtree. In this case, you should compute the changes by
enumerating the directory or subtree.

It seems that ReadDirectoryChangesW needs sufficient buffer for synchronous
mode.

Here is my test code:

changenotify_init(VALUE self, VALUE rbPath, VALUE rbSubtree, VALUE rbFilter)
{
   HANDLE hDir;
   VALUE rbObject, rbStruct, rbAction;
   FILE_NOTIFY_INFORMATION fni[1024];
   LPCTSTR lpPathName = RSTRING(rbPath)->ptr;
   BOOL bWatchSubtree = (rbSubtree == Qtrue) ? TRUE : FALSE;
   DWORD dwNotifyFilter = NUM2INT(rbFilter);
   DWORD dwBytesReturned = 0;
   ChangeNotifyStruct* ptr;
   int i = 0;
   char filename[256];

   Data_Get_Struct(self,ChangeNotifyStruct,ptr);

   // 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()));
   }
   memset(&fni[0],0x00,sizeof(fni[0])*1024);
   if(ReadDirectoryChangesW(
      hDir,
      &fni[0],
      sizeof(fni[0])*1024,
      bWatchSubtree,
      dwNotifyFilter,
      &dwBytesReturned,
      NULL,
      NULL
   )==0){
      rb_raise(cChangeNotifyError,ErrorDescription(GetLastError()));
   }

   WideCharToMultiByte(CP_ACP,0,fni[0].FileName,-1,filename,256,NULL,NULL);

   printf("changenotify action=%ld,return=%ld,filenamd=%s
\n",fni[0].Action,dwBytesReturned,filename);
.....

}

Regards,

Park Heesob