private void AuditObjectRequestHandle(ref Rec rec, AuditLogonEnv env, string logonId, string username, string userSid, string handleId, string processId, string processName, string objectName, string accessMask, ref int sentItems)
        {
            var access = (uint)GetPid(accessMask);

            AuditHandle handle;
            if (!env.Handles.TryGetValue(handleId, out handle))
            {
                handle = new AuditHandle()
                    {
                        Handle = handleId,
                        Object = new AuditObject()
                    };
                env.Handles[handleId] = handle;
            }

            if (!string.IsNullOrEmpty(objectName))
            {
                var kernel = RegKernelPath.Match(objectName);
                if (kernel.Success)
                    objectName = QueryDosPath(kernel.Groups[1].Value, kernel.Groups[2].Value);
            }
            handle.Object.LogonId = logonId;
            handle.Object.Name = objectName;
            handle.Object.Owner = user;
            handle.Object.OwnerSid = userSid;
            handle.OwnerProcess[processId] = processName;
            handle.Object.Handles[handleId] = handle;
            handle.AccessType = (AccessMask)access;
            try
            {
                AuditHandle lastHandle;
                if (env.ProcessLastAudit.TryGetValue(processId, out lastHandle))
                {
                    if (lastHandle.Object.Name == handle.Object.Name)
                    {
                        lastHandle.AccessType |= handle.AccessType;
                        env.Handles.Remove(handle.Handle);
                        handle = lastHandle;
                        return;
                    }
                    if ((lastHandle.AccessType & AccessMask.Delete) == AccessMask.Delete
                        && (handle.AccessType & (AccessMask.WriteOrAddFile | AccessMask.AppendOrAddSubDir)) != AccessMask.None)
                    {
                        string customStr2;
                        if ((handle.AccessType & AccessMask.WriteOrAddFile) == AccessMask.WriteOrAddFile)
                            customStr2 = "File";
                        else
                            customStr2 = "Directory";
                        env.Handles.Remove(lastHandle.Handle);
                        int pid = GetPid(processId);
                        var prevName = lastHandle.Object.Name;
                        var op = "MOVE";
                        if (prevName != null)
                        {
                            var currName = handle.Object.Name;
                            if (currName != null)
                            {
                                if (!currName.EndsWith("\\"))
                                    currName += "\\";
                                if (currName.Length < prevName.Length &&
                                    prevName.StartsWith(currName) &&
                                    prevName.IndexOf('\\', currName.Length) < 0)
                                    op = "RENAME";
                            }
                        }
                        SendData(ref rec, op, customStr2, lastHandle.Object.Name, userSid, username, processName,
                                 pid, accessMask, objectName);
                        sentItems++;
                    }
                }
                else if ((handle.AccessType & AccessMask.WriteDac) == AccessMask.WriteDac)
                {
                    int pid = GetPid(processId);
                    if ((handle.AccessType & FileMask) == FileMask)
                    {
                        SendData(ref rec, "NEW", "File", handle.Object.Name, userSid, user, processName, pid, accessMask,
                                 string.Empty);
                        sentItems++;
                    }
                    else if ((handle.AccessType & DirectoryMask) == DirectoryMask)
                    {
                        SendData(ref rec, "NEW", "Directory", handle.Object.Name, userSid, user, processName, pid,
                                 accessMask, string.Empty);
                        sentItems++;
                    }
                }
            }
            finally
            {
                env.ProcessLastAudit[processId] = handle;
            }
        }
        private void AuditDuplicateHandle(ref Rec rec, AuditLogonEnv env, string logonId, string user, string userSid, string sourceHandleId, string sourceProcessId, string targetHandleId, string targetProcessId, ref int sentItems)
        {
            try
            {
                long pid = GetPid(targetProcessId);
                if (pid == 4)
                    targetProcessId = sourceProcessId;

                AuditCloseHandle(ref rec, env, user, userSid, targetHandleId, targetProcessId, string.Empty, ref sentItems, false);

                AuditHandle handle;
                if (!env.Handles.TryGetValue(sourceHandleId, out handle))
                {
                    handle = new AuditHandle()
                        {
                            Handle = sourceHandleId,
                            Object = new AuditObject() { LogonId = logonId, Owner = user, OwnerSid = userSid }
                        };
                    env.Handles[sourceHandleId] = handle;
                }
                env.Handles[targetHandleId] = handle;
                handle.Object.Handles[sourceHandleId] = handle;
                handle.Object.Handles[targetHandleId] = handle;
                handle.OwnerProcess[sourceProcessId] = sourceProcessId;
                if (targetProcessId != sourceProcessId)
                    handle.OwnerProcess[targetProcessId] = targetProcessId;
            }
            finally
            {
                env.ProcessLastAudit.Remove(sourceProcessId);
            }
        }