You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
158 lines
4.6 KiB
158 lines
4.6 KiB
//
|
|
// The MIT License
|
|
//
|
|
// Copyright (c) 2010 James E Beveridge
|
|
//
|
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
// of this software and associated documentation files (the "Software"), to deal
|
|
// in the Software without restriction, including without limitation the rights
|
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
// copies of the Software, and to permit persons to whom the Software is
|
|
// furnished to do so, subject to the following conditions:
|
|
//
|
|
// The above copyright notice and this permission notice shall be included in
|
|
// all copies or substantial portions of the Software.
|
|
//
|
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
// THE SOFTWARE.
|
|
|
|
|
|
// This sample code is for my blog entry titled, "Understanding ReadDirectoryChangesW"
|
|
// http://qualapps.blogspot.com/2010/05/understanding-readdirectorychangesw.html
|
|
// See ReadMe.txt for overview information.
|
|
|
|
|
|
#include "stdafx.h"
|
|
#include "ReadDirectoryChanges.h"
|
|
#include "CEInfo.h"
|
|
|
|
LPCWSTR ExplainAction( DWORD dwAction );
|
|
bool TryGetKeyboardInput( HANDLE hStdIn, bool &bTerminate, char* buf );
|
|
|
|
|
|
//
|
|
// When the application starts, it immediately starts monitoring your home
|
|
// directory, including children, as well as C:\, not including children.
|
|
// The application exits when you hit Esc.
|
|
// You can add a directory to the monitoring list by typing the directory
|
|
// name and hitting Enter. Notifications will pause while you type.
|
|
//
|
|
|
|
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
|
|
{
|
|
const DWORD dwNotificationFlags =
|
|
FILE_NOTIFY_CHANGE_LAST_WRITE
|
|
| FILE_NOTIFY_CHANGE_CREATION
|
|
| FILE_NOTIFY_CHANGE_FILE_NAME;
|
|
|
|
// Create the monitor and add two directories.
|
|
CReadDirectoryChanges changes;
|
|
changes.AddDirectory(_tgetenv(_T("USERPROFILE")), true, dwNotificationFlags);
|
|
changes.AddDirectory(_T("C:\\"), false, dwNotificationFlags);
|
|
|
|
HANDLE hStdIn = ::GetStdHandle(STD_INPUT_HANDLE);
|
|
const HANDLE handles[] = { hStdIn, changes.GetWaitHandle() };
|
|
|
|
char buf[MAX_PATH];
|
|
bool bTerminate = false;
|
|
|
|
while (!bTerminate)
|
|
{
|
|
DWORD rc = ::WaitForMultipleObjectsEx(_countof(handles), handles, false, INFINITE, true);
|
|
switch (rc)
|
|
{
|
|
case WAIT_OBJECT_0 + 0:
|
|
// hStdIn was signaled. This can happen due to mouse input, focus change,
|
|
// Shift keys, and more. Delegate to TryGetKeyboardInput().
|
|
// TryGetKeyboardInput sets bTerminate to true if the user hits Esc.
|
|
if (TryGetKeyboardInput(hStdIn, bTerminate, buf))
|
|
{
|
|
std::string strbuf(buf);
|
|
std::wstring wstrbuf(strbuf.begin(), strbuf.end());
|
|
changes.AddDirectory(wstrbuf.c_str(), false, dwNotificationFlags);
|
|
}
|
|
|
|
break;
|
|
case WAIT_OBJECT_0 + 1:
|
|
// We've received a notification in the queue.
|
|
{
|
|
DWORD dwAction;
|
|
std::wstring wstrFilename;
|
|
if (changes.CheckOverflow())
|
|
wprintf(L"Queue overflowed.\n");
|
|
else
|
|
{
|
|
changes.Pop(dwAction, wstrFilename);
|
|
if (wstrFilename.find(CE_DETECTION_1) != std::wstring::npos ||
|
|
wstrFilename.find(CE_DETECTION_2) != std::wstring::npos
|
|
)
|
|
{
|
|
wprintf(L"Find CE:%s %s\n", ExplainAction(dwAction), wstrFilename.c_str());
|
|
}
|
|
|
|
}
|
|
}
|
|
break;
|
|
case WAIT_IO_COMPLETION:
|
|
// Nothing to do.
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Just for sample purposes. The destructor will
|
|
// call Terminate() automatically.
|
|
changes.Terminate();
|
|
|
|
return EXIT_SUCCESS;
|
|
}
|
|
|
|
LPCWSTR ExplainAction( DWORD dwAction )
|
|
{
|
|
switch (dwAction)
|
|
{
|
|
case FILE_ACTION_ADDED :
|
|
return L"Added";
|
|
case FILE_ACTION_REMOVED :
|
|
return L"Deleted";
|
|
case FILE_ACTION_MODIFIED :
|
|
return L"Modified";
|
|
case FILE_ACTION_RENAMED_OLD_NAME :
|
|
return L"Renamed From";
|
|
case FILE_ACTION_RENAMED_NEW_NAME :
|
|
return L"Renamed To";
|
|
default:
|
|
return L"BAD DATA";
|
|
}
|
|
}
|
|
|
|
bool TryGetKeyboardInput( HANDLE hStdIn, bool &bTerminate, char* buf )
|
|
{
|
|
DWORD dwNumberOfEventsRead=0;
|
|
INPUT_RECORD rec = {0};
|
|
|
|
if (!::PeekConsoleInput(hStdIn, &rec, 1, &dwNumberOfEventsRead))
|
|
return false;
|
|
|
|
if (rec.EventType == KEY_EVENT)
|
|
{
|
|
if (rec.Event.KeyEvent.wVirtualKeyCode == VK_ESCAPE)
|
|
bTerminate = true;
|
|
else if (rec.Event.KeyEvent.wVirtualKeyCode > VK_HELP)
|
|
{
|
|
if (!gets_s(buf, MAX_PATH)) // End of file, usually Ctrl-Z
|
|
bTerminate = true;
|
|
else
|
|
return true;
|
|
}
|
|
}
|
|
|
|
::FlushConsoleInputBuffer(hStdIn);
|
|
|
|
return false;
|
|
}
|