#include-once

#include <WinAPI.au3>
#include <DismConstants1.2.au3> ; ändern
#include <Constants.au3>
#include <Array.au3>
#include <Date.au3>

; #INDEX# =======================================================================================================================
; Title .........: Dismapi v1 (1/03/2013)
; AutoIt Version : 3.3.8.1
; Description ...: Functions for creating and manipulating WIM images.
; Author(s) .....: André Cut
; Dll ...........: dismapi.dll
; ===============================================================================================================================

; #VARIABLES# ===================================================================================================================
Global $ghdismapi = "C:\Program Files (x86)\Windows Kits\8.0\Assessment and Deployment Kit\Deployment Tools\x86\DISM\dismapi.dll"
; ===============================================================================================================================

; #CONSTANTS# ===================================================================================================================
Global Const $DISM_ERROR_TYPE = 0 ; 0 = Return Error Message Text, 1 = Return Error Code
; ===============================================================================================================================


; #CURRENT# =====================================================================================================================
; 	_DISM_AddDriver
; 	_DISM_AddPackage
; 	_DISM_ApplyUnattend
;~ ; 	_DISM_CheckImageHealth ; requires Windows 8
; 	_DISM_CleanupMountpoints
; 	_DISM_CloseSession
; 	_DISM_CommitImage
; 	_DISM_Delete
; 	_DISM_DisableFeature
; 	_DISM_EnableFeature
; 	_DISM_GetDriverInfo
; 	_DISM_GetDrivers
; 	_DISM_GetFeatureInfo
; 	_DISM_GetFeatureParent
; 	_DISM_GetFeatures
; 	_DISM_GetImageInfo
; 	_DISM_GetLastErrorMessage
; 	_DISM_GetMountedImageInfo
; 	_DISM_GetPackageInfo
; 	_DISM_GetPackages
; 	_DISM_Initialize
; 	_DISM_MountImage
; 	_DISM_OpenSession
; 	_DISM_RemountImage
; 	_DISM_RemoveDriver
; 	_DISM_RemovePackage
;~ ; 	_DISM_RestoreImageHealth ; requires Windows 8
; 	_DISM_Shutdown
; 	_DISM_UnmountImage
; ===============================================================================================================================


; #CURRENT SUB# =================================================================================================================
; 	_DISM_GetErrorMesageText
; 	_DISM_GetFullyOfflineInstallableType
; 	_DISM_GetImageBootable
; 	_DISM_GetImageType
; 	_DISM_GetMountMode
; 	_DISM_GetMountStatus
; 	_DISM_GetPackageFeatureState
; 	_DISM_GetReleaseType
; 	_DISM_GetRestartType
; ===============================================================================================================================

; #FUNCTION# ====================================================================================================================
; Name...........: _DISM_AddDriver
; Description ...: Adds a third party driver (.inf) to an offline Windows® image.
; Syntax.........: _DISM_AddDriver($Session, $DriverPath, $ForceUnsigned = True)
; Parameters ....: $Session       - A valid DISM Session. The DISM Session must be associated with an image. You can associate a session with an image by using the DismOpenSession Function.
;				   $DriverPath 	  - A relative or absolute path to the driver .inf file.
;				   $ForceUnsigned - A Boolean value that specifies whether to accept unsigned drivers to an x64-based image. Unsigned drivers will automatically be added to an x86-based image.
; 				              		| True  - Add unsigned drivers to an x64-based image.
; 				              		| False - Do not add unsigned drivers to an x64-based image.
; Return values .: Success - Returns $S_OK.
;                  Failure - Returns _DISM_GetErrorMessageText() and Sets @Error:
;                  			 | 0 - No DLLCall error.
; 				   			 | 1 - Unable to use the DLL file
; 				   			 | 2 - Unknown "return type"
; 				   			 | 3 - "function" not found in the DLL file
;				   			 | 4 - Bad number of parameters.
;				   Both    - Sets @Extended to _WinAPI_GetLastError()
; Author(s) .....: André Cut
; Modified.......:
; Remarks .......: This function is only supported for offline images.
;
;				   Removing a boot-critical driver can make the offline Windows image unbootable.
; Related .......: _DISM_GetDriverInfo, _DISM_GetDrivers, _DISM_RemoveDriver
; Link ..........; http://msdn.microsoft.com/en-us/library/windows/desktop/hh824764.aspx
; Example .......; In this example, the driver being added is located on the technician computer in the folder C:\drivers\.
;				   The driver has the filename usb.inf on the technician computer, but is renamed to "OEM1.inf" or "OEM2.inf" in the target image.
;				   The numbering of the OEMx.inf files is dependent on the number of drivers added.
;				   The new name, for example OEM1.inf, is returned in the DismDriverPackage Structure when you call the DismGetDrivers Function.
;				   You should use the new name, OEM1.inf, to specify the DriverPath when you use the DismGetDriverInfo Function.
;
;				   HRESULT hr = S_OK;
;				   hr = DismAddDriver(Session, L"C:\\Drivers\\usb.inf", FALSE);
;
; ===============================================================================================================================
Func _DISM_AddDriver($Session, $DriverPath, $ForceUnsigned = True)

   Local $aResult = DllCall($ghdismapi, "LONG", "DismAddDriver", _
		 "PTR", $Session, _
		 "WSTR", $DriverPath, _
		 "BOOL", $ForceUnsigned _
		 )
   If @error Then Return SetError(@error, @extended, 0)
   Return SetExtended(_WinAPI_GetLastError(), _DISM_GetErrorMessageText($aResult[0]))
EndFunc   ;==>_DISM_AddDriver


; #FUNCTION# ====================================================================================================================
; Name...........: _DISM_AddPackage
; Description ...: Adds a single .cab or .msu file to a Windows® image.
; Syntax.........: _DISM_AddPackage($Session, $PackagePath, $IgnoreCheck = False, $PreventPending = False)
; Parameters ....: $Session 	   - A valid DISM Session. The DISM Session must be associated with an image. You can associate a session with an image by using the DismOpenSession Function.
;				   $PackagePath    - A relative or absolute path to the .cab or .msu file being added, a folder with one or more packages, or a folder containing the expanded files of a single .cab file.
;				   $IgnoreCheck    - A Boolean value to specify whether to ignore the internal applicability checks that are done when a package is added.
;									 | True  - Ignore the internal applicability checks.
;									 | False - Do not ignore the internal applicability checks.
;				   $PreventPending - A Boolean value to specify whether to add a package if it has pending online actions.
;									 | True  - Prevent the installation of a package that has pending online actions.
;									 | False - Allow the installation of a package that has pending online actions.
; Return values .: Success - Returns $DISMAPI_S_RELOAD_IMAGE_SESSION_REQUIRED (1).
;                  Failure - Returns _DISM_GetErrorMessageText() and Sets @Error:
;                  			 | 0 - No DLLCall error.
; 				   			 | 1 - Unable to use the DLL file
; 				   			 | 2 - Unknown "return type"
; 				   			 | 3 - "function" not found in the DLL file
;				   			 | 4 - Bad number of parameters.
;				   Both    - Sets @Extended to _WinAPI_GetLastError()
; Author(s) .....: André Cut
; Modified.......:
; Remarks .......: Only .cab files can be added to an online image. Either .cab or .msu files can be added to an offline image.
;			       This function will return a special error code if the package is not applicable. You can use the DismGetPackageInfo Function to determine if a package is applicable to the target image.
; Related .......: _DISM_AddDriver, _DISM_EnableFeature, _DISM_GetPackages, _DISM_GetPackageInfo, _DISM_RemovePackage
; Link ..........; http://msdn.microsoft.com/en-us/library/windows/desktop/hh824788.aspx
; Example .......; HRESULT hr = S_OK;
;				   hr = DismAddPackage(Session, "C:\\packages\\calc.cab", FALSE, FALSE, NULL, NULL, NULL);
;
; ===============================================================================================================================
Func _DISM_AddPackage($Session, $PackagePath, $IgnoreCheck = False, $PreventPending = False)

   Local $aResult = DllCall($ghdismapi, "LONG", "DismAddPackage", _
		 "PTR", $Session, _
		 "WSTR", $PackagePath, _
		 "BOOL", $IgnoreCheck, _
		 "BOOL", $PreventPending, _
		 "PTR", 0, _
		 "PTR", 0, _
		 "PTR", 0 _
		 )
   If @error Then Return SetError(@error, @extended, 0)
   Return SetExtended(_WinAPI_GetLastError(), _DISM_GetErrorMessageText($aResult[0]))
EndFunc   ;==>_DISM_RemovePackage


; #FUNCTION# ====================================================================================================================
; Name...........: _DISM_ApplyUnattend
; Description ...: Applies an unattended answer file to a Windows® image.
; Syntax.........: _DISM_ApplyUnattend($Session, $UnattendFile, $SingleSession = True)
; Parameters ....: $Session       - A valid DISM Session. The DISM Session must be associated with an image. You can associate a session with an image by using the DismOpenSession Function.
;				   $UnattendFile  - A relative or absolute path to the answer file that will be applied to the image.
;				   $SingleSession - A Boolean value that specifies whether the packages that are listed in an answer file will be processed in a single session or in multiple sessions.
; 				              		| True  - The unattended answer file will be processed in a single session.
; 				              		| False - All of the packages that are listed in the answer file will be processed in multiple sessions.
; Return values .: Success - Returns $S_OK.
;                  Failure - Returns _DISM_GetErrorMessageText() and Sets @Error:
;                  			 | 0 - No DLLCall error.
; 				   			 | 1 - Unable to use the DLL file
; 				   			 | 2 - Unknown "return type"
; 				   			 | 3 - "function" not found in the DLL file
;				   			 | 4 - Bad number of parameters.
;				   Both    - Sets @Extended to _WinAPI_GetLastError()
; Author(s) .....: André Cut
; Modified.......:
; Remarks .......: When you use DISM to apply an answer file to an image, the unattended settings in the offlineServicing configuration pass are applied to the Windows image. For more information, see Unattended Servicing Command-Line Options.
; Related .......: _DISM_AddDriver, _DISM_AddPackage, _DISM_EnableFeature
; Link ..........; http://msdn.microsoft.com/en-us/library/windows/desktop/hh825840.aspx
; Example .......; HRESULT hr = S_OK;
;				   hr = DismApplyUnattend(Session, "C:\test\unattend.xml", TRUE);
;
; ===============================================================================================================================
Func _DISM_ApplyUnattend($Session, $UnattendFile, $SingleSession = True)

   Local $aResult = DllCall($ghdismapi, "LONG", "DismApplyUnattend", _
		 "PTR", $Session, _
		 "WSTR", $UnattendFile, _
		 "BOOL", $SingleSession _
		 )
   If @error Then Return SetError(@error, @extended, 0)
   Return SetExtended(_WinAPI_GetLastError(), _DISM_GetErrorMessageText($aResult[0]))
EndFunc   ;==>_DISM_ApplyUnattend


; #FUNCTION# ====================================================================================================================
; Name...........: _DISM_CleanupMountpoints
; Description ...: Removes files and releases resources associated with corrupted or invalid mount paths.
; Syntax.........: _DISM_CleanupMountpoints()
; Parameters ....:
; Return values .: Success - Returns $S_OK.
;                  Failure - Returns _DISM_GetErrorMessageText() and Sets @Error:
;                  			 | 0 - No DLLCall error.
; 				   			 | 1 - Unable to use the DLL file
; 				   			 | 2 - Unknown "return type"
; 				   			 | 3 - "function" not found in the DLL file
;				   			 | 4 - Bad number of parameters.
;				   Both    - Sets @Extended to _WinAPI_GetLastError()
; Author(s) .....: André Cut
; Modified.......:
; Remarks .......:
; Related .......: _DISM_UnmountImage, _DISM_Delete
; Link ..........; http://msdn.microsoft.com/en-us/library/windows/desktop/hh824743.aspx
; Example .......; HRESULT hr = S_OK;
;				   hr = DismCleanupMountpoints();
;
; ===============================================================================================================================
Func _DISM_CleanupMountpoints()

   Local $aResult = DllCall($ghdismapi, "LONG", "DismCleanupMountpoints")
   If @error Then Return SetError(@error, @extended, 0)
   Return SetExtended(_WinAPI_GetLastError(), _DISM_GetErrorMessageText($aResult[0]))
EndFunc   ;==>_DISM_CleanupMountpoints


; #FUNCTION# ====================================================================================================================
; Name...........: _DISM_CloseSession
; Description ...: Closes a DISMSession created by DismOpenSession Function. This function does not unmount the image. To unmount the image, use the DismUnmountImage Function once all sessions are closed.
; Syntax.........: _DISM_CloseSession($Session)
; Parameters ....: $Session - A valid DISM Session. The DISM Session must be associated with an image. You can associate a session with an image by using the DismOpenSession Function.
; Return values .: Success - Returns $S_OK.
;                  Failure - Returns _DISM_GetErrorMessageText() and Sets @Error:
;							 Notice: If the DISMSession is performing operations on other threads, those operations will complete before the DISMSession is destroyed.
;						     If additional operations are invoked by other threads after DismCloseSession is called, but before DismCloseSession returns, those operations will fail and return a $DISMAPI_E_INVALID_DISM_SESSION error.
;							 The DISMSession handle will become invalid after completion of this call. Operations invoked on the DISMSession after completion of DismCloseSession will fail and return the error $S_FALSE.
;                  			 | 0 - No DLLCall error.
; 				   			 | 1 - Unable to use the DLL file
; 				   			 | 2 - Unknown "return type"
; 				   			 | 3 - "function" not found in the DLL file
;				   			 | 4 - Bad number of parameters.
;				   Both    - Sets @Extended to _WinAPI_GetLastError()
; Author(s) .....: André Cut
; Modified.......:
; Remarks .......: The DISMSession will be shut down after this call is completed but the image will not be unmounted. To unmount the image, use the DismUnmountImage Function once all sessions are closed.
; Related .......: _DISM_OpenSession
; Link ..........; http://msdn.microsoft.com/en-us/library/windows/desktop/hh825839.aspx
; Example .......; HRESULT hr = S_OK;
;				   DismSession session;
; 				   hr = DismOpenSession( DISM_ONLINE_IMAGE, NULL, NULL, &session );
;				   hr = DismCloseSession( session );
;
; ===============================================================================================================================
Func _DISM_CloseSession($Session)

   Local $aResult = DllCall($ghdismapi, "LONG", "DismCloseSession", _
		 "PTR", $Session _
		 )
   If @error Then Return SetError(@error, @extended, 0)
   Return SetExtended(_WinAPI_GetLastError(), _DISM_GetErrorMessageText($aResult[0]))
EndFunc   ;==>_DISM_CloseSession


; #FUNCTION# ====================================================================================================================
; Name...........: _DISM_CommitImage
; Description ...: Commits the changes made to a Windows® image in a mounted .wim or .vhd file. The image must be mounted using the DismMountImage Function.
; Syntax.........: _DISM_CommitImage($Session, $Flags = $DISM_COMMIT_IMAGE)
; Parameters ....: $Session - A valid DISM Session. The DISM Session must be associated with an image. You can associate a session with an image by using the DismOpenSession Function.
;				   $Flags   - The commit flags to use for this operation. For more information about mount flags, see DISM API Constants.
; 				              | $DISM_COMMIT_IMAGE              - Indicates to the DismCommitImage Function or the DismUnmountImage Function that changes to the image should be saved.
; 				              | $DISM_DISCARD_IMAGE             - Indicates to the DismCommitImage Function or the DismUnmountImage Function that changes to the image should not be saved.
; 				              | $DISM_COMMIT_GENERATE_INTEGRITY - Indicates to the DismCommitImage Function or the DismUnmountImage Function to set a flag on the image specifying whether the image is corrupted.
; 				              | $DISM_COMMIT_APPEND             - Indicates to the DismCommitImage Function or the DismUnmountImage Function that changes to the image should be saved.
; Return values .: Success - Returns $S_OK.
;                  Failure - Returns _DISM_GetErrorMessageText() and Sets @Error:
;                  			 | 0 - No DLLCall error.
; 				   			 | 1 - Unable to use the DLL file
; 				   			 | 2 - Unknown "return type"
; 				   			 | 3 - "function" not found in the DLL file
;				   			 | 4 - Bad number of parameters.
;				   Both    - Sets @Extended to _WinAPI_GetLastError()
; Author(s) .....: André Cut
; Modified.......:
; Remarks .......: The DismCommitImage function does not unmount the image.
;				   DismCommitImage can only be used on an image that is mounted within the DISM infrastructure.
;				   It does not apply to images mounted by another tool, such as the DiskPart tool, which are serviced using the DismOpenSession Function.
;				   You must use the DismMountImage Function to mount an image within the DISM infrastructure.
; Related .......: _DISM_MountImage, _DISM_UnmountImage
; Link ..........; http://msdn.microsoft.com/en-us/library/windows/desktop/hh825835.aspx
; Example .......; HRESULT hr = S_OK;
;				   hr = DismCommitImage(Session, 0, NULL, NULL, NULL);
;
; ===============================================================================================================================
Func _DISM_CommitImage($Session, $Flags = $DISM_COMMIT_IMAGE)

   Local $aResult = DllCall($ghdismapi, "LONG", "DismCommitImage", _
		 "PTR", $Session, _
		 "DWORD", $Flags, _
		 "PTR", 0, _
		 "PTR", 0, _
		 "PTR", 0 _
		 )
   If @error Then Return SetError(@error, @extended, 0)
   Return SetExtended(_WinAPI_GetLastError(), _DISM_GetErrorMessageText($aResult[0]))
EndFunc   ;==>_DISM_CommitImage


; #FUNCTION# ====================================================================================================================
; Name...........: _DISM_Delete
; Description ...: Releases resources held by a structure or an array of structures returned by other DISM API functions.
; Syntax.........: _DISM_Delete($DismStructure)
; Parameters ....: $DismStructure - A pointer to the structure, or array of structures, to be deleted. The structure must have been returned by an earlier call to a DISM API function.
; Return values .: Success - Returns $S_OK.
;                  Failure - Returns _DISM_GetErrorMessageText() and Sets @Error:
;                  			 | 0 - No DLLCall error.
; 				   			 | 1 - Unable to use the DLL file
; 				   			 | 2 - Unknown "return type"
; 				   			 | 3 - "function" not found in the DLL file
;				   			 | 4 - Bad number of parameters.
;				   Both    - Sets @Extended to _WinAPI_GetLastError()
; Author(s) .....: André Cut
; Modified.......:
; Remarks .......: All structures that are returned by DISM API functions are allocated on the heap. The client must not delete or free these structures directly.
;				   Instead, the client should call DismDelete and pass in the pointer that was returned by the earlier DISM API call.
; Related .......:
; Link ..........; http://msdn.microsoft.com/en-us/library/windows/desktop/hh824768.aspx
; Example .......; HRESULT hr = S_OK;
;				   hr = DismDelete(ImageInfo);
;
; ===============================================================================================================================
Func _DISM_Delete($DismStructure)

   Local $aResult = DllCall($ghdismapi, "LONG", "DismDelete", _
		 "PTR", $DismStructure _
		 )
   If @error Then Return SetError(@error, @extended, 0)
   Return SetExtended(_WinAPI_GetLastError(), _DISM_GetErrorMessageText($aResult[0]))
EndFunc   ;==>_DISM_GetFeatures


; #FUNCTION# ====================================================================================================================
; Name...........: _DISM_DisableFeature
; Description ...: Disables a feature in the current image.
; Syntax.........: _DISM_DisableFeature($Session, $FeatureName, $PackageName = 0, $RemovePayload = False)
; Parameters ....: $Session       - A valid DISM Session. The DISM Session must be associated with an image. You can associate a session with an image by using the DismOpenSession Function.
;				   $FeatureName   - The name of the feature that you want to disable. To disable more than one feature, separate each feature name with a semicolon.
;				   $PackageName   - [Optional]. The name of the parent package that the feature is a part of. This is an optional parameter. If no package is specified, then the default Windows® Foundation package is used.
;				   $RemovePayload - A Boolean value specifying whether to remove the files required to enable the feature.
;				   				    | True  - The files are removed.
;				   				    | False - The files are not removed.
; Return values .: Success - Returns $DISMAPI_S_RELOAD_IMAGE_SESSION_REQUIRED (1).
;                  Failure - Returns _DISM_GetErrorMessageText() and Sets @Error:
;                  			 | 0 - No DLLCall error.
; 				   			 | 1 - Unable to use the DLL file
; 				   			 | 2 - Unknown "return type"
; 				   			 | 3 - "function" not found in the DLL file
;				   			 | 4 - Bad number of parameters.
;				   Both    - Sets @Extended to _WinAPI_GetLastError()
; Author(s) .....: André Cut
; Modified.......:
; Remarks .......:
; Related .......: _DISM_EnableFeature, _DISM_GetFeatures, _DISM_GetFeatureInfo
; Link ..........; http://msdn.microsoft.com/en-us/library/windows/desktop/hh824766.aspx
; Example .......; HRESULT hr = S_OK;
;				   hr = DismDisableFeature(Session, "WindowsMediaPlayer", NULL, FALSE, NULL, NULL, NULL);
;
; ===============================================================================================================================
Func _DISM_DisableFeature($Session, $FeatureName, $PackageName = 0, $RemovePayload = False)

   ; control param passing
   Local $sType = "WSTR"
   If Not IsString($PackageName) And $PackageName = 0 Then $sType = "PTR"

   Local $aResult = DllCall($ghdismapi, "LONG", "DismDisableFeature", _
		 "PTR", $Session, _
		 "WSTR", $FeatureName, _
		 $sType, $PackageName, _
		 "BOOL", $RemovePayload, _
		 "PTR", 0, _
		 "PTR", 0, _
		 "PTR", 0 _
		 )
   If @error Then Return SetError(@error, @extended, 0)
   Return SetExtended(_WinAPI_GetLastError(), _DISM_GetErrorMessageText($aResult[0]))
EndFunc   ;==>_DISM_DisableFeature

; #FUNCTION# ====================================================================================================================
; Name...........: _DISM_EnableFeature
; Description ...: Enables a feature in an image. Features are identified by a name and can optionally be tied to a package.
; Syntax.........: _DISM_EnableFeature($Session, $FeatureName, $Identifier = 0, $PackageIdentifier = 0, $LimitAccess = True, $EnableAll = False)
; Parameters ....: $Session           - A valid DISM Session. The DISM Session must be associated with an image. You can associate a session with an image by using the DismOpenSession Function.
;				   $FeatureName       - The name of the feature that is being enabled. To enable more than one feature, separate each feature name with a semicolon.
;				   $Identifier		  - [Optional]. Either an absolute path to a .cab file or the package name, depending on the PackageIdentifier parameter value.
;				   $PackageIdentifier - [Optional]. Specifies whether a package is identified by name or by file path.
;				   						| $DismPackageNone 	   - No package is specified.
;				   						| $DismPackageName 	   - The package is identified by its name.
;				   						| $DismDismPackagePath - The package is specified by its path.
;				   $LimitAccess       - A Boolean value indicating whether Windows Update (WU) should be contacted as a source location for downloading files if none are found in other specified locations. Before checking WU, DISM will check for the files in the SourcePaths provided and in any locations specified in the registry by group policy. If the files required to enable the feature are still present on the computer, this flag is ignored.
;				   				        | True  - Do not check WU for repair files.
;				   				        | False - Default. Check WU for repair files.
;				   $EnableAll         - Enable all dependencies of the feature. If the specified feature or any one of its dependencies cannot be enabled, none of them will be changed from their existing state.
;				   				        | True  - Enable all dependencies of the feature.
;				   				        | False - Only enable the specified feature.
; Return values .: Success - Returns $DISMAPI_S_RELOAD_IMAGE_SESSION_REQUIRED (1).
;                  Failure - Returns _DISM_GetErrorMessageText() and Sets @Error:
;                  			 | 0 - No DLLCall error.
; 				   			 | 1 - Unable to use the DLL file
; 				   			 | 2 - Unknown "return type"
; 				   			 | 3 - "function" not found in the DLL file
;				   			 | 4 - Bad number of parameters.
;				   Both    - Sets @Extended to _WinAPI_GetLastError()
; Author(s) .....: André Cut
; Modified.......:
; Remarks .......: If the feature is present in the foundation package, you do not have to specify any package information.
;				   If the feature is in an optional package or feature pack that has already been installed in the image, specify a package name in the Identifier parameter and specify DismPackageName as the PackageIdentifier.
;				   If the feature cannot be enabled due to the parent feature not being enabled, a special error code will be returned.
;				   You can use EnableAll to enable the parent features when you enable the specified features, or you can use the DismGetFeatureParent Function to enumerate the parent features and enable them first.
;				   If the feature to be enabled is not a component of the foundation package, you must add the parent optional package with the DismAddPackage Function before you enable the feature.
;				   Do not you specify a path to a .cab file of an optional package that has not been added to the image in the Identifier parameter.
;			       If you specify a package that has not been added, and you specify DismPackagePath as the PackageIdentifier, the function will complete successfully but the feature will not be enabled.
; Related .......: _DISM_AddPackage, _DISM_DisableFeature, _DISM_GetFeatures, _DISM_GetFeatureInfo
; Link ..........; http://msdn.microsoft.com/en-us/library/windows/desktop/hh824737.aspx
; Example .......; HRESULT hr = S_OK;
; 				   hr = DismEnableFeature(Session, “WindowsMediaPlayer”, NULL, PackageNone, TRUE, NULL, 0, FALSE, NULL, NULL, NULL);
;
; ===============================================================================================================================
Func _DISM_EnableFeature($Session, $FeatureName, $Identifier = 0, $PackageIdentifier = 0, $LimitAccess = True, $SourcePaths = 0, $SourcePathCount = 0, $EnableAll = False)

   ; control param passing
   Local $sType[2] = ["WSTR", "WSTR*"]
   If Not IsString($Identifier) And $Identifier = 0 Then $sType[0] = "PTR"
   If Not IsString($SourcePaths) And $SourcePaths = 0 Then $sType[1] = "PTR*"

   Local $aResult = DllCall($ghdismapi, "LONG", "DismEnableFeature", _
		 "PTR", $Session, _
		 "WSTR", $FeatureName, _
		 $sType[0], $Identifier, _
		 "INT", $PackageIdentifier, _
		 "BOOL", $LimitAccess, _
		 $sType[1], $SourcePaths, _
		 "UINT", $SourcePathCount, _
		 "BOOL", $EnableAll, _
		 "PTR", 0, _
		 "PTR", 0, _
		 "PTR", 0 _
		 )
   If @error Then Return SetError(@error, @extended, 0)
   Return SetExtended(_WinAPI_GetLastError(), _DISM_GetErrorMessageText($aResult[0]))
EndFunc   ;==>_DISM_EnableFeature


; #FUNCTION# ====================================================================================================================
; Name...........: _DISM_GetDriverInfo
; Description ...: Gets information about an .inf file in a specified image.
; Syntax.........: _DISM_GetDriverInfo($Session, $DriverPath, ByRef $DriverPackage, $ExtendedDriverInfo = False)
; Parameters ....: $Session    			- A valid DISM Session. The DISM Session must be associated with an image. You can associate a session with an image by using the DismOpenSession Function.
;				   $DriverPath 			- A relative or absolute path to the driver .inf file.
;				   $DriverPackage  	    - A Reference to an 2D Array where:
;				   						  | $aDriverPackage[0][0]  - PublishedName 	  - The published driver name.
;				   						  | $aDriverPackage[0][1]  - OriginalFileName - The original file name of the driver.
;				   						  | $aDriverPackage[0][2]  - InBox 			  - TRUE if the driver is included on the Windows distribution media and automatically installed as part of Windows®, otherwise FALSE.
;				   						  | $aDriverPackage[0][3]  - CatalogFile 	  - The catalog file for the driver.
;				   						  | $aDriverPackage[0][4]  - ClassName 		  - The class name of the driver.
;				   						  | $aDriverPackage[0][5]  - ClassGuid 		  - The class GUID of the driver.
;				   						  | $aDriverPackage[0][6]  - ClassDescription - The class description of the driver.
;				   						  | $aDriverPackage[0][7]  - BootCritical 	  - TRUE if the driver is boot-critical, otherwise FALSE.
;				   						  | $aDriverPackage[0][8]  - DriverSignature  - The driver signature status.
;				   						  | $aDriverPackage[0][9]  - ProviderName 	  - The provider of the driver.
;				   						  | $aDriverPackage[0][10] - Date 			  - The manufacturer's build date of the driver.
;				   						  | $aDriverPackage[0][11] - Version 	      - Is composed of the following parameter:
;				   						  				      				   	        | MajorVersion - The major version number of the driver.
;				   						  				      				   	        | MinorVersion - The minor version number of the driver.
;				   						  				      				   	        | Build        - The build number of the driver.
;				   						  				      				   	        | Revision	   - The revision number of the driver.
;				   $ExtendedDriverInfo  - A Boolean value specifying if extended driver information will be returned.
;										  | True  - Return extended driver information
;										  | False - No extended driver information
; Return values .: Success - Returns an 2D array where:
;				   			 | $aReturn[0][0]  - ManufacturerName 	 - The manufacturer name of the driver.
;				   			 | $aReturn[0][1]  - HardwareDescription - A hardware description of the driver.
;				   			 | $aReturn[0][2]  - HardwareId 		 - The hardware ID of the driver.
;				   			 | $aReturn[0][3]  - Architecture 		 - The architecture of the driver.
;				   			 | $aReturn[0][4]  - ServiceName 		 - The service name of the driver.
;				   			 | $aReturn[0][5]  - CompatibleIds 	  	 - The compatible IDs of the driver.
;				   			 | $aReturn[0][6]  - ExcludeIds 		 - The exclude IDs of the driver.
;                  Failure - Returns _DISM_GetErrorMessageText() and Sets @Error:
;                  			 | 0 - No DLLCall error.
; 				   			 | 1 - Unable to use the DLL file
; 				   			 | 2 - Unknown "return type"
; 				   			 | 3 - "function" not found in the DLL file
;				   			 | 4 - Bad number of parameters.
;				   Both    - Sets @Extended to _WinAPI_GetLastError()
; Author(s) .....: André Cut
; Modified.......:
; Remarks .......: This function returns information about the .inf file installed on the image. The driver associated with the .inf file may or may not be installed in the image.
; Related .......: _DISM_GetDrivers, _DISM_AddDriver, _DISM_RemoveDriver, _DISM_Delete
; Link ..........; http://msdn.microsoft.com/en-us/library/windows/desktop/hh824733.aspx
; Example .......; HRESULT hr = S_OK;
;				   DismDriverInfo* DriverInfo;
;				   UINT Count;
;				   hr = DismGetDriverInfo(Session, L"usb.inf", &DriverInfo, &Count, &DriverPackageInfo);
;
; ===============================================================================================================================
Func _DISM_GetDriverInfo($Session, $DriverPath, ByRef $DriverPackage, $ExtendedDriverInfo = False)
   
   Local $ptr = "PTR"
   Local $Driver, $Count

   If $ExtendedDriverInfo = True Then $ptr = "PTR*"
   
   Local $aResult = DllCall($ghdismapi, "LONG", "DismGetDriverInfo", _
		 "PTR", $Session, _
		 "WSTR", $DriverPath, _
		 "PTR*", $Driver, _
		 "UINT*", $Count, _
		 $ptr, $DriverPackage _
		 )
   If @error Then Return SetError(@error, @extended, 0)
   If IsArray($aResult) = 1 Then
	  If $aResult[0] <> $S_OK Then Return SetError(@error, @extended, _DISM_GetErrorMessageText($aResult[0]))
   EndIf

   $Driver = $aResult[3]
   $Count = $aResult[4]
   If $Count <> 0 Then
	  Local $tmp_tagDismDriver = ""
	  
	  Local $dParams = "ManufacturerName;HardwareDescription;HardwareId;Architecture;ServiceName;CompatibleIds;ExcludeIds" ; driver info params
	  Local $a_dParams = StringSplit($dParams, ';') ; array of driver info params
   
	  Local $aReturn[$Count+1][$a_dParams[0]] ; Add a row for Description
	  ; create column titles
	  For $i = 1 To $a_dParams[0]
		 $aReturn[0][$i-1] = $a_dParams[$i]
	  Next
   
	  For $i = 1 To $Count
		 $tmp_tagDismDriver &= $tagDismDriver
		 If $i = $Count Then ExitLoop
		 $tmp_tagDismDriver &= ";"
	  Next
   
	  Local $getDriverInfo = DllStructCreate($tmp_tagDismDriver, $Driver)
   
	  Local $e = 0 ; running element
	  
	  ; get DriverInfo
	  For $row = 1 To $Count
		 For $col = 1 To $a_dParams[0]
			$e += 1
			
			If $a_dParams[$col] = "Architecture" Then
			   ; Set Architecture
			   If DllStructGetData($getDriverInfo, $e) = 9 Then $aReturn[$row][$col-1] = "amd64"
			   If DllStructGetData($getDriverInfo, $e) = 6 Then $aReturn[$row][$col-1] = "ia64"
			   If DllStructGetData($getDriverInfo, $e) = 0 Then $aReturn[$row][$col-1] = "x86"
			   ContinueLoop
			EndIf
			$curElement = DllStructGetData(DllStructCreate("WCHAR [260]", DllStructGetData($getDriverInfo, $e)), 1)
			$aReturn[$row][$col-1] = $curElement
		 Next	  
	  Next
	  
	  ; free resources
	  _DISM_Delete($getDriverInfo)	  
   EndIf
   
   $DriverPackage = $aResult[5]
   If $DriverPackage <> 0 Then
	  Local $iTime = 8, $iDriverVers = 4
	  
	  ; create DismDriverPackage Structure
	  Local $getDriverPackage = DllStructCreate($tagDismDriverPackage, $DriverPackage)
	  Local $getDate  		  = DllStructCreate($_tagSYSTEMTIME)
	  
	  ; driver package params
	  Local $dpParams = "PublishedName;OriginalFileName;InBox;CatalogFile;ClassName;ClassGuid;ClassDescription;BootCritical;" & _
						"DriverSignature;ProviderName;Date;Version"
	  ; array of driver package params
	  Local $a_dpParams = StringSplit($dpParams, ';')
	  Local $aStDataTypes = StringSplit($tagDismDriverPackage, ';')
	  
	  Local $aDriverPackage[2][$a_dpParams[0]]
	  ; create column titles
	  For $i = 1 To $a_dpParams[0]
		 $aDriverPackage[0][$i-1] = $a_dpParams[$i]
	  Next
	  
	  Local $e = 1 ; running element
	  
	  ; get DriverPackage
	  For $col = 1 To $a_dpParams[0]
		 Local $DriverVersion = "", $index = $col ; reset index and DriverVersion after every column
   
		 ; check if data is empty		 
		 If StringInStr($aStDataTypes[$e], "PTR") <> 0 Then
			$curElement = DllStructGetData(DllStructCreate("WCHAR [260]", DllStructGetData($getDriverPackage, $e)), 1)
			If $curElement == "" Then
			   $e += 1
			   ContinueLoop
			EndIf
			; create entry point to switch loop
			$index = "PTR"
		 ElseIf DllStructGetData($getDriverPackage, $e) == "" Then
			$e += 1
			ContinueLoop
		 EndIf
		 
		 Switch $index
			Case "PTR"
			   $aDriverPackage[1][$col-1] = $curElement
			Case 11
			   For $i = 1 To $iTime
				  DllStructSetData($getDate, $i, DllStructGetData($getDriverPackage, $e))
				  $e += 1
			   Next
			   $aDriverPackage[1][$col-1] = _Date_Time_SystemTimeToDateStr($getDate)
			   ContinueLoop
			Case 12
			   For $i = 1 To $iDriverVers
				  $DriverVersion &= DllStructGetData($getDriverPackage, $e)
				  $e += 1
				  If $i = $iDriverVers Then ExitLoop
				  $DriverVersion &= "."
			   Next
			   $aDriverPackage[1][$col-1] = $DriverVersion
			   ExitLoop
			Case Else
			   $aDriverPackage[1][$col-1] = DllStructGetData($getDriverPackage, $e)
		 EndSwitch
		 $e += 1
	  Next	  

	  ; free resources
	  _DISM_Delete($getDriverPackage)
	  _DISM_Delete($getDate)

	  $DriverPackage = $aDriverPackage
   EndIf

   Return SetExtended(_WinAPI_GetLastError(), $aReturn)
EndFunc   ;==>_DISM_GetDriverInfo


; #FUNCTION# ====================================================================================================================
; Name...........: _DISM_GetDrivers
; Description ...: Lists the drivers in an image.
; Syntax.........: _DISM_GetDrivers($Session, $AllDrivers = True)
; Parameters ....: $Session    - A valid DISM Session. The DISM Session must be associated with an image. You can associate a session with an image by using the DismOpenSession Function.
;				   $AllDrivers - A Boolean value specifying which drivers to retrieve.
; 				                 | True  - Retrieve all drivers.
; 				                 | False - Retrieve only out-of-box drivers. Out-of-box drivers are drivers that were not originally included in the Windows image.
; Return values .: Success - Returns an 2D array where:
;				   			 | $aReturn[0][0]  - PublishedName    - The published driver name.
;				   			 | $aReturn[0][1]  - OriginalFileName - The original file name of the driver.
;				   			 | $aReturn[0][2]  - InBox 		      - TRUE if the driver is included on the Windows distribution media and automatically installed as part of Windows®, otherwise FALSE.
;				   			 | $aReturn[0][3]  - CatalogFile 	  - The catalog file for the driver.
;				   			 | $aReturn[0][4]  - ClassName 	      - The class name of the driver.
;				   			 | $aReturn[0][5]  - ClassGuid 	      - The class GUID of the driver.
;				   			 | $aReturn[0][6]  - ClassDescription - The class description of the driver.
;				   			 | $aReturn[0][7]  - BootCritical 	  - TRUE if the driver is boot-critical, otherwise FALSE.
;				   			 | $aReturn[0][8]  - DriverSignature  - The driver signature status.
;				   			 | $aReturn[0][9]  - ProviderName 	  - The provider of the driver.
;				   			 | $aReturn[0][10] - Date 			  - The manufacturer's build date of the driver.
;				   			 | $aReturn[0][11] - Version    	  - Is composed of the following parameter:
;				   			 				      					| MajorVersion - The major version number of the driver.
;				   			 				      					| MinorVersion - The minor version number of the driver.
;				   			 				      					| Build        - The build number of the driver.
;				   			 				      					| Revision	   - The revision number of the driver.
;                  Failure - Returns _DISM_GetErrorMessageText() and Sets @Error:
;                  			 | 0 - No DLLCall error.
; 				   			 | 1 - Unable to use the DLL file
; 				   			 | 2 - Unknown "return type"
; 				   			 | 3 - "function" not found in the DLL file
;				   			 | 4 - Bad number of parameters.
;				   Both    - Sets @Extended to _WinAPI_GetLastError()
; Author(s) .....: André Cut
; Modified.......:
; Remarks .......:
; Related .......: _DISM_AddDriver, _DISM_RemoveDriver, _DISM_GetDriverInfo, _DISM_Delete
; Link ..........; http://msdn.microsoft.com/en-us/library/windows/desktop/hh824784.aspx
; Example .......; HRESULT hr = S_OK;
;				   DismDriver* DriverPackageInfos;
;				   UINT Count;
;				   hr = DismGetDrivers(Session, TRUE, &DriverPackageInfos, &Count);
;
; ===============================================================================================================================
Func _DISM_GetDrivers($Session, $AllDrivers = False)

   Local $DriverPackage, $Count
   
   Local $aResult = DllCall($ghdismapi, "LONG", "DismGetDrivers", _
		 "PTR", $Session, _
		 "BOOL", $AllDrivers, _
		 "PTR*", $DriverPackage, _
		 "UINT*", $Count _
		 )
   If @error Then Return SetError(@error, @extended, 0)
   If IsArray($aResult) = 1 Then
	  If $aResult[0] <> $S_OK Then Return SetError(@error, @extended, _DISM_GetErrorMessageText($aResult[0]))
   EndIf

   $DriverPackage = $aResult[3]
   $Count = $aResult[4]
   If $Count <> 0 Then
	  Local $tmp_tagDismDriverPackage = ""
	  Local $iDate = 8, $iDriverVers = 4

	  ; create array of DismDriverPackage Structure
	  For $i = 1 To $Count
		 $tmp_tagDismDriverPackage &= $tagDismDriverPackage
		 If $i = $Count Then ExitLoop
		 $tmp_tagDismDriverPackage &= ";"
	  Next

	  ; create DismDriverPackage Structure
	  Local $getDriverPackage = DllStructCreate($tmp_tagDismDriverPackage, $DriverPackage)
	  Local $getDate  		  = DllStructCreate($_tagSYSTEMTIME)

	  ; driver package params
	  Local $dpParams = "PublishedName;OriginalFileName;InBox;CatalogFile;ClassName;ClassGuid;ClassDescription;BootCritical;" & _
						"DriverSignature;ProviderName;Date;Version"
	  ; array of driver package params
	  Local $a_dpParams = StringSplit($dpParams, ';')
	  Local $aStDataTypes = StringSplit($tmp_tagDismDriverPackage, ';') 
	  
	  Local $aReturn[$Count+1][$a_dpParams[0]] ; Add a row for Description
	  ; create column titles
	  For $i = 1 To $a_dpParams[0]
		 $aReturn[0][$i-1] = $a_dpParams[$i]
	  Next
	  
	  Local $e = 1 ; running element
	  
	  ; get DriverPackage
	  For $row = 1 To $Count
		 For $col = 1 To $a_dpParams[0]
			Local $DriverVersion = "", $index = $col ; reset index and DriverVersion after every column

			; check if data is empty
			If StringInStr($aStDataTypes[$e], "PTR") <> 0 Then
			   $curElement = DllStructGetData(DllStructCreate("WCHAR [260]", DllStructGetData($getDriverPackage, $e)), 1)
			   If $curElement = "" Then
				  $e += 1
				  ContinueLoop
			   EndIf
			   ; create entry point to switch loop
			   $index = "PTR"
			ElseIf DllStructGetData($getDriverPackage, $e) == "" Then
			   $e += 1
			   ContinueLoop			
			EndIf
			
			Switch $index
			   Case "PTR"
				  $aReturn[$row][$col-1] = $curElement
			   Case 11
				  For $i = 1 To $iDate
					 DllStructSetData($getDate, $i, DllStructGetData($getDriverPackage, $e))
					 $e += 1
				  Next
				  $aReturn[$row][$col-1] = _Date_Time_SystemTimeToDateStr($getDate)
				  ContinueLoop
			   Case 12
				  For $i = 1 To $iDriverVers
					 $DriverVersion &= DllStructGetData($getDriverPackage, $e)
					 $e += 1
					 If $i = $iDriverVers Then ExitLoop
					 $DriverVersion &= "."
				  Next
				  $aReturn[$row][$col-1] = $DriverVersion
				  ContinueLoop
			   Case Else
				  $aReturn[$row][$col-1] = DllStructGetData($getDriverPackage, $e)
			EndSwitch
			$e += 1
		 Next	  
	  Next
	  
	  ; free resources
	  _DISM_Delete($getDriverPackage)
	  _DISM_Delete($getDate)

	  Return SetExtended(_WinAPI_GetLastError(), $aReturn)
   EndIf

   Return SetExtended(_WinAPI_GetLastError(), _DISM_GetErrorMessageText($aResult[0]))
EndFunc   ;==>_DISM_GetDrivers


; #FUNCTION# ====================================================================================================================
; Name...........: _DISM_GetFeatureInfo
; Description ...: Gets detailed information for the specified feature.
; Syntax.........: _DISM_GetFeatureInfo($Session, $FeatureName, ByRef $CustomProperty, $Identifier = 0, $PackageIdentifier = 0)
; Parameters ....: $Session 	   	  - A valid DISM Session. The DISM Session must be associated with an image. You can associate a session with an image by using the DismOpenSession Function.
;				   $FeatureName		  - The name of the feature that you want to get more information about.
;				   $CustomProperty	  - A Reference to an array where:
;				   						| $aCustomProperty[0] - Name  - The name of the custom property.
;				   						| $aCustomProperty[1] - Value - The value of the custom property.
;				   						| $aCustomProperty[2] - Path  - The path of the custom property.
;				   $Identifier		  - [Optional]. Either an absolute path to a .cab file or the package name, depending on the PackageIdentifier parameter value.
;				   $PackageIdentifier - [Optional]. Specifies whether a package is identified by name or by file path.
;				   						| $DismPackageNone 	   - No package is specified.
;				   						| $DismPackageName 	   - The package is identified by its name.
;				   						| $DismDismPackagePath - The package is specified by its path.
; Return values .: Success - Returns an 2D array where:
;				   			 | $aReturn[0][0] - FeatureName     - The name of the feature.
;				   			 | $aReturn[0][1] - FeatureState    - Specifies the state of a package or a feature.
;							 							          | NotPresent		   - The package or feature is not present.
;							 							          | UninstallPending   - An uninstall process for the package or feature is pending. Additional processes are pending and must be completed before the package or feature is successfully uninstalled.
;							 							          | Staged 			   - The package or feature is staged.
;							 							          | Resolved 		   - Metadata about the package or feature has been added to the system, but the package or feature is not present.
;							 							          | Removed 		   - Same as $DismStateResolved
;							 							          | Installed 		   - The package or feature is installed.
;							 							          | InstallPending 	   - The install process for the package or feature is pending. Additional processes are pending and must be completed before the package or feature is successfully installed.
;							 							          | Superseded 		   - The package or feature has been superseded by a more recent package or feature.
;							 							          | PartiallyInstalled - The package or feature is partially installed. Some parts of the package or feature have not been installed.
;				   			 | $aReturn[0][2] - DisplayName     - The display name of the feature. This is not always unique across all features.
;				   			 | $aReturn[0][3] - Description     - The description of the feature.
;				   			 | $aReturn[0][4] - RestartRequired - Specifies whether a restart is required after enabling a feature or installing a package.
;				   			 									  | $DismRestartNo 	     - No restart is required.
;				   			 									  | $DismRestartPossible - This package or feature might require a restart.
;				   			 									  | $DismRestartRequired - This package or feature always requires a restart.
;                  Failure - Returns _DISM_GetErrorMessageText() and Sets @Error:
;                  			 | 0 - No DLLCall error.
; 				   			 | 1 - Unable to use the DLL file
; 				   			 | 2 - Unknown "return type"
; 				   			 | 3 - "function" not found in the DLL file
;				   			 | 4 - Bad number of parameters.
;				   Both    - Sets @Extended to _WinAPI_GetLastError()
; Author(s) .....: André Cut
; Modified.......:
; Remarks .......: You can use this function to get the custom properties of a feature. If the feature has custom properties, they will be stored in the CustomProperty field as an array. Not all features have custom properties.
; Related .......: _DISM_EnableFeature, _DISM_DisableFeature, _DISM_GetFeatureParent, _DISM_Delete
; Link ..........; http://msdn.microsoft.com/en-us/library/windows/desktop/hh824735.aspx
; Example .......; HRESULT hr = S_OK;
;				   DismFeatureInfo FeatureInfo; hr = DismGetFeatureInfo(Session, "Xps-Foundation-Xps-Viewer", NULL, NULL, &FeatureInfo);
;
; ===============================================================================================================================
Func _DISM_GetFeatureInfo($Session, $FeatureName, ByRef $CustomProperty, $Identifier = 0, $PackageIdentifier = 0)
   
   ; control param passing
   Local $sType = "WSTR"
   If Not IsString($Identifier) And $Identifier = 0 Then $sType = "PTR"   
   
   Local $FeatureInfo, $Count
   
   Local $aResult = DllCall($ghdismapi, "LONG", "DismGetFeatureInfo", _
		 "PTR", $Session, _
		 "WSTR", $FeatureName, _		 
		 $sType, $Identifier, _
		 "INT", $PackageIdentifier, _
		 "PTR*", $FeatureInfo _	 
		 )
   If @error Then Return SetError(@error, @extended, 0)
   If IsArray($aResult) = 1 Then
	  If $aResult[0] <> $S_OK Then Return SetError(@error, @extended, _DISM_GetErrorMessageText($aResult[0]))
   EndIf

   $FeatureInfo = $aResult[5]
   
   ; create DismFeatureInfo Structure
   Local $getFeatureInfo = DllStructCreate($tagDismFeatureInfo, $FeatureInfo)

   Local $fParams = "FeatureName;FeatureState;DisplayName;Description;RestartRequired" ; feature info params
   Local $a_fParams = StringSplit($fParams, ';') ; array of feature info params
   Local $aStDataTypes = StringSplit($tagDismFeatureInfo, ';') 
 
   Local $aReturn[2][$a_fParams[0]]
   ; create column titles
   For $i = 1 To $a_fParams[0]
	  $aReturn[0][$i-1] = $a_fParams[$i]
   Next

   ; get custom property count
   $cCount = DllStructGetData($getFeatureInfo, "CustomPropertyCount")
   If $cCount <> 0 Then
	  ; create DismCustomProperty Structure
	  Local $getCustomProperty = DllStructCreate($tagDismCustomProperty, DllStructGetData($getFeatureInfo, "CustomProperty"))
	  
	  Local $cParams = "Name;Value;Path" ; custom property params
	  Local $a_cParams = StringSplit($cParams, ';') ; array of custom property params
	  
	  Local $aCustomProperty[2][$a_cParams[0]]
	  ; create column titles
	  For $i = 1 To $a_cParams[0]
		 $aCustomProperty[0][$i-1] = $a_cParams[$i]
	  Next
	  
	  Local $e = 0 ; running element
	  
	  ; get CustomProperty
	  For $col = 1 To $a_cParams[0]
		 $e += 1
		 $curElement = DllStructGetData(DllStructCreate("WCHAR [260]", DllStructGetData($getCustomProperty, $e)), 1)
		 $aCustomProperty[1][$col-1] = $curElement
	  Next
	  
	  ; free resources
	  _DISM_Delete($getCustomProperty)	  
	  
	  $CustomProperty = $aCustomProperty
   EndIf

   Local $e = 1 ; running element
   
   ; get FeatureInfo
   For $col = 1 To $a_fParams[0]
	  $index = $col ; reset index after every column

	  ; check if data is empty
	  If StringInStr($aStDataTypes[$e], "PTR") <> 0 Then
		 $curElement = DllStructGetData(DllStructCreate("WCHAR [260]", DllStructGetData($getFeatureInfo, $e)), 1)
		 If $curElement = "" Then
			$e += 1
			ContinueLoop
		 EndIf
		 ; create entry point to switch loop
		 $index = "PTR"
	  ElseIf DllStructGetData($getFeatureInfo, $e) == "" Then
		 $e += 1
		 ContinueLoop	  
	  EndIf
	  
	  Switch $index		 
		 Case "PTR"
			$aReturn[1][$col-1] = $curElement
		 Case 2
			$aReturn[1][$col-1] = _DISM_GetPackageFeatureState(DllStructGetData($getFeatureInfo, $e))
		 Case 5
			$aReturn[1][$col-1] = _DISM_GetRestartType(DllStructGetData($getFeatureInfo, $e))
	  EndSwitch
	  $e += 1
   Next
   
   ; free resources
   _DISM_Delete($getFeatureInfo)

   Return SetExtended(_WinAPI_GetLastError(), $aReturn)
EndFunc   ;==>_DISM_GetFeatureInfo


; #FUNCTION# ====================================================================================================================
; Name...........: _DISM_GetFeatureParent
; Description ...: Gets the parent features of a specified feature.
; Syntax.........: _DISM_GetFeatureParent($Session, $FeatureName, $Identifier = 0, $PackageIdentifier = 0)
; Parameters ....: $Session 	   	  - A valid DISM Session. The DISM Session must be associated with an image. You can associate a session with an image by using the DismOpenSession Function.
;				   $FeatureName		  - The name of the feature that you want to find the parent of.
;				   $Identifier		  - [Optional]. Either an absolute path to a .cab file or the package name, depending on the PackageIdentifier parameter value.
;				   $PackageIdentifier - [Optional]. Specifies whether a package is identified by name or by file path.
;				   						| $DismPackageNone 	   - No package is specified.
;				   						| $DismPackageName 	   - The package is identified by its name.
;				   						| $DismDismPackagePath - The package is specified by its path.
; Return values .: Success - Returns an 2D array where:
;				   			 | $aReturn[0][0] - FeatureName - The name of the feature.
;				   			 | $aReturn[0][1] - State 	    - Specifies the state of a package or a feature.
;							 							      | NotPresent		   - The package or feature is not present.
;							 							      | UninstallPending   - An uninstall process for the package or feature is pending. Additional processes are pending and must be completed before the package or feature is successfully uninstalled.
;							 							      | Staged 			   - The package or feature is staged.
;							 							      | Resolved 		   - Metadata about the package or feature has been added to the system, but the package or feature is not present.
;							 							      | Removed 		   - Same as $DismStateResolved
;							 							      | Installed 		   - The package or feature is installed.
;							 							      | InstallPending 	   - The install process for the package or feature is pending. Additional processes are pending and must be completed before the package or feature is successfully installed.
;							 							      | Superseded 		   - The package or feature has been superseded by a more recent package or feature.
;							 							      | PartiallyInstalled - The package or feature is partially installed. Some parts of the package or feature have not been installed.
;                  Failure - Returns _DISM_GetErrorMessageText() and Sets @Error:
;                  			 | 0 - No DLLCall error.
; 				   			 | 1 - Unable to use the DLL file
; 				   			 | 2 - Unknown "return type"
; 				   			 | 3 - "function" not found in the DLL file
;				   			 | 4 - Bad number of parameters.
;				   Both    - Sets @Extended to _WinAPI_GetLastError()
; Author(s) .....: André Cut
; Modified.......:
; Remarks .......: For a feature to be enabled, one or more of its parent features must be enabled. You can use this function to enumerate the parent features and determine which parent needs to be enabled.
; Related .......: _DISM_EnableFeature, _DISM_DisableFeature, _DISM_GetFeatures, _DISM_GetFeatureInfo, _DISM_Delete
; Link ..........; http://msdn.microsoft.com/en-us/library/windows/desktop/hh824798.aspx
; Example .......; HRESULT hr = S_OK;
;				   DismFeature* Feature;
;				   UINT FeatureCount;
;				   hr = DismGetFeatureParent(Session,"Xps-Foundation-Xps-Viewer", NULL, NULL, &Feature, &FeatureCount);
;
; ===============================================================================================================================
Func _DISM_GetFeatureParent($Session, $FeatureName, $Identifier = 0, $PackageIdentifier = 0)
   
   ; control param passing
   Local $sType = "WSTR"
   If Not IsString($Identifier) And $Identifier = 0 Then $sType = "PTR"   
   
   Local $Feature, $Count
   
   Local $aResult = DllCall($ghdismapi, "LONG", "DismGetFeatureParent", _
		 "PTR", $Session, _
		 "WSTR", $FeatureName, _		 
		 $sType, $Identifier, _
		 "INT", $PackageIdentifier, _
		 "PTR*", $Feature, _
		 "UINT*", $Count _		 
		 )
   If @error Then Return SetError(@error, @extended, 0)
   If IsArray($aResult) = 1 Then
	  If $aResult[0] <> $S_OK Then Return SetError(@error, @extended, _DISM_GetErrorMessageText($aResult[0]))
   EndIf

   $Feature = $aResult[5]
   $Count   = $aResult[6]
   If $Count <> 0 Then	  
	  Local $tmp_tagDismFeature = ""
	  
	  ; create array of DismFeature Structure
	  For $i = 1 To $Count
		 $tmp_tagDismFeature &= $tagDismFeature
		 If $i = $Count Then ExitLoop
		 $tmp_tagDismFeature &= ";"
	  Next
	  
	  ; create DismFeature Structure
	  Local $getFeature = DllStructCreate($tmp_tagDismFeature, $Feature)
	  
	  Local $fParams = "FeatureName;State" ; feature params
	  Local $a_fParams = StringSplit($fParams, ';') ; array of feature params
	  
	  Local $aReturn[$Count+1][$a_fParams[0]]
	  ; create column titles
	  For $i = 1 To $a_fParams[0]
		 $aReturn[0][$i-1] = $a_fParams[$i]
	  Next
	  
	  Local $e = 0 ; running element
	  
	  ; get Features
	  For $row = 1 To $Count
		 For $col = 1 To $a_fParams[0]
			$e += 1
			
			If $a_fParams[$col] = "FeatureName" Then
			   $curElement = DllStructGetData(DllStructCreate("WCHAR [260]", DllStructGetData($getFeature, $e)), 1)
			   $aReturn[$row][$col-1] = $curElement
			   ContinueLoop
			EndIf
			$aReturn[$row][$col-1] = _DISM_GetPackageFeatureState(DllStructGetData($getFeature, $e))
		 Next	  
	  Next
	  
	  ; free resources
	  _DISM_Delete($getFeature)
	  
	  Return SetExtended(_WinAPI_GetLastError(), $aReturn)
   EndIf

   Return SetExtended(_WinAPI_GetLastError(), _DISM_GetErrorMessageText($aResult[0]))
EndFunc   ;==>_DISM_GetFeatureParent


; #FUNCTION# ====================================================================================================================
; Name...........: _DISM_GetFeatures
; Description ...: Gets all the features in an image, regardless of whether the features are enabled or disabled.
; Syntax.........: _DISM_GetFeatures($Session, $Identifier = 0, $PackageIdentifier = 0)
; Parameters ....: $Session - A valid DISM Session. The DISM Session must be associated with an image. You can associate a session with an image by using the DismOpenSession Function.
;				   $Identifier		  - [Optional]. Either an absolute path to a .cab file or the package name, depending on the PackageIdentifier parameter value.
;				   $PackageIdentifier - [Optional]. Specifies whether a package is identified by name or by file path.
;				   						| $DismPackageNone 	   - No package is specified.
;				   						| $DismPackageName 	   - The package is identified by its name.
;				   						| $DismDismPackagePath - The package is specified by its path.
; Return values .: Success - Returns an 2D array where:
;				   			 | $aReturn[0][0] - FeatureName - The name of the feature.
;				   			 | $aReturn[0][1] - State 	    - Specifies the state of a package or a feature.
;							 							      | NotPresent		   - The package or feature is not present.
;							 							      | UninstallPending   - An uninstall process for the package or feature is pending. Additional processes are pending and must be completed before the package or feature is successfully uninstalled.
;							 							      | Staged 			   - The package or feature is staged.
;							 							      | Resolved 		   - Metadata about the package or feature has been added to the system, but the package or feature is not present.
;							 							      | Removed 		   - Same as $DismStateResolved
;							 							      | Installed 		   - The package or feature is installed.
;							 							      | InstallPending 	   - The install process for the package or feature is pending. Additional processes are pending and must be completed before the package or feature is successfully installed.
;							 							      | Superseded 		   - The package or feature has been superseded by a more recent package or feature.
;							 							      | PartiallyInstalled - The package or feature is partially installed. Some parts of the package or feature have not been installed.
;                  Failure - Returns _DISM_GetErrorMessageText() and Sets @Error:
;                  			 | 0 - No DLLCall error.
; 				   			 | 1 - Unable to use the DLL file
; 				   			 | 2 - Unknown "return type"
; 				   			 | 3 - "function" not found in the DLL file
;				   			 | 4 - Bad number of parameters.
;				   Both    - Sets @Extended to _WinAPI_GetLastError()
; Author(s) .....: André Cut
; Modified.......:
; Remarks .......:
; Related .......: _DISM_EnableFeature, _DISM_DisableFeature, _DISM_GetFeatureInfo, _DISM_GetFeatureParent, _DISM_Delete
; Link ..........; http://msdn.microsoft.com/en-us/library/windows/desktop/hh824771.aspx
; Example .......; HRESULT hr = S_OK;
;				   DismFeature* Feature;
;				   UINT FeatureCount;
;				   hr = DismGetFeatures(Session, NULL, NULL, &Feature, &FeatureCount);
;
; ===============================================================================================================================
Func _DISM_GetFeatures($Session, $Identifier = 0, $PackageIdentifier = 0)

   ; control param passing
   Local $sType = "WSTR"
   If Not IsString($Identifier) And $Identifier = 0 Then $sType = "PTR"

   Local $Feature, $Count
   
   Local $aResult = DllCall($ghdismapi, "LONG", "DismGetFeatures", _
		 "PTR", $Session, _
		 $sType, $Identifier, _
		 "INT", $PackageIdentifier, _
		 "PTR*", $Feature, _
		 "UINT*", $Count _
		 )
   If @error Then Return SetError(@error, @extended, 0)
   If IsArray($aResult) = 1 Then
	  If $aResult[0] <> $S_OK Then Return SetError(@error, @extended, _DISM_GetErrorMessageText($aResult[0]))
   EndIf

   $Feature = $aResult[4]
   $Count = $aResult[5]
   If $Count <> 0 Then	  
	  Local $tmp_tagDismFeature = ""
	  
	  ; create array of DismFeature Structure
	  For $i = 1 To $Count
		 $tmp_tagDismFeature &= $tagDismFeature
		 If $i = $Count Then ExitLoop
		 $tmp_tagDismFeature &= ";"
	  Next
	  
	  ; create DismFeature Structure
	  Local $getFeature = DllStructCreate($tmp_tagDismFeature, $Feature)
	  
	  Local $fParams = "FeatureName;State" ; feature params
	  Local $a_fParams = StringSplit($fParams, ';') ; array of feature params
	  
	  Local $aReturn[$Count+1][$a_fParams[0]]
	  ; create column titles
	  For $i = 1 To $a_fParams[0]
		 $aReturn[0][$i-1] = $a_fParams[$i]
	  Next
	  
	  Local $e = 0 ; running element
	  
	  ; get Features
	  For $row = 1 To $Count
		 For $col = 1 To $a_fParams[0]
			$e += 1
			
			If $a_fParams[$col] = "FeatureName" Then
			   $curElement = DllStructGetData(DllStructCreate("WCHAR [260]", DllStructGetData($getFeature, $e)), 1)
			   $aReturn[$row][$col-1] = $curElement
			   ContinueLoop
			EndIf
			$aReturn[$row][$col-1] = _DISM_GetPackageFeatureState(DllStructGetData($getFeature, $e))
		 Next	  
	  Next
	  
	  ; free resources
	  _DISM_Delete($getFeature)
	  
	  Return SetExtended(_WinAPI_GetLastError(), $aReturn)
   EndIf

   Return SetExtended(_WinAPI_GetLastError(), _DISM_GetErrorMessageText($aResult[0]))
EndFunc   ;==>_DISM_GetFeatures


; #FUNCTION# ====================================================================================================================
; Name...........: _DISM_GetLastErrorMessage
; Description ...: Retrieves the error message in the current thread immediately after a failure.
; Syntax.........: _DISM_GetLastErrorMessage()
; Parameters ....:
; Return values .: Success - Returns $S_OK.
;                  Failure - Returns _DISM_GetErrorMessageText() and Sets @Error:
;                  			 | 0 - No DLLCall error.
; 				   			 | 1 - Unable to use the DLL file
; 				   			 | 2 - Unknown "return type"
; 				   			 | 3 - "function" not found in the DLL file
;				   			 | 4 - Bad number of parameters.
;				   Both    - Sets @Extended to _WinAPI_GetLastError()
; Author(s) .....: André Cut
; Modified.......:
; Remarks .......: You can retrieve a detailed error message immediately after a DISM API failure. The last error message is maintained on a per-thread basis. An error message on a thread will not overwrite the last error message on another thread.
;				   DismGetLastErrorMessage does not apply to the DismShutdown function, DismDelete function, or the DismGetLastErrorMessage function.
;				   You must call the DismDelete function to free the memory of ErrorMessage when the return value is S_OK.
; Related .......: _DISM_GetErrorMesageText
; Link ..........; http://msdn.microsoft.com/en-us/library/windows/desktop/hh824754.aspx
; Example .......; Retrieve the error message in the current thread.
;				   HRESULT hr = S_OK;
;				   DismString* ErrorMessage;
;				   hr = DismGetLastErrorMessage(&ErrorMessage);
;
; ===============================================================================================================================
Func _DISM_GetLastErrorMessage()

   Local $aResult = DllCall($ghdismapi, "LONG", "DismGetLastErrorMessage", _
		 "PTR*", $ErrorMessage _
		 )
   If @error Then Return SetError(@error, @extended, 0)
   If IsArray($aResult) = 1 Then
	  If $aResult[0] <> $S_OK Then Return SetError(@error, @extended, _DISM_GetErrorMessageText($aResult[0]))
   EndIf

   $ErrorMessage = $aResult[1]
 
   Local $aReturn[2][1]
   ; create column titles
   $aReturn[0][0] = "Value"

   ; create DismString Structure
   Local $getErrorMessage = DllStructCreate($tagDismString)
   $aReturn[1][0] = DllStructGetData($getErrorMessage, "Value")

   ; free resources
   _DISM_Delete($getErrorMessage)

   Return SetExtended(_WinAPI_GetLastError(), $aReturn)
EndFunc   ;==>_DISM_GetLastErrorMessage


; #FUNCTION# ====================================================================================================================
; Name...........: _DISM_GetImageInfo
; Description ...: Returns an array of DismImageInfo Structure elements that describe the images in a .wim or .vhd file.
; Syntax.........: _DISM_GetImageInfo($ImageFilePath)
; Parameters ....: $ImageFilePath - A relative or absolute path to a .wim or .vhd file.
; Return values .: Success - Returns an 2D array where:
;				   			 | $aReturn[0][0]  - ImageType 	         - Specifies the file type of the Windows® image container.
;																	   | Unsupported - The file type is unsupported. The image must be in a .wim, .vhd, or .vhdx file.
;																	   | Wim         - The image is in a .wim file.
;																	   | Vhd         - The image is in a .vhd or .vhdx file.
;				   			 | $aReturn[0][1]  - ImageIndex 	     - The index number, starting at 1, of the image.
;				   			 | $aReturn[0][2]  - ImageName 	         - The name of the image.
;				   			 | $aReturn[0][3]  - ImageDescription    - A description of the image.
;				   			 | $aReturn[0][4]  - ImageSize 	         - The size of the image in bytes.
;				   			 | $aReturn[0][5]  - Architecture 	     - The architecture of the image.
;				   			 | $aReturn[0][6]  - ProductName 	     - The name of the product, for example, "Microsoft Windows Operating System".
;				   			 | $aReturn[0][7]  - EditionId 	         - The edition of the product, for example, "Ultimate".
;				   			 | $aReturn[0][8]  - InstallationType    - A string identifying whether the installation is a Client or Server type.
;				   			 | $aReturn[0][9]  - HAL 		  	     - The hardware abstraction layer (HAL) type of the operating system.
;				   			 | $aReturn[0][10] - ProductType 	     - The product type, for example, "WinNT".
;				   			 | $aReturn[0][11] - ProductSuite 	     - The product suite, for example, "Terminal Server".
;				   			 | $aReturn[0][12] - Version 		     - Is composed of the following parameter:
;				   						  				      	       | MajorVersion - The major version number of the driver.
;				   						  				      	       | MinorVersion - The minor version number of the driver.
;				   						  				      	       | Build        - The build number of the driver.
;				   			 | $aReturn[0][13] - Service Pack-Build  - The service pack build.
;				   			 | $aReturn[0][14] - Service Pack-Number - The service pack number.
;				   			 | $aReturn[0][15] - Bootable 		     - Indicates whether an image is a bootable image type.
;				   						  				      	       | Yes     - The image is bootable.
;				   						  				      	       | No      - The image is not bootable.
;				   						  				      	       | Unknown - The image type is unknown.
;				   			 | $aReturn[0][16] - SystemRoot 	     - The Windows directory.
;				   			 | $aReturn[0][17] - Language(s) 	     - An array of DismLanguage Structure objects representing the languages in the image.
;				   			 | $aReturn[0][18] - DefaultLanguage     - The default language.
;				   			 | $aReturn[0][19] - Size 		  	     - The size of the DismWimCustomizedInfo structure. I Concatenated both array of structs.
;				   			 | $aReturn[0][20] - DirectoryCount      - The number of directories in the image.
;				   			 | $aReturn[0][21] - FileCount 	         - The number of files in the image.
;				   			 | $aReturn[0][22] - CreatedTime 	     - The time that the image file was created.
;				   			 | $aReturn[0][23] - ModifiedTime 	     - The time that the image file was last modified.
;                  Failure - Returns _DISM_GetErrorMessageText() and Sets @Error:
;                  			 | 0 - No DLLCall error.
; 				   			 | 1 - Unable to use the DLL file
; 				   			 | 2 - Unknown "return type"
; 				   			 | 3 - "function" not found in the DLL file
;				   			 | 4 - Bad number of parameters.
;				   Both    - Sets @Extended to _WinAPI_GetLastError()
; Author(s) .....: André Cut
; Modified.......:
; Remarks .......: The array of DismImageInfo structures are allocated by DISM API on the heap.
;				   You must call the DismDelete Function, passing the ImageInfo pointer, to free the resources associated with the DismImageInfo structures.
; Related .......: _DISM_GetMountedImageInfo, _DISM_Delete
; Link ..........; http://msdn.microsoft.com/en-us/library/windows/desktop/hh824767.aspx
; Example .......; HRESULT hr = S_OK;
;				   UINT* ImageInfoCount;
;				   hr = DismGetImageInfo(L"C:\\Images\\Image1.vhd", &ImageInfo, &ImageInfoCount);
;
; ===============================================================================================================================
Func _DISM_GetImageInfo($ImageFilePath)

   Local $ImageInfo, $Count

   Local $aResult = DllCall($ghdismapi, "LONG", "DismGetImageInfo", _
		 "WSTR", $ImageFilePath, _
		 "PTR*", $ImageInfo, _
		 "UINT*", $Count _
		 )
   If @error Then Return SetError(@error, @extended, 0)
   If IsArray($aResult) = 1 Then
	  If $aResult[0] <> $S_OK Then Return SetError(@error, @extended, _DISM_GetErrorMessageText($aResult[0]))
   EndIf

   $ImageInfo = $aResult[2]
   $Count = $aResult[3]
   If $Count <> 0 Then
	  Local $tmp_tagDismImageInfo = ""
	  Local $iOSVersion = 3

	  ; create array of DismImageInfo Structure
	  For $i = 1 To $Count
		 $tmp_tagDismImageInfo &= $tagDismImageInfo
		 If $i = $Count Then ExitLoop
		 $tmp_tagDismImageInfo &= ";"
	  Next

	  ; create DismImageInfo Structure
	  Local $getImageInfo = DllStructCreate($tmp_tagDismImageInfo, $ImageInfo)

	  ; image info params
	  Local $iiParams = "ImageType;ImageIndex;ImageName;ImageDescription;ImageSize;Architecture;ProductName;EditionId;" & _
						"InstallationType;Hal;ProductType;ProductSuite;Version;Service Pack-Build;Service Pack-Number;" & _
						"Bootable;SystemRoot;Language(s);DefaultLanguage;Size;DirectoryCount;FileCount;CreatedTime;ModifiedTime"
	  ; array of image info params
	  Local $a_iiParams = StringSplit($iiParams, ';')
	  Local $aStDataTypes = StringSplit($tmp_tagDismImageInfo, ';') 
	  
	  Local $aReturn[$Count+1][$a_iiParams[0]] ; Add a row for Description
	  ; create column titles
	  For $i = 1 To $a_iiParams[0]
		 $aReturn[0][$i-1] = $a_iiParams[$i]
	  Next
	  
	  Local $e = 1 ; running element

	  ; get ImageInfo
	  For $row = 1 To $Count
		 For $col = 1 To $a_iiParams[0]
			Local $OSVersion = "", $index = $col ; reset index and OSVersion after every column
			
			; check if data is empty
			If StringInStr($aStDataTypes[$e], "PTR") <> 0 Then
			   If Not ($aStDataTypes[$e] = "PTR Language") And Not ($aStDataTypes[$e] = "PTR CustomizedInfo") Then
				  $curElement = DllStructGetData(DllStructCreate("WCHAR [260]", DllStructGetData($getImageInfo, $e)), 1)
				  If $curElement = "" Then
					 $e += 1
					 ContinueLoop
				  EndIf
				  ; create entry point to switch loop
				  $index = "PTR"
			   EndIf
			ElseIf DllStructGetData($getImageInfo, $e) == "" Then
			   $e += 1
			   ContinueLoop
			EndIf
			
			Switch $index
			   Case "PTR"
				  $aReturn[$row][$col-1] = $curElement
			   Case 1
				  $aReturn[$row][$col-1] = _DISM_GetImageType(DllStructGetData($getImageInfo, $e))
			   Case 6
				  ; Set Architecture
				  If DllStructGetData($getImageInfo, $e) = 9 Then $aReturn[$row][$col-1] = "x64"
				  If DllStructGetData($getImageInfo, $e) = 6 Then $aReturn[$row][$col-1] = "ia64"
				  If DllStructGetData($getImageInfo, $e) = 0 Then $aReturn[$row][$col-1] = "x86"
			   Case 13
				  For $i = 1 To $iOSVersion
					 $OSVersion &= DllStructGetData($getImageInfo, $e)
					 $e += 1
					 If $i = $iOSVersion Then ExitLoop
					 $OSVersion &= "."
				  Next
				  $aReturn[$row][$col-1] = $OSVersion
				  ContinueLoop
			   Case 16
				  $aReturn[$row][$col-1] = _DISM_GetImageBootable(DllStructGetData($getImageInfo, $e))
			   Case 18
				  ; get Language
				  $lCount = DllStructGetData($getImageInfo, $e+1)
				  If $lCount <> 0 Then
					 Local $tmp_tagDismLanguage = ""

					 ; create array of DismLanguage Structure
					 For $i = 1 To $lCount
						$tmp_tagDismLanguage &= $tagDismLanguage
						If $i = $lCount Then ExitLoop
						$tmp_tagDismLanguage &= ";"
					 Next

					 ; create DismLanguage Structure
					 Local $getLanguage = DllStructCreate($tmp_tagDismLanguage, DllStructGetData($getImageInfo, $e))
					 
					 ; language(s) temp
					 Local $aLang[$lCount]
					 
					 For $i = 1 To $lCount
						$curElement = DllStructGetData(DllStructCreate("WCHAR [260]", DllStructGetData($getLanguage, $i)), 1)
						$aReturn[$row][$col-1] &= $curElement
						$aLang[$i-1] = $curElement
						If $i = $lCount Then ExitLoop
						$aReturn[$row][$col-1] &= ";"
					 Next
					 
					 ; get DefaultLanguage
					 $col += 1
					 $langIndex = DllStructGetData($getImageInfo, $e+2)
					 $aReturn[$row][$col-1] = $aLang[$langIndex]

					 ; free resources
					 _DISM_Delete($getLanguage)
				  EndIf
				  $e += 2
			   Case 20
				  ; get WimCustomizedInfo
				  $WimCustomizedInfo = DllStructGetData($getImageInfo, $e)
				  If $WimCustomizedInfo <> 0 Then
					 Local $iWimCustomizedInfo = 5, $iTime = 8
					 
					 ; create DismWimCustomizedInfo Structure
					 Local $getWimCustomizedInfo = DllStructCreate($tagDismWimCustomizedInfo, $WimCustomizedInfo)
					 Local $getTime              = DllStructCreate($_tagSYSTEMTIME)

					 Local $e2 = 1 ; running element 2

					 For $col = $col To $a_iiParams[0]
						If StringInStr($a_iiParams[$col], "Time") <> 0 Then
						   For $i = 1 To $iTime
							  DllStructSetData($getTime, $i, DllStructGetData($getWimCustomizedInfo, $e2))
							  $e2 += 1
						   Next
						   $aReturn[$row][$col-1] = _Date_Time_SystemTimeToDateTimeStr($getTime)
						   ContinueLoop
						EndIf
						
						$aReturn[$row][$col-1] = DllStructGetData($getWimCustomizedInfo, $e2)
						$e2 += 1
					 Next
					 
					 ; free resources
					 _DISM_Delete($getWimCustomizedInfo)
					 _DISM_Delete($getTime)
				  EndIf
			   Case Else
				  $aReturn[$row][$col-1] = DllStructGetData($getImageInfo, $e)
			EndSwitch
			$e += 1
		 Next
	  Next
	  
	  ; free resources
	  _DISM_Delete($getImageInfo)
	  
	  Return SetExtended(_WinAPI_GetLastError(), $aReturn)
   EndIf  

   Return SetExtended(_WinAPI_GetLastError(), _DISM_GetErrorMessageText($aResult[0]))
EndFunc   ;==>_DISM_GetImageInfo


; #FUNCTION# ====================================================================================================================
; Name...........: _DISM_GetMountedImageInfo
; Description ...: Returns an array of DismMountedImageInfo Structure elements that describe the images that are mounted currently.
; Syntax.........: _DISM_GetMountedImageInfo()
; Parameters ....:
; Return values .: Success - Returns an 2D array where:
;				   			 | $aReturn[0][0] - MountPath     - A relative or absolute path to the mounted image.
;				   			 | $aReturn[0][1] - ImageFilePath - A relative or absolute path to the image file.
;				   			 | $aReturn[0][2] - ImageIndex    - The index number of the image. Index numbering starts at 1.
;				   			 | $aReturn[0][3] - MountMode     - Specifies whether an image is mounted as read-only or as read-write.
;															    | ReadWrite - Mounts an image in read-write mode.
;															    | ReadOnly  - Mounts an image in read-only mode.
;				   			 | $aReturn[0][4] - MountStatus   - Indicates whether a mounted image needs to be remounted.
;															    | Ok           - Indicates that the mounted image is mounted and ready for servicing.
;															    | NeedsRemount - Indicates that the mounted image needs to be remounted before being serviced.
;															    | Invalid      - Indicates that the mounted image is corrupt and is in an invalid state.
;                  Failure - Returns _DISM_GetErrorMessageText() and Sets @Error:
;                  			 | 0 - No DLLCall error.
; 				   			 | 1 - Unable to use the DLL file
; 				   			 | 2 - Unknown "return type"
; 				   			 | 3 - "function" not found in the DLL file
;				   			 | 4 - Bad number of parameters.
;				   Both    - Sets @Extended to _WinAPI_GetLastError()
; Author(s) .....: André Cut
; Modified.......:
; Remarks .......: Only images mounted using the DISM infrastructure will be returned. If a .vhd file is mounted outside of DISM, such as with the DiskPart tool,
;				   this call will not return information about that image. You must use the DismMountImage Function to mount the image.
;				   The array of DismMountedImageInfo structures are allocated by the DISM API on the heap.
;				   You must call the DismDelete Function, passing the ImageInfo pointer, to free the resources associated with the DismImageInfo structures.
; Related .......: _DISM_GetImageInfo, _DISM_MountImage, _DISM_Delete
; Link ..........; http://msdn.microsoft.com/en-us/library/windows/desktop/hh824745.aspx
; Example .......; HRESULT hr = S_OK;
;				   DismMountedImageInfo* ImageInfo;
;				   UINT& ImageInfoCount;
;				   hr = DismGetMountedImageInfo(&ImageInfo, &ImageInfoCount);
;
; ===============================================================================================================================
Func _DISM_GetMountedImageInfo()

   Local $MountedImageInfo, $Count
   
   Local $aResult = DllCall($ghdismapi, "LONG", "DismGetMountedImageInfo", _
		 "PTR*", $MountedImageInfo, _
		 "UINT*", $Count)
   If @error Then Return SetError(@error, @extended, 0)
   If IsArray($aResult) = 1 Then
	  If $aResult[0] <> $S_OK Then Return SetError(@error, @extended, _DISM_GetErrorMessageText($aResult[0]))
   EndIf

   $MountedImageInfo = $aResult[1]
   $Count = $aResult[2]
   If $Count <> 0 Then  
	  Local $tmp_tagDismMountedImageInfo = ""
	  
	  ; create array of DismGetMountedImageInfo Structure
	  For $i = 1 To $Count
		 $tmp_tagDismMountedImageInfo &= $tagDismMountedImageInfo
		 If $i = $Count Then ExitLoop
		 $tmp_tagDismMountedImageInfo &= ";"
	  Next
	  
	  Local $getMountedImageInfo = DllStructCreate($tmp_tagDismMountedImageInfo, $MountedImageInfo)
	  
	  Local $gmiiParams = "MountPath;ImageFilePath;ImageIndex;MountMode;MountStatus" ; mounted image info params
	  Local $a_gmiiParams = StringSplit($gmiiParams, ';') ; array of mounted image info params
	  
	  Local $aReturn[$Count+1][$a_gmiiParams[0]]
	  ; create column titles
	  For $i = 1 To $a_gmiiParams[0]
		 $aReturn[0][$i-1] = $a_gmiiParams[$i]
	  Next
	  
	  Local $e = 1 ; running element
	  
	  ; get MountedImageInfo
	  For $row = 1 To $Count
		 For $col = 1 To $a_gmiiParams[0]
			$index = $col ; reset index after every column

			; check if data is empty
			If DllStructGetData($getMountedImageInfo, $e) == "" Then
			   $e += 1
			   ContinueLoop
			EndIf
			
			Switch $index		 
			   Case 1, 2
				  $curElement = DllStructGetData(DllStructCreate("WCHAR [260]", DllStructGetData($getMountedImageInfo, $e)), 1)
				  ; check if data is empty
				  If $curElement == "" Then
					 $e += 1
					 ContinueLoop
				  EndIf				  
				  $aReturn[1][$col-1] = $curElement
			   Case 3
				  $aReturn[1][$col-1] = DllStructGetData($getMountedImageInfo, $e)
			   Case 4
				  $aReturn[1][$col-1] = _DISM_GetMountMode(DllStructGetData($getMountedImageInfo, $e))
			   Case 5
				  $aReturn[1][$col-1] = _DISM_GetMountStatus(DllStructGetData($getMountedImageInfo, $e))
			EndSwitch
			$e += 1
		 Next
	  Next
	  
	  ; free resources
	  _DISM_Delete($getMountedImageInfo)
   
	  Return SetExtended(_WinAPI_GetLastError(), $aReturn)
   EndIf
   
   Return SetExtended(_WinAPI_GetLastError(), _DISM_GetErrorMessageText($aResult[0]))
EndFunc   ;==>_DISM_GetMountedImageInfo


; #FUNCTION# ====================================================================================================================
; Name...........: _DISM_GetPackageInfo
; Description ...: Retrieves all of the standard package properties as the DismGetPackages Function, as well as more specific package information and custom properties.
; Syntax.........: _DISM_GetPackageInfo($Session, $Identifier, ByRef $CustomProperty, ByRef $Feature, $PackageIdentifier = $DismPackageName)
; Parameters ....: $Session 	   	  - A valid DISM Session. The DISM Session must be associated with an image. You can associate a session with an image by using the DismOpenSession Function.
;				   $Identifier		  - Either an absolute path to a .cab file or the package name, depending on the PackageIdentifier parameter value.
;				   $CustomProperty	  - A Reference to an array where:
;				   						| $aCustomProperty[0] - Name  - The name of the custom property.
;				   						| $aCustomProperty[1] - Value - The value of the custom property.
;				   						| $aCustomProperty[2] - Path  - The path of the custom property.
;				   $Feature			  - A Reference to an 2D array where:
;				   						| $aFeature[0][0] - FeatureName - The name of the feature.
;				   						| $aFeature[0][1] - State 	    - Specifies the state of a package or a feature.
;																	      | NotPresent		   - The package or feature is not present.
;																	      | UninstallPending   - An uninstall process for the package or feature is pending. Additional processes are pending and must be completed before the package or feature is successfully uninstalled.
;																	      | Staged 			   - The package or feature is staged.
;																	      | Resolved 		   - Metadata about the package or feature has been added to the system, but the package or feature is not present.
;																	      | Removed 		   - Same as $DismStateResolved.
;																	      | Installed 		   - The package or feature is installed.
;																	      | InstallPending 	   - The install process for the package or feature is pending. Additional processes are pending and must be completed before the package or feature is successfully installed.
;																	      | Superseded 		   - The package or feature has been superseded by a more recent package or feature.
;																	      | PartiallyInstalled - The package or feature is partially installed. Some parts of the package or feature have not been installed.
;				   $PackageIdentifier - Specifies whether a package is identified by name or by file path.
;				   						| $DismPackageNone 	   - No package is specified.
;				   						| $DismPackageName 	   - The package is identified by its name.
;				   						| $DismDismPackagePath - The package is specified by its path.
; Return values .: Success - Returns an 2D array where:
;				   			 | $aReturn[0][0]  - PackageName 	  	- The name of the package.
;				   			 | $aReturn[0][1]  - PackageState 	    - Specifies the state of a package or a feature, see feature state above.
;				   			 | $aReturn[0][2]  - ReleaseType 		- Specifies the release type of a package.
;				   			 										  | CriticalUpdate - The package is a critical update.
;				   			 										  | Driver 		   - The package is a driver.
;				   			 										  | FeaturePack    - The package is a feature pack.
;				   			 										  | Hotfix 		   - The package is a hotfix.
;				   			 										  | SecurityUpdate - The package is a security update.
;				   			 										  | SoftwareUpdate - The package is a software update.
;				   			 										  | Update 		   - The package is a general update.
;				   			 										  | UpdateRollup   - The package is an update rollup.
;				   			 										  | LanguagePack   - The package is a language pack.
;				   			 										  | Foundation 	   - The package is a foundation package.
;				   			 										  | ServicePack    - The package is a service pack.
;				   			 										  | Product 	   - The package is a product release.
;				   			 										  | LocalPack 	   - The package is a local pack.
;				   			 										  | Other 		   - The package is another type of release.
;				   			 | $aReturn[0][3]  - InstallTime 	    - The date and time that the package was installed. This field is local time, based on the servicing host computer.
;				   			 | $aReturn[0][4]  - Applicable 		- TRUE if the package is applicable to the image, otherwise FALSE.
;				   			 | $aReturn[0][5]  - Copyright 	  	    - The copyright information of the package.
;				   			 | $aReturn[0][6]  - Company 		    - The company that released the package.
;				   			 | $aReturn[0][7]  - CreationTime 	    - The date and time that the package was created. This field is local time, based on the time zone of the computer that created the package.
;				   			 | $aReturn[0][8]  - DisplayName 	    - The display name of the package.
;				   			 | $aReturn[0][9]  - Description 		- A description of the purpose of the package.
;				   			 | $aReturn[0][10] - InstallClient 	  	- The client that installed this package.
;				   			 | $aReturn[0][11] - InstallPackageName - The original file name used for the package during installation.
;				   			 | $aReturn[0][12] - LastUpdateTime 	- The date and time when this package was last updated. This field is local time, based on the servicing host computer.
;				   			 | $aReturn[0][13] - ProductName 		- The product name for this package.
;				   			 | $aReturn[0][14] - ProductVersion 	- The product version for this package.
;				   			 | $aReturn[0][15] - RestartRequired 	- Specifies whether a restart is required after enabling a feature or installing a package.
;				   			 										  | No       - No restart is required.
;				   			 										  | Possible - This package or feature might require a restart.
;				   			 										  | Required - This package or feature always requires a restart.
;				   			 | $aReturn[0][16] - FullyOffline 	    - Specifies whether a package can be installed to an offline image without booting the image.
;				   			 										  | Installable       	    - The package can be installed to an offline image without booting the image.
;				   			 										  | NotInstallable 		    - You must boot into the image in order to complete installation of this package.
;				   			 										  | InstallableUndetermined - You may have to boot the image in order to complete the installation of this package.
;				   			 | $aReturn[0][17] - SupportInformation - A string listing additional support information for this package.
;                  Failure - Returns _DISM_GetErrorMessageText() and Sets @Error:
;                  			 | 0 - No DLLCall error.
; 				   			 | 1 - Unable to use the DLL file
; 				   			 | 2 - Unknown "return type"
; 				   			 | 3 - "function" not found in the DLL file
;				   			 | 4 - Bad number of parameters.
;				   Both    - Sets @Extended to _WinAPI_GetLastError()
; Author(s) .....: André Cut
; Modified.......:
; Remarks .......: You can use this function to determine whether a package is applicable to the specified image.
;				   The DismPackageInfo Structure contains an Applicable field, which is a Boolean that returns TRUE if the package is applicable and FALSE if the package is not applicable to the specified image.
; Related .......: _DISM_GetPackages, _DISM_RemovePackage, _DISM_AddPackage, _DISM_Delete
; Link ..........; http://msdn.microsoft.com/en-us/library/windows/desktop/hh824801.aspx
; Example .......; HRESULT hr = S_OK;
;				   DismPackageInfo PackageInfo;
;
;				   hr = DismGetPackageInfo(Session, "C:\packages\calc.cab", PackagePath, &PackageInfo);
;
; ===============================================================================================================================
Func _DISM_GetPackageInfo($Session, $Identifier, ByRef $CustomProperty, ByRef $Feature, $PackageIdentifier = $DismPackageName)

   Local $PackageInfo
   
   Local $aResult = DllCall($ghdismapi, "LONG", "DismGetPackageInfo", _
		 "PTR", $Session, _
		 "WSTR", $Identifier, _
		 "INT", $PackageIdentifier, _
		 "PTR*", $PackageInfo _
		 )
   If @error Then Return SetError(@error, @extended, 0)
   If IsArray($aResult) = 1 Then
	  If $aResult[0] <> $S_OK Then Return SetError(@error, @extended, _DISM_GetErrorMessageText($aResult[0]))
   EndIf

   $PackageInfo = $aResult[4]
   If $PackageInfo <> 0 Then
	  Local $cCount, $fCount, $iTime = 8

	  ; create DismPackageInfo Structure
	  Local $getPackageInfo    = DllStructCreate($tagDismPackageInfo, $PackageInfo)
	  Local $getInstallTime    = DllStructCreate($_tagSYSTEMTIME)
	  Local $getCreationTime   = DllStructCreate($_tagSYSTEMTIME)
	  Local $getLastUpdateTime = DllStructCreate($_tagSYSTEMTIME)

	  ; package info params
	  Local $pParams = "PackageName;PackageState;ReleaseType;InstallTime;Applicable;Copyright;Company;CreationTime;DisplayName;Description;InstallClient;InstallPackageName;" & _
						"LastUpdateTime;ProductName;ProductVersion;RestartRequired;FullyOffline;SupportInformation"
	  ; array of package info params
	  Local $a_pParams    = StringSplit($pParams, ';')
	  Local $aStDataTypes = StringSplit($tagDismPackageInfo, ';')

	  Local $aReturn[2][$a_pParams[0]]
	  ; create column titles
	  For $i = 1 To $a_pParams[0]
		 $aReturn[0][$i-1] = $a_pParams[$i]
	  Next

	  ; get custom property count
	  $cCount = DllStructGetData($getPackageInfo, "CustomPropertyCount")
	  If $cCount <> 0 Then
		 ; create DismCustomProperty Structure
		 Local $getCustomProperty = DllStructCreate($tagDismCustomProperty, DllStructGetData($getPackageInfo, "CustomProperty"))
		 
		 Local $cParams = "Name;Value;Path" ; custom property params
		 Local $a_cParams = StringSplit($cParams, ';') ; array of custom property params
		 
		 Local $aCustomProperty[2][$a_cParams[0]]
		 ; create column titles
		 For $i = 1 To $a_cParams[0]
			$aCustomProperty[0][$i-1] = $a_cParams[$i]
		 Next
		 
		 Local $e = 0 ; running element
		 
		 ; get CustomProperty
		 For $col = 1 To $a_cParams[0]
			$e += 1
			$curElement = DllStructGetData(DllStructCreate("WCHAR [260]", DllStructGetData($getCustomProperty, $e)), 1)
			$aCustomProperty[1][$col-1] = $curElement
		 Next
		 
		 ; free resources
		 _DISM_Delete($getCustomProperty)	  
		 
		 $CustomProperty = $aCustomProperty
	  EndIf
	  
	  ; get feature count
	  $fCount = DllStructGetData($getPackageInfo, "FeatureCount")
	  If $fCount <> 0 Then	  
		 Local $tmp_tagDismFeature = ""
		 
		 ; create array of DismFeature Structure
		 For $i = 1 To $fCount
			$tmp_tagDismFeature &= $tagDismFeature
			If $i = $fCount Then ExitLoop
			$tmp_tagDismFeature &= ";"
		 Next
		 
		 Local $getFeature = DllStructCreate($tmp_tagDismFeature, DllStructGetData($getPackageInfo, "Feature"))
		 
		 Local $fParams = "FeatureName;State" ; feature params
		 Local $a_fParams = StringSplit($fParams, ';') ; array of feature params
		 
		 Local $aFeature[$fCount+1][$a_fParams[0]]
		 ; create column titles
		 For $i = 1 To $a_fParams[0]
			$aFeature[0][$i-1] = $a_fParams[$i]
		 Next
		 
		 Local $e = 0 ; running element
		 
		 ; get Feature
		 For $row = 1 To $fCount
			For $col = 1 To $a_fParams[0]
			   $e += 1
			   
			   If $a_fParams[$col] = "FeatureName" Then
				  $curElement = DllStructGetData(DllStructCreate("WCHAR [260]", DllStructGetData($getFeature, $e)), 1)
				  $aFeature[$row][$col-1] = $curElement
				  ContinueLoop
			   EndIf
			   $aFeature[$row][$col-1] = _DISM_GetPackageFeatureState(DllStructGetData($getFeature, $e))
			Next	  
		 Next
		 
		 ; free resources
		 _DISM_Delete($getFeature)
		 
		 ; assign 2D-Array to Reference
	  $Feature = $aFeature
	  EndIf
   
	  Local $e = 1 ; running element
	  
	  ; get PackageInfo
	  For $col = 1 To $a_pParams[0]
		 $index = $col ; reset index
   
		 ; check if data is empty
		 If StringInStr($aStDataTypes[$e], "PTR") <> 0 Then
			$curElement = DllStructGetData(DllStructCreate("WCHAR [260]", DllStructGetData($getPackageInfo, $e)), 1)
			If $curElement = "" Then
			   $e += 1
			   ContinueLoop
			EndIf
			; create entry point to switch loop
			$index = "PTR"
		 ElseIf DllStructGetData($getPackageInfo, $e) == "" Then
			$e += 1
			ContinueLoop		 
		 EndIf
		 
		 Switch $index		 
			Case "PTR"
			   $aReturn[1][$col-1] = $curElement
			Case 2
			   $aReturn[1][$col-1] = _DISM_GetPackageFeatureState(DllStructGetData($getPackageInfo, $e))
			Case 3
			   $aReturn[1][$col-1] = _DISM_GetReleaseType(DllStructGetData($getPackageInfo, $e))
			Case 4
			   For $i = 1 To $iTime
				  DllStructSetData($getInstallTime, $i, DllStructGetData($getPackageInfo, $e))
				  $e += 1
			   Next
			   $aReturn[1][$col-1] = _Date_Time_SystemTimeToDateTimeStr($getInstallTime)
			   ContinueLoop
			Case 8
			   For $i = 1 To $iTime
				  DllStructSetData($getCreationTime, $i, DllStructGetData($getPackageInfo, $e))
				  $e += 1
			   Next
			   $aReturn[1][$col-1] = _Date_Time_SystemTimeToDateTimeStr($getCreationTime)
			   ContinueLoop
			Case 13
			   For $i = 1 To $iTime
				  DllStructSetData($getLastUpdateTime, $i, DllStructGetData($getPackageInfo, $e))
				  $e += 1
			   Next
			   $aReturn[1][$col-1] = _Date_Time_SystemTimeToDateTimeStr($getLastUpdateTime)
			   ContinueLoop		
			Case 16
			   $aReturn[1][$col-1] = _DISM_GetRestartType(DllStructGetData($getPackageInfo, $e))
			Case 17
			   $aReturn[1][$col-1] = _DISM_GetFullyOfflineInstallableType(DllStructGetData($getPackageInfo, $e))
			Case Else
			   $aReturn[1][$col-1] = DllStructGetData($getPackageInfo, $e)
		 EndSwitch	  
		 $e += 1
	  Next
   
	  ; free resources
	  _DISM_Delete($getInstallTime)
	  _DISM_Delete($getCreationTime)
	  _DISM_Delete($getLastUpdateTime)
	  _DISM_Delete($getPackageInfo)
   
	  Return SetExtended(_WinAPI_GetLastError(), $aReturn)
   EndIf

   Return SetExtended(_WinAPI_GetLastError(), _DISM_GetErrorMessageText($aResult[0]))
EndFunc   ;==>_DISM_GetPackageInfo


; #FUNCTION# ====================================================================================================================
; Name...........: _DISM_GetPackages
; Description ...: Lists each package in an image and provides basic information about each package, such as the package name and type of package.
; Syntax.........: _DISM_GetPackages($Session)
; Parameters ....: $Session - A valid DISM Session. The DISM Session must be associated with an image. You can associate a session with an image by using the DismOpenSession Function.
; Return values .: Success - Returns an 2D array where:
;				   			 | $aReturn[0][0] - PackageName  - The name of the package.
;				   			 | $aReturn[0][1] - PackageState - Specifies the state of a package or a feature.
;														       | NotPresent	        - The package or feature is not present.
;														       | UninstallPending   - An uninstall process for the package or feature is pending. Additional processes are pending and must be completed before the package or feature is successfully uninstalled.
;														       | Staged 		    - The package or feature is staged.
;														       | Resolved 		    - Metadata about the package or feature has been added to the system, but the package or feature is not present.
;														       | Removed 		    - Same as $DismStateResolved.
;														       | Installed 	        - The package or feature is installed.
;														       | InstallPending     - The install process for the package or feature is pending. Additional processes are pending and must be completed before the package or feature is successfully installed.
;														       | Superseded 	    - The package or feature has been superseded by a more recent package or feature.
;														       | PartiallyInstalled - The package or feature is partially installed. Some parts of the package or feature have not been installed.
;				   			 | $aReturn[0][2] - ReleaseType  - Specifies the release type of a package.
;				   			 							       | CriticalUpdate - The package is a critical update.
;				   			 							       | Driver 		- The package is a driver.
;				   			 							       | FeaturePack    - The package is a feature pack.
;				   			 							       | Hotfix 		- The package is a hotfix.
;				   			 							       | SecurityUpdate - The package is a security update.
;				   			 							       | SoftwareUpdate - The package is a software update.
;				   			 							       | Update 		- The package is a general update.
;				   			 							       | UpdateRollup   - The package is an update rollup.
;				   			 							       | LanguagePack   - The package is a language pack.
;				   			 							       | Foundation 	- The package is a foundation package.
;				   			 							       | ServicePack    - The package is a service pack.
;				   			 							       | Product 	    - The package is a product release.
;				   			 							       | LocalPack 	    - The package is a local pack.
;				   			 							       | Other 		    - The package is another type of release.
;				   			 | $aReturn[0][3] - InstallTime  - The date and time that the package was installed. This field is local time, based on the servicing host computer.
;                  Failure - Returns _DISM_GetErrorMessageText() and Sets @Error:
;                  			 | 0 - No DLLCall error.
; 				   			 | 1 - Unable to use the DLL file
; 				   			 | 2 - Unknown "return type"
; 				   			 | 3 - "function" not found in the DLL file
;				   			 | 4 - Bad number of parameters.
;				   Both    - Sets @Extended to _WinAPI_GetLastError()
; Author(s) .....: André Cut
; Modified.......:
; Remarks .......: When you are finished with the Package array, you must remove it by using the DismDelete Function.
; Related .......: _DISM_Delete, _DISM_GetPackageInfo, _DISM_RemovePackage, _DISM_AddPackage
; Link ..........; http://msdn.microsoft.com/en-us/library/windows/desktop/hh824759.aspx
; Example .......; HRESULT hr = S_OK;
;				   DismPackage* Package = NULL;
;				   UINT Count = 0;
;				   hr = DismGetPackages(Session, &Package, &Count);
;
; ===============================================================================================================================
Func _DISM_GetPackages($Session)

   Local $Package, $Count
   
   Local $aResult = DllCall($ghdismapi, "LONG", "DismGetPackages", _
		 "PTR", $Session, _
		 "PTR*", $Package, _
		 "UINT*", $Count _
		 )
   If @error Then Return SetError(@error, @extended, 0)
   If IsArray($aResult) = 1 Then
	  If $aResult[0] <> $S_OK Then Return SetError(@error, @extended, _DISM_GetErrorMessageText($aResult[0]))
   EndIf

   $Package = $aResult[2]
   $Count   = $aResult[3]
   If $Count <> 0 Then
	  Local $tmp_tagDismPackage = "", $iInstallTime = 8

	  ; Create array of DismPackage Structure
	  For $i = 1 To $Count
		 $tmp_tagDismPackage &= $tagDismPackage
		 If $i = $Count Then ExitLoop
		 $tmp_tagDismPackage &= ";"
	  Next
	  
	  ; Create DismPackage Structure
	  Local $getPackage     = DllStructCreate($tmp_tagDismPackage, $Package)
	  Local $getInstallTime = DllStructCreate($_tagSYSTEMTIME)

	  Local $pParams = "PackageName;PackageState;ReleaseType;InstallTime" ; package params
	  Local $a_pParams = StringSplit($pParams, ';') ; array of package params

	  Local $aReturn[$Count+1][$a_pParams[0]]
	  ; Create column titles
	  For $i = 1 To $a_pParams[0]
		 $aReturn[0][$i-1] = $a_pParams[$i]
	  Next

	  Local $e = 1 ; running element
	  
	  ; get Packages
	  For $row = 1 To $Count
		 For $col = 1 To $a_pParams[0]
			$index = $col ; reset index
	  
			; check if data is empty
			If DllStructGetData($getPackage, $e) == "" Then
			   $e += 1
			   ContinueLoop		 
			EndIf
			
			Switch $index
			   Case 1
				  $curElement = DllStructGetData(DllStructCreate("WCHAR [260]", DllStructGetData($getPackage, $e)), 1)
				  If $curElement = "" Then
					 $e += 1
					 ContinueLoop
				  EndIf
				  $aReturn[$row][$col-1] = $curElement
			   Case 2
				  $aReturn[$row][$col-1] = _DISM_GetPackageFeatureState(DllStructGetData($getPackage, $e))
			   Case 3
				  $aReturn[$row][$col-1] = _DISM_GetReleaseType(DllStructGetData($getPackage, $e))
			   Case 4
				  For $i = 1 To $iInstallTime
					 DllStructSetData($getInstallTime, $i, DllStructGetData($getPackage, $e))
					 $e += 1
				  Next
				  $aReturn[$row][$col-1] = _Date_Time_SystemTimeToDateTimeStr($getInstallTime)
				  ExitLoop
			EndSwitch
			$e += 1
		 Next
	  Next
   
	  ; free resources
	  _DISM_Delete($getPackage)
	  _DISM_Delete($getInstallTime)
   
	  Return SetExtended(_WinAPI_GetLastError(), $aReturn)
   EndIf
   
   Return SetExtended(_WinAPI_GetLastError(), _DISM_GetErrorMessageText($aResult[0]))
EndFunc   ;==>_DISM_GetPackages


; #FUNCTION# ====================================================================================================================
; Name...........: _DISM_Initialize
; Description ...: Initializes DISM API. DismInitialize must be called once per process before calling any other DISM API functions.
; Syntax.........: _DISM_Initialize($LogLevel, $LogFilePath, $ScratchDirectory)
; Parameters ....: $LogLevel         - Specifies the kind of information that is reported in the log file.
;							           | $DismLogErrors             - Log file only contains errors.
;							           | $DismLogErrorsWarnings     - Log file contains errors and warnings.
;							           | $DismLogErrorsWarningsInfo - Log file contains errors, warnings, and additional information.
;				   $LogFilePath      - [Optional]. A relative or absolute path to a log file. All messages generated will be logged to this path. If NULL, the default log path, %windir%\Logs\DISM\dism.log, will be used.
;				   $ScratchDirectory - [Optional]. A relative or absolute path to a scratch directory. DISM API will use this directory for internal operations. If NULL, the default temp directory, \Windows\%Temp%, will be used.
; Return values .: Success - Returns $S_OK.
;                  Failure - Returns _DISM_GetErrorMessageText() and Sets @Error:
; 							 Sets @Error:
;                  			 | 0 - No DLLCall error.
; 				   			 | 1 - Unable to use the DLL file
; 				   			 | 2 - Unknown "return type"
; 				   			 | 3 - "function" not found in the DLL file
;				   			 | 4 - Bad number of parameters.
;				   Both    - Sets @Extended to _WinAPI_GetLastError()
; Author(s) .....: André Cut
; Modified.......:
; Remarks .......: The client code must call DismInitialize once per process. DISM API will serialize concurrent calls to DismInitialize.
;				   The first call will succeed and the others will fail. For more information, see Using the DISM API.
; Related .......: _DISM_Shutdown
; Link ..........; http://msdn.microsoft.com/en-us/library/windows/desktop/hh824803.aspx
; Example .......; HRESULT hr = S_OK;
;				   DismLogLevel Level = DismLogErrorsWarningsInfo;
;				   hr = DismInitialize(Level, NULL, NULL);
;
; ===============================================================================================================================
Func _DISM_Initialize($LogLevel, $LogFilePath = 0, $ScratchDirectory = 0)

   ; control param passing
   Local $sType[2] = ["WSTR", "WSTR"]
   If Not IsString($LogFilePath) And $LogFilePath = 0 Then $sType[0] = "PTR"
   If Not IsString($ScratchDirectory) And $ScratchDirectory = 0 Then $sType[1] = "PTR"  
   
   Local $aResult = DllCall($ghdismapi, "LONG", "DismInitialize", _
		 "INT", $LogLevel, _
		 $sType[0], $LogFilePath, _
		 $sType[1], $ScratchDirectory _
		 )
   If @error Then Return SetError(@error, @extended, 0)
   Return SetExtended(_WinAPI_GetLastError(), _DISM_GetErrorMessageText($aResult[0]))
EndFunc   ;==>_DISM_Initialize


; #FUNCTION# ====================================================================================================================
; Name...........: _DISM_MountImage
; Description ...: Returns an array of DismMountedImageInfo Structure elements that describe the images that are mounted currently.
; Syntax.........: _DISM_MountImage($ImageFilePath, $MountPath, $ImageIndex, $ImageIdentifier = $DismImageIndex, $Flags = $DISM_MOUNT_READONLY)
; Parameters ....: $ImageFilePath   - The path to the WIM or VHD file on the local computer. A .wim, .vhd, or .vhdx file name extension is required.
;				   $MountPath       - The path of the location where the image should be mounted. This mount path must already exist on the computer. The Windows image in a .wim, .vhd, or .vhdx file can be mounted to an empty folder on an NTFS formatted drive. A Windows image in a .vhd or .vhdx file can also be mounted to an unassigned drive letter. You cannot mount an image to the root of the existing drive.
;				   $ImageIndex      - The index of the image in the WIM file that you want to mount. For a VHD file, you must specify an index of 1.
;				   $ImageName       - [Optional]. The name of the image that you want to mount.
;				   $ImageIdentifier - A DismImageIdentifier Enumeration value such as DismImageIndex.
;                                     | $DismImageIndex - Identify the image by index number.
;                                     | $DismImageName  - Identify the image by name.
;				   $Flags           - The mount flags to use for this operation. For more information about mount flags, see DISM API Constants.
;                                     | $DISM_MOUNT_READWRITE       - Indicates to the DismMountImage Function that the image should be mounted with both read and write access.
;                                     | $DISM_MOUNT_READONLY        - Indicates to the DismMountImage Function that the image should be mounted with read access only.
;                                     | $DISM_MOUNT_OPTIMIZE        - Indicates to the DismMountImage Function that the image should be mounted with optimization. When the optimize option is used, only the top level of the file directory in the image will be mapped to the mount location. The first time that you access a file path that is not initially mapped, that branch of the directory will be mounted. As a result, there may be an increase in the time that is required to access a directory for the first time after mounting an image using the optimize option.
;                                     | $DISM_MOUNT_CHECK_INTEGRITY - Indicates to the DismMountImage Function to set a flag on the image specifying whether the image is corrupted.
; Return values .: Success - Returns $S_OK.
;                  Failure - Returns _DISM_GetErrorMessageText() and Sets @Error:
;                  			 | 0 - No DLLCall error.
; 				   			 | 1 - Unable to use the DLL file
; 				   			 | 2 - Unknown "return type"
; 				   			 | 3 - "function" not found in the DLL file
;				   			 | 4 - Bad number of parameters.
;				   Both    - Sets @Extended to _WinAPI_GetLastError()
; Author(s) .....: André Cut
; Modified.......:
; Remarks .......: After mounting an image, use the DismOpenSession Function to start a servicing session. For more information, see Using the DISM API.
;				   Mounting an image from a WIM or VHD file that is stored on the network is not supported. You must specify a file on the local computer.
;				   To mount an image from a VHD file, you must specify an ImageIndex of 1.
;				   The MountPath must be a file path that already exists on the computer. Images in WIM and VHD files can be mounted to an empty folder on an NTFS formatted drive.
;				   You can also mount an image from a VHD file to an unassigned drive letter. You cannot mount an image to the root of the existing drive.
;				   When mounting an image in a WIM file, the image can either be identified by the image index number specified by ImageIndex, or the name of the image specified by ImageName.
;				   ImageIdentifier specifies whether to use the ImageIndex or ImageName parameter to identify the image.
; Related .......: _DISM_OpenSession, _DISM_UnmountImage
; Link ..........; http://msdn.microsoft.com/en-us/library/windows/desktop/hh824731.aspx
; Example .......; HRESULT hr = S_OK;
;				   hr = DismMountImage(L” C:\\test\\images\\myimage.wim”, L"C:\\test\\offline", 1, NULL, DismImageIndex, DISM_MOUNT_READWRITE, NULL, NULL, NULL);
;
; ===============================================================================================================================
Func _DISM_MountImage($ImageFilePath, $MountPath, $ImageIndex, $ImageName = 0, $ImageIdentifier = $DismImageIndex, $Flags = $DISM_MOUNT_READONLY)

   ; control param passing
   Local $sType = "WSTR"
   If Not IsString($ImageName) And $ImageName = 0 Then $sType = "PTR"   
   
   Local $aResult = DllCall($ghdismapi, "LONG", "DismMountImage", _
		 "WSTR", $ImageFilePath, _
		 "WSTR", $MountPath, _
		 "UINT", $ImageIndex, _
		 $sType, $ImageName, _
		 "INT", $ImageIdentifier, _
		 "DWORD", $Flags, _
		 "PTR", 0, _
		 "PTR", 0, _
		 "PTR", 0 _
		 )
   If @error Then Return SetError(@error, @extended, 0)
   Return SetExtended(_WinAPI_GetLastError(), _DISM_GetErrorMessageText($aResult[0]))
EndFunc   ;==>_DISM_MountImage


; #FUNCTION# ====================================================================================================================
; Name...........: _DISM_OpenSession
; Description ...: Associates an offline or online Windows image with a DISMSession.
; Syntax.........: _DISM_OpenSession($ImagePath)
; Parameters ....: $ImagePath - Set ImagePath to one of the following values:
;							    | An absolute or relative path to the root directory of an offline Windows image.
;							    | An absolute or relative path to the root directory of a mounted Windows image. You can mount the image before calling DismOpenSession by using an external tool or by using the DismMountImage Function.
;							    | DISM_ONLINE_IMAGE to associate the DISMSession with the online Windows installation.
; Return values .: Success - Returns a valid DISMSession.
;                  Failure - Returns _DISM_GetErrorMessageText() and Sets @Error:
;                  			 | 0 - No DLLCall error.
; 				   			 | 1 - Unable to use the DLL file
; 				   			 | 2 - Unknown "return type"
; 				   			 | 3 - "function" not found in the DLL file
;				   			 | 4 - Bad number of parameters.
;				   Both    - Sets @Extended to _WinAPI_GetLastError()
; Author(s) .....: André Cut
; Modified.......:
; Remarks .......: The DISMSession can be used to service the image after the DISMOpenSession call is successfully completed.
;				   The DISMSession must be shut down by calling the DismCloseSession Function.
; Related .......: _DISM_CloseSession, _DISM_MountImage
; Link ..........; http://msdn.microsoft.com/en-us/library/windows/desktop/hh824800.aspx
; Example .......; HRESULT hr = S_OK;
;				   DismSession Session = DISM_SESSION_DEFAULT;
;  				   hr = DismOpenSession(L"C:\\Mount\\", NULL, NULL, &Session);
;
; ===============================================================================================================================
Func _DISM_OpenSession($ImagePath, $WindowsDirectory = 0, $SystemDrive = 0)

   ; control param passing
   Local $sType[2] = ["WSTR", "WSTR"]
   If Not IsString($WindowsDirectory) And $WindowsDirectory = 0 Then $sType[0] = "PTR"
   If Not IsString($SystemDrive) And $SystemDrive = 0 Then $sType[1] = "PTR"

   Local $Session

   Local $aResult = DllCall($ghdismapi, "LONG", "DismOpenSession", _
		 "WSTR", $ImagePath, _
		 $sType[0], $WindowsDirectory, _
		 $sType[1], $SystemDrive, _
		 "PTR*", $Session _
		 )
   If @error Then Return SetError(@error, @extended, 0)
   If IsArray($aResult) = 1 Then
	  If $aResult[0] <> $S_OK Then Return SetError(@error, @extended, _DISM_GetErrorMessageText($aResult[0]))
   EndIf

   $Session = $aResult[4]
   If $Session <> 0 Then
	  Return SetExtended(_WinAPI_GetLastError(), Number($Session))
   EndIf

   Return SetExtended(_WinAPI_GetLastError(), _DISM_GetErrorMessageText($aResult[0]))
EndFunc   ;==>_DISM_OpenSession


; #FUNCTION# ====================================================================================================================
; Name...........: _DISM_RemountImage
; Description ...: Remounts a Windows image from the .wim or .vhd file that was previously mounted at the path specified by MountPath. Use the DismOpenSession Function to associate the image with a DISMSession after it is remounted.
;				   You can use the DismRemountImage function when the image is in the DismMountStatusNeedsRemount state, as described by the DismMountStatus Enumeration. The image may enter this state if it is mounted and then a reboot occurs.
; Syntax.........: _DISM_RemountImage($MountPath)
; Parameters ....: $MountPath - A relative or absolute path to the mount directory of the image.
; Return values .: Success - Returns $S_OK.
;                  Failure - Returns _DISM_GetErrorMessageText() and Sets @Error:
;		 					 Notice: Returns $DISMAPI_E_OPEN_HANDLES_UNABLE_TO_REMOUNT_IMAGE_PATH
;                  			 | 0 - No DLLCall error.
; 				   			 | 1 - Unable to use the DLL file
; 				   			 | 2 - Unknown "return type"
; 				   			 | 3 - "function" not found in the DLL file
;				   			 | 4 - Bad number of parameters.
;				   Both    - Sets @Extended to _WinAPI_GetLastError()
; Author(s) .....: André Cut
; Modified.......:
; Remarks .......:
; Related .......: _DISM_MountImage, _DISM_UnmountImage
; Link ..........; http://msdn.microsoft.com/en-us/library/windows/desktop/hh824778.aspx
; Example .......; HRESULT hr = S_OK;
;				   DismSession* Session = NULL;
;				   hr = DismRemountImage(L"C:\\Mount\\");
;
; ===============================================================================================================================
Func _DISM_RemountImage($MountPath)

   Local $aResult = DllCall($ghdismapi, "LONG", "DismRemountImage", _
		 "WSTR", $MountPath _
		 )
   If @error Then Return SetError(@error, @extended, 0)
   Return SetExtended(_WinAPI_GetLastError(), _DISM_GetErrorMessageText($aResult[0]))
EndFunc   ;==>_DISM_RemountImage


; #FUNCTION# ====================================================================================================================
; Name...........: _DISM_RemoveDriver
; Description ...: Removes an out-of-box driver from an offline image.
; Syntax.........: _DISM_RemoveDriver($Session, $DriverPath)
; Parameters ....: $Session    - A valid DISM Session. The DISM Session must be associated with an image. You can associate a session with an image by using the DismOpenSession Function.
;				   $DriverPath - The published file name of the driver that has been added to the image, for example OEM1.inf. You can use the DismGetDrivers Function to get the published name of the driver.
; Return values .: Success - Returns $S_OK.
;                  Failure - Returns _DISM_GetErrorMessageText() and Sets @Error:
;                  			 | 0 - No DLLCall error.
; 				   			 | 1 - Unable to use the DLL file
; 				   			 | 2 - Unknown "return type"
; 				   			 | 3 - "function" not found in the DLL file
;				   			 | 4 - Bad number of parameters.
;				   Both    - Sets @Extended to _WinAPI_GetLastError()
; Author(s) .....: André Cut
; Modified.......:
; Remarks .......: This function only supports offline images.
;				   Removing a boot-critical driver can make the offline Windows image unbootable.
; Related .......: _DISM_AddDriver
; Link ..........; http://msdn.microsoft.com/en-us/library/windows/desktop/hh824729.aspx
; Example .......; HRESULT hr = S_OK;
;				   hr = DismRemoveDriver(Session, "Oem1.inf");
;
; ===============================================================================================================================
Func _DISM_RemoveDriver($Session, $DriverPath)

   Local $aResult = DllCall($ghdismapi, "LONG", "DismRemoveDriver", _
		 "PTR", $Session, _
		 "WSTR", $DriverPath _
		 )
   If @error Then Return SetError(@error, @extended, 0)
   Return SetExtended(_WinAPI_GetLastError(), _DISM_GetErrorMessageText($aResult[0]))
EndFunc   ;==>_DISM_RemoveDriver


; #FUNCTION# ====================================================================================================================
; Name...........: _DISM_RemovePackage
; Description ...: Removes a package from an image.
; Syntax.........: _DISM_RemovePackage($Session, $Identifier, $PackageIdentifier = $DismPackageName)
; Parameters ....: $Session 		  - A valid DISM Session. The DISM Session must be associated with an image. You can associate a session with an image by using the DismOpenSession Function.
;				   $Identifier 		  - Either an absolute path to a .cab file or the package name, depending on the PackageIdentifier parameter value.
;				   $PackageIdentifier - The parameter for a DismPackageIdentifier Enumeration.
;									    | $DismPackageName - Use this value when you want to specify a package by using the package name.
;									    | $DismPackagePath - Use this value when you want to specify a package by using an absolute path to a .cab file.
;									    | $DismPackageNone - Is not a valid value for this function.
; Return values .: Success - Returns $DISMAPI_S_RELOAD_IMAGE_SESSION_REQUIRED.
;                  Failure - Returns _DISM_GetErrorMessageText() and Sets @Error:
;                  			 | 0 - No DLLCall error.
; 				   			 | 1 - Unable to use the DLL file
; 				   			 | 2 - Unknown "return type"
; 				   			 | 3 - "function" not found in the DLL file
;				   			 | 4 - Bad number of parameters.
;				   Both    - Sets @Extended to _WinAPI_GetLastError()
; Author(s) .....: André Cut
; Modified.......:
; Remarks .......: The DismRemovePackage function does not support .msu files.
; Related .......: _DISM_AddPackage, _DISM_GetPackages, _DISM_RemoveDriver, _DISM_DisableFeature
; Link ..........; http://msdn.microsoft.com/en-us/library/windows/desktop/hh824732.aspx
; Example .......; HRESULT hr = S_OK;
;				   hr = DismRemovePackage(Session, "C:\\packages\\test.CAB", PackagePath, NULL, NULL, NULL);
;
; ===============================================================================================================================
Func _DISM_RemovePackage($Session, $Identifier, $PackageIdentifier = $DismPackageName)

   Local $aResult = DllCall($ghdismapi, "LONG", "DismRemovePackage", _
		 "PTR", $Session, _
		 "WSTR", $Identifier, _
		 "INT", $PackageIdentifier, _
		 "PTR", 0, _
		 "PTR", 0, _
		 "PTR", 0 _
		 )
   If @error Then Return SetError(@error, @extended, 0)
   Return SetExtended(_WinAPI_GetLastError(), _DISM_GetErrorMessageText($aResult[0]))
EndFunc   ;==>_DISM_RemovePackage


; #FUNCTION# ====================================================================================================================
; Name...........: _DISM_Shutdown
; Description ...: Shuts down DISM API. DismShutdown must be called once per process. Other DISM API function calls will fail after DismShutdown has been called.
; Syntax.........: _DISM_Shutdown()
; Parameters ....:
; Return values .: Success - Returns $S_OK.
;                  Failure - Returns _DISM_GetErrorMessageText() and Sets @Error:
;							 Notice: Returns $DISMAPI_E_DISMAPI_NOT_INITIALIZED if the DismInitialize Function has not been called.
;							 		 Returns $DISMAPI_E_OPEN_SESSION_HANDLES if any open DISMSession have not been closed.
;                  			 | 0 - No DLLCall error.
; 				   			 | 1 - Unable to use the DLL file
; 				   			 | 2 - Unknown "return type"
; 				   			 | 3 - "function" not found in the DLL file
;				   			 | 4 - Bad number of parameters.
;				   Both    - Sets @Extended to _WinAPI_GetLastError()
; Author(s) .....: André Cut
; Modified.......:
; Remarks .......: You must call DismShutdown once per process. Calls to DismShutdown must be matched to an earlier call to the DismInitialize Function.
; 				   DISM API will serialize concurrent calls to DismShutdown. The first call will succeed and the other calls will fail.
;				   Before calling DismShutdown, you must close all DISMSession using the DismCloseSession Function. If there are open DismSessions when calling DismShutdown, then the DismShutdown call will fail.
;				   For more information, see Using the DISM API.
; Related .......: _DISM_Initialize, _DISM_CloseSession
; Link ..........; http://msdn.microsoft.com/en-us/library/windows/desktop/hh824773.aspx
; Example .......; HRESULT hr = S_OK;
;				   hr = DismShutdown();
;
; ===============================================================================================================================
Func _DISM_Shutdown()
   
   Local $aResult = DllCall($ghdismapi, "LONG", "DismShutdown")
   If @error Then Return SetError(@error, @extended, 0)
   Return SetExtended(_WinAPI_GetLastError(), _DISM_GetErrorMessageText($aResult[0]))
EndFunc   ;==>_DISM_Shutdown


; #FUNCTION# ====================================================================================================================
; Name...........: _DISM_UnmountImage
; Description ...: Unmounts a Windows image from a specified location.
; Syntax.........: _DISM_UnmountImage($MountPath, $Flags)
; Parameters ....: $MountPath - A relative or absolute path to the mount directory of the image.
; 				   $Flags     - The unmount flags to use for this operation. For more information about unmount flags, see DISM API Constants.
; 				                | $DISM_COMMIT_IMAGE              - Indicates to the DismCommitImage Function or the DismUnmountImage Function that changes to the image should be saved.
; 				                | $DISM_DISCARD_IMAGE             - Indicates to the DismCommitImage Function or the DismUnmountImage Function that changes to the image should not be saved.
; 				                | $DISM_COMMIT_GENERATE_INTEGRITY - Indicates to the DismCommitImage Function or the DismUnmountImage Function to set a flag on the image specifying whether the image is corrupted.
; 				                | $DISM_COMMIT_APPEND             - Indicates to the DismCommitImage Function or the DismUnmountImage Function that changes to the image should be saved.
; 				                | $DISM_COMMIT_MASK               - Indicates to the DismUnmountImage Function that all changes should be saved. This flag is equivalent to using DISM_COMMIT_IMAGE, DISM_COMMIT_GENERATE_INTEGRITY, and DISM_COMMIT_APPEND.
; Return values .: Success - Returns $S_OK.
;                  Failure - Returns _DISM_GetErrorMessageText() and Sets @Error:
;                  			 | 0 - No DLLCall error.
; 				   			 | 1 - Unable to use the DLL file
; 				   			 | 2 - Unknown "return type"
; 				   			 | 3 - "function" not found in the DLL file
;				   			 | 4 - Bad number of parameters.
;				   Both    - Sets @Extended to _WinAPI_GetLastError()
; Author(s) .....: André Cut
; Modified.......:
; Remarks .......: After you use the DismCloseSession Function to end every active DISMSession, you can unmount the image using the DismUnmountImage function.
; Related .......: _DISM_MountImage, _DISM_CloseSession, _DISM_RemountImage
; Link ..........; http://msdn.microsoft.com/en-us/library/windows/desktop/hh824802.aspx
; Example .......; HRESULT hr = S_OK;
;				   hr = DismMountImage(L” C:\\test\\images\\myimage.wim”, L"C:\\test\\offline", 1, NULL, DismImageIndex, DISM_MOUNT_READWRITE, NULL, NULL, NULL);
;				   hr = DismUnmountImage (L"C:\\test\\offline", DISM_COMMIT_IMAGE, NULL, NULL, NULL);
;
; ===============================================================================================================================
Func _DISM_UnmountImage($MountPath, $Flags = $DISM_DISCARD_IMAGE)

   Local $aResult = DllCall($ghdismapi, "LONG", "DismUnmountImage", _
		 "WSTR", $MountPath, _
		 "DWORD", $Flags, _
		 "PTR", 0, _
		 "PTR", 0, _
		 "PTR", 0 _
		 )
   If @error Then Return SetError(@error, @extended, 0)
   Return SetExtended(_WinAPI_GetLastError(), _DISM_GetErrorMessageText($aResult[0]))
EndFunc   ;==>_DISM_UnmountImage


; #FUNCTION# ====================================================================================================================
; Name...........: _DISM_GetErrorMesageText
; Description ...: Converts an Error Code to its Message Text
; Syntax.........: _DISM_GetErrorMesageText($ErrorCode)
; Parameters ....: $ErrorCode - Specifies the return value of an UDF as an error code.
;				   			 	| C0040001 - $DISMAPI_E_DISMAPI_NOT_INITIALIZED
;				   			 	| C0040002 - $DISMAPI_E_SHUTDOWN_IN_PROGRESS
;				   			 	| C0040003 - $DISMAPI_E_OPEN_SESSION_HANDLES
;				   			 	| C0040004 - $DISMAPI_E_INVALID_DISM_SESSION
;				   			 	| C0040005 - $DISMAPI_E_INVALID_IMAGE_INDEX
;				   			 	| C0040006 - $DISMAPI_E_INVALID_IMAGE_NAME
;				   			 	| C0040007 - $DISMAPI_E_UNABLE_TO_UNMOUNT_IMAGE_PATH
;				   			 	| C0040009 - $DISMAPI_E_LOGGING_DISABLED
;				   			 	| C004000A - $DISMAPI_E_OPEN_HANDLES_UNABLE_TO_UNMOUNT_IMAGE_PATH
;				   			 	| C004000B - $DISMAPI_E_OPEN_HANDLES_UNABLE_TO_MOUNT_IMAGE_PATH
;				   			 	| C004000C - $DISMAPI_E_OPEN_HANDLES_UNABLE_TO_REMOUNT_IMAGE_PATH
;				   			 	| C004000D - $DISMAPI_E_PARENT_FEATURE_DISABLED
;				   			 	| C004000E - $DISMAPI_E_MUST_SPECIFY_ONLINE_IMAGE
;				   			 	| C1510114 - $DISMAPI_E_NEEDS_REMOUNT
;				   			 	| 800f080c - $DISMAPI_E_UNKNOWN_FEATURE
;				   			 	| 800f0902 - $DISMAPI_E_BUSY
; Return values .: Success - Returns $ErrorMessageText
;                  Failure - Not implemented
; Author(s) .....: André Cut
; Modified.......:
; Remarks .......:
; Related .......: _DISM_GetLastErrorMessage
;
; ===============================================================================================================================
Func _DISM_GetErrorMessageText($ErrorCode)

   If $DISM_ERROR_TYPE = 1 Then Return $ErrorCode

   Local $ErrorMessageText = ""

   If $ErrorCode = $S_OK Then Return ($ErrorMessageText & "Success.") ; On Success (0x00000000)
   If $ErrorCode = $DISMAPI_S_RELOAD_IMAGE_SESSION_REQUIRED Then Return ($ErrorMessageText & "The DISM session needs to be reloaded.") ; DISM session needs to be reloaded (0x00000001)
;~ ConsoleWrite("errorcode int: " & $ErrorCode & " errorcode hex: " & Hex($ErrorCode) & @CRLF)
   Switch $ErrorCode
	  Case $DISMAPI_E_DISMAPI_NOT_INITIALIZED
		 $ErrorCode = "DISM API was not initialized for this process"
	  Case $DISMAPI_E_SHUTDOWN_IN_PROGRESS
		 $ErrorCode = "A DismSession was being shutdown when another operation was called on it"
	  Case $DISMAPI_E_OPEN_SESSION_HANDLES
		 $ErrorCode = "A DismShutdown was called while there were open DismSession handles"
	  Case $DISMAPI_E_INVALID_DISM_SESSION
		 $ErrorCode = "An invalid DismSession handle was passed into a DISMAPI function"
	  Case $DISMAPI_E_INVALID_IMAGE_INDEX
		 $ErrorCode = "An invalid image index was specified"
	  Case $DISMAPI_E_INVALID_IMAGE_NAME
		 $ErrorCode = "An invalid image name was specified"
	  Case $DISMAPI_E_UNABLE_TO_UNMOUNT_IMAGE_PATH
		 $ErrorCode = "An image that is not a mounted WIM or mounted VHD was attempted to be unmounted"
	  Case $DISMAPI_E_LOGGING_DISABLED
		 $ErrorCode = "Failed to gain access to the log file user specified." & @CRLF & _
					  "Logging has been disabled.."
	  Case $DISMAPI_E_OPEN_HANDLES_UNABLE_TO_UNMOUNT_IMAGE_PATH
		 $ErrorCode = "A DismSession with open handles was attempted to be unmounted"
	  Case $DISMAPI_E_OPEN_HANDLES_UNABLE_TO_MOUNT_IMAGE_PATH
		 $ErrorCode = "A DismSession with open handles was attempted to be mounted"
	  Case $DISMAPI_E_OPEN_HANDLES_UNABLE_TO_REMOUNT_IMAGE_PATH
		 $ErrorCode = "A DismSession with open handles was attempted to be remounted"
	  Case $DISMAPI_E_PARENT_FEATURE_DISABLED
		 $ErrorCode = "One or several parent features are disabled so current feature can not be enabled." & @CRLF & _
					  "Solutions:" & @CRLF & _
					  "1 Call function DismGetFeatureParent to get all parent features and enable all of them. Or" & @CRLF & _
					  "2 Set EnableAll to TRUE when calling function DismEnableFeature."
	  Case $DISMAPI_E_MUST_SPECIFY_ONLINE_IMAGE
		 $ErrorCode = "The offline image specified is the running system." & @CRLF & _
		 			  "The macro DISM_ONLINE_IMAGE must be used instead."
	  Case $DISMAPI_E_NEEDS_REMOUNT
		 $ErrorCode = "The image needs to be remounted before any servicing operation."
	  Case $DISMAPI_E_UNKNOWN_FEATURE
		 $ErrorCode = "The feature is not present in the package."
	  Case $DISMAPI_E_BUSY
		 $ErrorCode = "The current package and feature servicing infrastructure is busy." & @CRLF & _
					  "Wait a bit and try the operation again."
	  Case $DISMAPI_E_FILE_NOT_FOUND
		 $ErrorCode = "File not found."
	  Case $E_INVALIDARG
		 $ErrorCode = "One or more arguments are not valid:" & @CRLF & "e.g. any of the paths are not well-formed, does not exist or are invalid." & @CRLF & _
					  "Or the DismSession is invalid or not associated with a mounted image."
	  Case $CBS_E_INVALID_PACKAGE
		 $ErrorCode = "The current package is invalid."
	  Case $CBS_E_CANNOT_UNINSTALL
		 $ErrorCode = "Permanent package cannot be uninstalled."
	  Case $DISMAPI_E_INVALID_MOUNT_PATH
		 $ErrorCode = "The assigned mount path is not a valid WIM mount path."
	  Case $DISMAPI_E_UNABLE_TO_UNMOUNT_IMAGE_PROPERLY
		 $ErrorCode = "The directory could not be completely unmounted."
	  Case $DISMAPI_E_UNABLE_TO_OPEN_IMAGE_PATH
		 $ErrorCode = "Failed to gain access to the mount path."
	  Case Else
		 $ErrorCode = "Error Code Unknown: " & $ErrorCode & "."
   EndSwitch

   $ErrorMessageText = $ErrorCode
   Return $ErrorMessageText
EndFunc   ;==>_DISM_GetErrorMesageText
   

; #FUNCTION# ====================================================================================================================
; Name...........: _DISM_GetFullyOfflineInstallableType
; Description ...: Converts a DismFullyOfflineInstallableType Enumeration Value to its Constant Name
; Syntax.........: _DISM_GetFullyOfflineInstallableType($FullyOfflineInstallableType)
; Parameters ....: $FullyOfflineInstallableType - Specifies whether a package can be installed to an offline image without booting the image.
;				   			 	  			      | 0 - $DismFullyOfflineInstallable
;				   			 	  			      | 1 - $DismFullyOfflineNotInstallable
;				   			 	  			      | 2 - $DismFullyOfflineInstallableUndetermined
; Return values .: Success - Returns $FullyOfflineInstallableType
;				   			 | Installable       	   - The package can be installed to an offline image without booting the image.
;				   			 | NotInstallable 		   - You must boot into the image in order to complete installation of this package.
;				   			 | InstallableUndetermined - You may have to boot the image in order to complete the installation of this package.
;                  Failure - Not implemented
; Author(s) .....: André Cut
; Modified.......:
; Remarks .......:
; Related .......: _DISM_GetPackageFeatureState, _DISM_GetReleaseType, _DISM_GetRestartType, _DISM_GetMountStatus, _DISM_GetMountMode, _DISM_GetImageBootable, _DISM_GetImageType
;
; ===============================================================================================================================
Func _DISM_GetFullyOfflineInstallableType($FullyOfflineInstallableType)
   Switch $FullyOfflineInstallableType
	  Case $DismFullyOfflineInstallable
		 $FullyOfflineInstallableType = "Installable"
	  Case $DismFullyOfflineNotInstallable
		 $FullyOfflineInstallableType = "NotInstallable"
	  Case $DismFullyOfflineInstallableUndetermined
		 $FullyOfflineInstallableType = "InstallableUndetermined"
   EndSwitch
   Return $FullyOfflineInstallableType
EndFunc   ;==>_DISM_GetFullyOfflineInstallableType


; #FUNCTION# ====================================================================================================================
; Name...........: _DISM_GetImageBootable
; Description ...: Converts a DismImageBootable Enumeration Value to its Constant Name
; Syntax.........: _DISM_GetImageBootable($ImageBootable)
; Parameters ....: $ImageBootable - Specifies the state of a package or a feature.
;						            | 0 - $DismImageBootableYes
;						            | 1 - $DismImageBootableNo
;						            | 2 - $DismImageBootableUnknown
; Return values .: Success - Returns $ImageBootable
;						     | Yes     - The image is bootable.
;						     | No      - The image is not bootable.
;						     | Unknown - The image type is unknown.
;                  Failure - Not implemented
; Author(s) .....: André Cut
; Modified.......:
; Remarks .......:
; Related .......: _DISM_GetReleaseType, _DISM_GetRestartType, _DISM_GetFullyOfflineInstallableType, _DISM_GetMountStatus, _DISM_GetMountMode, _DISM_GetImageType, _DISM_GetPackageFeatureState
;
; ===============================================================================================================================
Func _DISM_GetImageBootable($ImageBootable)
   Switch $ImageBootable
	  Case $DismImageBootableYes
		 $ImageBootable = "Yes"
	  Case $DismImageBootableNo
		 $ImageBootable = "No"
	  Case $DismImageBootableUnknown
		 $ImageBootable = "Unknown"
   EndSwitch
   Return $ImageBootable
EndFunc   ;==>_DISM_GetImageBootable


; #FUNCTION# ====================================================================================================================
; Name...........: _DISM_GetImageType
; Description ...: Converts a DismImageType Enumeration Value to its Constant Name
; Syntax.........: _DISM_GetImageType($ImageType)
; Parameters ....: $ImageType - Specifies the state of a package or a feature.
;						        | -1 - $DismImageTypeUnsupported
;						        | 0  - $DismImageTypeWim
;						        | 1  - $DismImageTypeVhd
; Return values .: Success - Returns $ImageType
;						     | Unsupported - The file type is unsupported. The image must be in a .wim, .vhd, or .vhdx file.
;						     | Wim         - The image is in a .wim file.
;						     | Vhd 		   - The image is in a .vhd or .vhdx file.
;                  Failure - Not implemented
; Author(s) .....: André Cut
; Modified.......:
; Remarks .......:
; Related .......: _DISM_GetReleaseType, _DISM_GetRestartType, _DISM_GetFullyOfflineInstallableType, _DISM_GetMountStatus, _DISM_GetMountMode, _DISM_GetImageBootable, _DISM_GetPackageFeatureState
;
; ===============================================================================================================================
Func _DISM_GetImageType($ImageType)
   Switch $ImageType
	  Case $DismImageTypeUnsupported
		 $ImageType = "Unsupported"
	  Case $DismImageTypeWim
		 $ImageType = "Wim"
	  Case $DismImageTypeVhd
		 $ImageType = "Vhd"
   EndSwitch
   Return $ImageType
EndFunc   ;==>_DISM_GetImageType


; #FUNCTION# ====================================================================================================================
; Name...........: _DISM_GetMountMode
; Description ...: Converts a DismMountMode Enumeration Value to its Constant Name
; Syntax.........: _DISM_GetMountMode($MountMode)
; Parameters ....: $MountMode - Specifies the state of a package or a feature.
;						        | 0 - $DismReadWrite
;						        | 1 - $DismReadOnly
; Return values .: Success - Returns $MountMode
;						     | R/W - Mounts an image in read-write mode.
;						     | R   - Mounts an image in read-only mode.
;                  Failure - Not implemented
; Author(s) .....: André Cut
; Modified.......:
; Remarks .......:
; Related .......: _DISM_GetReleaseType, _DISM_GetRestartType, _DISM_GetFullyOfflineInstallableType, _DISM_GetMountStatus, _DISM_GetImageBootable, _DISM_GetImageType, _DISM_GetPackageFeatureState
;
; ===============================================================================================================================
Func _DISM_GetMountMode($MountMode)
   Switch $MountMode
	  Case $DismReadWrite
		 $MountMode = "R/W"
	  Case $DismReadOnly
		 $MountMode = "R"
   EndSwitch
   Return $MountMode
EndFunc   ;==>_DISM_GetMountMode


; #FUNCTION# ====================================================================================================================
; Name...........: _DISM_GetMountStatus
; Description ...: Converts a DismMountStatus Enumeration Value to its Constant Name
; Syntax.........: _DISM_GetMountStatus($MountStatus)
; Parameters ....: $MountStatus - Specifies the state of a package or a feature.
;						          | 0 - $DismMountStatusOk
;						          | 1 - $DismMountStatusNeedsRemount
;						          | 2 - $DismMountStatusInvalid
; Return values .: Success - Returns $MountStatus
;						     | OK           - Indicates that the mounted image is mounted and ready for servicing.
;						     | NeedsRemount - Indicates that the mounted image needs to be remounted before being serviced.
;						     | Invalid      - Indicates that the mounted image is corrupt and is in an invalid state.
;                  Failure - Not implemented
; Author(s) .....: André Cut
; Modified.......:
; Remarks .......:
; Related .......: _DISM_GetReleaseType, _DISM_GetRestartType, _DISM_GetFullyOfflineInstallableType, _DISM_GetMountMode, _DISM_GetImageBootable, _DISM_GetImageType, _DISM_GetPackageFeatureState
;
; ===============================================================================================================================
Func _DISM_GetMountStatus($MountStatus)
   Switch $MountStatus
	  Case $DismMountStatusOk
		 $MountStatus = "Ok"
	  Case $DismMountStatusNeedsRemount
		 $MountStatus = "NeedsRemount"
	  Case $DismMountStatusInvalid
		 $MountStatus = "Invalid"
   EndSwitch
   Return $MountStatus
EndFunc   ;==>_DISM_GetMountStatus


; #FUNCTION# ====================================================================================================================
; Name...........: _DISM_GetPackageFeatureState
; Description ...: Converts a DismPackageFeatureState Enumeration Value to its Constant Name
; Syntax.........: _DISM_GetPackageFeatureState($PackageState)
; Parameters ....: $PackageState - Specifies the state of a package or a feature.
;						           | 0 - $DismStateNotPresent
;						           | 1 - $DismStateUninstallPending
;						           | 2 - $DismStateStaged
;						           | 3 - $DismStateResolved
;						           | 3 - $DismStateRemoved
;						           | 4 - $DismStateInstalled
;						           | 5 - $DismStateInstallPending
;						           | 6 - $DismStateSuperseded
;						           | 7 - $DismStatePartiallyInstalled
; Return values .: Success - Returns $PackageState
;						     | NotPresent		  - The package or feature is not present.
;						     | UninstallPending   - An uninstall process for the package or feature is pending. Additional processes are pending and must be completed before the package or feature is successfully uninstalled.
;						     | Staged 			  - The package or feature is staged.
;						     | Resolved 		  - Metadata about the package or feature has been added to the system, but the package or feature is not present.
;						     | Removed 		      - Same as StateResolved
;						     | Installed 		  - The package or feature is installed.
;						     | InstallPending 	  - The install process for the package or feature is pending. Additional processes are pending and must be completed before the package or feature is successfully installed.
;						     | Superseded 		  - The package or feature has been superseded by a more recent package or feature.
;						     | PartiallyInstalled - The package or feature is partially installed. Some parts of the package or feature have not been installed.
;                  Failure - Not implemented
; Author(s) .....: André Cut
; Modified.......:
; Remarks .......:
; Related .......: _DISM_GetReleaseType, _DISM_GetRestartType, _DISM_GetFullyOfflineInstallableType, _DISM_GetMountStatus, _DISM_GetMountMode, _DISM_GetImageBootable, _DISM_GetImageType
;
; ===============================================================================================================================
Func _DISM_GetPackageFeatureState($PackageState)
   Switch $PackageState
	  Case $DismStateNotPresent
		 $PackageState = "NotPresent"
	  Case $DismStateUninstallPending
		 $PackageState = "UninstallPending"
	  Case $DismStateStaged
		 $PackageState = "Staged"
	  Case $DismStateRemoved, $DismStateResolved
		 $PackageState = "Resolved"
	  Case $DismStateInstalled
		 $PackageState = "Installed"
	  Case $DismStateInstallPending
		 $PackageState = "InstallPending"
	  Case $DismStateSuperseded
		 $PackageState = "Superseded"
	  Case $DismStatePartiallyInstalled
		 $PackageState = "PartiallyInstalled"
   EndSwitch
   Return $PackageState
EndFunc   ;==>_DISM_GetPackageFeatureState


; #FUNCTION# ====================================================================================================================
; Name...........: _DISM_GetReleaseType
; Description ...: Converts a DismPackageFeatureState Enumeration Value to its Constant Name
; Syntax.........: _DISM_GetReleaseType($ReleaseType)
; Parameters ....: $ReleaseType - Specifies the release type of a package.
;				   			 	  | 0  - $DismReleaseTypeCriticalUpdate
;				   			 	  | 1  - $DismReleaseTypeDriver
;				   			 	  | 2  - $DismReleaseTypeFeaturePack
;				   			 	  | 3  - $DismReleaseTypeHotfix
;				   			 	  | 4  - $DismReleaseTypeSecurityUpdate
;				   			 	  | 5  - $DismReleaseTypeSoftwareUpdate
;				   			 	  | 6  - $DismReleaseTypeUpdate
;				   			 	  | 7  - $DismReleaseTypeUpdateRollup
;				   			 	  | 8  - $DismReleaseTypeLanguagePack
;				   			 	  | 9  - $DismReleaseTypeFoundation
;				   			 	  | 10 - $DismReleaseTypeServicePack
;				   			 	  | 11 - $DismReleaseTypeProduct
;				   			 	  | 12 - $DismReleaseTypeLocalPack
;				   			 	  | 13 - $DismReleaseTypeOther
; Return values .: Success - Returns $ReleaseType
;				   			 | CriticalUpdate - The package is a critical update.
;				   			 | Driver 		  - The package is a driver.
;				   			 | FeaturePack 	  - The package is a feature pack.
;				   			 | Hotfix 		  - The package is a hotfix.
;				   			 | SecurityUpdate - The package is a security update.
;				   			 | SoftwareUpdate - The package is a software update.
;				   			 | Update 		  - The package is a general update.
;				   			 | UpdateRollup   - The package is an update rollup.
;				   			 | LanguagePack   - The package is a language pack.
;				   			 | Foundation 	  - The package is a foundation package.
;				   			 | ServicePack 	  - The package is a service pack.
;				   			 | Product 		  - The package is a product release.
;				   			 | LocalPack 	  - The package is a local pack.
;				   			 | Other 		  - The package is another type of release.
;                  Failure - Not implemented
; Author(s) .....: André Cut
; Modified.......:
; Remarks .......:
; Related .......: _DISM_GetPackageFeatureState, _DISM_GetRestartType, _DISM_GetFullyOfflineInstallableType, _DISM_GetMountStatus, _DISM_GetMountMode, _DISM_GetImageBootable, _DISM_GetImageType
;
; ===============================================================================================================================
Func _DISM_GetReleaseType($ReleaseType)
   Switch $ReleaseType
	  Case $DismReleaseTypeCriticalUpdate
		 $ReleaseType = "CriticalUpdate"
	  Case $DismReleaseTypeDriver
		 $ReleaseType = "Driver"
	  Case $DismReleaseTypeFeaturePack
		 $ReleaseType = "FeaturePack"
	  Case $DismReleaseTypeHotfix
		 $ReleaseType = "HotFix"
	  Case $DismReleaseTypeSecurityUpdate
		 $ReleaseType = "SecurityUpdate"
	  Case $DismReleaseTypeSoftwareUpdate
		 $ReleaseType = "SoftwareUpdate"
	  Case $DismReleaseTypeUpdate
		 $ReleaseType = "Update"
	  Case $DismReleaseTypeUpdateRollup
		 $ReleaseType = "UpdateRollup"
	  Case $DismReleaseTypeLanguagePack
		 $ReleaseType = "LanguagePack"
	  Case $DismReleaseTypeFoundation
		 $ReleaseType = "Foundation"
	  Case $DismReleaseTypeServicePack
		 $ReleaseType = "ServicePack"
	  Case $DismReleaseTypeProduct
		 $ReleaseType = "Product"
	  Case $DismReleaseTypeLocalPack
		 $ReleaseType = "LocalPack"
	  Case $DismReleaseTypeOther
		 $ReleaseType = "Other"
   EndSwitch
   Return $ReleaseType
EndFunc   ;==>_DISM_GetReleaseType


; #FUNCTION# ====================================================================================================================
; Name...........: _DISM_GetRestartType
; Description ...: Converts a DismRestartType Enumeration Value to its Constant Name
; Syntax.........: _DISM_GetRestartType($RestartType)
; Parameters ....: $RestartType - Specifies whether a restart is required after enabling a feature or installing a package.
;				   			 	  | 0 - $DismRestartNo
;				   			 	  | 1 - $DismRestartPossible
;				   			 	  | 2 - $DismRestartRequired
; Return values .: Success - Returns $RestartType
;				   			 | No       - No restart is required.
;				   			 | Possible - This package or feature might require a restart.
;				   			 | Required - This package or feature always requires a restart.
;                  Failure - Not implemented
; Author(s) .....: André Cut
; Modified.......:
; Remarks .......:
; Related .......: _DISM_GetPackageFeatureState, _DISM_GetReleaseType, _DISM_GetFullyOfflineInstallableType, _DISM_GetMountStatus, _DISM_GetMountMode, _DISM_GetImageBootable, _DISM_GetImageType
;
; ===============================================================================================================================
Func _DISM_GetRestartType($RestartType)
   Switch $RestartType
	  Case $DismRestartNo
		 $RestartType = "No"
	  Case $DismRestartPossible
		 $RestartType = "Possible"
	  Case $DismRestartRequired
		 $RestartType = "Required"
   EndSwitch
   Return $RestartType
EndFunc   ;==>_DISM_GetRestartType
