Created
February 7, 2011 13:51
-
-
Save loarabia/814384 to your computer and use it in GitHub Desktop.
Synchronous Windows File System Monitoring Code
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import os | |
import os.path | |
import random | |
import re | |
import uuid | |
from optparse import OptionParser | |
class FileSystemRandomizer: | |
def __init__(self, root): | |
self.root = root | |
self.currentDirectory = root | |
self.currentDepth = 0 | |
self.numberOfWatchableActions = 0 | |
self.actions = [ | |
self.addDirectory, | |
self.deleteDirectory, | |
self.renameDirectory, | |
self.enterDirectory, | |
self.leaveDirectory, | |
self.addFile, | |
self.deleteFile, | |
self.renameFile, | |
self.writeToFile] | |
self.validator = re.compile("[0-9a-f]{32}") | |
self.addDir = 0 | |
self.deleteDir = 0 | |
self.renameDir = 0 | |
self.enterDir = 0 | |
self.leaveDir = 0 | |
self.addFile = 0 | |
self.deleteFile = 0 | |
self.renameFile = 0 | |
self.writeToFile = 0 | |
def stressFileSystem(self): | |
for i in range(1,10): | |
stressAction = random.choice(self.actions) | |
stressAction() | |
print("Performed " + str(self.numberOfWatchableActions) + " actions") | |
print("Max Depth " + str(self.maxDepth())) | |
print("\tAddDir " + str(self.addDir)) | |
print("\tDelDir " + str(self.deleteDir)) | |
print("\trenameDir " + str(self.renameDir)) | |
print("\tenterDir " + str(self.enterDir)) | |
print("\tleaveDir " + str(self.leaveDir)) | |
print("\taddFile " + str(self.addFile)) | |
print("\tdeleteFile " + str(self.deleteFile)) | |
print("\trenameFile " + str(self.renameFile)) | |
print("\twriteToFile " + str(self.writeToFile)) | |
def maxDepth(self): | |
depth = 0 | |
for root, dontCare1, dontCare2 in os.walk(self.root): | |
if( root == self.root): | |
continue | |
localDepth = 0 | |
localDir = root | |
while( localDir != self.root): | |
localDir = os.path.dirname(localDir) | |
localDepth += 1 | |
depth = max(depth, localDepth) | |
return depth | |
def addDirectory(self): | |
newDirPath = os.path.join(self.root, str(uuid.uuid4().hex)) | |
os.mkdir( newDirPath ) | |
self.numberOfWatchableActions += 1 | |
self.addDir += 1 | |
print(newDirPath +" : ADDED " + str(self.numberOfWatchableActions)) | |
def addFile(self): | |
newFilePath = os.path.join(self.root, str(uuid.uuid4().hex)) | |
fd = open( newFilePath, "w") | |
fd.close() | |
self.numberOfWatchableActions += 1 | |
self.addFile += 1 | |
print(newFilePath +" : ADDED " + str(self.numberOfWatchableActions)) | |
def enterDirectory(self): | |
if( self.maxDepth() == 0): | |
return | |
if( self.currentDepth == self.maxDepth()): | |
return | |
fileSysGenerator = os.walk(self.root) | |
dontCare1, dirs, dontCare2 = next(fileSysGenerator) | |
if( len(dirs) == 0): | |
return | |
newDirPath = random.choice(dirs) | |
self.currentDirectory = os.path.join(self.currentDirectory, dirs[0]) | |
self.currentDepth += 1 | |
self.enterDir += 1 | |
def leaveDirectory(self): | |
if( self.currentDepth == 0): | |
return | |
self.currentDirectory = os.path.dirname(self.currentDirectory) | |
self.currentDepth -= 1 | |
self.leaveDir += 1 | |
def deleteDirectory(self): | |
if( self.currentDepth == 0): | |
return | |
if( self.maxDepth() == self.currentDepth): | |
return | |
fileSysGenerator = os.walk(self.currentDirectory) | |
dontCare1, dirs, dontCare2 = next(fileSysGenerator) | |
if( len(dirs) == 0): | |
return | |
deleteDir = random.choice(dirs) | |
assert( len(deleteDir) == 32) | |
assert( self.validator.match(deleteDir) != None) | |
deleteDirPath = os.path.join(self.currentDirectory, deleteDir) | |
os.rmdir(deleteDirPath) | |
self.numberOfWatchableActions += 1 | |
self.deleteDir += 1 | |
print(os.path.join( self.currentDirectory, deleteDir)+" : REMOVED " + str(self.numberOfWatchableActions)) | |
def deleteFile(self): | |
fileSysGenerator = os.walk(self.currentDirectory) | |
dontCare1, dontCare2, files = next(fileSysGenerator) | |
if( len(files) == 0): | |
return | |
file = random.choice(files) | |
assert( len(file) == 32) | |
assert( self.validator.match(file) != None) | |
os.remove(os.path.join(self.currentDirectory, file)) | |
self.numberOfWatchableActions += 1 | |
self.deleteFile += 1 | |
print(os.path.join( self.currentDirectory,file)+" : REMOVED " + str(self.numberOfWatchableActions)) | |
def renameDirectory(self): | |
if( self.currentDepth == self.maxDepth()): | |
return | |
if( self.maxDepth() == 0): | |
return | |
fileSysGenerator = os.walk(self.currentDirectory) | |
dontCare1, dirs, dontCare2 = next(fileSysGenerator) | |
if( len(dirs) == 0): | |
return | |
oldDir = random.choice(dirs) | |
assert( len(oldDir) == 32) | |
assert( self.validator.match(oldDir) != None) | |
oldDirPath = os.path.join(self.currentDirectory, oldDir) | |
newDirPath = os.path.join(self.currentDirectory, str(uuid.uuid4().hex)) | |
os.rename(oldDirPath, newDirPath) | |
self.numberOfWatchableActions += 1 | |
self.renameDir += 1 | |
print(oldDirPath +" : RENAME" + str(self.numberOfWatchableActions)) | |
def renameFile(self): | |
fileSysGenerator = os.walk(self.currentDirectory) | |
dontCare1, dontCare2, files = next(fileSysGenerator) | |
if( len(files) == 0): | |
return | |
oldFile = random.choice(files) | |
assert( len(oldFile) == 32) | |
assert( self.validator.match(oldFile) != None) | |
oldFilePath = os.path.join(self.currentDirectory, oldFile) | |
newFilePath = os.path.join(self.currentDirectory, str(uuid.uuid4().hex)) | |
os.rename(oldFilePath, newFilePath) | |
self.numberOfWatchableActions += 1 | |
self.renameFile += 1 | |
print(oldFilePath +" : RENAME" + str(self.numberOfWatchableActions)) | |
def writeToFile(self): | |
fileSysGenerator = os.walk(self.currentDirectory) | |
dontCare1, dontCare2, files = next(fileSysGenerator) | |
if( len(files) == 0): | |
return | |
file = random.choice(files) | |
assert( len(file) == 32) | |
assert self.validator.match(file) != None, file | |
filePath = os.path.join(self.currentDirectory, file) | |
fd = open(filePath,"a+") | |
fd.write("1") | |
fd.close() | |
self.numberOfWatchableActions += 1 | |
self.writeToFile += 1 | |
print(filePath +" : MODIFIED" + str(self.numberOfWatchableActions)) | |
def parseOptions(): | |
parser = OptionParser() | |
(options, args) = parser.parse_args() | |
return args | |
if __name__ == "__main__": | |
args = parseOptions() | |
FileSystemRandomizer(args[0]).stressFileSystem() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "stdafx.h" | |
void WatchDirectory(LPCTSTR); | |
int _tmain(int argc, _TCHAR* argv[]) | |
{ | |
if( argc != 2) | |
{ | |
_tprintf( TEXT("Usage: %s <dir>\n"), argv[0]); | |
return 1; | |
} | |
WatchDirectory( (LPCTSTR)argv[1]); | |
return 0; | |
} | |
void WatchDirectory(LPCTSTR lpDir) | |
{ | |
HANDLE hDir = CreateFile( | |
lpDir, | |
FILE_LIST_DIRECTORY, | |
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, | |
NULL, | |
OPEN_EXISTING, | |
FILE_FLAG_BACKUP_SEMANTICS, | |
NULL); | |
BOOL result; | |
const int size = 1024 * sizeof(FILE_NOTIFY_INFORMATION); | |
char buffer[size]; | |
DWORD notifications = FILE_NOTIFY_CHANGE_FILE_NAME | | |
FILE_NOTIFY_CHANGE_DIR_NAME | | |
FILE_NOTIFY_CHANGE_ATTRIBUTES | | |
FILE_NOTIFY_CHANGE_SIZE | | |
FILE_NOTIFY_CHANGE_LAST_WRITE; | |
DWORD bytesReturned = 0; | |
int actions = 0; | |
wchar_t szFilename[MAX_PATH]; | |
wchar_t szNewFilename[MAX_PATH]; | |
ZeroMemory(szNewFilename, MAX_PATH); | |
while( TRUE) | |
{ | |
int index = 0; | |
result = ReadDirectoryChangesW( | |
hDir, | |
buffer, | |
size, | |
TRUE, | |
notifications, | |
&bytesReturned, | |
NULL, | |
NULL); | |
FILE_NOTIFY_INFORMATION *pNotifyInfoCurr = NULL; | |
FILE_NOTIFY_INFORMATION *pNotifyInfoPrev = NULL; | |
pNotifyInfoCurr = (FILE_NOTIFY_INFORMATION *)buffer; | |
while( pNotifyInfoCurr != pNotifyInfoPrev) | |
{ | |
ZeroMemory(szFilename, MAX_PATH); | |
wcsncpy(szFilename, pNotifyInfoCurr->FileName, pNotifyInfoCurr->FileNameLength/2); // Oy, Fix your string handling. | |
wprintf(L"\n%s :", szFilename); | |
switch( pNotifyInfoCurr->Action) | |
{ | |
case FILE_ACTION_ADDED: | |
printf(" ADDED "); | |
break; | |
case FILE_ACTION_REMOVED: | |
printf(" REMOVED "); | |
break; | |
case FILE_ACTION_MODIFIED: | |
if( wcsncmp(szNewFilename, szFilename, MAX_PATH) == 0) | |
{ | |
actions--; | |
printf(" MODIFIED "); | |
ZeroMemory(szNewFilename, MAX_PATH); | |
} | |
else | |
{ | |
printf(" MODIFIED "); | |
} | |
break; | |
case FILE_ACTION_RENAMED_OLD_NAME: | |
printf(" RENAME "); | |
break; | |
case FILE_ACTION_RENAMED_NEW_NAME: | |
printf(" RENAME NEW"); | |
wcsncpy(szNewFilename, pNotifyInfoCurr->FileName,pNotifyInfoCurr->FileNameLength/2); | |
actions--; | |
break; | |
default: | |
printf(" OTHER "); | |
} | |
printf("\t%d", actions); | |
actions++; | |
pNotifyInfoPrev = pNotifyInfoCurr; | |
index += pNotifyInfoCurr->NextEntryOffset; | |
pNotifyInfoCurr = (FILE_NOTIFY_INFORMATION *)(&buffer[index]); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment