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:
parent
1d206602e6
commit
31ebd9b08f
@ -184,7 +184,7 @@ namespace winstd
|
|||||||
///
|
///
|
||||||
/// \return Duplicated object handle
|
/// \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();
|
h->AddRef();
|
||||||
return h;
|
return h;
|
||||||
@ -271,9 +271,12 @@ namespace winstd
|
|||||||
///
|
///
|
||||||
/// \sa [SysAllocString function](https://msdn.microsoft.com/en-us/library/windows/desktop/ms221458.aspx)
|
/// \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();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -854,7 +854,7 @@ namespace winstd
|
|||||||
///
|
///
|
||||||
/// \param[inout] h A reference of another object
|
/// \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 (this != std::addressof(h)) {
|
||||||
if (h.m_h != invalid) {
|
if (h.m_h != invalid) {
|
||||||
handle_type h_new = duplicate_internal(h.m_h);
|
handle_type h_new = duplicate_internal(h.m_h);
|
||||||
if (h_new != invalid) {
|
|
||||||
if (m_h != invalid)
|
|
||||||
free_internal();
|
|
||||||
|
|
||||||
m_h = h_new;
|
if (m_h != invalid)
|
||||||
} else
|
free_internal();
|
||||||
assert(0); // Could not duplicate the handle
|
|
||||||
|
m_h = h_new;
|
||||||
} else {
|
} else {
|
||||||
if (m_h != invalid)
|
if (m_h != invalid)
|
||||||
free_internal();
|
free_internal();
|
||||||
@ -932,27 +930,24 @@ namespace winstd
|
|||||||
///
|
///
|
||||||
/// \param[in] h Object handle of existing object
|
/// \param[in] h Object handle of existing object
|
||||||
///
|
///
|
||||||
/// \return
|
void attach_duplicated(_In_opt_ handle_type h)
|
||||||
/// - 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)
|
|
||||||
{
|
{
|
||||||
if (m_h != invalid)
|
if (m_h != invalid)
|
||||||
free_internal();
|
free_internal();
|
||||||
|
|
||||||
return h != invalid ? (m_h = duplicate_internal(h)) != invalid : (m_h = invalid, true);
|
m_h = h != invalid ? duplicate_internal(h) : invalid;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
///
|
///
|
||||||
/// Abstract member function that must be implemented by child classes to do the actual object handle duplication.
|
/// 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
|
/// \param[in] h Object handle of existing object
|
||||||
///
|
///
|
||||||
/// \return Duplicated object handle
|
/// \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;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// @}
|
/// @}
|
||||||
|
@ -370,8 +370,9 @@ namespace winstd
|
|||||||
///
|
///
|
||||||
/// \sa [CertDuplicateCertificateContext function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa376045.aspx)
|
/// \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);
|
return CertDuplicateCertificateContext(h);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -415,10 +416,11 @@ namespace winstd
|
|||||||
///
|
///
|
||||||
/// \return Duplicated certificate chain context handle
|
/// \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);
|
return CertDuplicateCertificateChain(h);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -531,10 +533,12 @@ namespace winstd
|
|||||||
///
|
///
|
||||||
/// \sa [CryptDuplicateHash function](https://msdn.microsoft.com/en-us/library/windows/desktop/aa379919.aspx)
|
/// \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;
|
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)
|
/// \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;
|
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");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -271,13 +271,10 @@ namespace winstd
|
|||||||
dwLength = a.dwLength;
|
dwLength = a.dwLength;
|
||||||
if (a.dwLength) {
|
if (a.dwLength) {
|
||||||
BYTE *pValueNew = new BYTE[a.dwLength];
|
BYTE *pValueNew = new BYTE[a.dwLength];
|
||||||
if (pValueNew) {
|
if (pValue)
|
||||||
if (pValue)
|
delete [] pValue;
|
||||||
delete [] pValue;
|
memcpy(pValueNew, a.pValue, a.dwLength);
|
||||||
memcpy(pValueNew, a.pValue, a.dwLength);
|
pValue = pValueNew;
|
||||||
pValue = pValueNew;
|
|
||||||
} else
|
|
||||||
assert(0); // Could not allocate memory
|
|
||||||
} else
|
} else
|
||||||
pValue = NULL;
|
pValue = NULL;
|
||||||
}
|
}
|
||||||
@ -472,16 +469,15 @@ namespace winstd
|
|||||||
///
|
///
|
||||||
/// Duplicates the EAP packet.
|
/// 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));
|
const WORD n = ntohs(*reinterpret_cast<WORD*>(h->Length));
|
||||||
handle_type h2 = static_cast<handle_type>(HeapAlloc(GetProcessHeap(), 0, n));
|
handle_type h2 = static_cast<handle_type>(HeapAlloc(GetProcessHeap(), 0, n));
|
||||||
if (h2 == NULL) {
|
if (h2 != invalid) {
|
||||||
SetLastError(ERROR_OUTOFMEMORY);
|
memcpy(h2, h, n);
|
||||||
return NULL;
|
return h2;
|
||||||
}
|
}
|
||||||
memcpy(h2, h, n);
|
throw std::bad_alloc();
|
||||||
return h2;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user