public NTTransactNotifyChangeRequest(byte[] setup) : base() { CompletionFilter = (NotifyChangeFilter)LittleEndianConverter.ToUInt32(setup, 0); FID = LittleEndianConverter.ToUInt16(setup, 4); WatchTree = (ByteReader.ReadByte(setup, 6) != 0); Reserved = ByteReader.ReadByte(setup, 7); }
public ChangeNotifyRequest(byte[] buffer, int offset) : base(buffer, offset) { StructureSize = LittleEndianConverter.ToUInt16(buffer, offset + SMB2Header.Length + 0); Flags = (ChangeNotifyFlags)LittleEndianConverter.ToUInt16(buffer, offset + SMB2Header.Length + 2); OutputBufferLength = LittleEndianConverter.ToUInt32(buffer, offset + SMB2Header.Length + 4); FileId = new FileID(buffer, offset + SMB2Header.Length + 8); CompletionFilter = (NotifyChangeFilter)LittleEndianConverter.ToUInt32(buffer, offset + SMB2Header.Length + 24); Reserved = LittleEndianConverter.ToUInt32(buffer, offset + SMB2Header.Length + 28); }
public NTStatus NotifyChange(out object ioRequest, object handle, NotifyChangeFilter completionFilter, bool watchTree, int outputBufferSize, OnNotifyChangeCompleted onNotifyChangeCompleted, object context) { byte[] buffer = new byte[outputBufferSize]; ManualResetEvent requestAddedEvent = new ManualResetEvent(false); PendingRequest request = new PendingRequest(); Thread m_thread = new Thread(delegate() { request.FileHandle = (IntPtr)handle; request.ThreadID = ThreadingHelper.GetCurrentThreadId(); m_pendingRequests.Add(request); // The request has been added, we can now return STATUS_PENDING. requestAddedEvent.Set(); // There is a possibility of race condition if the caller will wait for STATUS_PENDING and then immediate call Cancel, but this scenario is very unlikely. NTStatus status = NtNotifyChangeDirectoryFile((IntPtr)handle, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, out request.IOStatusBlock, buffer, (uint)buffer.Length, completionFilter, watchTree); if (status == NTStatus.STATUS_SUCCESS) { int length = (int)request.IOStatusBlock.Information; buffer = ByteReader.ReadBytes(buffer, 0, length); } else { const NTStatus STATUS_ALERTED = (NTStatus)0x00000101; const NTStatus STATUS_OBJECT_TYPE_MISMATCH = (NTStatus)0xC0000024; buffer = new byte[0]; if (status == STATUS_OBJECT_TYPE_MISMATCH) { status = NTStatus.STATUS_INVALID_HANDLE; } else if (status == STATUS_ALERTED) { status = NTStatus.STATUS_CANCELLED; } // If the handle is closing and we had to cancel a ChangeNotify request as part of a cleanup, // we return STATUS_NOTIFY_CLEANUP as specified in [MS-FSA] 2.1.5.4. if (status == NTStatus.STATUS_CANCELLED && request.Cleanup) { status = NTStatus.STATUS_NOTIFY_CLEANUP; } } onNotifyChangeCompleted(status, buffer, context); m_pendingRequests.Remove((IntPtr)handle, request.ThreadID); }); m_thread.Start(); // We must wait for the request to be added in order for Cancel to function properly. requestAddedEvent.WaitOne(); ioRequest = request; return(NTStatus.STATUS_PENDING); }
private static extern NTStatus NtNotifyChangeDirectoryFile(IntPtr handle, IntPtr evt, IntPtr apcRoutine, IntPtr apcContext, out IO_STATUS_BLOCK ioStatusBlock, byte[] buffer, uint bufferSize, NotifyChangeFilter completionFilter, bool watchTree);
public void NotifyChange(out object ioRequest, NtHandle handle, NotifyChangeFilter completionFilter, bool watchTree, int outputBufferSize, OnNotifyChangeCompleted onNotifyChangeCompleted, object context) { throw new NotImplementedException(); }
public NTStatus NotifyChange(out object ioRequest, object handle, NotifyChangeFilter completionFilter, bool watchTree, int outputBufferSize, OnNotifyChangeCompleted onNotifyChangeCompleted, object context) { ioRequest = null; return(NTStatus.STATUS_NOT_SUPPORTED); }