Thursday, January 07, 2010

File notification events on Windows

One of my most popular posts is example code for Inotify on Linux. I have also been asked for similar code for Windows, so yer tis:

There are two different interfaces available on Win32, I prefer ReadDirectoryChangesW because it is easier to control:



// ------------------------------------------------------------------
// Clive Darke QA Training
// ReadDirectoryChangesW example
// ------------------------------------------------------------------

#define _WIN32_WINNT 0x0400 // <<<<<<<<>
#include <iostream>
#include <windows.h>

void DisplayLastError( LPSTR lpszText );

// ------------------------------------------------------------------

int main ( int argc, char *argv[] )
{
HANDLE hDir;
DWORD dwReturned;
BOOL bResult;
FILE_NOTIFY_INFORMATION *pNotify;

if ( argc < 2 )
{
cerr << "You must supply a directory name" << endl;
return 1;
}

// Note FILE_FLAG_BACKUP_SEMANTICS, which is the strange
// attribute required to get a handle to a directory.

hDir = CreateFile (
argv[1], // pointer to the file name
FILE_LIST_DIRECTORY, // access (read-write) mode
FILE_SHARE_READ|FILE_SHARE_DELETE, // share mode
NULL, // security descriptor
OPEN_EXISTING, // how to create
FILE_FLAG_BACKUP_SEMANTICS, // file attributes
NULL // file with attributes to copy
);

char Buffer[MAX_PATH] = {0};

while (TRUE )
{
char szAction[42];
char szFilename[MAX_PATH];

bResult = ReadDirectoryChangesW (hDir, &Buffer, sizeof(Buffer),
TRUE, FILE_NOTIFY_CHANGE_FILE_NAME, &dwReturned, NULL, NULL);

if ( !bResult )
break;

pNotify = (FILE_NOTIFY_INFORMATION *) Buffer;

switch (pNotify->Action)
{
case FILE_ACTION_ADDED : {
strcpy (szAction, "added");
break;
case FILE_ACTION_REMOVED :
strcpy (szAction, "removed");
break;
case FILE_ACTION_MODIFIED :
strcpy (szAction, "modified");
break;
case FILE_ACTION_RENAMED_OLD_NAME :
strcpy (szAction, "renamed");
break;
case FILE_ACTION_RENAMED_NEW_NAME :
strcpy (szAction, "renamed");
break;
default:
strcpy (szAction, "Unknown action");
}

wcstombs( szFilename, pNotify->FileName, MAX_PATH);
cout << "File " << dwerror =" GetLastError();" lpmessagebuffer =" NULL;">

No comments: