Skip to content

Instantly share code, notes, and snippets.

@loarabia
Created February 7, 2011 13:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save loarabia/814384 to your computer and use it in GitHub Desktop.
Save loarabia/814384 to your computer and use it in GitHub Desktop.
Synchronous Windows File System Monitoring Code
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()
#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