Make duplicate_internal() and other allocation methods throw

An exception can be way more elaborate why duplication failed and it
doesn't require consistent checking for result.

Signed-off-by: Simon Rozman <simon@rozman.si>
This commit is contained in:
Simon Rozman 2023-03-08 08:56:10 +01:00
parent 1d206602e6
commit 31ebd9b08f
4 changed files with 37 additions and 37 deletions

View File

@ -184,7 +184,7 @@ namespace winstd
///
/// \return Duplicated object handle
///
handle_type duplicate_internal(_In_ handle_type h) const noexcept override
handle_type duplicate_internal(_In_ handle_type h) const override
{
h->AddRef();
return h;
@ -271,9 +271,12 @@ namespace winstd
///
/// \sa [SysAllocString function](https://msdn.microsoft.com/en-us/library/windows/desktop/ms221458.aspx)
///
handle_type duplicate_internal(_In_ handle_type h) const noexcept override
handle_type duplicate_internal(_In_ handle_type h) const override
{
return SysAllocStringLen(h, SysStringLen(h));
handle_type h_new = SysAllocStringLen(h, SysStringLen(h));
if (h_new != invalid)
return h_new;
throw std::bad_alloc();
}
};

View File

@ -854,7 +854,7 @@ namespace winstd
///
/// \param[inout] h A reference of another object
///
dplhandle<handle_type, INVAL>(_In_ const dplhandle<handle_type, INVAL> &h) noexcept : handle<handle_type, INVAL>(duplicate_internal(h.m_h))
dplhandle<handle_type, INVAL>(_In_ const dplhandle<handle_type, INVAL> &h) : handle<handle_type, INVAL>(duplicate_internal(h.m_h))
{
}
@ -888,13 +888,11 @@ namespace winstd
if (this != std::addressof(h)) {
if (h.m_h != invalid) {
handle_type h_new = duplicate_internal(h.m_h);
if (h_new != invalid) {
if (m_h != invalid)
free_internal();
m_h = h_new;
} else
assert(0); // Could not duplicate the handle
if (m_h != invalid)
free_internal();
m_h = h_new;
} else {
if (m_h != invalid)
free_internal();
@ -932,27 +930,24 @@ namespace winstd
///
/// \param[in] h Object handle of existing object
///
/// \return
/// - true when duplication succeeds;
/// - false when duplication fails. In case of failure obtaining the extended error information is object type specific (for example: `GetLastError()`).
///
bool attach_duplicated(_In_opt_ handle_type h)
void attach_duplicated(_In_opt_ handle_type h)
{
if (m_h != invalid)
free_internal();
return h != invalid ? (m_h = duplicate_internal(h)) != invalid : (m_h = invalid, true);
m_h = h != invalid ? duplicate_internal(h) : invalid;
}
protected:
///
/// Abstract member function that must be implemented by child classes to do the actual object handle duplication.
/// On failure, it should throw appropriate exception describing the cause, rather than return an invalid handle.
///
/// \param[in] h Object handle of existing object
///
/// \return Duplicated object handle
///
virtual handle_type duplicate_internal(_In_ handle_type h) const noexcept = 0;
virtual handle_type duplicate_internal(_In_ handle_type h) const = 0;
};
/// @}

View File

@ -370,8 +370,9 @@ namespace winstd
///
/// \sa [CertDuplicateCertificateContext function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa376045.aspx)
///
handle_type duplicate_internal(_In_ handle_type h) const noexcept override
handle_type duplicate_internal(_In_ handle_type h) const override
{
// As per doc, this only increases refcounter. Should never fail.
return CertDuplicateCertificateContext(h);
}
};
@ -415,10 +416,11 @@ namespace winstd
///
/// \return Duplicated certificate chain context handle
///
/// \sa [CertDuplicateCertificateContext function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa376045.aspx)
/// \sa [CertDuplicateCertificateChain function](https://learn.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-certduplicatecertificatechain)
///
handle_type duplicate_internal(_In_ handle_type h) const noexcept override
handle_type duplicate_internal(_In_ handle_type h) const override
{
// As per doc, this only increases refcounter. Should never fail.
return CertDuplicateCertificateChain(h);
}
};
@ -531,10 +533,12 @@ namespace winstd
///
/// \sa [CryptDuplicateHash function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa379919.aspx)
///
handle_type duplicate_internal(_In_ handle_type h) const noexcept override
handle_type duplicate_internal(_In_ handle_type h) const override
{
handle_type hNew;
return CryptDuplicateHash(h, NULL, 0, &hNew) ? hNew : invalid;
if (CryptDuplicateHash(h, NULL, 0, &hNew))
return hNew;
throw win_runtime_error("CryptDuplicateHash failed");
}
};
@ -652,10 +656,12 @@ namespace winstd
///
/// \sa [CryptDuplicateKey function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa379920.aspx)
///
handle_type duplicate_internal(_In_ handle_type h) const noexcept override
handle_type duplicate_internal(_In_ handle_type h) const override
{
handle_type hNew;
return CryptDuplicateKey(h, NULL, 0, &hNew) ? hNew : invalid;
if (CryptDuplicateKey(h, NULL, 0, &hNew))
return hNew;
throw win_runtime_error("CryptDuplicateKey failed");
}
};

View File

@ -271,13 +271,10 @@ namespace winstd
dwLength = a.dwLength;
if (a.dwLength) {
BYTE *pValueNew = new BYTE[a.dwLength];
if (pValueNew) {
if (pValue)
delete [] pValue;
memcpy(pValueNew, a.pValue, a.dwLength);
pValue = pValueNew;
} else
assert(0); // Could not allocate memory
if (pValue)
delete [] pValue;
memcpy(pValueNew, a.pValue, a.dwLength);
pValue = pValueNew;
} else
pValue = NULL;
}
@ -472,16 +469,15 @@ namespace winstd
///
/// Duplicates the EAP packet.
///
handle_type duplicate_internal(_In_ handle_type h) const noexcept override
handle_type duplicate_internal(_In_ handle_type h) const override
{
const WORD n = ntohs(*reinterpret_cast<WORD*>(h->Length));
handle_type h2 = static_cast<handle_type>(HeapAlloc(GetProcessHeap(), 0, n));
if (h2 == NULL) {
SetLastError(ERROR_OUTOFMEMORY);
return NULL;
if (h2 != invalid) {
memcpy(h2, h, n);
return h2;
}
memcpy(h2, h, n);
return h2;
throw std::bad_alloc();
}
};