Skip to content

Commit

Permalink
Added INFHandleGuard
Browse files Browse the repository at this point in the history
  • Loading branch information
nefarius committed Aug 7, 2024
1 parent 05f4637 commit fda5cf2
Show file tree
Hide file tree
Showing 5 changed files with 97 additions and 31 deletions.
1 change: 1 addition & 0 deletions NefConUtil.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -546,6 +546,7 @@
<ClInclude Include=".\src\resource.h" />
<ClInclude Include=".\src\UniUtil.h" />
<ClInclude Include="src\MultiStringArray.hpp" />
<ClInclude Include="src\ScopeGuards.hpp" />
<ClInclude Include="src\Win32Error.hpp" />
</ItemGroup>
<ItemGroup>
Expand Down
3 changes: 3 additions & 0 deletions NefConUtil.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@
<ClInclude Include="src\Win32Error.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\ScopeGuards.hpp">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include=".\src\NefConUtil.rc">
Expand Down
47 changes: 16 additions & 31 deletions src/Devcon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
#include <wil/resource.h>

#include "MultiStringArray.hpp"
#include "ScopeGuards.hpp"

using namespace nefarius::util;

Expand Down Expand Up @@ -974,17 +975,9 @@ std::expected<void, Win32Error> devcon::inf_default_install(
return std::unexpected(Win32Error(ERROR_BAD_PATHNAME));
}

const HINF hInf = SetupOpenInfFileW(normalisedInfPath, nullptr, INF_STYLE_WIN4, nullptr);
INFHandleGuard hInf(SetupOpenInfFileW(normalisedInfPath, nullptr, INF_STYLE_WIN4, nullptr));

const auto guard = sg::make_scope_guard([hInf]() noexcept
{
if (hInf != INVALID_HANDLE_VALUE)
{
SetupCloseInfFile(hInf);
}
});

if (hInf == INVALID_HANDLE_VALUE)
if (hInf.is_invalid())
{
return std::unexpected(Win32Error());
}
Expand All @@ -993,14 +986,14 @@ std::expected<void, Win32Error> devcon::inf_default_install(
// Try default section first, which is common to class filter driver, filesystem drivers and alike
//
if (SetupDiGetActualSectionToInstallW(
hInf,
hInf.get(),
L"DefaultInstall",
InfSectionWithExt,
LINE_LEN,
reinterpret_cast<PDWORD>(&sysInfo.lpMinimumApplicationAddress),
nullptr)
&& SetupFindFirstLineW(
hInf,
hInf.get(),
InfSectionWithExt,
nullptr,
reinterpret_cast<PINFCONTEXT>(&sysInfo.lpMaximumApplicationAddress)
Expand Down Expand Up @@ -1048,8 +1041,12 @@ std::expected<void, Win32Error> devcon::inf_default_install(
//
// If we have no Default, but a Manufacturer section we can attempt classic installation
//
if (!SetupFindFirstLineW(hInf, L"Manufacturer", nullptr,
reinterpret_cast<PINFCONTEXT>(&sysInfo.lpMaximumApplicationAddress)))
if (!SetupFindFirstLineW(
hInf.get(),
L"Manufacturer",
nullptr,
reinterpret_cast<PINFCONTEXT>(&sysInfo.lpMaximumApplicationAddress)
))
{
//
// We need either one or the other, this INF appears to not be compatible with this install method
Expand Down Expand Up @@ -1105,30 +1102,22 @@ std::expected<void, Win32Error> devcon::inf_default_uninstall(const std::wstring
return std::unexpected(Win32Error(ERROR_BAD_PATHNAME));
}

const HINF hInf = SetupOpenInfFileW(normalisedInfPath, nullptr, INF_STYLE_WIN4, nullptr);

const auto guard = sg::make_scope_guard([hInf]() noexcept
{
if (hInf != INVALID_HANDLE_VALUE)
{
SetupCloseInfFile(hInf);
}
});
INFHandleGuard hInf(SetupOpenInfFileW(normalisedInfPath, nullptr, INF_STYLE_WIN4, nullptr));

if (hInf == INVALID_HANDLE_VALUE)
if (hInf.is_invalid())
{
return std::unexpected(Win32Error());
}

if (SetupDiGetActualSectionToInstallW(
hInf,
hInf.get(),
L"DefaultUninstall",
InfSectionWithExt,
LINE_LEN,
reinterpret_cast<PDWORD>(&sysInfo.lpMinimumApplicationAddress),
nullptr)
&& SetupFindFirstLineW(
hInf,
hInf.get(),
InfSectionWithExt,
nullptr,
reinterpret_cast<PINFCONTEXT>(&sysInfo.lpMaximumApplicationAddress)
Expand Down Expand Up @@ -1165,12 +1154,8 @@ std::expected<void, Win32Error> devcon::inf_default_uninstall(const std::wstring

return {};
}
else
{
return std::unexpected(Win32Error(ERROR_SECTION_NOT_FOUND));
}

return std::unexpected(Win32Error(ERROR_INTERNAL_ERROR));
return std::unexpected(Win32Error(ERROR_SECTION_NOT_FOUND));
}

bool devcon::find_by_hwid(const std::wstring& matchstring)
Expand Down
1 change: 1 addition & 0 deletions src/NefConUtil.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,3 +50,4 @@
#include "Devcon.h"
#include "NefConSetup.h"
#include "UniUtil.h"
#include "ScopeGuards.hpp"
76 changes: 76 additions & 0 deletions src/ScopeGuards.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
#pragma once

#include <Windows.h>
#include <SetupAPI.h>

namespace nefarius::util
{
class INFHandleGuard
{
public:
// Constructor takes the HINF handle to manage
explicit INFHandleGuard(HINF handle) : handle_(handle)
{
}

// Destructor releases the HINF resource
~INFHandleGuard()
{
if (handle_ != INVALID_HANDLE_VALUE)
{
SetupCloseInfFile(handle_);
}
}

// Disable copy constructor and copy assignment operator
INFHandleGuard(const INFHandleGuard&) = delete;
INFHandleGuard& operator=(const INFHandleGuard&) = delete;

// Move constructor
INFHandleGuard(INFHandleGuard&& other) noexcept : handle_(other.handle_)
{
other.handle_ = INVALID_HANDLE_VALUE;
}

// Move assignment operator
INFHandleGuard& operator=(INFHandleGuard&& other) noexcept
{
if (this != &other)
{
// Release current resource
if (handle_ != INVALID_HANDLE_VALUE)
{
SetupCloseInfFile(handle_);
}
// Transfer ownership
handle_ = other.handle_;
other.handle_ = INVALID_HANDLE_VALUE;
}
return *this;
}

// Function to manually release the handle, if needed
void release()
{
if (handle_ != INVALID_HANDLE_VALUE)
{
SetupCloseInfFile(handle_);
handle_ = INVALID_HANDLE_VALUE;
}
}

// Accessor for the handle
HINF get() const
{
return handle_;
}

bool is_invalid() const
{
return handle_ == INVALID_HANDLE_VALUE;
}

private:
HINF handle_;
};
}

0 comments on commit fda5cf2

Please sign in to comment.