/// <summary>
        /// Un-registers the specified callback for the <see cref="WimHandle" />.
        /// </summary>
        /// <param name="wimHandle">A <see cref="WimHandle" /> of a windows image file.</param>
        /// <param name="messageCallback">The <see cref="WimMessageCallback" /> method to un-register.</param>
        /// <returns><c>true</c> if the callback was successfully un-registered, otherwise <c>false</c>.</returns>
        /// <exception cref="ArgumentNullException">wimHandle or messageCallback is null.</exception>
        public bool UnregisterCallback(WimHandle wimHandle, WimMessageCallback messageCallback)
        {
            // See if wimHandle is null
            if (wimHandle == null)
            {
                throw new ArgumentNullException(nameof(wimHandle));
            }

            // See if messageCallback is null
            if (messageCallback == null)
            {
                throw new ArgumentNullException(nameof(messageCallback));
            }

            // See if the callback isn't registered
            if (!IsCallbackRegistered(wimHandle, messageCallback))
            {
                return(false);
            }

            // Remove the callback from the list
            _registeredCallbacksByHandle[wimHandle].Remove(messageCallback);

            // See if the dictionary for the wimHandle is now empty
            if (_registeredCallbacksByHandle[wimHandle].Count == 0)
            {
                // Remove the wimHandle dictionary item
                _registeredCallbacksByHandle.Remove(wimHandle);
            }

            return(true);
        }
예제 #2
0
        public void ApplyImageTest_Abort()
        {
            using (var wimHandle = WimgApi.CreateFile(TestWimPath, WimFileAccess.Read, WimCreationDisposition.OpenExisting, WimCreateFileOptions.None, WimCompressionType.None))
            {
                WimgApi.SetTemporaryPath(wimHandle, TempPath);

                WimMessageCallback messageCallback = (messageType, message, userData) => messageType == WimMessageType.Process ? WimMessageResult.Abort : WimMessageResult.Done;

                WimgApi.RegisterMessageCallback(wimHandle, messageCallback);

                try
                {
                    using (var imageHandle = WimgApi.LoadImage(wimHandle, 1))
                    {
                        var imageHandleCopy = imageHandle;

                        Should.Throw <OperationCanceledException>(() =>
                                                                  WimgApi.ApplyImage(imageHandleCopy, ApplyPath, WimApplyImageOptions.NoApply));
                    }
                }
                finally
                {
                    WimgApi.UnregisterMessageCallback(wimHandle, messageCallback);
                }
            }
        }
        /// <summary>
        /// Registers a callback for the specified <see cref="WimHandle" />.
        /// </summary>
        /// <param name="wimHandle">A <see cref="WimHandle" /> of a windows image file.</param>
        /// <param name="messageCallback">The <see cref="WimMessageCallback" /> method to register.</param>
        /// <param name="userData">User-defined data to pass to the callback.</param>
        /// <returns><c>true</c> if the callback was successfully registered, otherwise <c>false</c>.</returns>
        /// <exception cref="ArgumentNullException">wimHandle or messageCallback is null.</exception>
        public bool RegisterCallback(WimHandle wimHandle, WimMessageCallback messageCallback, object userData)
        {
            // See if wimHandle is null
            if (wimHandle == null)
            {
                throw new ArgumentNullException(nameof(wimHandle));
            }

            // See if messageCallback is null
            if (messageCallback == null)
            {
                throw new ArgumentNullException(nameof(messageCallback));
            }

            // See if the callback is already registered
            if (IsCallbackRegistered(wimHandle, messageCallback))
            {
                return(false);
            }

            // See if the dictionary doesn't contain the wimHandle
            if (!_registeredCallbacksByHandle.ContainsKey(wimHandle))
            {
                // Add an item for the wimHandle to the dictionary
                _registeredCallbacksByHandle.Add(wimHandle, new Dictionary <WimMessageCallback, WimMessageCallbackWrapper>());
            }

            // Create a callback wrapper and add the callback to the list
            _registeredCallbacksByHandle[wimHandle].Add(messageCallback, new WimMessageCallbackWrapper(messageCallback, userData));

            return(true);
        }
예제 #4
0
        /// <summary>
        /// Initializes a new instance of the <see cref="WimMessageCallbackWrapper"/> class.
        /// Initializes a new instance of the WimMessageCallbackWrapper class
        /// </summary>
        /// <param name="callback">
        /// A <see cref="WimMessageCallback" /> delegate to call when a message is received from the
        /// Windows® Imaging API.
        /// </param>
        /// <param name="userData">An object containing data to be used by the method.</param>
        public WimMessageCallbackWrapper(WimMessageCallback callback, object userData)
        {
            // Store the values
            _callback = callback;
            _userData = userData;

            // Store a reference to the native callback to avoid garbage collection
            NativeCallback = WimMessageCallback;
        }
        /// <summary>
        /// Gets a native callback for passing to the WIMGAPI for the specified globally registered callback.
        /// </summary>
        /// <param name="messageCallback">The <see cref="WimMessageCallback" /> method that was registered.</param>
        /// <returns>A <see cref="WimgApi.WIMMessageCallback" /> method that can be passed to the native WIMGAPI.</returns>
        /// ///
        /// <exception cref="InvalidOperationException">The specified callback is not registered.</exception>
        public WimgApi.WIMMessageCallback GetNativeCallback(WimMessageCallback messageCallback)
        {
            // Verify the callback is registered
            if (!IsCallbackRegistered(messageCallback))
            {
                throw new InvalidOperationException("Specified callback is not registered.");
            }

            // Return the native callback
            return(_registeredCallbacksGlobal[messageCallback].NativeCallback);
        }
        /// <summary>
        /// Gets a native callback for passing to the WIMGAPI for the specified registered callback associated with the
        /// <see cref="WimHandle" />.
        /// </summary>
        /// <param name="wimHandle">A <see cref="WimHandle" /> of a windows image file.</param>
        /// <param name="messageCallback">The <see cref="WimMessageCallback" /> method that was registered.</param>
        /// <returns>A <see cref="WimgApi.WIMMessageCallback" /> method that can be passed to the native WIMGAPI.</returns>
        /// <exception cref="InvalidOperationException">
        /// The specified handle has no registered callbacks or the specified callback
        /// is not registered for the handle.
        /// </exception>
        public WimgApi.WIMMessageCallback GetNativeCallback(WimHandle wimHandle, WimMessageCallback messageCallback)
        {
            // Verify the callback is registered for the handle
            if (!IsCallbackRegistered(wimHandle, messageCallback))
            {
                throw new InvalidOperationException("Specified callback is not registered.");
            }

            // Return the native callback
            return(_registeredCallbacksByHandle[wimHandle][messageCallback].NativeCallback);
        }
        /// <summary>
        /// Registers a callback globally.
        /// </summary>
        /// <param name="messageCallback">The <see cref="WimMessageCallback" /> method to register.</param>
        /// <param name="userData">User-defined data to pass to the callback.</param>
        /// <returns><c>true</c> if the callback was successfully registered, otherwise <c>false</c>.</returns>
        /// <exception cref="ArgumentNullException">messageCallback is null.</exception>
        public bool RegisterCallback(WimMessageCallback messageCallback, object userData)
        {
            // See if messageCallback is null
            if (messageCallback == null)
            {
                throw new ArgumentNullException(nameof(messageCallback));
            }

            // See if the callback is already registered
            if (IsCallbackRegistered(messageCallback))
            {
                return(false);
            }

            // Create a callback wrapper and add the callback to the list
            _registeredCallbacksGlobal.Add(messageCallback, new WimMessageCallbackWrapper(messageCallback, userData));

            return(true);
        }
        /// <summary>
        /// Un-registers the specified callback.
        /// </summary>
        /// <param name="messageCallback">The <see cref="WimMessageCallback" /> method to un-register.</param>
        /// <returns><c>true</c> if the callback was successfully un-registered, otherwise <c>false</c>.</returns>
        /// <exception cref="ArgumentNullException">messageCallback is null.</exception>
        public bool UnregisterCallback(WimMessageCallback messageCallback)
        {
            // See if messageCallback is null
            if (messageCallback == null)
            {
                throw new ArgumentNullException(nameof(messageCallback));
            }

            // See if the callback isn't registered
            if (!IsCallbackRegistered(messageCallback))
            {
                return(false);
            }

            // Remove the callback from the list
            _registeredCallbacksGlobal.Remove(messageCallback);

            return(true);
        }
예제 #9
0
        public void ApplyImageTest_NoApply()
        {
            WimMessageCallback messageCallback = (messageType, message, userData) =>
            {
                if (messageType == WimMessageType.SetRange)
                {
                    _noApplyFileCount = ((WimMessageSetRange)message).FileCount;
                }

                return(WimMessageResult.Done);
            };

            var applyPath = Path.Combine(TestContext.CurrentContext.WorkDirectory, "Apply");

            using (var wimHandle = WimgApi.CreateFile(TestWimPath, WimFileAccess.Read, WimCreationDisposition.OpenExisting, WimCreateFileOptions.None, WimCompressionType.None))
            {
                WimgApi.SetTemporaryPath(wimHandle, TempPath);

                WimgApi.RegisterMessageCallback(wimHandle, messageCallback);

                try
                {
                    using (var imageHandle = WimgApi.LoadImage(wimHandle, 1))
                    {
                        WimgApi.ApplyImage(imageHandle, applyPath, WimApplyImageOptions.NoApply);
                    }
                }
                finally
                {
                    WimgApi.UnregisterMessageCallback(wimHandle, messageCallback);
                }
            }

            var fileCount = Directory.EnumerateFiles(ApplyPath).Count();

            fileCount.ShouldBe(0);

            _noApplyFileCount.ShouldBe(TestWimFileCount);
        }
예제 #10
0
        private IEnumerable <string> GetImageFiles(WimHandle imageHandle)
        {
            var files = new List <String>();

            WimMessageCallback messageCallback = delegate(WimMessageType messageType, object message, object userData)
            {
                if (messageType == WimMessageType.FileInfo)
                {
                    var messageFileInfo = (WimMessageFileInfo)message;

                    if ((messageFileInfo.FileInfo.Attributes | FileAttributes.Directory) != FileAttributes.Directory)
                    {
                        ((List <String>)userData).Add(messageFileInfo.Path.Replace(ApplyPath, ""));
                    }
                }

                return(WimMessageResult.Done);
            };

            WimgApi.RegisterMessageCallback(TestWimHandle, messageCallback, files);

            try
            {
                WimgApi.ApplyImage(imageHandle, ApplyPath, WimApplyImageOptions.NoApply | WimApplyImageOptions.FileInfo);
            }
            catch (Win32Exception win32Exception)
            {
                if (win32Exception.NativeErrorCode != 1235)
                {
                    throw;
                }
            }
            finally
            {
                WimgApi.UnregisterMessageCallback(TestWimHandle, messageCallback);
            }

            return(files);
        }
        /// <summary>
        /// Unregisters a method from being called with imaging-specific data for only the specified WIM file.
        /// </summary>
        /// <param name="wimHandle">A <see cref="WimHandle"/> of a .wim file returned by <see cref="CreateFile"/>.</param>
        /// <param name="messageCallback">An application-defined callback method.</param>
        /// <exception cref="ArgumentOutOfRangeException">messageCallback is not registered.</exception>
        /// <exception cref="Win32Exception">The Windows® Imaging API reported a failure.</exception>
        public static void UnregisterMessageCallback(WimHandle wimHandle, WimMessageCallback messageCallback)
        {
            // See if wimHandle is null
            if (wimHandle == null)
            {
                throw new ArgumentNullException(nameof(wimHandle));
            }

            // Establish a lock
            lock (WimgApi.LockObject)
            {
                // See if wimHandle was not specified but the message callback was
                if (wimHandle == WimHandle.Null && messageCallback != null)
                {
                    // See if the message callback is registered
                    if (!WimgApi.RegisteredCallbacks.IsCallbackRegistered(messageCallback))
                    {
                        // Throw an ArgumentOutOfRangeException
                        throw new ArgumentOutOfRangeException(nameof(messageCallback), "Message callback is not registered.");
                    }
                }

                // See if the wimHandle and callback were specified
                if (wimHandle != WimHandle.Null && messageCallback != null)
                {
                    // See if the callback is registered
                    if (!WimgApi.RegisteredCallbacks.IsCallbackRegistered(wimHandle, messageCallback))
                    {
                        // Throw an ArgumentOutOfRangeException
                        throw new ArgumentOutOfRangeException(nameof(messageCallback), "Message callback is not registered under this handle.");
                    }
                }

                // See if the message callback is null, meaning the user wants to unregister all callbacks
                bool success = messageCallback == null
                    ? WimgApi.NativeMethods.WIMUnregisterMessageCallback(
                    wimHandle,
                    fpMessageProc : null)
                    : WimgApi.NativeMethods.WIMUnregisterMessageCallback(
                    wimHandle,
                    wimHandle == WimHandle.Null
                            ? WimgApi.RegisteredCallbacks.GetNativeCallback(messageCallback)
                            : WimgApi.RegisteredCallbacks.GetNativeCallback(wimHandle, messageCallback));

                // See if the native call succeeded
                if (!success)
                {
                    // Throw a Win32Exception based on the last error code
                    throw new Win32Exception();
                }

                // See if a single globally registered callback should be removed
                if (wimHandle == WimHandle.Null && messageCallback != null)
                {
                    // Unregister the globally registered callback
                    WimgApi.RegisteredCallbacks.UnregisterCallback(messageCallback);
                }

                // See if a single registered callback by handle should be removed
                if (wimHandle != WimHandle.Null && messageCallback != null)
                {
                    // Unregister the callback for the handle
                    WimgApi.RegisteredCallbacks.UnregisterCallback(wimHandle, messageCallback);
                }

                // See if all registered callbacks for this handle should be removed
                if (wimHandle != WimHandle.Null && messageCallback == null)
                {
                    // Unregister all callbacks for this handle
                    WimgApi.RegisteredCallbacks.UnregisterCallbacks(wimHandle);
                }

                // See if all registered callbacks by handle and all globally registered callbacks should be removed
                if (wimHandle == WimHandle.Null && messageCallback == null)
                {
                    // Unregister all callbacks
                    WimgApi.RegisteredCallbacks.UnregisterCallbacks();
                }
            } // Release lock
        }
 /// <summary>
 /// Unregisters a method from being called with imaging-specific data for all image handles.
 /// </summary>
 /// <param name="messageCallback">An application-defined callback method.</param>
 /// <exception cref="ArgumentOutOfRangeException">messageCallback is not registered.</exception>
 /// <exception cref="Win32Exception">The Windows® Imaging API reported a failure.</exception>
 public static void UnregisterMessageCallback(WimMessageCallback messageCallback)
 {
     UnregisterMessageCallback(WimHandle.Null, messageCallback);
 }
예제 #13
0
        /// <summary>
        /// Registers a function to be called with imaging-specific data for only the specified WIM file.
        /// </summary>
        /// <param name="wimHandle">An optional <see cref="WimHandle"/> of a .wim file returned by <see cref="CreateFile"/>.</param>
        /// <param name="messageCallback">An application-defined callback method.</param>
        /// <param name="userData">A pointer that specifies an application-defined value to be passed to the callback function.</param>
        /// <returns>-1 if the callback is already registered, otherwise the zero-based index of the callback.</returns>
        /// <exception cref="ArgumentNullException">messageCallback is null.</exception>
        /// <exception cref="Win32Exception">The Windows® Imaging API reported a failure.</exception>
        public static int RegisterMessageCallback(WimHandle wimHandle, WimMessageCallback messageCallback, object userData)
        {
            // See if wimHandle is null
            if (wimHandle == null)
            {
                throw new ArgumentNullException(nameof(wimHandle));
            }

            // See if messageCallback is null
            if (messageCallback == null)
            {
                // Throw an ArgumentNullException
                throw new ArgumentNullException(nameof(messageCallback));
            }

            // Establish a lock
            lock (WimgApi.LockObject)
            {
                // See if the user wants to register the handler in the global space for all WIMs
                if (wimHandle == WimHandle.Null)
                {
                    // See if the callback is already registered
                    if (WimgApi.RegisteredCallbacks.IsCallbackRegistered(messageCallback))
                    {
                        // Just exit, the callback is already registered
                        return(-1);
                    }

                    // Add the callback to the globally registered callbacks
                    if (!WimgApi.RegisteredCallbacks.RegisterCallback(messageCallback, userData))
                    {
                        return(-1);
                    }
                }
                else
                {
                    // See if the message callback is already registered
                    if (WimgApi.RegisteredCallbacks.IsCallbackRegistered(wimHandle, messageCallback))
                    {
                        // Just exit, the callback is already registered
                        return(-1);
                    }

                    // Add the callback to the registered callbacks by handle
                    WimgApi.RegisteredCallbacks.RegisterCallback(wimHandle, messageCallback, userData);
                }

                // Call the native function
                DWORD hr = WimgApi.NativeMethods.WIMRegisterMessageCallback(wimHandle, wimHandle == WimHandle.Null ? WimgApi.RegisteredCallbacks.GetNativeCallback(messageCallback) : WimgApi.RegisteredCallbacks.GetNativeCallback(wimHandle, messageCallback), IntPtr.Zero);

                // See if the function returned INVALID_CALLBACK_VALUE
                if (hr == WimgApi.INVALID_CALLBACK_VALUE)
                {
                    // Throw a Win32Exception based on the last error code
                    throw new Win32Exception();
                }

                // Return the zero-based index of the callback
                return((int)hr);
            }
        }
예제 #14
0
 /// <summary>
 /// Registers a function to be called with imaging-specific data for only the specified WIM file.
 /// </summary>
 /// <param name="wimHandle">An optional <see cref="WimHandle"/> of a .wim file returned by <see cref="CreateFile"/>.</param>
 /// <param name="messageCallback">An application-defined callback function.</param>
 /// <returns>The zero-based index of the callback.</returns>
 /// <exception cref="ArgumentNullException">messageCallback is null.</exception>
 /// <exception cref="Win32Exception">The Windows® Imaging API reported a failure.</exception>
 public static int RegisterMessageCallback(WimHandle wimHandle, WimMessageCallback messageCallback)
 {
     // Call an overload
     return(WimgApi.RegisterMessageCallback(wimHandle, messageCallback, null));
 }
예제 #15
0
 /// <summary>
 /// Registers a function to be called with imaging-specific data for all image handles.
 /// </summary>
 /// <param name="messageCallback">An application-defined callback function.</param>
 /// <returns>The zero-based index of the callback.</returns>
 /// <exception cref="ArgumentNullException">messageCallback is null.</exception>
 /// <exception cref="Win32Exception">The Windows® Imaging API reported a failure.</exception>
 public static int RegisterMessageCallback(WimMessageCallback messageCallback)
 {
     // Call an overload
     return(RegisterMessageCallback(messageCallback, null));
 }
예제 #16
0
 /// <summary>
 ///     Gets a value indicating if the specified callback is registered for the handle.
 /// </summary>
 /// <param name="wimHandle">A <see cref="WimHandle" /> of a windows image file.</param>
 /// <param name="messageCallback">The <see cref="WimMessageCallback" /> method that was registered.</param>
 /// <returns><c>true</c> if the callback is registered, otherwise <c>false</c>.</returns>
 public bool IsCallbackRegistered(WimHandle wimHandle, WimMessageCallback messageCallback)
 {
     return(_registeredCallbacksByHandle.ContainsKey(wimHandle) &&
            _registeredCallbacksByHandle[wimHandle].ContainsKey(messageCallback));
 }
예제 #17
0
 /// <summary>
 ///     Gets a value indicating if the specified callback is globally registered.
 /// </summary>
 /// <param name="messageCallback">The <see cref="WimMessageCallback" /> method that was registered.</param>
 /// <returns><c>true</c> if the callback is registered, otherwise <c>false</c>.</returns>
 public bool IsCallbackRegistered(WimMessageCallback messageCallback)
 {
     return(_registeredCallbacksGlobal.ContainsKey(messageCallback));
 }
예제 #18
0
 /// <summary>
 /// Registers a function to be called with imaging-specific data for all image handles.
 /// </summary>
 /// <param name="messageCallback">An application-defined callback method.</param>
 /// <param name="userData">A pointer that specifies an application-defined value to be passed to the callback function.</param>
 /// <returns>-1 if the callback is already registered, otherwise the zero-based index of the callback.</returns>
 /// <exception cref="ArgumentNullException">messageCallback is null.</exception>
 /// <exception cref="Win32Exception">The Windows® Imaging API reported a failure.</exception>
 public static int RegisterMessageCallback(WimMessageCallback messageCallback, object userData)
 {
     // Call an overload
     return(RegisterMessageCallback(WimHandle.Null, messageCallback, userData));
 }