diff --git a/3rdParty/Regsvr64.exe b/3rdParty/Regsvr64.exe deleted file mode 100644 index bf80bb4..0000000 Binary files a/3rdParty/Regsvr64.exe and /dev/null differ diff --git a/3rdParty/Regsvr64_64.exe b/3rdParty/Regsvr64_64.exe deleted file mode 100644 index 445ac40..0000000 Binary files a/3rdParty/Regsvr64_64.exe and /dev/null differ diff --git a/PathCopyCopy.sln b/PathCopyCopy.sln index 47de112..cdcc6e9 100644 --- a/PathCopyCopy.sln +++ b/PathCopyCopy.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.28803.202 +# Visual Studio Version 17 +VisualStudioVersion = 17.10.35027.167 MinimumVisualStudioVersion = 10.0.40219.1 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PathCopyCopy", "PathCopyCopy\PathCopyCopy.vcxproj", "{AA106D7B-966E-4A98-8EAD-0AE2AE0038D2}" ProjectSection(ProjectDependencies) = postProject @@ -32,6 +32,13 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PathCopyCopyLocalization_en EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PathCopyCopyLocalization_fr", "PathCopyCopy\localization\PathCopyCopyLocalization_fr\PathCopyCopyLocalization_fr.vcxproj", "{69A53834-5AF9-4B92-B78B-15567FE6DE30}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".github", ".github", "{B42127A5-4EEF-4EFD-93EB-F3387D71C17F}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{FCDBD36A-5A37-41BC-982C-67E8DE995A26}" + ProjectSection(SolutionItems) = preProject + .github\workflows\main.yml = .github\workflows\main.yml + EndProjectSection +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 @@ -100,6 +107,10 @@ Global GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {B42127A5-4EEF-4EFD-93EB-F3387D71C17F} = {0B4523A6-521E-43F6-BC87-44919C8CA492} + {FCDBD36A-5A37-41BC-982C-67E8DE995A26} = {B42127A5-4EEF-4EFD-93EB-F3387D71C17F} + EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {95CB2D2A-C347-4A94-9C44-BDC4A9A76CB1} EndGlobalSection diff --git a/PathCopyCopy/PathCopyCopy.vcxproj b/PathCopyCopy/PathCopyCopy.vcxproj index caca2e9..fcb2a57 100644 --- a/PathCopyCopy/PathCopyCopy.vcxproj +++ b/PathCopyCopy/PathCopyCopy.vcxproj @@ -30,28 +30,28 @@ false Static Unicode - v142 + v143 DynamicLibrary false Static Unicode - v142 + v143 DynamicLibrary false Static Unicode - v142 + v143 DynamicLibrary false Static Unicode - v142 + v143 @@ -137,7 +137,7 @@ Disabled Disabled EnableFastChecks - stdcpp17 + stdcpp20 true 26485;26486;26487;26489;28251 true @@ -148,7 +148,7 @@ $(IntDir);.\prihdr;..\prihdr;.\pubhdr;..\pubhdr;%(AdditionalIncludeDirectories) - true + false mpr.lib;netapi32.lib;gdiplus.lib;ws2_32.lib;comsuppw.lib;%(AdditionalDependencies) .\src\PathCopyCopy.def true @@ -159,6 +159,12 @@ $(ProjectDir)rsrc\PathCopyCopy.dll.manifest %(AdditionalManifestFiles) + + regsvr32 /s /n /i:user "$(TargetPath)" + + + Registering output... + @@ -184,7 +190,7 @@ Disabled Disabled EnableFastChecks - stdcpp17 + stdcpp20 true 26485;26486;26487;26489;28251 true @@ -203,8 +209,8 @@ MachineX64 - Registering output (x64)... - "$(SolutionDir)3rdParty\Regsvr64.exe" /s "$(TargetPath)" + Registering output... + regsvr32 /s /n /i:user "$(TargetPath)" $(ProjectDir)rsrc\PathCopyCopy.dll.manifest %(AdditionalManifestFiles) @@ -232,7 +238,7 @@ Use Level4 ProgramDatabase - stdcpp17 + stdcpp20 true 26485;26486;26487;26489;28251 true @@ -243,7 +249,7 @@ $(IntDir);.\prihdr;..\prihdr;.\pubhdr;..\pubhdr;%(AdditionalIncludeDirectories) - true + false mpr.lib;netapi32.lib;gdiplus.lib;ws2_32.lib;comsuppw.lib;%(AdditionalDependencies) .\src\PathCopyCopy.def true @@ -255,6 +261,12 @@ $(ProjectDir)rsrc\PathCopyCopy.dll.manifest %(AdditionalManifestFiles) + + regsvr32 /s /n /i:user "$(TargetPath)" + + + Registering output... + @@ -277,7 +289,7 @@ Use Level4 ProgramDatabase - stdcpp17 + stdcpp20 true 26485;26486;26487;26489;28251 true @@ -298,8 +310,8 @@ MachineX64 - Registering output (x64)... - "$(SolutionDir)3rdParty\Regsvr64.exe" /s "$(TargetPath)" + Registering output... + regsvr32 /s /n /i:user "$(TargetPath)" $(ProjectDir)rsrc\PathCopyCopy.dll.manifest %(AdditionalManifestFiles) diff --git a/PathCopyCopy/localization/PathCopyCopyLocalization_en/PathCopyCopyLocalization_en.vcxproj b/PathCopyCopy/localization/PathCopyCopyLocalization_en/PathCopyCopyLocalization_en.vcxproj index f51324c..0021652 100644 --- a/PathCopyCopy/localization/PathCopyCopyLocalization_en/PathCopyCopyLocalization_en.vcxproj +++ b/PathCopyCopy/localization/PathCopyCopyLocalization_en/PathCopyCopyLocalization_en.vcxproj @@ -27,13 +27,13 @@ DynamicLibrary true - v142 + v143 Unicode DynamicLibrary false - v142 + v143 true Unicode diff --git a/PathCopyCopy/localization/PathCopyCopyLocalization_fr/PathCopyCopyLocalization_fr.vcxproj b/PathCopyCopy/localization/PathCopyCopyLocalization_fr/PathCopyCopyLocalization_fr.vcxproj index 50450a7..1d7da13 100644 --- a/PathCopyCopy/localization/PathCopyCopyLocalization_fr/PathCopyCopyLocalization_fr.vcxproj +++ b/PathCopyCopy/localization/PathCopyCopyLocalization_fr/PathCopyCopyLocalization_fr.vcxproj @@ -27,13 +27,13 @@ DynamicLibrary true - v142 + v143 Unicode DynamicLibrary false - v142 + v143 true Unicode diff --git a/PathCopyCopy/prihdr/PluginPipelineElements.h b/PathCopyCopy/prihdr/PluginPipelineElements.h index 6f3f451..31939b3 100644 --- a/PathCopyCopy/prihdr/PluginPipelineElements.h +++ b/PathCopyCopy/prihdr/PluginPipelineElements.h @@ -327,7 +327,7 @@ namespace PCC { public: CopyNPathPartsPipelineElement(size_t p_NumParts, - bool p_First); + bool p_First) noexcept; CopyNPathPartsPipelineElement(const CopyNPathPartsPipelineElement&) = delete; CopyNPathPartsPipelineElement& operator=(const CopyNPathPartsPipelineElement&) = delete; @@ -395,9 +395,9 @@ namespace PCC class PushToStackPipelineElement : public PipelineElement { public: - PushToStackPipelineElement(); + PushToStackPipelineElement() noexcept; PushToStackPipelineElement(size_t p_Begin, - size_t p_End); + size_t p_End) noexcept; PushToStackPipelineElement(const std::wstring& p_Regex, bool p_IgnoreCase, size_t p_Group); @@ -437,9 +437,9 @@ namespace PCC class PopFromStackPipelineElement : public PipelineElement { public: - explicit PopFromStackPipelineElement(PopFromStackLocation p_Location); + explicit PopFromStackPipelineElement(PopFromStackLocation p_Location) noexcept; PopFromStackPipelineElement(size_t m_Begin, - size_t m_End); + size_t m_End) noexcept; PopFromStackPipelineElement(const std::wstring& p_Regex, bool p_IgnoreCase); PopFromStackPipelineElement(const PopFromStackPipelineElement&) = delete; @@ -537,7 +537,7 @@ namespace PCC RecursiveCopyPipelineElement& operator=(const RecursiveCopyPipelineElement&) = delete; - void ModifyOptions(PipelineOptions& p_rOptions) const override; + void ModifyOptions(PipelineOptions& p_rOptions) const noexcept override; }; // @@ -618,12 +618,12 @@ namespace PCC { public: DisplayForSelectionPipelineElement(bool p_ShowForFiles, - bool p_ShowForFolders); + bool p_ShowForFolders) noexcept; DisplayForSelectionPipelineElement(const DisplayForSelectionPipelineElement&) = delete; DisplayForSelectionPipelineElement& operator=(const DisplayForSelectionPipelineElement&) = delete; - void ModifyOptions(PipelineOptions& p_rOptions) const override; + void ModifyOptions(PipelineOptions& p_rOptions) const noexcept override; private: bool m_ShowForFiles; // Whether the plugin should be displayed when files are selected. diff --git a/PathCopyCopy/prihdr/dllmain.h b/PathCopyCopy/prihdr/dllmain.h index bf93c12..66e66d9 100644 --- a/PathCopyCopy/prihdr/dllmain.h +++ b/PathCopyCopy/prihdr/dllmain.h @@ -37,6 +37,10 @@ public : DECLARE_REGISTRY_APPID_RESOURCEID(IDR_PATHCOPYCOPY, "{44F7E5A2-1286-45F5-9A7A-A95A41B72918}") CPathCopyCopyModule(); + CPathCopyCopyModule(const CPathCopyCopyModule&) = delete; + CPathCopyCopyModule(CPathCopyCopyModule&&) = delete; + CPathCopyCopyModule& operator=(const CPathCopyCopyModule&) = delete; + CPathCopyCopyModule& operator=(CPathCopyCopyModule&&) = delete; ~CPathCopyCopyModule(); HRESULT DllRegisterServer(BOOL p_RegisterTypeLib = TRUE) throw(); diff --git a/PathCopyCopy/src/PathCopyCopyContextMenuExt.cpp b/PathCopyCopy/src/PathCopyCopyContextMenuExt.cpp index b9eff79..998cddb 100644 --- a/PathCopyCopy/src/PathCopyCopyContextMenuExt.cpp +++ b/PathCopyCopy/src/PathCopyCopyContextMenuExt.cpp @@ -47,9 +47,9 @@ namespace { -const wchar_t* const DEFAULT_PATHS_SEPARATOR = L"\r\n"; // Default separator used between paths when copying multiple file names. +const wchar_t* const DEFAULT_PATHS_SEPARATOR = L"\r\n"; // Default separator used between paths when copying multiple file names. -const int32_t DEFAULT_ICON_SIZE = 16; // Default width & height for loaded icons. +constexpr int32_t DEFAULT_ICON_SIZE = 16; // Default width & height for loaded icons. } @@ -243,7 +243,7 @@ STDMETHODIMP CPathCopyCopyContextMenuExt::Initialize( // Get each file in turn. for (UINT i = 0; i < fileCount; ++i) { const auto bufferSize = ::DragQueryFileW(static_cast(stgMedium.Get().hGlobal), i, nullptr, 0); - std::wstring buffer(bufferSize + 1, L'\0'); + std::wstring buffer(static_cast(bufferSize) + 1, L'\0'); ::DragQueryFileW(static_cast(stgMedium.Get().hGlobal), i, &*buffer.begin(), gsl::narrow(buffer.size())); m_vFiles.emplace_back(buffer.c_str()); } @@ -411,7 +411,7 @@ STDMETHODIMP CPathCopyCopyContextMenuExt::QueryContextMenu( try { // Fetch list of plugins to display in the submenu. PCC::PluginSPV vspPlugins; - const PCC::PluginSPV* pvspPlugins = nullptr; + gsl::not_null pvspPlugins{&m_vspPluginsInDefaultOrder}; vPluginIds.clear(); rSettings.GetSubmenuPluginDisplayOrder(vPluginIds); if (!vPluginIds.empty()) { @@ -420,7 +420,6 @@ STDMETHODIMP CPathCopyCopyContextMenuExt::QueryContextMenu( pvspPlugins = &vspPlugins; } else { // No plugin specified, use all plugins in default order. - pvspPlugins = &m_vspPluginsInDefaultOrder; } // Iterate plugins and try to add them to the submenu. @@ -830,13 +829,13 @@ HRESULT CPathCopyCopyContextMenuExt::AddPluginToMenu(const PCC::PluginSP& p_spPl // In some language, this will leave the first letter in lowercase. // Convert it to uppercase in that case. - if (!description.empty() && ::iswlower(description[0])) { - description[0] = ::towupper(description[0]); + if (!description.empty() && ::iswlower(description.front())) { + description.front() = ::towupper(description.front()); } // ...or maybe the first letter is the shortcut character... - if (description.size() >= 2 && description[0] == L'&' && ::iswlower(description[1])) { - description[1] = ::towupper(description[1]); + if (description.size() >= 2 && description.at(0) == L'&' && ::iswlower(description.at(1))) { + description.at(1) = ::towupper(description.at(1)); } } } @@ -1030,24 +1029,23 @@ HBITMAP CPathCopyCopyContextMenuExt::GetIconForIconFile(const std::wstring& p_Ic StGdiplusStartup gdiPlusStartup; if (gdiPlusStartup.Started()) { // Load original bitmap using GDI+. - std::shared_ptr spFileBitmap(Gdiplus::Bitmap::FromStream(cpIconFileStream, FALSE)); + std::unique_ptr upFileBitmap{Gdiplus::Bitmap::FromStream(cpIconFileStream, FALSE)}; // If necessary, rescale bitmap to fit. - auto spTempBitmap = std::make_shared(DEFAULT_ICON_SIZE, DEFAULT_ICON_SIZE); + Gdiplus::Bitmap bitmap{DEFAULT_ICON_SIZE, DEFAULT_ICON_SIZE}; { - Gdiplus::Graphics graphics(spTempBitmap.get()); - graphics.ScaleTransform(static_cast(DEFAULT_ICON_SIZE) / static_cast(spFileBitmap->GetWidth()), - static_cast(DEFAULT_ICON_SIZE) / static_cast(spFileBitmap->GetHeight())); - graphics.DrawImage(spFileBitmap.get(), 0, 0); + Gdiplus::Graphics graphics{&bitmap}; + graphics.ScaleTransform(static_cast(DEFAULT_ICON_SIZE) / static_cast(upFileBitmap->GetWidth()), + static_cast(DEFAULT_ICON_SIZE) / static_cast(upFileBitmap->GetHeight())); + graphics.DrawImage(upFileBitmap.get(), 0, 0); } - spFileBitmap = spTempBitmap; // Extract HBITMAP using GDI+. - HBITMAP hFileBitmap = nullptr; - if (spFileBitmap->GetHBITMAP(Gdiplus::Color(), &hFileBitmap) == Gdiplus::Ok) { + HBITMAP hBitmap = nullptr; + if (bitmap.GetHBITMAP(Gdiplus::Color(), &hBitmap) == Gdiplus::Ok) { // We have HBITMAP, save it in the map. #pragma warning(suppress: 26414) // spImage IS copied in emplace, but the compiler can't see it - const auto spImage = std::make_shared(hFileBitmap, IMAGE_BITMAP, false); + const auto spImage = std::make_shared(hBitmap, IMAGE_BITMAP, false); m_mspIcons.emplace(lowerIconFile, spImage); if (spImage->GetLoadResult() == ERROR_SUCCESS) { hIconBitmap = spImage->GetBitmap(); @@ -1178,7 +1176,7 @@ PCC::FilesV CPathCopyCopyContextMenuExt::GetFilesToActOn(const bool p_Recursivel PCC::FilesV vFilesToScan; vFilesToScan.swap(vNewFiles); for (const auto& fileToScan : vFilesToScan) { - auto attributes = ::GetFileAttributesW(fileToScan.c_str()); + const auto attributes = ::GetFileAttributesW(fileToScan.c_str()); if (attributes != INVALID_FILE_ATTRIBUTES && (attributes & FILE_ATTRIBUTE_DIRECTORY) != 0) { WIN32_FIND_DATAW findData; HANDLE hFind = ::FindFirstFileW((fileToScan + L"\\*").c_str(), &findData); diff --git a/PathCopyCopy/src/PluginPipelineDecoder.cpp b/PathCopyCopy/src/PluginPipelineDecoder.cpp index fe0322a..de2851b 100644 --- a/PathCopyCopy/src/PluginPipelineDecoder.cpp +++ b/PathCopyCopy/src/PluginPipelineDecoder.cpp @@ -177,6 +177,7 @@ namespace PCC } case ELEMENT_CODE_DUPLICATE_STACK_VALUE: { spElement = std::make_shared(); + // FIXME: there should be a `break` here! } case ELEMENT_CODE_PATHS_SEPARATOR: { spElement = DecodePathsSeparatorElement(p_rStream); @@ -319,8 +320,8 @@ namespace PCC } case PushToStackMethod::Range: { // Encoded stream contains begin and end of range. - const auto begin = static_cast(p_rStream.ReadLong()); - const auto end = static_cast(p_rStream.ReadLong()); + const auto begin = gsl::narrow_cast(p_rStream.ReadLong()); + const auto end = gsl::narrow_cast(p_rStream.ReadLong()); spElement = std::make_shared(begin, end); break; } @@ -328,7 +329,7 @@ namespace PCC // Encoded stream contains the regex, ignore case flag and group number. const auto regex = p_rStream.ReadString(); const auto ignoreCase = p_rStream.ReadBool(); - const auto group = static_cast(p_rStream.ReadLong()); + const auto group = gsl::narrow_cast(p_rStream.ReadLong()); spElement = std::make_shared(regex, ignoreCase, group); break; } diff --git a/PathCopyCopy/src/PluginPipelineElements.cpp b/PathCopyCopy/src/PluginPipelineElements.cpp index fddc28f..d592c54 100644 --- a/PathCopyCopy/src/PluginPipelineElements.cpp +++ b/PathCopyCopy/src/PluginPipelineElements.cpp @@ -336,7 +336,7 @@ namespace PCC // @param p_First Whether to copy the first (true) or last (false) path parts. // CopyNPathPartsPipelineElement::CopyNPathPartsPipelineElement(const size_t p_NumParts, - const bool p_First) + const bool p_First) noexcept : m_NumParts(p_NumParts), m_First(p_First) { @@ -358,7 +358,7 @@ namespace PCC if (m_NumParts < vPathParts.size()) { // Try auto-detecting the separator type used in this path. const auto separatorPos = p_rPath.find_first_of(L"\\/"); - const auto separator = separatorPos != std::wstring::npos ? p_rPath[separatorPos] : L'\\'; + const auto separator = separatorPos != std::wstring::npos ? p_rPath.at(separatorPos) : L'\\'; // Keep only the required number of path parts and join them using separator. if (m_First) { @@ -493,7 +493,7 @@ namespace PCC // Default constructor. The element will push the entire path // to the stack. // - PushToStackPipelineElement::PushToStackPipelineElement() + PushToStackPipelineElement::PushToStackPipelineElement() noexcept : m_Method(PushToStackMethod::Entire) { } @@ -506,7 +506,7 @@ namespace PCC // @param p_End Index of end of range to push to the stack (exclusive). // PushToStackPipelineElement::PushToStackPipelineElement(const size_t p_Begin, - const size_t p_End) + const size_t p_End) noexcept : m_Method(PushToStackMethod::Range), m_Begin(p_Begin), m_End(p_End) @@ -594,7 +594,11 @@ namespace PCC std::wsmatch match; if (std::regex_search(p_Path, match, regex)) { - part = match[m_Group]; + // Note: here, gsl::at() should not be necessary because + // std::match_results::operator[] is actually safe (it returns + // a reference to an empty sub-match if the index is out of range). + // However, C++ Code Analysis doesn't seem to know this. + part = gsl::at(match, m_Group); } } } catch (const std::regex_error&) { @@ -617,7 +621,7 @@ namespace PCC // // @param p_Location Location where to store popped value. // - PopFromStackPipelineElement::PopFromStackPipelineElement(const PopFromStackLocation p_Location) + PopFromStackPipelineElement::PopFromStackPipelineElement(const PopFromStackLocation p_Location) noexcept : m_Location(p_Location) { } @@ -630,7 +634,7 @@ namespace PCC // @param p_End End of range to replace with the popped value. // PopFromStackPipelineElement::PopFromStackPipelineElement(const size_t p_Begin, - const size_t p_End) + const size_t p_End) noexcept : m_Location(PopFromStackLocation::Range), m_Begin(p_Begin), m_End(p_End) @@ -803,7 +807,7 @@ namespace PCC // // @param p_rOptions Global options to modify (in-place). // - void RecursiveCopyPipelineElement::ModifyOptions(PipelineOptions& p_rOptions) const + void RecursiveCopyPipelineElement::ModifyOptions(PipelineOptions& p_rOptions) const noexcept { p_rOptions.SetCopyPathsRecursively(true); } @@ -902,7 +906,7 @@ namespace PCC // @param p_ShowForFolders Whether to display the plugin when folders are selected. // DisplayForSelectionPipelineElement::DisplayForSelectionPipelineElement(const bool p_ShowForFiles, - const bool p_ShowForFolders) + const bool p_ShowForFolders) noexcept : m_ShowForFiles(p_ShowForFiles), m_ShowForFolders(p_ShowForFolders) { @@ -914,7 +918,7 @@ namespace PCC // // @param p_rOptions Global options to modify. // - void DisplayForSelectionPipelineElement::ModifyOptions(PipelineOptions& p_rOptions) const + void DisplayForSelectionPipelineElement::ModifyOptions(PipelineOptions& p_rOptions) const noexcept { p_rOptions.SetShowForFiles(m_ShowForFiles); p_rOptions.SetShowForFolders(m_ShowForFolders); diff --git a/PathCopyCopy/src/PluginUtils.cpp b/PathCopyCopy/src/PluginUtils.cpp index ccd6209..6cf7306 100644 --- a/PathCopyCopy/src/PluginUtils.cpp +++ b/PathCopyCopy/src/PluginUtils.cpp @@ -171,7 +171,7 @@ namespace PCC if (hFile != nullptr) { const auto bufferSize = ::GetFinalPathNameByHandleW(hFile, nullptr, 0, FILE_NAME_NORMALIZED | VOLUME_NAME_DOS); if (bufferSize != 0) { - std::wstring finalPath(bufferSize + 1, L'\0'); + std::wstring finalPath(static_cast(bufferSize) + 1, L'\0'); const auto finalPathRes = ::GetFinalPathNameByHandleW(hFile, &*finalPath.begin(), bufferSize + 1, diff --git a/PathCopyCopy/src/dllmain.cpp b/PathCopyCopy/src/dllmain.cpp index 918abb9..68acd48 100644 --- a/PathCopyCopy/src/dllmain.cpp +++ b/PathCopyCopy/src/dllmain.cpp @@ -44,6 +44,7 @@ EXTERN_C IMAGE_DOS_HEADER __ImageBase; // // Constructor. // +[[gsl::suppress(f.6)]] CPathCopyCopyModule::CPathCopyCopyModule() : ATL::CAtlDllModuleT() { diff --git a/PathCopyCopyCOMPluginExecutor/PathCopyCopyCOMPluginExecutor.vcxproj b/PathCopyCopyCOMPluginExecutor/PathCopyCopyCOMPluginExecutor.vcxproj index 1e67c82..f40f805 100644 --- a/PathCopyCopyCOMPluginExecutor/PathCopyCopyCOMPluginExecutor.vcxproj +++ b/PathCopyCopyCOMPluginExecutor/PathCopyCopyCOMPluginExecutor.vcxproj @@ -29,14 +29,14 @@ true Unicode Static - v142 + v143 Application true Unicode Static - v142 + v143 Application @@ -44,7 +44,7 @@ true Unicode Static - v142 + v143 Application @@ -52,7 +52,7 @@ true Unicode Static - v142 + v143 diff --git a/PathCopyCopyRegexTester/PathCopyCopyRegexTester.vcxproj b/PathCopyCopyRegexTester/PathCopyCopyRegexTester.vcxproj index 624dfdd..ec80d7a 100644 --- a/PathCopyCopyRegexTester/PathCopyCopyRegexTester.vcxproj +++ b/PathCopyCopyRegexTester/PathCopyCopyRegexTester.vcxproj @@ -21,14 +21,14 @@ Application true Unicode - v142 + v143 Application false true Unicode - v142 + v143 diff --git a/PathCopyCopySettings/UI/Forms/MainForm.cs b/PathCopyCopySettings/UI/Forms/MainForm.cs index a41e292..f79b7e0 100644 --- a/PathCopyCopySettings/UI/Forms/MainForm.cs +++ b/PathCopyCopySettings/UI/Forms/MainForm.cs @@ -119,8 +119,8 @@ public MainForm() // Connect all checkboxes in the Options page to the CheckChanged event handler that // will enable the Apply button. foreach (Control control in MiscOptionsPage.Controls) { - if (control is CheckBox) { - (control as CheckBox).CheckedChanged += Chk_CheckedChanged; + if (control is CheckBox checkBox) { + checkBox.CheckedChanged += Chk_CheckedChanged; } } diff --git a/Testing/TestPlugins/TestPlugins.vcxproj b/Testing/TestPlugins/TestPlugins.vcxproj index 969278a..01bd642 100644 --- a/Testing/TestPlugins/TestPlugins.vcxproj +++ b/Testing/TestPlugins/TestPlugins.vcxproj @@ -29,28 +29,28 @@ false Static Unicode - v142 + v143 DynamicLibrary false Static Unicode - v142 + v143 DynamicLibrary false Static Unicode - v142 + v143 DynamicLibrary false Static Unicode - v142 + v143 @@ -147,13 +147,19 @@ $(IntDir);.\rsrc;.\prihdr;.\generated;%(AdditionalIncludeDirectories) - true + false .\src\TestPlugins.def true Windows MachineX86 false + + regsvr32 /s /n /i:user "$(TargetPath)" + + + Registering output... + @@ -197,8 +203,8 @@ MachineX64 - Registering output (x64)... - "$(SolutionDir)3rdParty\Regsvr64.exe" /s "$(TargetPath)" + Registering output... + regsvr32 /s /n /i:user "$(TargetPath)" @@ -235,7 +241,7 @@ $(IntDir);.\rsrc;.\prihdr;.\generated;%(AdditionalIncludeDirectories) - true + false .\src\TestPlugins.def true Windows @@ -243,6 +249,12 @@ true MachineX86 + + regsvr32 /s /n /i:user "$(TargetPath)" + + + Registering output... + @@ -286,8 +298,8 @@ MachineX64 - Registering output (x64)... - "$(SolutionDir)3rdParty\Regsvr64.exe" /s "$(TargetPath)" + Registering output... + regsvr32 /s /n /i:user "$(TargetPath)" diff --git a/Testing/TestPlugins/src/TestPlugins.cpp b/Testing/TestPlugins/src/TestPlugins.cpp index 976b831..1c28514 100644 --- a/Testing/TestPlugins/src/TestPlugins.cpp +++ b/Testing/TestPlugins/src/TestPlugins.cpp @@ -24,6 +24,7 @@ #include "TestPlugins_i.h" #include "dllmain.h" #include "dlldatax.h" +#include "StAtlPerUserOverride.h" // Used to determine whether the DLL can be unloaded by OLE STDAPI DllCanUnloadNow(void) @@ -51,6 +52,12 @@ STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv) // DllRegisterServer - Adds entries to the system registry STDAPI DllRegisterServer(void) { + // Setup per-user registration if needed. + StAtlPerUserOverride perUserOverride; + if (!perUserOverride.Succeeded()) { + return E_FAIL; + } + // registers object, typelib and all interfaces in typelib HRESULT hr = _AtlModule.DllRegisterServer(); #ifdef _MERGE_PROXYSTUB @@ -65,6 +72,12 @@ STDAPI DllRegisterServer(void) // DllUnregisterServer - Removes entries from the system registry STDAPI DllUnregisterServer(void) { + // Setup per-user unregistration if needed. + StAtlPerUserOverride perUserOverride; + if (!perUserOverride.Succeeded()) { + return E_FAIL; + } + HRESULT hr = _AtlModule.DllUnregisterServer(); #ifdef _MERGE_PROXYSTUB if (FAILED(hr)) diff --git a/Testing/TestPlugins/src/dllmain.cpp b/Testing/TestPlugins/src/dllmain.cpp index 4a2df57..5ccce12 100644 --- a/Testing/TestPlugins/src/dllmain.cpp +++ b/Testing/TestPlugins/src/dllmain.cpp @@ -42,104 +42,112 @@ CTestPluginsModule _AtlModule; [[gsl::suppress(c.128)]] HRESULT CTestPluginsModule::DllRegisterServer(BOOL bRegTypeLib /*= TRUE*/) throw() { - // Create PathCopyCopy registration object and check if it supports per-user install. - ATL::CComPtr cpPccExt; - HRESULT hRes = cpPccExt.CoCreateInstance(__uuidof(PathCopyCopyContextMenuExt)); - if (SUCCEEDED(hRes)) { - ATL::CComQIPtr cpPccExt2(cpPccExt); - - // Setup per-user registration. If user asked for a per-user install - // but the registration object does not support it, fail. - StAtlPerUserOverride perUserOverride; - hRes = perUserOverride.Succeeded() ? S_OK : E_FAIL; - if (SUCCEEDED(hRes) && perUserOverride.Overridden() && cpPccExt2.p == nullptr) { - hRes = E_NOTIMPL; - } + try { + // Create PathCopyCopy registration object and check if it supports per-user install. + ATL::CComPtr cpPccExt; + HRESULT hRes = cpPccExt.CoCreateInstance(__uuidof(PathCopyCopyContextMenuExt)); if (SUCCEEDED(hRes)) { - // First perform DLL registration. - hRes = ATL::CAtlDllModuleT::DllRegisterServer(bRegTypeLib); + ATL::CComQIPtr cpPccExt2(cpPccExt); + + // Check for per-user registration. If user asked for a per-user install + // but the registration object does not support it, fail. + bool perUserRegistration = false; + hRes = ATL::AtlGetPerUserRegistration(&perUserRegistration); + if (SUCCEEDED(hRes) && perUserRegistration && cpPccExt2.p == nullptr) { + hRes = E_NOTIMPL; + } if (SUCCEEDED(hRes)) { - // Perform per-user registration if available, otherwise fall back to - // the default interface. We'll have verified that this is OK before. - if (cpPccExt2.p != nullptr) { - const VARIANT_BOOL varPerUser = perUserOverride.Overridden() ? VARIANT_TRUE : VARIANT_FALSE; - const auto registerPlugin = [&](REFCLSID p_CLSID) { - if (SUCCEEDED(hRes)) { - hRes = cpPccExt2->RegisterPlugin2(p_CLSID, varPerUser); - } - }; - registerPlugin(__uuidof(PathCopyCopyPlugin1a)); - registerPlugin(__uuidof(PathCopyCopyPlugin1b)); - registerPlugin(__uuidof(PathCopyCopyPlugin2a)); - registerPlugin(__uuidof(PathCopyCopyPlugin2b)); - } else { - const auto registerPlugin = [&](REFCLSID p_CLSID) { - if (SUCCEEDED(hRes)) { - hRes = cpPccExt->RegisterPlugin(p_CLSID); - } - }; - registerPlugin(__uuidof(PathCopyCopyPlugin1a)); - registerPlugin(__uuidof(PathCopyCopyPlugin1b)); - registerPlugin(__uuidof(PathCopyCopyPlugin2a)); - registerPlugin(__uuidof(PathCopyCopyPlugin2b)); + // First perform DLL registration. + hRes = ATL::CAtlDllModuleT::DllRegisterServer(bRegTypeLib); + if (SUCCEEDED(hRes)) { + // Perform per-user registration if available, otherwise fall back to + // the default interface. We'll have verified that this is OK before. + if (cpPccExt2.p != nullptr) { + const VARIANT_BOOL varPerUser = perUserRegistration ? VARIANT_TRUE : VARIANT_FALSE; + const auto registerPlugin = [&](REFCLSID p_CLSID) { + if (SUCCEEDED(hRes)) { + hRes = cpPccExt2->RegisterPlugin2(p_CLSID, varPerUser); + } + }; + registerPlugin(__uuidof(PathCopyCopyPlugin1a)); + registerPlugin(__uuidof(PathCopyCopyPlugin1b)); + registerPlugin(__uuidof(PathCopyCopyPlugin2a)); + registerPlugin(__uuidof(PathCopyCopyPlugin2b)); + } else { + const auto registerPlugin = [&](REFCLSID p_CLSID) { + if (SUCCEEDED(hRes)) { + hRes = cpPccExt->RegisterPlugin(p_CLSID); + } + }; + registerPlugin(__uuidof(PathCopyCopyPlugin1a)); + registerPlugin(__uuidof(PathCopyCopyPlugin1b)); + registerPlugin(__uuidof(PathCopyCopyPlugin2a)); + registerPlugin(__uuidof(PathCopyCopyPlugin2b)); + } } } } + return hRes; + } catch (...) { + return E_UNEXPECTED; } - return hRes; } // Unregisters our COM object. We will also remove our plugins from Path Copy Copy. [[gsl::suppress(c.128)]] HRESULT CTestPluginsModule::DllUnregisterServer(BOOL bUnRegTypeLib /*= TRUE*/) throw() { - // Setup per-user unregistration. - StAtlPerUserOverride perUserOverride; - HRESULT hRes = perUserOverride.Succeeded() ? S_OK : E_FAIL; - if (SUCCEEDED(hRes)) { - // First perform DLL unregistration. - hRes = ATL::CAtlDllModuleT::DllUnregisterServer(bUnRegTypeLib); + try { + // Setup per-user unregistration. + bool perUserRegistration = false; + HRESULT hRes = ATL::AtlGetPerUserRegistration(&perUserRegistration); if (SUCCEEDED(hRes)) { - // Create PathCopyCopy registration object and check if it supports per-user uninstall. - ATL::CComPtr cpPccExt; - hRes = cpPccExt.CoCreateInstance(__uuidof(PathCopyCopyContextMenuExt)); + // First perform DLL unregistration. + hRes = ATL::CAtlDllModuleT::DllUnregisterServer(bUnRegTypeLib); if (SUCCEEDED(hRes)) { - ATL::CComQIPtr cpPccExt2(cpPccExt); + // Create PathCopyCopy registration object and check if it supports per-user uninstall. + ATL::CComPtr cpPccExt; + hRes = cpPccExt.CoCreateInstance(__uuidof(PathCopyCopyContextMenuExt)); + if (SUCCEEDED(hRes)) { + ATL::CComQIPtr cpPccExt2(cpPccExt); - // If user asked for a per-user uninstall but the registration - // object does not support it, fail. - if (SUCCEEDED(hRes) && perUserOverride.Overridden() && cpPccExt2.p == nullptr) { - hRes = E_NOTIMPL; - } else { - // Perform per-user unregistration if available, otherwise fall back to - // the default interface. We'll have verified that this is OK before. - if (cpPccExt2.p != nullptr) { - const VARIANT_BOOL varPerUser = perUserOverride.Overridden() ? VARIANT_TRUE : VARIANT_FALSE; - const auto unregisterPlugin = [&](REFCLSID p_CLSID) { - if (SUCCEEDED(hRes)) { - hRes = cpPccExt2->UnregisterPlugin2(p_CLSID, varPerUser); - } - }; - unregisterPlugin(__uuidof(PathCopyCopyPlugin1a)); - unregisterPlugin(__uuidof(PathCopyCopyPlugin1b)); - unregisterPlugin(__uuidof(PathCopyCopyPlugin2a)); - unregisterPlugin(__uuidof(PathCopyCopyPlugin2b)); + // If user asked for a per-user uninstall but the registration + // object does not support it, fail. + if (SUCCEEDED(hRes) && perUserRegistration && cpPccExt2.p == nullptr) { + hRes = E_NOTIMPL; } else { - const auto unregisterPlugin = [&](REFCLSID p_CLSID) { - if (SUCCEEDED(hRes)) { - hRes = cpPccExt->UnregisterPlugin(p_CLSID); - } - }; - unregisterPlugin(__uuidof(PathCopyCopyPlugin1a)); - unregisterPlugin(__uuidof(PathCopyCopyPlugin1b)); - unregisterPlugin(__uuidof(PathCopyCopyPlugin2a)); - unregisterPlugin(__uuidof(PathCopyCopyPlugin2b)); + // Perform per-user unregistration if available, otherwise fall back to + // the default interface. We'll have verified that this is OK before. + if (cpPccExt2.p != nullptr) { + const VARIANT_BOOL varPerUser = perUserRegistration ? VARIANT_TRUE : VARIANT_FALSE; + const auto unregisterPlugin = [&](REFCLSID p_CLSID) { + if (SUCCEEDED(hRes)) { + hRes = cpPccExt2->UnregisterPlugin2(p_CLSID, varPerUser); + } + }; + unregisterPlugin(__uuidof(PathCopyCopyPlugin1a)); + unregisterPlugin(__uuidof(PathCopyCopyPlugin1b)); + unregisterPlugin(__uuidof(PathCopyCopyPlugin2a)); + unregisterPlugin(__uuidof(PathCopyCopyPlugin2b)); + } else { + const auto unregisterPlugin = [&](REFCLSID p_CLSID) { + if (SUCCEEDED(hRes)) { + hRes = cpPccExt->UnregisterPlugin(p_CLSID); + } + }; + unregisterPlugin(__uuidof(PathCopyCopyPlugin1a)); + unregisterPlugin(__uuidof(PathCopyCopyPlugin1b)); + unregisterPlugin(__uuidof(PathCopyCopyPlugin2a)); + unregisterPlugin(__uuidof(PathCopyCopyPlugin2b)); + } } } } } + return hRes; + } catch (...) { + return E_UNEXPECTED; } - return hRes; } // Returns the instance handle passed to our module's DllMain.