summaryrefslogtreecommitdiff
path: root/native/fileWatcher/fileWatcher3.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'native/fileWatcher/fileWatcher3.cpp')
-rw-r--r--native/fileWatcher/fileWatcher3.cpp757
1 files changed, 350 insertions, 407 deletions
diff --git a/native/fileWatcher/fileWatcher3.cpp b/native/fileWatcher/fileWatcher3.cpp
index 7e3669ecdec7..07dbe52095a5 100644
--- a/native/fileWatcher/fileWatcher3.cpp
+++ b/native/fileWatcher/fileWatcher3.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2011 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,20 +14,23 @@
* limitations under the License.
*/
-#include "stdafx.h"
+#include <process.h>
+#include <stdio.h>
+#include <tchar.h>
+#include <windows.h>
struct WatchRootInfo {
- char driveLetter;
- HANDLE hThread;
- HANDLE hStopEvent;
- bool bInitialized;
- bool bUsed;
- bool bFailed;
+ char driveLetter;
+ HANDLE hThread;
+ HANDLE hStopEvent;
+ bool bInitialized;
+ bool bUsed;
+ bool bFailed;
};
struct WatchRoot {
- char *path;
- WatchRoot *next;
+ char *path;
+ WatchRoot *next;
};
const int ROOT_COUNT = 26;
@@ -38,139 +41,123 @@ WatchRoot *firstWatchRoot = NULL;
CRITICAL_SECTION csOutput;
-void NormalizeSlashes(char *path, char slash)
-{
- for(char *p=path; *p; p++)
- if (*p == '\\' || *p == '/')
- *p = slash;
+void NormalizeSlashes(char *path, char slash) {
+ for (char *p = path; *p; p++)
+ if (*p == '\\' || *p == '/')
+ *p = slash;
}
// -- Watchable root checks ---------------------------------------------------
-bool IsNetworkDrive(const char *name)
-{
+bool IsNetworkDrive(const char *name) {
const int BUF_SIZE = 1024;
char buffer[BUF_SIZE];
- UNIVERSAL_NAME_INFO* uni = (UNIVERSAL_NAME_INFO*) buffer;
+ UNIVERSAL_NAME_INFO *uni = (UNIVERSAL_NAME_INFO *) buffer;
DWORD size = BUF_SIZE;
DWORD result = WNetGetUniversalNameA(
- name, // path for network resource
- UNIVERSAL_NAME_INFO_LEVEL, // level of information
- buffer, // name buffer
- &size // size of buffer
+ name, // path for network resource
+ UNIVERSAL_NAME_INFO_LEVEL, // level of information
+ buffer, // name buffer
+ &size // size of buffer
);
return result == NO_ERROR;
}
-bool IsUnwatchableFS(const char *path)
-{
+bool IsUnwatchableFS(const char *path) {
char volumeName[MAX_PATH];
- char fsName[MAX_PATH];
- DWORD fsFlags;
- DWORD maxComponentLength;
- SetErrorMode(SEM_FAILCRITICALERRORS);
- if (!GetVolumeInformationA(path, volumeName, MAX_PATH-1, NULL, &maxComponentLength, &fsFlags, fsName, MAX_PATH-1))
- return false;
- if (strcmp(fsName, "NTFS") && strcmp(fsName, "FAT") && strcmp(fsName, "FAT32") && stricmp(fsName, "exFAT"))
- return true;
-
- if (!strcmp(fsName, "NTFS") && maxComponentLength != 255 && !(fsFlags & FILE_SUPPORTS_REPARSE_POINTS))
- {
- // SAMBA reports itself as NTFS
- return true;
- }
-
- return false;
+ char fsName[MAX_PATH];
+ DWORD fsFlags;
+ DWORD maxComponentLength;
+ SetErrorMode(SEM_FAILCRITICALERRORS);
+ if (!GetVolumeInformationA(path, volumeName, MAX_PATH - 1, NULL, &maxComponentLength, &fsFlags, fsName, MAX_PATH - 1))
+ return false;
+ if (strcmp(fsName, "NTFS") && strcmp(fsName, "FAT") && strcmp(fsName, "FAT32") && _stricmp(fsName, "exFAT") && _stricmp(fsName, "reFS"))
+ return true;
+
+ if (!strcmp(fsName, "NTFS") && maxComponentLength != 255 && !(fsFlags & FILE_SUPPORTS_REPARSE_POINTS)) {
+ // SAMBA reports itself as NTFS
+ return true;
+ }
+
+ return false;
}
-bool IsWatchable(const char *path)
-{
- if (IsNetworkDrive(path))
- return false;
- if (IsUnwatchableFS(path))
- return false;
- return true;
+bool IsWatchable(const char *path) {
+ if (IsNetworkDrive(path))
+ return false;
+ if (IsUnwatchableFS(path))
+ return false;
+ return true;
}
// -- Substed drive checks ----------------------------------------------------
-void PrintRemapForSubstDrive(char driveLetter)
-{
+void PrintRemapForSubstDrive(char driveLetter) {
const int BUF_SIZE = 1024;
char targetPath[BUF_SIZE];
- char rootPath[8];
- sprintf_s(rootPath, 8, "%c:", driveLetter);
+ char rootPath[8];
+ sprintf_s(rootPath, 8, "%c:", driveLetter);
DWORD result = QueryDosDeviceA(rootPath, targetPath, BUF_SIZE);
if (result == 0) {
return;
}
- else
- {
- if (targetPath[0] == '\\' && targetPath[1] == '?' && targetPath[2] == '?' && targetPath[3] == '\\')
- {
- // example path: \??\C:\jetbrains\idea
- NormalizeSlashes(targetPath, '/');
- printf("%c:\n%s\n", driveLetter, targetPath+4);
- }
+ else {
+ if (targetPath[0] == '\\' && targetPath[1] == '?' && targetPath[2] == '?' && targetPath[3] == '\\') {
+ // example path: \??\C:\jetbrains\idea
+ NormalizeSlashes(targetPath, '/');
+ printf("%c:\n%s\n", driveLetter, targetPath + 4);
+ }
}
}
-void PrintRemapForSubstDrives()
-{
- for(int i=0; i<ROOT_COUNT; i++)
- {
- if (watchRootInfos [i].bUsed)
- {
- PrintRemapForSubstDrive(watchRootInfos [i].driveLetter);
- }
- }
+void PrintRemapForSubstDrives() {
+ for (int i = 0; i < ROOT_COUNT; i++) {
+ if (watchRootInfos[i].bUsed) {
+ PrintRemapForSubstDrive(watchRootInfos[i].driveLetter);
+ }
+ }
}
// -- Mount point enumeration -------------------------------------------------
const int BUFSIZE = 1024;
-void PrintDirectoryReparsePoint(const char *path)
-{
- int size = strlen(path)+2;
- char *directory = (char *) malloc(size);
- strcpy_s(directory, size, path);
- NormalizeSlashes(directory, '\\');
- if (directory [strlen(directory)-1] != '\\')
- strcat_s(directory, size, "\\");
-
- char volumeName[_MAX_PATH];
- int rc = GetVolumeNameForVolumeMountPointA(directory, volumeName, sizeof(volumeName));
- if (rc)
- {
- char volumePathNames[_MAX_PATH];
- DWORD returnLength;
- rc = GetVolumePathNamesForVolumeNameA(volumeName, volumePathNames, sizeof(volumePathNames), &returnLength);
- if (rc)
- {
- char *p = volumePathNames;
- while(*p)
- {
- if (_stricmp(p, directory)) // if it's not the path we've already found
- {
- NormalizeSlashes(directory, '/');
- NormalizeSlashes(p, '/');
- puts(directory);
- puts(p);
- }
- p += strlen(p)+1;
- }
- }
- }
- free(directory);
+void PrintDirectoryReparsePoint(const char *path) {
+ int size = strlen(path) + 2;
+ char *directory = (char *) malloc(size);
+ strcpy_s(directory, size, path);
+ NormalizeSlashes(directory, '\\');
+ if (directory[strlen(directory) - 1] != '\\')
+ strcat_s(directory, size, "\\");
+
+ char volumeName[_MAX_PATH];
+ int rc = GetVolumeNameForVolumeMountPointA(directory, volumeName, sizeof(volumeName));
+ if (rc) {
+ char volumePathNames[_MAX_PATH];
+ DWORD returnLength;
+ rc = GetVolumePathNamesForVolumeNameA(volumeName, volumePathNames, sizeof(volumePathNames), &returnLength);
+ if (rc) {
+ char *p = volumePathNames;
+ while (*p) {
+ if (_stricmp(p, directory)) // if it's not the path we've already found
+ {
+ NormalizeSlashes(directory, '/');
+ NormalizeSlashes(p, '/');
+ puts(directory);
+ puts(p);
+ }
+ p += strlen(p) + 1;
+ }
+ }
+ }
+ free(directory);
}
-bool PrintMountPointsForVolume(HANDLE hVol, const char* volumePath, char *Buf)
-{
+bool PrintMountPointsForVolume(HANDLE hVol, const char *volumePath, char *Buf) {
HANDLE hPt; // handle for mount point scan
char Path[BUFSIZE]; // string buffer for mount points
DWORD dwSysFlags; // flags that describe the file system
@@ -182,39 +169,38 @@ bool PrintMountPointsForVolume(HANDLE hVol, const char* volumePath, char *Buf)
// Detect support for reparse points, and therefore for volume
// mount points, which are implemented using reparse points.
- if (! (dwSysFlags & FILE_SUPPORTS_REPARSE_POINTS)) {
- return true;
+ if (!(dwSysFlags & FILE_SUPPORTS_REPARSE_POINTS)) {
+ return true;
}
// Start processing mount points on this volume.
hPt = FindFirstVolumeMountPointA(
- Buf, // root path of volume to be scanned
- Path, // pointer to output string
- BUFSIZE // size of output buffer
+ Buf, // root path of volume to be scanned
+ Path, // pointer to output string
+ BUFSIZE // size of output buffer
);
// Shall we error out?
if (hPt == INVALID_HANDLE_VALUE) {
- return GetLastError() != ERROR_ACCESS_DENIED;
+ return GetLastError() != ERROR_ACCESS_DENIED;
}
// Process the volume mount point.
- char *buf = new char[MAX_PATH];
+ char *buf = new char[MAX_PATH];
do {
- strcpy_s(buf, MAX_PATH, volumePath);
- strcat_s(buf, MAX_PATH, Path);
- PrintDirectoryReparsePoint(buf);
+ strcpy_s(buf, MAX_PATH, volumePath);
+ strcat_s(buf, MAX_PATH, Path);
+ PrintDirectoryReparsePoint(buf);
} while (FindNextVolumeMountPointA(hPt, Path, BUFSIZE));
FindVolumeMountPointClose(hPt);
- return true;
+ return true;
}
-bool PrintMountPoints(const char *path)
-{
- char volumeUniqueName[128];
- BOOL res = GetVolumeNameForVolumeMountPointA(path, volumeUniqueName, 128);
- if (!res) {
+bool PrintMountPoints(const char *path) {
+ char volumeUniqueName[128];
+ BOOL res = GetVolumeNameForVolumeMountPointA(path, volumeUniqueName, 128);
+ if (!res) {
return false;
}
@@ -222,7 +208,7 @@ bool PrintMountPoints(const char *path)
HANDLE hVol; // handle for the volume scan
// Open a scan for volumes.
- hVol = FindFirstVolumeA(buf, BUFSIZE );
+ hVol = FindFirstVolumeA(buf, BUFSIZE);
// Shall we error out?
if (hVol == INVALID_HANDLE_VALUE) {
@@ -230,329 +216,286 @@ bool PrintMountPoints(const char *path)
}
bool success = true;
- do {
- if (!strcmp(buf, volumeUniqueName)) {
- success = PrintMountPointsForVolume(hVol, path, buf);
- if (!success) break;
- }
+ do {
+ if (!strcmp(buf, volumeUniqueName)) {
+ success = PrintMountPointsForVolume(hVol, path, buf);
+ if (!success) break;
+ }
} while (FindNextVolumeA(hVol, buf, BUFSIZE));
FindVolumeClose(hVol);
- return success;
+ return success;
}
// -- Searching for mount points in watch roots (fallback) --------------------
-void PrintDirectoryReparsePoints(const char *path)
-{
- char *const buf = _strdup(path);
- while(strchr(buf, '/'))
- {
- DWORD attributes = GetFileAttributesA(buf);
- if (attributes == INVALID_FILE_ATTRIBUTES)
- break;
- if (attributes & FILE_ATTRIBUTE_REPARSE_POINT)
- {
- PrintDirectoryReparsePoint(buf);
- }
- char *pSlash = strrchr(buf, '/');
- if (pSlash)
- {
- *pSlash = '\0';
- }
- }
- free(buf);
+void PrintDirectoryReparsePoints(const char *path) {
+ char *const buf = _strdup(path);
+ while (strchr(buf, '/')) {
+ DWORD attributes = GetFileAttributesA(buf);
+ if (attributes == INVALID_FILE_ATTRIBUTES)
+ break;
+ if (attributes & FILE_ATTRIBUTE_REPARSE_POINT) {
+ PrintDirectoryReparsePoint(buf);
+ }
+ char *pSlash = strrchr(buf, '/');
+ if (pSlash) {
+ *pSlash = '\0';
+ }
+ }
+ free(buf);
}
// This is called if we got an ERROR_ACCESS_DENIED when trying to enumerate all mount points for volume.
// In this case, we walk the directory tree up from each watch root, and look at each parent directory
// to check whether it's a reparse point.
-void PrintWatchRootReparsePoints()
-{
- WatchRoot *pWatchRoot = firstWatchRoot;
- while(pWatchRoot)
- {
- PrintDirectoryReparsePoints(pWatchRoot->path);
- pWatchRoot = pWatchRoot->next;
- }
+void PrintWatchRootReparsePoints() {
+ WatchRoot *pWatchRoot = firstWatchRoot;
+ while (pWatchRoot) {
+ PrintDirectoryReparsePoints(pWatchRoot->path);
+ pWatchRoot = pWatchRoot->next;
+ }
}
// -- Watcher thread ----------------------------------------------------------
-void PrintChangeInfo(char *rootPath, FILE_NOTIFY_INFORMATION *info)
-{
- char FileNameBuffer[_MAX_PATH];
- int converted = WideCharToMultiByte(CP_ACP, 0, info->FileName, info->FileNameLength/sizeof(WCHAR), FileNameBuffer, _MAX_PATH-1, NULL, NULL);
- FileNameBuffer[converted] = '\0';
- char *command;
- if (info->Action == FILE_ACTION_ADDED || info->Action == FILE_ACTION_RENAMED_OLD_NAME)
- {
- command = "CREATE";
- }
- else if (info->Action == FILE_ACTION_REMOVED || info->Action == FILE_ACTION_RENAMED_OLD_NAME)
- {
- command = "DELETE";
- }
- else if (info->Action == FILE_ACTION_MODIFIED)
- {
- command = "CHANGE";
- }
- else
- {
- return; // unknown command
- }
-
- EnterCriticalSection(&csOutput);
- puts(command);
- printf("%s", rootPath);
- puts(FileNameBuffer);
- fflush(stdout);
- LeaveCriticalSection(&csOutput);
+void PrintChangeInfo(char *rootPath, FILE_NOTIFY_INFORMATION *info) {
+ char FileNameBuffer[_MAX_PATH];
+ int converted = WideCharToMultiByte(CP_ACP, 0, info->FileName, info->FileNameLength / sizeof(WCHAR), FileNameBuffer, _MAX_PATH - 1, NULL, NULL);
+ FileNameBuffer[converted] = '\0';
+ char *command;
+ if (info->Action == FILE_ACTION_ADDED || info->Action == FILE_ACTION_RENAMED_OLD_NAME) {
+ command = "CREATE";
+ }
+ else if (info->Action == FILE_ACTION_REMOVED || info->Action == FILE_ACTION_RENAMED_OLD_NAME) {
+ command = "DELETE";
+ }
+ else if (info->Action == FILE_ACTION_MODIFIED) {
+ command = "CHANGE";
+ }
+ else {
+ return; // unknown command
+ }
+
+ EnterCriticalSection(&csOutput);
+ puts(command);
+ printf("%s", rootPath);
+ puts(FileNameBuffer);
+ fflush(stdout);
+ LeaveCriticalSection(&csOutput);
}
-void PrintEverythingChangedUnderRoot(char *rootPath)
-{
- EnterCriticalSection(&csOutput);
- puts("RECDIRTY");
- puts(rootPath);
- fflush(stdout);
- LeaveCriticalSection(&csOutput);
+void PrintEverythingChangedUnderRoot(char *rootPath) {
+ EnterCriticalSection(&csOutput);
+ puts("RECDIRTY");
+ puts(rootPath);
+ fflush(stdout);
+ LeaveCriticalSection(&csOutput);
}
-DWORD WINAPI WatcherThread(void *param)
-{
- WatchRootInfo *info = (WatchRootInfo *) param;
-
- OVERLAPPED overlapped;
- memset(&overlapped, 0, sizeof(overlapped));
- overlapped.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
-
- char rootPath[8];
- sprintf_s(rootPath, 8, "%c:\\", info->driveLetter);
- HANDLE hRootDir = CreateFileA(rootPath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
- NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED, NULL);
-
- int buffer_size = 10240;
- char *buffer = new char[buffer_size];
-
- HANDLE handles [2];
- handles [0] = info->hStopEvent;
- handles [1] = overlapped.hEvent;
- while(true)
- {
- int rcDir = ReadDirectoryChangesW(hRootDir, buffer, buffer_size, TRUE,
- FILE_NOTIFY_CHANGE_FILE_NAME |
- FILE_NOTIFY_CHANGE_DIR_NAME |
- FILE_NOTIFY_CHANGE_ATTRIBUTES |
- FILE_NOTIFY_CHANGE_SIZE |
- FILE_NOTIFY_CHANGE_LAST_WRITE,
- NULL,
- &overlapped,
- NULL);
- if (rcDir == 0)
- {
- info->bFailed = true;
- break;
- }
-
- int rc = WaitForMultipleObjects(2, handles, FALSE, INFINITE);
- if (rc == WAIT_OBJECT_0)
- {
- break;
- }
- if (rc == WAIT_OBJECT_0+1)
- {
- DWORD dwBytesReturned;
- if(!GetOverlappedResult(hRootDir, &overlapped, &dwBytesReturned, FALSE))
- {
- info->bFailed = true;
- break;
- }
-
- if (dwBytesReturned == 0)
- {
- // don't send dirty too much, everything is changed anyway
- if (WaitForSingleObject(info->hStopEvent, 500) == WAIT_OBJECT_0)
- break;
-
- // Got a buffer overflow => current changes lost => send RECDIRTY on root
- PrintEverythingChangedUnderRoot(rootPath);
- } else {
- FILE_NOTIFY_INFORMATION *info = (FILE_NOTIFY_INFORMATION *) buffer;
- while(true)
- {
- PrintChangeInfo(rootPath, info);
- if (!info->NextEntryOffset)
- break;
- info = (FILE_NOTIFY_INFORMATION *) ((char *) info + info->NextEntryOffset);
- }
- }
- }
- }
- CloseHandle(overlapped.hEvent);
- CloseHandle(hRootDir);
- delete[] buffer;
- return 0;
+DWORD WINAPI WatcherThread(void *param) {
+ WatchRootInfo *info = (WatchRootInfo *) param;
+
+ OVERLAPPED overlapped;
+ memset(&overlapped, 0, sizeof(overlapped));
+ overlapped.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
+
+ char rootPath[8];
+ sprintf_s(rootPath, 8, "%c:\\", info->driveLetter);
+ HANDLE hRootDir = CreateFileA(rootPath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
+ NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED, NULL);
+
+ int buffer_size = 10240;
+ char *buffer = new char[buffer_size];
+
+ HANDLE handles[2];
+ handles[0] = info->hStopEvent;
+ handles[1] = overlapped.hEvent;
+ while (true) {
+ int rcDir = ReadDirectoryChangesW(hRootDir, buffer, buffer_size, TRUE,
+ FILE_NOTIFY_CHANGE_FILE_NAME |
+ FILE_NOTIFY_CHANGE_DIR_NAME |
+ FILE_NOTIFY_CHANGE_ATTRIBUTES |
+ FILE_NOTIFY_CHANGE_SIZE |
+ FILE_NOTIFY_CHANGE_LAST_WRITE,
+ NULL,
+ &overlapped,
+ NULL);
+ if (rcDir == 0) {
+ info->bFailed = true;
+ break;
+ }
+
+ int rc = WaitForMultipleObjects(2, handles, FALSE, INFINITE);
+ if (rc == WAIT_OBJECT_0) {
+ break;
+ }
+ if (rc == WAIT_OBJECT_0 + 1) {
+ DWORD dwBytesReturned;
+ if (!GetOverlappedResult(hRootDir, &overlapped, &dwBytesReturned, FALSE)) {
+ info->bFailed = true;
+ break;
+ }
+
+ if (dwBytesReturned == 0) {
+ // don't send dirty too much, everything is changed anyway
+ if (WaitForSingleObject(info->hStopEvent, 500) == WAIT_OBJECT_0)
+ break;
+
+ // Got a buffer overflow => current changes lost => send RECDIRTY on root
+ PrintEverythingChangedUnderRoot(rootPath);
+ } else {
+ FILE_NOTIFY_INFORMATION *info = (FILE_NOTIFY_INFORMATION *) buffer;
+ while (true) {
+ PrintChangeInfo(rootPath, info);
+ if (!info->NextEntryOffset)
+ break;
+ info = (FILE_NOTIFY_INFORMATION *)((char *) info + info->NextEntryOffset);
+ }
+ }
+ }
+ }
+ CloseHandle(overlapped.hEvent);
+ CloseHandle(hRootDir);
+ delete[] buffer;
+ return 0;
}
// -- Roots update ------------------------------------------------------------
-void MarkAllRootsUnused()
-{
- for(int i=0; i<ROOT_COUNT; i++)
- {
- watchRootInfos [i].bUsed = false;
- }
+void MarkAllRootsUnused() {
+ for (int i = 0; i < ROOT_COUNT; i++) {
+ watchRootInfos[i].bUsed = false;
+ }
}
-void StartRoot(WatchRootInfo *info)
-{
- info->hStopEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
- info->hThread = CreateThread(NULL, 0, &WatcherThread, info, 0, NULL);
- info->bInitialized = true;
+void StartRoot(WatchRootInfo *info) {
+ info->hStopEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
+ info->hThread = CreateThread(NULL, 0, &WatcherThread, info, 0, NULL);
+ info->bInitialized = true;
}
-void StopRoot(WatchRootInfo *info)
-{
- SetEvent(info->hStopEvent);
- WaitForSingleObject(info->hThread, INFINITE);
- CloseHandle(info->hThread);
- CloseHandle(info->hStopEvent);
- info->bInitialized = false;
+void StopRoot(WatchRootInfo *info) {
+ SetEvent(info->hStopEvent);
+ WaitForSingleObject(info->hThread, INFINITE);
+ CloseHandle(info->hThread);
+ CloseHandle(info->hStopEvent);
+ info->bInitialized = false;
}
-void UpdateRoots()
-{
- char infoBuffer [256];
- strcpy_s(infoBuffer, "UNWATCHEABLE\n");
- for(int i=0; i<ROOT_COUNT; i++)
- {
- if (watchRootInfos [i].bInitialized && (!watchRootInfos [i].bUsed || watchRootInfos [i].bFailed))
- {
- StopRoot(&watchRootInfos [i]);
- watchRootInfos [i].bFailed = false;
- }
- if (watchRootInfos [i].bUsed)
- {
- char rootPath[8];
- sprintf_s(rootPath, 8, "%c:\\", watchRootInfos [i].driveLetter);
- if (!IsWatchable(rootPath))
- {
- strcat_s(infoBuffer, rootPath);
- strcat_s(infoBuffer, "\n");
- continue;
- }
- if (!watchRootInfos [i].bInitialized)
- {
- StartRoot(&watchRootInfos [i]);
- }
- }
- }
- EnterCriticalSection(&csOutput);
- fprintf(stdout, "%s", infoBuffer);
- puts("#\nREMAP");
- PrintRemapForSubstDrives();
- bool printedMountPoints = true;
- for(int i=0; i<ROOT_COUNT; i++)
- {
- if (watchRootInfos [i].bUsed)
- {
- char rootPath[8];
- sprintf_s(rootPath, 8, "%c:\\", watchRootInfos [i].driveLetter);
- if (!PrintMountPoints(rootPath))
- printedMountPoints = false;
- }
- }
- if (!printedMountPoints)
- {
- PrintWatchRootReparsePoints();
- }
- puts("#");
- fflush(stdout);
- LeaveCriticalSection(&csOutput);
+void UpdateRoots() {
+ char infoBuffer[256];
+ strcpy_s(infoBuffer, "UNWATCHEABLE\n");
+ for (int i = 0; i < ROOT_COUNT; i++) {
+ if (watchRootInfos[i].bInitialized && (!watchRootInfos[i].bUsed || watchRootInfos[i].bFailed)) {
+ StopRoot(&watchRootInfos[i]);
+ watchRootInfos[i].bFailed = false;
+ }
+ if (watchRootInfos[i].bUsed) {
+ char rootPath[8];
+ sprintf_s(rootPath, 8, "%c:\\", watchRootInfos[i].driveLetter);
+ if (!IsWatchable(rootPath)) {
+ strcat_s(infoBuffer, rootPath);
+ strcat_s(infoBuffer, "\n");
+ continue;
+ }
+ if (!watchRootInfos[i].bInitialized) {
+ StartRoot(&watchRootInfos[i]);
+ }
+ }
+ }
+ EnterCriticalSection(&csOutput);
+ fprintf(stdout, "%s", infoBuffer);
+ puts("#\nREMAP");
+ PrintRemapForSubstDrives();
+ bool printedMountPoints = true;
+ for (int i = 0; i < ROOT_COUNT; i++) {
+ if (watchRootInfos[i].bUsed) {
+ char rootPath[8];
+ sprintf_s(rootPath, 8, "%c:\\", watchRootInfos[i].driveLetter);
+ if (!PrintMountPoints(rootPath))
+ printedMountPoints = false;
+ }
+ }
+ if (!printedMountPoints) {
+ PrintWatchRootReparsePoints();
+ }
+ puts("#");
+ fflush(stdout);
+ LeaveCriticalSection(&csOutput);
}
-void AddWatchRoot(const char *path)
-{
- WatchRoot *watchRoot = (WatchRoot *) malloc(sizeof(WatchRoot));
- watchRoot->next = NULL;
- watchRoot->path = _strdup(path);
- watchRoot->next = firstWatchRoot;
- firstWatchRoot = watchRoot;
+void AddWatchRoot(const char *path) {
+ WatchRoot *watchRoot = (WatchRoot *) malloc(sizeof(WatchRoot));
+ watchRoot->next = NULL;
+ watchRoot->path = _strdup(path);
+ watchRoot->next = firstWatchRoot;
+ firstWatchRoot = watchRoot;
}
-void FreeWatchRootsList()
-{
- WatchRoot *pWatchRoot = firstWatchRoot;
- WatchRoot *pNext;
- while(pWatchRoot)
- {
- pNext = pWatchRoot->next;
- free(pWatchRoot->path);
- free(pWatchRoot);
- pWatchRoot=pNext;
- }
- firstWatchRoot = NULL;
+void FreeWatchRootsList() {
+ WatchRoot *pWatchRoot = firstWatchRoot;
+ WatchRoot *pNext;
+ while (pWatchRoot) {
+ pNext = pWatchRoot->next;
+ free(pWatchRoot->path);
+ free(pWatchRoot);
+ pWatchRoot = pNext;
+ }
+ firstWatchRoot = NULL;
}
// -- Main - filewatcher protocol ---------------------------------------------
-int _tmain(int argc, _TCHAR* argv[])
-{
- InitializeCriticalSection(&csOutput);
-
- for(int i=0; i<26; i++)
- {
- watchRootInfos [i].driveLetter = 'A' + i;
- watchRootInfos [i].bInitialized = false;
- watchRootInfos [i].bUsed = false;
- }
-
- char buffer[8192];
- while(true)
- {
- if (!gets_s(buffer, sizeof(buffer)-1))
- break;
-
- if (!strcmp(buffer, "ROOTS"))
- {
- MarkAllRootsUnused();
- FreeWatchRootsList();
- bool failed = false;
- while(true)
- {
- if (!gets_s(buffer, sizeof(buffer)-1))
- {
- failed = true;
- break;
- }
- if (buffer [0] == '#')
- break;
- int driveLetterPos = 0;
- char *pDriveLetter = buffer;
- if (*pDriveLetter == '|')
- pDriveLetter++;
-
- AddWatchRoot(pDriveLetter);
-
- _strupr_s(buffer, sizeof(buffer)-1);
- char driveLetter = *pDriveLetter;
- if (driveLetter >= 'A' && driveLetter <= 'Z')
- {
- watchRootInfos [driveLetter-'A'].bUsed = true;
- }
- }
- if (failed)
- break;
-
- UpdateRoots();
- }
- if (!strcmp(buffer, "EXIT"))
- break;
- }
-
- MarkAllRootsUnused();
- UpdateRoots();
-
- DeleteCriticalSection(&csOutput);
+int _tmain(int argc, _TCHAR *argv[]) {
+ InitializeCriticalSection(&csOutput);
+
+ for (int i = 0; i < 26; i++) {
+ watchRootInfos[i].driveLetter = 'A' + i;
+ watchRootInfos[i].bInitialized = false;
+ watchRootInfos[i].bUsed = false;
+ }
+
+ char buffer[8192];
+ while (true) {
+ if (!gets_s(buffer, sizeof(buffer) - 1))
+ break;
+
+ if (!strcmp(buffer, "ROOTS")) {
+ MarkAllRootsUnused();
+ FreeWatchRootsList();
+ bool failed = false;
+ while (true) {
+ if (!gets_s(buffer, sizeof(buffer) - 1)) {
+ failed = true;
+ break;
+ }
+ if (buffer[0] == '#')
+ break;
+ int driveLetterPos = 0;
+ char *pDriveLetter = buffer;
+ if (*pDriveLetter == '|')
+ pDriveLetter++;
+
+ AddWatchRoot(pDriveLetter);
+
+ _strupr_s(buffer, sizeof(buffer) - 1);
+ char driveLetter = *pDriveLetter;
+ if (driveLetter >= 'A' && driveLetter <= 'Z') {
+ watchRootInfos[driveLetter - 'A'].bUsed = true;
+ }
+ }
+ if (failed)
+ break;
+
+ UpdateRoots();
+ }
+ if (!strcmp(buffer, "EXIT"))
+ break;
+ }
+
+ MarkAllRootsUnused();
+ UpdateRoots();
+
+ DeleteCriticalSection(&csOutput);
}