From 6663fffec0e3482d8a3adc3e8d84f50d28c33ff6 Mon Sep 17 00:00:00 2001 From: Stephen Kwok Date: Sun, 1 Nov 2020 21:21:14 -0800 Subject: [PATCH] Enable users to mount CIMs with just the image path and without a volume id --- MsixCore/msixmgr/CIMProvider.cpp | 12 ++-- MsixCore/msixmgr/CIMProvider.hpp | 8 +-- MsixCore/msixmgr/CommandLineInterface.cpp | 13 ---- MsixCore/msixmgr/msixmgr.cpp | 84 +++++++++++------------ MsixCore/msixmgr/msixmgr.rc | 7 +- MsixCore/msixmgr/resource.h | 11 ++- 6 files changed, 58 insertions(+), 77 deletions(-) diff --git a/MsixCore/msixmgr/CIMProvider.cpp b/MsixCore/msixmgr/CIMProvider.cpp index a35e8b59..db446e4b 100644 --- a/MsixCore/msixmgr/CIMProvider.cpp +++ b/MsixCore/msixmgr/CIMProvider.cpp @@ -77,14 +77,14 @@ namespace MsixCoreLib HRESULT MountCIM( std::wstring cimFilePath, - GUID volumeId) + std::wstring& volumeId) { CreateCIMDll createCIM; RETURN_IF_FAILED(createCIM.load()); typedef HRESULT(STDMETHODCALLTYPE *MOUNTCIM)( std::wstring cimFilePath, - GUID volumeId); + std::wstring& volumeId); MOUNTCIM MountCIMFunc = reinterpret_cast @@ -96,19 +96,21 @@ namespace MsixCoreLib } HRESULT UnmountCIM( - GUID volumeId) + _In_opt_ std::wstring cimFilePath, + _In_opt_ std::wstring volumeIdString) { CreateCIMDll createCIM; RETURN_IF_FAILED(createCIM.load()); typedef HRESULT(STDMETHODCALLTYPE *UNMOUNTCIM)( - GUID volumeId); + std::wstring cimFilePath, + std::wstring volumeIdString); UNMOUNTCIM UnmountCIMFunc = reinterpret_cast (GetProcAddress(createCIM.get(), "UnmountCIM")); - RETURN_IF_FAILED(UnmountCIMFunc(volumeId)); + RETURN_IF_FAILED(UnmountCIMFunc(cimFilePath, volumeIdString)); return S_OK; } diff --git a/MsixCore/msixmgr/CIMProvider.hpp b/MsixCore/msixmgr/CIMProvider.hpp index 70797a1b..4c300b85 100644 --- a/MsixCore/msixmgr/CIMProvider.hpp +++ b/MsixCore/msixmgr/CIMProvider.hpp @@ -9,12 +9,12 @@ namespace MsixCoreLib _In_ std::wstring rootDirectory); HRESULT MountCIM( - std::wstring cimFilePath, - GUID volumeId); + _In_ std::wstring cimFilePath, + _Out_ std::wstring& volumeId); HRESULT UnmountCIM( - GUID volumeId); - + _In_opt_ std::wstring cimFilePath, + _In_opt_ std::wstring volumeIdString); } diff --git a/MsixCore/msixmgr/CommandLineInterface.cpp b/MsixCore/msixmgr/CommandLineInterface.cpp index 26f5ee4e..c4e1da56 100644 --- a/MsixCore/msixmgr/CommandLineInterface.cpp +++ b/MsixCore/msixmgr/CommandLineInterface.cpp @@ -249,19 +249,6 @@ std::map CommandLineInterface::s_opt return S_OK; }), }, - { - L"-volumeId", - Option(true, IDS_STRING_HELP_OPTION_MOUNTIMAGE_VOLUMEID, - [&](CommandLineInterface* commandLineInterface, const std::string& volumeId) - { - if (commandLineInterface->m_operationType != OperationType::MountImage) - { - return E_INVALIDARG; - } - commandLineInterface->m_volumeId = utf8_to_utf16(volumeId); - return S_OK; - }), - }, { L"-fileType", Option(true, IDS_STRING_HELP_OPTION_MOUNT_FILETYPE, diff --git a/MsixCore/msixmgr/msixmgr.cpp b/MsixCore/msixmgr/msixmgr.cpp index 007bf3f5..9fc02e24 100644 --- a/MsixCore/msixmgr/msixmgr.cpp +++ b/MsixCore/msixmgr/msixmgr.cpp @@ -512,27 +512,19 @@ int main(int argc, char * argv[]) case OperationType::MountImage: { WVDFileType fileType = cli.GetFileType(); + + if (cli.GetMountImagePath().empty()) + { + std::wcout << std::endl; + std::wcout << "Please provide the path to the image you would like to mount." << std::endl; + std::wcout << std::endl; + return E_INVALIDARG; + } + if (fileType == WVDFileType::CIM) { - if (cli.GetVolumeId().empty()) - { - std::wcout << std::endl; - std::wcout << "Please provide a volume id in order to mount a CIM image" << std::endl; - std::wcout << std::endl; - return E_INVALIDARG; - } - - std::wstring volumeIdString = cli.GetVolumeId(); - GUID volumeIdFromString; - if (UuidFromStringW((RPC_WSTR)(cli.GetVolumeId().c_str()), &volumeIdFromString) != RPC_S_OK) - { - std::wcout << std::endl; - std::wcout << "Failed to convert specified volume id {" << volumeIdString << "} to GUID" << std::endl; - std::wcout << std::endl; - return E_UNEXPECTED; - } - - HRESULT hrMountCIM = MsixCoreLib::MountCIM(cli.GetMountImagePath(), volumeIdFromString); + std::wstring volumeId; + HRESULT hrMountCIM = MsixCoreLib::MountCIM(cli.GetMountImagePath(), volumeId); if (FAILED(hrMountCIM)) { std::wcout << std::endl; @@ -545,23 +537,16 @@ int main(int argc, char * argv[]) std::wcout << std::endl; std::wcout << "Image successfully mounted!" << std::endl; std::wcout << "To examine contents in File Explorer, press Win + R and enter the following: " << std::endl; - std::wcout << "\\\\?\\Volume{" << volumeIdString << "}" << std::endl; + std::wcout << "\\\\?\\Volume{" << volumeId << "}" << std::endl; std::wcout << std::endl; - std::wcout << "To unmount, run the following command: " << std::endl; - std::wcout << "msixmgr.exe -unmountimage -volumeid " << volumeIdString << " -filetype CIM" << std::endl; + std::wcout << "To unmount, run one of the followings commands: " << std::endl; + std::wcout << "msixmgr.exe -unmountimage -imagePath " << cli.GetMountImagePath() << " -filetype CIM" << std::endl; + std::wcout << "msixmgr.exe -unmountimage -volumeid " << volumeId << " -filetype CIM" << std::endl; std::wcout << std::endl; } } else if (fileType == WVDFileType::VHD || fileType == WVDFileType::VHDX) { - if (cli.GetMountImagePath().empty()) - { - std::wcout << std::endl; - std::wcout << "Please provide the path to the image you would like to mount." << std::endl; - std::wcout << std::endl; - return E_INVALIDARG; - } - std::wstring driveLetter; HRESULT hrMountVHD = MsixCoreLib::MountVHD(cli.GetMountImagePath(), cli.isMountReadOnly(), driveLetter); if (FAILED(hrMountVHD)) @@ -595,37 +580,46 @@ int main(int argc, char * argv[]) WVDFileType fileType = cli.GetFileType(); if (fileType == WVDFileType::CIM) { - if (cli.GetVolumeId().empty()) + if (cli.GetVolumeId().empty() && cli.GetMountImagePath().empty()) { std::wcout << std::endl; - std::wcout << "Please provide the id of the volume you would like to unmount using the -volumeId option" << std::endl; + std::wcout << "To unmount an CIM image, please provide either the CIM file path or the volume the image was mounted to." << std::endl; + std::wcout << "The CIM file path can be specified using the -imagepath option." << std::endl; + std::wcout << "The volume can be specified using the -volumeId option." << std::endl; std::wcout << std::endl; return E_INVALIDARG; } - std::wstring volumeIdString = cli.GetVolumeId(); - GUID volumeIdFromString; - if (UuidFromStringW((RPC_WSTR)(cli.GetVolumeId().c_str()), &volumeIdFromString) != RPC_S_OK) - { - std::wcout << std::endl; - std::wcout << "Failed to convert specified volume id {" << volumeIdString << "} to GUID" << std::endl; - std::wcout << std::endl; - return E_UNEXPECTED; - } - - HRESULT hrUnmountCIM = MsixCoreLib::UnmountCIM(volumeIdFromString); + HRESULT hrUnmountCIM = MsixCoreLib::UnmountCIM(cli.GetMountImagePath(), cli.GetVolumeId()); if (FAILED(hrUnmountCIM)) { std::wcout << std::endl; - std::wcout << "Unmounting the CIM with volume id " << volumeIdString << " failed with HRESULT 0x" << std::hex << hrUnmountCIM << std::endl; + std::wcout << "Unmounting the CIM " << " failed with HRESULT 0x" << std::hex << hrUnmountCIM << std::endl; + + // ERROR_NOT_FOUND may be returned if only the mount image path but not the volume id was provided + // and msixmgr was unable to find the volume id associated with a given image path. + if (hrUnmountCIM == HRESULT_FROM_WIN32(ERROR_NOT_FOUND) && cli.GetVolumeId().empty()) + { + std::wcout << "The error ERROR_NOT_FOUND may indicate a failure to find the volume id associated with a given image path."<< std::endl; + std::wcout << "Please try unmounting using the -volumeId option." << std::endl; + } + std::wcout << std::endl; return hrUnmountCIM; } else { std::wcout << std::endl; - std::wcout << "Successfully unmounted the CIM with volume id " << volumeIdString << std::endl; + if (!cli.GetMountImagePath().empty()) + { + std::wcout << "Successfully unmounted the CIM file: " << cli.GetMountImagePath() << std::endl; + } + else + { + std::wcout << "Successfully unmounted the CIM with volume id: " << cli.GetVolumeId() << std::endl; + } + std::wcout << std::endl; } } diff --git a/MsixCore/msixmgr/msixmgr.rc b/MsixCore/msixmgr/msixmgr.rc index 83b2b870..65909567 100644 --- a/MsixCore/msixmgr/msixmgr.rc +++ b/MsixCore/msixmgr/msixmgr.rc @@ -75,7 +75,7 @@ BEGIN IDS_STRING_HELP_OPTION_FINDPACKAGE "Find package with the specific package full name." IDS_STRING_HELP_OPTION_HELP "Display this help text." - IDS_STRING_HELPTEXT_USAGE " Usage:\n ------\n \tmsixmgr.exe [options]\n \tmsixmgr.exe -Unpack -packagePath -destination [-applyacls] [-create] [-vhdSize ] [-filetype ] [-rootDirectory ] \n \tmsixmgr.exe -ApplyACLs -packagePath \n \tmsixmgr.exe -MountImage -imagePath -fileType [ VHD | VHDX ]\n \tmsixmgr.exe -MountImage -imagePath -volumeId -fileType CIM\n\n" + IDS_STRING_HELPTEXT_USAGE " Usage:\n ------\n \tmsixmgr.exe [options]\n \tmsixmgr.exe -Unpack -packagePath -destination [-applyacls] [-create] [-vhdSize ] [-filetype ] [-rootDirectory ] \n \tmsixmgr.exe -ApplyACLs -packagePath \n \tmsixmgr.exe -MountImage -imagePath -fileType [ VHD | VHDX | CIM ]\n \tmsixmgr.exe -UnmountImage -imagePath -fileType [ VHD | VHDX | CIM ]\n\n" IDS_STRING_UI_CANCEL "Cancel" END @@ -127,11 +127,10 @@ BEGIN IDS_STRING_HELP_OPTION_UNPACK_CREATE "optional parameter that creates a new image with the specified -filetype and unpacks the packages to that image" IDS_STRING_HELP_OPTION_UNPACK_ROOTDIRECTORY "root directory on an image to unpack packages to. Required parameter for unpacking to new and existing CIM files" IDS_STRING_HELP_OPTION_UNPACK_FILETYPE "the type of file to unpack packages to. Valid file types include {VHD, VHDX, CIM}. This is a required parameter when unpacking to CIM files" - IDS_STRING_HELP_OPTION_MOUNTIMAGE "Mounts an image of the specified file type. Supported file types include {VHD, VHDX, CIM}." + IDS_STRING_HELP_OPTION_MOUNTIMAGE "Mounts the VHD, VHDX, or CIM image." IDS_STRING_HELP_OPTION_MOUNTIMAGE_IMAGEPATH "the path to the image file to mount or unmount." - IDS_STRING_HELP_OPTION_MOUNTIMAGE_VOLUMEID "a GUID (specified without curly braces) to associate with the mounted image. Use this GUID to unmount the mounted image. Use only for CIM files." IDS_STRING_HELP_OPTION_UNMOUNTIMAGE "Unmounts the VHD, VHDX, or CIM image" - IDS_STRING_HELP_OPTION_UNMOUNTIMAGE_VOLUMEID "the GUID (specified without curly braces) associated with the image to unmount. Use only for CIM files." + IDS_STRING_HELP_OPTION_UNMOUNTIMAGE_VOLUMEID "the GUID (specified without curly braces) associated with the image to unmount. This is an optional parameter only for CIM files." IDS_STRING_HELP_OPTION_MOUNT_FILETYPE "the type of file to mount or unmount. The following file types are currently supported: {VHD, VHDX, CIM}" IDS_STRING_HELP_OPTION_UNPACK_VHDSIZE "the desired size of the VHD or VHDX file in MB. Must be between 5 and 2040000 MB. Use only for VHD or VHDX files" IDS_STRING_HELP_OPTION_MOUNT_READONLY "boolean (true of false) indicating whether a VHD(X) should be mounted as read only. If not specified, the image is mounted as read-only by default" diff --git a/MsixCore/msixmgr/resource.h b/MsixCore/msixmgr/resource.h index 8b6bc71e..b81409bb 100644 --- a/MsixCore/msixmgr/resource.h +++ b/MsixCore/msixmgr/resource.h @@ -61,12 +61,11 @@ #define IDS_STRING_HELP_OPTION_UNPACK_FILETYPE 156 #define IDS_STRING_HELP_OPTION_MOUNTIMAGE 157 #define IDS_STRING_HELP_OPTION_MOUNTIMAGE_IMAGEPATH 158 -#define IDS_STRING_HELP_OPTION_MOUNTIMAGE_VOLUMEID 159 -#define IDS_STRING_HELP_OPTION_UNMOUNTIMAGE 160 -#define IDS_STRING_HELP_OPTION_UNMOUNTIMAGE_VOLUMEID 161 -#define IDS_STRING_HELP_OPTION_MOUNT_FILETYPE 162 -#define IDS_STRING_HELP_OPTION_UNPACK_VHDSIZE 163 -#define IDS_STRING_HELP_OPTION_MOUNT_READONLY 164 +#define IDS_STRING_HELP_OPTION_UNMOUNTIMAGE 159 +#define IDS_STRING_HELP_OPTION_UNMOUNTIMAGE_VOLUMEID 160 +#define IDS_STRING_HELP_OPTION_MOUNT_FILETYPE 161 +#define IDS_STRING_HELP_OPTION_UNPACK_VHDSIZE 162 +#define IDS_STRING_HELP_OPTION_MOUNT_READONLY 163 // Next default values for new objects //