Skip to content

Instantly share code, notes, and snippets.

@Varriount
Last active August 29, 2015 14:00
Show Gist options
  • Save Varriount/cece02012ff743e39c3e to your computer and use it in GitHub Desktop.
Save Varriount/cece02012ff743e39c3e to your computer and use it in GitHub Desktop.
import winlean, os, asyncdispatch
# Put in Winlean
type
LPOVERLAPPED_COMPLETION_ROUTINE* = proc (para1: DWORD, para2: DWORD,
para3: ptr TOVERLAPPED){.stdcall.}
const FILE_LIST_DIRECTORY* = 0x00000001 # directory
const
FILE_NOTIFY_CHANGE_FILE_NAME* = 0x00000001.dword
FILE_NOTIFY_CHANGE_DIR_NAME* = 0x00000002.dword
FILE_NOTIFY_CHANGE_ATTRIBUTES* = 0x00000004.dword
FILE_NOTIFY_CHANGE_SIZE* = 0x00000008.dword
FILE_NOTIFY_CHANGE_LAST_WRITE* = 0x00000010.dword
FILE_NOTIFY_CHANGE_LAST_ACCESS* = 0x00000020.dword
FILE_NOTIFY_CHANGE_CREATION* = 0x00000040.dword
FILE_NOTIFY_CHANGE_SECURITY* = 0x00000100.dword
proc ReadDirectoryChangesW*(
hDirectory: THandle,
lpBuffer: pointer,
nBufferLength: dword,
bWatchSubtree: WINBOOL,
dwNotifyFilter: dword,
lpBytesReturned: PDWORD,
lpOverlapped: POverlapped,
lpCompletionRoutine: LPOVERLAPPED_COMPLETION_ROUTINE
): WINBOOL {.stdcall, importc: "ReadDirectoryChangesW", dynlib: "Kernel32.dll".}
# End
# Associate a directory handle with an IO completion port
# Create a buffer to store file changes
# Call the ReadDirectoryChanges
proc openAsyncHandle(path: string, followSymlink=true): TAsyncFD =
var flags = (FILE_FLAG_BACKUP_SEMANTICS or
FILE_FLAG_OVERLAPPED)
if not followSymlink:
flags = flags or FILE_FLAG_OPEN_REPARSE_POINT
when useWinUnicode:
result = createFileW(
newWideCString(path), FILE_LIST_DIRECTORY,
FILE_SHARE_DELETE or FILE_SHARE_READ or FILE_SHARE_WRITE,
nil, OPEN_EXISTING, flags, 0
).TAsyncFD
else:
result = createFileA(
path, FILE_LIST_DIRECTORY,
FILE_SHARE_DELETE or FILE_SHARE_READ or FILE_SHARE_WRITE,
nil, OPEN_EXISTING, flags, 0
).TAsyncFD
if result == INVALID_HANDLE_VALUE.TAsyncFD:
osError(osLastError())
proc main =
var
dirName = r"C:\Users\Clay\Projects\Nimrod-Scripts\pathstuff\"
dirHandle = openAsyncHandle(dirName)
aligned: tuple [alignIt: int32, buffer: array [2000, byte]]
bufferLen: int32 = aligned.buffer.len().int32
filterFlags = (FILE_NOTIFY_CHANGE_FILE_NAME or
FILE_NOTIFY_CHANGE_DIR_NAME or
FILE_NOTIFY_CHANGE_ATTRIBUTES or
FILE_NOTIFY_CHANGE_SIZE
)
ol = cast[PCustomOverlapped](alloc0(sizeof(TCustomOverlapped)))
ol.data = TCompletionData(sock: dirHandle, cb:
proc (sock: TAsyncFD, bytesCount: DWord, errcode: TOSErrorCode) =
sock.repr.echo
bytesCount.echo
errcode.echo
)
dirHandle.register()
osLastError().echo
let r = ReadDirectoryChangesW(dirHandle.THandle,
addr aligned.buffer[0],
bufferLen,
true.winbool,
filterFlags,
cast[ptr dword](nil),
cast[POverlapped](ol),
cast[LPOVERLAPPED_COMPLETION_ROUTINE](nil)
)
osLastError().echo()
if r == 0:
osError(osLastError())
while true:
poll()
when isMainModule:
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment