Example #1
0
        // NOTE: this function throws a COMException if the object was not found
        public static object?GetActiveObject(string progId)
        {
            if (progId is null)
            {
                throw new ArgumentNullException(nameof(progId));
            }

            // get the CLSID for the supplied ProgId
            var getClsidResult = ExtendedPInvoke.CLSIDFromProgIDEx(progId, out var clsid);

            if (getClsidResult != (uint)ExtendedPInvoke.S_OK)
            {
                switch (getClsidResult)
                {
                case (uint)ExtendedPInvoke.Win32ErrorCode.CO_E_CLASSSTRING:
                    throw new COMException("Invalid class string");

                case (uint)ExtendedPInvoke.Win32ErrorCode.REGDB_E_WRITEREGDB:
                    throw new COMException("Could not write key to registry");
                }
            }

            var getActiveObjectResult = ExtendedPInvoke.GetActiveObject(ref clsid, IntPtr.Zero, out var activeObject);

            if (getActiveObjectResult != (uint)ExtendedPInvoke.S_OK)
            {
                // if we could not get the object, return null
                // NOTE: if we want to distinguish between error results (i.e. object not active vs. others), we could read the win32 "last error" code
                return(null);
            }

            return(activeObject);
        }
        //
        public static MorphicResult <string, GetPathToExecutableForFileError> GetAssociatedExecutableForFile(string path)
        {
            StringBuilder pathToExecutable = new StringBuilder(ExtendedPInvoke.MAX_PATH + 1);
            var           resultCode       = ExtendedPInvoke.FindExecutable(path, null, pathToExecutable);

            if (resultCode.ToInt64() > 32)
            {
                // success
                return(MorphicResult.OkResult(pathToExecutable.ToString()));
            }
            else
            {
                // failure
                switch (resultCode.ToInt64())
                {
                case (Int64)ExtendedPInvoke.ShellExecuteErrorCode.SE_ERR_FNF:
                    return(MorphicResult.ErrorResult(GetPathToExecutableForFileError.FileNotFound));

                case (Int64)ExtendedPInvoke.ShellExecuteErrorCode.SE_ERR_PNF:
                    return(MorphicResult.ErrorResult(GetPathToExecutableForFileError.PathIsInvalid));

                case (Int64)ExtendedPInvoke.ShellExecuteErrorCode.SE_ERR_ACCESSDENIED:
                    return(MorphicResult.ErrorResult(GetPathToExecutableForFileError.AccessDenied));

                case (Int64)ExtendedPInvoke.ShellExecuteErrorCode.SE_ERR_OOM:
                    return(MorphicResult.ErrorResult(GetPathToExecutableForFileError.OutOfMemoryOrResources));

                case (Int64)ExtendedPInvoke.ShellExecuteErrorCode.SE_ERR_NOASSOC:
                    return(MorphicResult.ErrorResult(GetPathToExecutableForFileError.NoAssociatedExecutable));

                default:
                    return(MorphicResult.ErrorResult(GetPathToExecutableForFileError.UnknownShellExecuteErrorCode));
                }
            }
        }
Example #3
0
        /* helper functions */

        // some more details: https://blog.quarkslab.com/playing-with-the-windows-notification-facility-wnf.html
        private static MorphicResult <byte[], MorphicUnit> QueryWnfStateData(ExtendedPInvoke.WNF_STATE_NAME stateName)
        {
            const uint MAX_BUFFER_LENGTH = 4096;
            uint       bufferSize        = MAX_BUFFER_LENGTH;

            var pointerToBuffer = Marshal.AllocHGlobal((int)bufferSize);

            try
            {
                uint changeStamp;
                var  queryWnfStateDataResult = ExtendedPInvoke.NtQueryWnfStateData(ref stateName, IntPtr.Zero, IntPtr.Zero, out changeStamp, pointerToBuffer, ref bufferSize);
                if (queryWnfStateDataResult != 0)
                {
                    return(MorphicResult.ErrorResult());
                }

                var bufferSizeAsInt = (int)bufferSize;

                var result = new byte[bufferSizeAsInt];
                Marshal.Copy(pointerToBuffer, result, 0, bufferSizeAsInt);

                return(MorphicResult.OkResult(result));
            }
            finally
            {
                Marshal.FreeHGlobal(pointerToBuffer);
            }
        }
        protected virtual void Dispose(bool disposing)
        {
            if (!_isDisposed)
            {
                if (disposing)
                {
                    // dispose any managed objects here
                }

                // free unmanaged resources

                // NOTE: this function will return false if it fails
                // NOTE: in theory the system should clean up after this hook handle automatically (so we could probably comment out the following two lines of code)
                _ = ExtendedPInvoke.UnhookWindowsHookEx(_hookHandle.DangerousGetHandle());
                _hookHandle.SetHandleAsInvalid();

                // set any large fields to null

                _isDisposed = true;
            }
        }
Example #5
0
        private static MorphicResult <MorphicUnit, MorphicUnit> UpdateWnfStateData(ExtendedPInvoke.WNF_STATE_NAME stateName, byte[] buffer)
        {
            var bufferLength = buffer.Length;

            var pointerToBuffer = Marshal.AllocHGlobal(bufferLength);

            try
            {
                Marshal.Copy(buffer, 0, pointerToBuffer, bufferLength);

                var updateWnfStateDataResult = ExtendedPInvoke.NtUpdateWnfStateData(ref stateName, pointerToBuffer, (uint)bufferLength, IntPtr.Zero /* null */, IntPtr.Zero, 0, 0);
                if (updateWnfStateDataResult != 0)
                {
                    return(MorphicResult.ErrorResult());
                }
            }
            finally
            {
                Marshal.FreeHGlobal(pointerToBuffer);
            }

            return(MorphicResult.OkResult());
        }