win32utils-devel@rubyforge.org
2005-Jan-20 16:42 UTC
[Win32utils-devel] ChangeNotify help wanted
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
win32utils-devel@rubyforge.org
2005-Jan-21 21:02 UTC
[Win32utils-devel] ChangeNotify help wanted
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, > > DanYou 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