diff --git a/atl.vcxproj b/atl.vcxproj new file mode 100644 index 0000000..70a1826 --- /dev/null +++ b/atl.vcxproj @@ -0,0 +1,119 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + libatl + {5A4EADF2-3237-457A-9DA8-BB9942A91019} + libatl + Win32Proj + + + + StaticLibrary + Unicode + + + StaticLibrary + Unicode + + + StaticLibrary + Unicode + + + StaticLibrary + Unicode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.40219.1 + + + + + + + X64 + + + + + + + + + X64 + + + + + + Create + Create + Create + Create + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/atl.vcxproj.filters b/atl.vcxproj.filters new file mode 100644 index 0000000..f305a55 --- /dev/null +++ b/atl.vcxproj.filters @@ -0,0 +1,47 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + + + Source Files + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + \ No newline at end of file diff --git a/atlcrypt.h b/atlcrypt.h new file mode 100644 index 0000000..5d08c36 --- /dev/null +++ b/atlcrypt.h @@ -0,0 +1,311 @@ +/* + Copyright 1991-2015 Amebis + + This file is part of libatl. + + Setup is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Setup is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Setup. If not, see . +*/ + +#pragma once + +#include "atlex.h" +#include +#include +#include + + +inline DWORD CertGetNameStringA(PCCERT_CONTEXT pCertContext, DWORD dwType, DWORD dwFlags, void *pvTypePara, ATL::CAtlStringA &sNameString) +{ + // Query the final string length first. + DWORD dwSize = ::CertGetNameStringA(pCertContext, dwType, dwFlags, pvTypePara, NULL, 0); + + // Prepare the buffer to format the string data into and read it. + LPSTR szBuffer = sNameString.GetBuffer(dwSize); + if (!szBuffer) return ERROR_OUTOFMEMORY; + dwSize = ::CertGetNameStringA(pCertContext, dwType, dwFlags, pvTypePara, szBuffer, dwSize); + sNameString.ReleaseBuffer(dwSize); + return dwSize; +} + + +inline DWORD CertGetNameStringW(PCCERT_CONTEXT pCertContext, DWORD dwType, DWORD dwFlags, void *pvTypePara, ATL::CAtlStringW &sNameString) +{ + // Query the final string length first. + DWORD dwSize = ::CertGetNameStringW(pCertContext, dwType, dwFlags, pvTypePara, NULL, 0); + + // Prepare the buffer to format the string data into and read it. + LPWSTR szBuffer = sNameString.GetBuffer(dwSize); + if (!szBuffer) return ERROR_OUTOFMEMORY; + dwSize = ::CertGetNameStringW(pCertContext, dwType, dwFlags, pvTypePara, szBuffer, dwSize); + sNameString.ReleaseBuffer(dwSize); + return dwSize; +} + + +inline BOOL CryptGetHashParam(__in HCRYPTHASH hHash, __in DWORD dwParam, __out ATL::CAtlArray &aData, __in DWORD dwFlags) +{ + DWORD dwHashSize; + + if (CryptGetHashParam(hHash, dwParam, NULL, &dwHashSize, dwFlags)) { + if (aData.SetCount(dwHashSize)) { + if (CryptGetHashParam(hHash, dwParam, aData.GetData(), &dwHashSize, dwFlags)) { + return TRUE; + } else { + aData.SetCount(0); + return FALSE; + } + } else { + SetLastError(ERROR_OUTOFMEMORY); + return FALSE; + } + } else + return FALSE; +} + + +inline BOOL CryptExportKey(__in HCRYPTKEY hKey, __in HCRYPTKEY hExpKey, __in DWORD dwBlobType, __in DWORD dwFlags, __out ATL::CAtlArray &aData) +{ + DWORD dwKeyBLOBSize; + + if (CryptExportKey(hKey, hExpKey, dwBlobType, dwFlags, NULL, &dwKeyBLOBSize)) { + if (aData.SetCount(dwKeyBLOBSize)) { + if (CryptExportKey(hKey, hExpKey, dwBlobType, dwFlags, aData.GetData(), &dwKeyBLOBSize)) { + return TRUE; + } else { + aData.SetCount(0); + return FALSE; + } + } else { + SetLastError(ERROR_OUTOFMEMORY); + return FALSE; + } + } else + return FALSE; +} + + +namespace ATL +{ + namespace Crypt + { + // + // CCertContext + // + class CCertContext : public ATL::CObjectWithHandleDuplT + { + public: + virtual ~CCertContext() throw() + { + if (m_h) + CertFreeCertificateContext(m_h); + } + + inline BOOL Create(_In_ DWORD dwCertEncodingType, _In_ const BYTE *pbCertEncoded, _In_ DWORD cbCertEncoded) throw() + { + HANDLE h = CertCreateCertificateContext(dwCertEncodingType, pbCertEncoded, cbCertEncoded); + if (h) { + Attach(h); + return TRUE; + } else + return FALSE; + } + + protected: + virtual void InternalFree() + { + CertFreeCertificateContext(m_h); + } + + virtual HANDLE InternalDuplicate(HANDLE h) const + { + return CertDuplicateCertificateContext(h); + } + }; + + + // + // CCertChainContext + // + class CCertChainContext : public ATL::CObjectWithHandleDuplT + { + public: + virtual ~CCertChainContext() throw() + { + if (m_h) + CertFreeCertificateChain(m_h); + } + + inline BOOL Create(__in_opt HCERTCHAINENGINE hChainEngine, __in PCCERT_CONTEXT pCertContext, __in_opt LPFILETIME pTime, __in_opt HCERTSTORE hAdditionalStore, __in PCERT_CHAIN_PARA pChainPara, __in DWORD dwFlags, __reserved LPVOID pvReserved) throw() + { + HANDLE h; + if (CertGetCertificateChain(hChainEngine, pCertContext, pTime, hAdditionalStore, pChainPara, dwFlags, pvReserved, &h)) { + Attach(h); + return TRUE; + } else + return FALSE; + } + + protected: + virtual void InternalFree() + { + CertFreeCertificateChain(m_h); + } + + virtual HANDLE InternalDuplicate(HANDLE h) const + { + return CertDuplicateCertificateChain(h); + } + }; + + + // + // CCertStore + // + class CCertStore : public ATL::CObjectWithHandleT + { + public: + virtual ~CCertStore() throw() + { + if (m_h) + CertCloseStore(m_h, 0); + } + + inline BOOL Create(__in LPCSTR lpszStoreProvider, __in DWORD dwEncodingType, __in_opt HCRYPTPROV_LEGACY hCryptProv, __in DWORD dwFlags, __in_opt const void *pvPara) throw() + { + HANDLE h = CertOpenStore(lpszStoreProvider, dwEncodingType, hCryptProv, dwFlags, pvPara); + if (h) { + Attach(h); + return TRUE; + } else + return FALSE; + } + + protected: + virtual void InternalFree() + { + CertCloseStore(m_h, 0); + } + }; + + + // + // CContext + // + class CContext : public ATL::CObjectWithHandleT + { + public: + virtual ~CContext() throw() + { + if (m_h) + CryptReleaseContext(m_h, 0); + } + + inline BOOL Create(__in_opt LPCTSTR szContainer, __in_opt LPCTSTR szProvider, __in DWORD dwProvType, __in DWORD dwFlags) throw() + { + HANDLE h; + if (CryptAcquireContext(&h, szContainer, szProvider, dwProvType, dwFlags)) { + Attach(h); + return TRUE; + } else + return FALSE; + } + + protected: + virtual void InternalFree() + { + CryptReleaseContext(m_h, 0); + } + }; + + + // + // CHash + // + class CHash : public ATL::CObjectWithHandleT + { + public: + virtual ~CHash() throw() + { + if (m_h) + CryptDestroyHash(m_h); + } + + inline BOOL Create(__in HCRYPTPROV hProv, __in ALG_ID Algid, __in HCRYPTKEY hKey, __in DWORD dwFlags) throw() + { + HANDLE h; + if (CryptCreateHash(hProv, Algid, hKey, dwFlags, &h)) { + Attach(h); + return TRUE; + } else + return FALSE; + } + + protected: + virtual void InternalFree() + { + CryptDestroyHash(m_h); + } + }; + + + // + // CKey + // + class CKey : public ATL::CObjectWithHandleT + { + public: + virtual ~CKey() throw() + { + if (m_h) + CryptDestroyKey(m_h); + } + + inline BOOL Generate(__in HCRYPTPROV hProv, __in ALG_ID Algid, __in DWORD dwFlags) throw() + { + HANDLE h; + if (CryptGenKey(hProv, Algid, dwFlags, &h)) { + Attach(h); + return TRUE; + } else + return FALSE; + } + + inline BOOL Import(__in HCRYPTPROV hProv, __in_bcount(dwDataLen) CONST BYTE *pbData, __in DWORD dwDataLen, __in HCRYPTKEY hPubKey, __in DWORD dwFlags) throw() + { + HANDLE h; + if (CryptImportKey(hProv, pbData, dwDataLen, hPubKey, dwFlags, &h)) { + Attach(h); + return TRUE; + } else + return FALSE; + } + + inline BOOL ImportPublic(__in HCRYPTPROV hCryptProv, __in DWORD dwCertEncodingType, __in PCERT_PUBLIC_KEY_INFO pInfo) throw() + { + HANDLE h; + if (CryptImportPublicKeyInfo(hCryptProv, dwCertEncodingType, pInfo, &h)) { + Attach(h); + return TRUE; + } else + return FALSE; + } + + protected: + virtual void InternalFree() + { + CryptDestroyKey(m_h); + } + }; + } +} diff --git a/atleap.h b/atleap.h new file mode 100644 index 0000000..5951c70 --- /dev/null +++ b/atleap.h @@ -0,0 +1,46 @@ +/* + Copyright 1991-2015 Amebis + + This file is part of libatl. + + Setup is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Setup is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Setup. If not, see . +*/ + +#pragma once + +#include + + +namespace ATL +{ + namespace EAP + { + class CEAPAttribute : public EAP_ATTRIBUTE + { + public: + CEAPAttribute() + { + eaType = eatReserved; + dwLength = 0; + pValue = NULL; + } + + ~CEAPAttribute() + { + if (pValue) + delete pValue; + } + }; + } +} diff --git a/atlex.h b/atlex.h new file mode 100644 index 0000000..adf0e93 --- /dev/null +++ b/atlex.h @@ -0,0 +1,324 @@ +/* + Copyright 1991-2015 Amebis + + This file is part of libatl. + + Setup is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Setup is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Setup. If not, see . +*/ + +#pragma once + +#include +#include +#include + + +namespace ATL +{ + // + // CObjectWithHandleT + // + template + class CObjectWithHandleT + { + public: + typedef T HANDLE; + + inline CObjectWithHandleT() throw() : m_h(NULL) + { + } + + inline CObjectWithHandleT(HANDLE h) throw() : m_h(h) + { + } + + inline operator HANDLE() const throw() + { + return m_h; + } + + inline HANDLE*& operator*() const + { + ATLENSURE(m_h != NULL); + return *m_h; + } + + inline HANDLE* operator&() throw() + { + ATLASSERT(m_h == NULL); + return &m_h; + } + + inline HANDLE operator->() const throw() + { + ATLASSERT(m_h != NULL); + return m_h; + } + + inline bool operator!() const throw() + { + return m_h == NULL; + } + + inline bool operator<(_In_opt_ HANDLE h) const throw() + { + return m_h < h; + } + + inline bool operator!=(_In_opt_ HANDLE h) const + { + return !operator==(h); + } + + inline bool operator==(_In_opt_ HANDLE h) const throw() + { + return m_h == h; + } + + inline void Attach(_In_opt_ HANDLE h) throw() + { + if (m_h) + InternalFree(); + m_h = h; + } + + inline HANDLE Detach() throw() + { + HANDLE h = m_h; + m_h = NULL; + return h; + } + + inline void Free() throw() + { + if (m_h) { + InternalFree(); + m_h = NULL; + } + } + + protected: + virtual void InternalFree() = 0; + + protected: + HANDLE m_h; + }; + + + // + // CObjectWithHandleDuplT + // + template + class CObjectWithHandleDuplT : public CObjectWithHandleT + { + public: + inline HANDLE GetDuplicate() const + { + return m_h ? InternalDuplicate(m_h) : NULL; + } + + inline BOOL DuplicateAndAttach(_In_opt_ HANDLE h) throw() + { + if (m_h) + InternalFree(); + + return h ? (m_h = InternalDuplicate(h)) != NULL : (m_h = NULL, TRUE); + } + + // + // Do not allow = operators. They are semantically ambigious: + // Do they attach the class to the existing instance of object, or do they duplicate it? + // To avoid confusion, user should use Attach() and Duplicate() methods explicitly. + // + //inline const CObjectWithHandleDuplT& operator=(_In_ const HANDLE src) + //{ + // Attach(src ? InternalDuplicate(src) : NULL); + // return *this; + //} + + //inline const CObjectWithHandleDuplT& operator=(_In_ const CObjectWithHandleDuplT &src) + //{ + // Attach(src.m_h ? InternalDuplicate(src.m_h) : NULL); + // return *this; + //} + + protected: + virtual HANDLE InternalDuplicate(HANDLE h) const = 0; + }; + + + // + // CStrFormatT, CStrFormatW, CStrFormatA, CStrFormat + // + template + class CStrFormatT : public CStringT + { + public: + CStrFormatT(_In_z_ _FormatMessage_format_string_ PCXSTR pszFormat, ...) + { + ATLASSERT(AtlIsValidString(pszFormat)); + + va_list argList; + va_start(argList, pszFormat); + FormatV(pszFormat, argList); + va_end(argList); + } + + CStrFormatT(_In_ _FormatMessage_format_string_ UINT nFormatID, ...) + { + CStringT strFormat(GetManager()); + ATLENSURE(strFormat.LoadString(nFormatID)); + + va_list argList; + va_start(argList, nFormatID); + FormatV(strFormat, argList); + va_end(argList); + } + + CStrFormatT(_In_ HINSTANCE hInstance, _In_ _FormatMessage_format_string_ UINT nFormatID, ...) + { + CStringT strFormat(GetManager()); + ATLENSURE(strFormat.LoadString(hInstance, nFormatID)); + + va_list argList; + va_start(argList, nFormatID); + FormatV(strFormat, argList); + va_end(argList); + } + + CStrFormatT(_In_ HINSTANCE hInstance, _In_ WORD wLanguageID, _In_ _FormatMessage_format_string_ UINT nFormatID, ...) + { + CStringT strFormat(GetManager()); + ATLENSURE(strFormat.LoadString(hInstance, nFormatID, wLanguageID)); + + va_list argList; + va_start(argList, nFormatID); + FormatV(strFormat, argList); + va_end(argList); + } + }; + + typedef CStrFormatT< wchar_t, StrTraitATL< wchar_t, ChTraitsCRT< wchar_t > > > CStrFormatW; + typedef CStrFormatT< char, StrTraitATL< char, ChTraitsCRT< char > > > CStrFormatA; + typedef CStrFormatT< TCHAR, StrTraitATL< TCHAR, ChTraitsCRT< TCHAR > > > CStrFormat; + + + // + // CStrFormatMsgT, CStrFormatMsgW, CStrFormatMsgA, CStrFormatMsg + // + template + class CStrFormatMsgT : public CStringT + { + public: + CStrFormatMsgT(_In_z_ _FormatMessage_format_string_ PCXSTR pszFormat, ...) + { + ATLASSERT(AtlIsValidString(pszFormat)); + + va_list argList; + va_start(argList, pszFormat); + FormatMessageV(pszFormat, &argList); + va_end(argList); + } + + CStrFormatMsgT(_In_ _FormatMessage_format_string_ UINT nFormatID, ...) + { + CStringT strFormat(GetManager()); + ATLENSURE(strFormat.LoadString(nFormatID)); + + va_list argList; + va_start(argList, nFormatID); + FormatMessageV(strFormat, &argList); + va_end(argList); + } + + CStrFormatMsgT(_In_ HINSTANCE hInstance, _In_ _FormatMessage_format_string_ UINT nFormatID, ...) + { + CStringT strFormat(GetManager()); + ATLENSURE(strFormat.LoadString(hInstance, nFormatID)); + + va_list argList; + va_start(argList, nFormatID); + FormatMessageV(strFormat, &argList); + va_end(argList); + } + + CStrFormatMsgT(_In_ HINSTANCE hInstance, _In_ WORD wLanguageID, _In_ _FormatMessage_format_string_ UINT nFormatID, ...) + { + CStringT strFormat(GetManager()); + ATLENSURE(strFormat.LoadString(hInstance, nFormatID, wLanguageID)); + + va_list argList; + va_start(argList, nFormatID); + FormatMessageV(strFormat, &argList); + va_end(argList); + } + }; + + typedef CStrFormatMsgT< wchar_t, StrTraitATL< wchar_t, ChTraitsCRT< wchar_t > > > CStrFormatMsgW; + typedef CStrFormatMsgT< char, StrTraitATL< char, ChTraitsCRT< char > > > CStrFormatMsgA; + typedef CStrFormatMsgT< TCHAR, StrTraitATL< TCHAR, ChTraitsCRT< TCHAR > > > CStrFormatMsg; + + + // + // CParanoidHeap + // + template + class CParanoidHeap : public BaseHeap { + public: + virtual void Free(_In_opt_ void* p) throw() + { + // Sanitize then free. + SecureZeroMemory(p, GetSize(p)); + BaseHeap::Free(p); + } + + _Ret_opt_bytecap_(nBytes) virtual void* Reallocate(_In_opt_ void* p, _In_ size_t nBytes) throw() + { + // Create a new sized copy. + void *pNew = Allocate(nBytes); + size_t nSizePrev = GetSize(p); + memcpy(pNew, p, nSizePrev); + + // Sanitize the old data then free. + SecureZeroMemory(p, nSizePrev); + Free(p); + + return pNew; + } + }; + + + // + // CW2AParanoidEX + // + template + class CW2AParanoidEX : public CW2AEX { + public: + CW2AParanoidEX(_In_z_ LPCWSTR psz) throw(...) : CW2AEX(psz) {} + CW2AParanoidEX(_In_z_ LPCWSTR psz, _In_ UINT nCodePage) throw(...) : CW2AEX(psz, nCodePage) {} + ~CW2AParanoidEX() throw() + { + // Sanitize before free. + if (m_psz != m_szBuffer) + SecureZeroMemory(m_psz, _msize(m_psz)); + else + SecureZeroMemory(m_szBuffer, sizeof(m_szBuffer)); + } + }; + + // + // CW2AParanoid + // + typedef CW2AParanoidEX<> CW2AParanoid; +} diff --git a/atlmsi.h b/atlmsi.h new file mode 100644 index 0000000..875d44e --- /dev/null +++ b/atlmsi.h @@ -0,0 +1,241 @@ +/* + Copyright 1991-2015 Amebis + + This file is part of libatl. + + Setup is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Setup is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Setup. If not, see . +*/ + +#pragma once + +#include +#include +#include + + +inline UINT MsiGetPropertyA(MSIHANDLE hInstall, LPCSTR szName, ATL::CAtlStringA &sValue) +{ + DWORD dwSize = 0; + UINT uiResult; + + // Query the actual string length first. + uiResult = ::MsiGetPropertyA(hInstall, szName, "", &dwSize); + if (uiResult == ERROR_MORE_DATA) { + // Prepare the buffer to read the string data into and read it. + LPSTR szBuffer = sValue.GetBuffer(dwSize++); + if (!szBuffer) return ERROR_OUTOFMEMORY; + uiResult = ::MsiGetPropertyA(hInstall, szName, szBuffer, &dwSize); + sValue.ReleaseBuffer(uiResult == NO_ERROR ? dwSize : 0); + return uiResult; + } else if (uiResult == NO_ERROR) { + // The string in database is empty. + sValue.Empty(); + return NO_ERROR; + } else { + // Return error code. + return uiResult; + } +} + + +inline UINT MsiGetPropertyW(MSIHANDLE hInstall, LPCWSTR szName, ATL::CAtlStringW &sValue) +{ + DWORD dwSize = 0; + UINT uiResult; + + // Query the actual string length first. + uiResult = ::MsiGetPropertyW(hInstall, szName, L"", &dwSize); + if (uiResult == ERROR_MORE_DATA) { + // Prepare the buffer to read the string data into and read it. + LPWSTR szBuffer = sValue.GetBuffer(dwSize++); + if (!szBuffer) return ERROR_OUTOFMEMORY; + uiResult = ::MsiGetPropertyW(hInstall, szName, szBuffer, &dwSize); + sValue.ReleaseBuffer(uiResult == NO_ERROR ? dwSize : 0); + return uiResult; + } else if (uiResult == NO_ERROR) { + // The string in database is empty. + sValue.Empty(); + return NO_ERROR; + } else { + // Return error code. + return uiResult; + } +} + + +inline UINT MsiRecordGetStringA(MSIHANDLE hRecord, unsigned int iField, ATL::CAtlStringA &sValue) +{ + DWORD dwSize = 0; + UINT uiResult; + + // Query the actual string length first. + uiResult = ::MsiRecordGetStringA(hRecord, iField, "", &dwSize); + if (uiResult == ERROR_MORE_DATA) { + // Prepare the buffer to read the string data into and read it. + LPSTR szBuffer = sValue.GetBuffer(dwSize++); + if (!szBuffer) return ERROR_OUTOFMEMORY; + uiResult = ::MsiRecordGetStringA(hRecord, iField, szBuffer, &dwSize); + sValue.ReleaseBuffer(uiResult == NO_ERROR ? dwSize : 0); + return uiResult; + } else if (uiResult == NO_ERROR) { + // The string in database is empty. + sValue.Empty(); + return NO_ERROR; + } else { + // Return error code. + return uiResult; + } +} + + +inline UINT MsiRecordGetStringW(MSIHANDLE hRecord, unsigned int iField, ATL::CAtlStringW &sValue) +{ + DWORD dwSize = 0; + UINT uiResult; + + // Query the actual string length first. + uiResult = ::MsiRecordGetStringW(hRecord, iField, L"", &dwSize); + if (uiResult == ERROR_MORE_DATA) { + // Prepare the buffer to read the string data into and read it. + LPWSTR szBuffer = sValue.GetBuffer(dwSize++); + if (!szBuffer) return ERROR_OUTOFMEMORY; + uiResult = ::MsiRecordGetStringW(hRecord, iField, szBuffer, &dwSize); + sValue.ReleaseBuffer(uiResult == NO_ERROR ? dwSize : 0); + return uiResult; + } else if (uiResult == NO_ERROR) { + // The string in database is empty. + sValue.Empty(); + return NO_ERROR; + } else { + // Return error code. + return uiResult; + } +} + + +inline UINT MsiFormatRecordA(MSIHANDLE hInstall, MSIHANDLE hRecord, ATL::CAtlStringA &sValue) +{ + DWORD dwSize = 0; + UINT uiResult; + + // Query the final string length first. + uiResult = ::MsiFormatRecordA(hInstall, hRecord, "", &dwSize); + if (uiResult == ERROR_MORE_DATA) { + // Prepare the buffer to format the string data into and read it. + LPSTR szBuffer = sValue.GetBuffer(dwSize++); + if (!szBuffer) return ERROR_OUTOFMEMORY; + uiResult = ::MsiFormatRecordA(hInstall, hRecord, szBuffer, &dwSize); + sValue.ReleaseBuffer(uiResult == NO_ERROR ? dwSize : 0); + return uiResult; + } else if (uiResult == NO_ERROR) { + // The result is empty. + sValue.Empty(); + return NO_ERROR; + } else { + // Return error code. + return uiResult; + } +} + + +inline UINT MsiFormatRecordW(MSIHANDLE hInstall, MSIHANDLE hRecord, ATL::CAtlStringW &sValue) +{ + DWORD dwSize = 0; + UINT uiResult; + + // Query the final string length first. + uiResult = ::MsiFormatRecordW(hInstall, hRecord, L"", &dwSize); + if (uiResult == ERROR_MORE_DATA) { + // Prepare the buffer to format the string data into and read it. + LPWSTR szBuffer = sValue.GetBuffer(dwSize++); + if (!szBuffer) return ERROR_OUTOFMEMORY; + uiResult = ::MsiFormatRecordW(hInstall, hRecord, szBuffer, &dwSize); + sValue.ReleaseBuffer(uiResult == NO_ERROR ? dwSize : 0); + return uiResult; + } else if (uiResult == NO_ERROR) { + // The result is empty. + sValue.Empty(); + return NO_ERROR; + } else { + // Return error code. + return uiResult; + } +} + + +inline UINT MsiRecordReadStream(MSIHANDLE hRecord, unsigned int iField, ATL::CAtlArray &binData) +{ + DWORD dwSize = 0; + UINT uiResult; + + // Query the actual data length first. + uiResult = ::MsiRecordReadStream(hRecord, iField, NULL, &dwSize); + if (uiResult == NO_ERROR) { + if (!binData.SetCount(dwSize)) return ERROR_OUTOFMEMORY; + return ::MsiRecordReadStream(hRecord, iField, (char*)binData.GetData(), &dwSize); + } else { + // Return error code. + return uiResult; + } +} + + +inline UINT MsiGetTargetPathA(MSIHANDLE hInstall, LPCSTR szFolder, ATL::CAtlStringA &sValue) +{ + DWORD dwSize = 0; + UINT uiResult; + + // Query the final string length first. + uiResult = ::MsiGetTargetPathA(hInstall, szFolder, "", &dwSize); + if (uiResult == ERROR_MORE_DATA) { + // Prepare the buffer to format the string data into and read it. + LPSTR szBuffer = sValue.GetBuffer(dwSize++); + if (!szBuffer) return ERROR_OUTOFMEMORY; + uiResult = ::MsiGetTargetPathA(hInstall, szFolder, szBuffer, &dwSize); + sValue.ReleaseBuffer(uiResult == NO_ERROR ? dwSize : 0); + return uiResult; + } else if (uiResult == NO_ERROR) { + // The result is empty. + sValue.Empty(); + return NO_ERROR; + } else { + // Return error code. + return uiResult; + } +} + + +inline UINT MsiGetTargetPathW(MSIHANDLE hInstall, LPCWSTR szFolder, ATL::CAtlStringW &sValue) +{ + DWORD dwSize = 0; + UINT uiResult; + + // Query the final string length first. + uiResult = ::MsiGetTargetPathW(hInstall, szFolder, L"", &dwSize); + if (uiResult == ERROR_MORE_DATA) { + // Prepare the buffer to format the string data into and read it. + LPWSTR szBuffer = sValue.GetBuffer(dwSize++); + if (!szBuffer) return ERROR_OUTOFMEMORY; + uiResult = ::MsiGetTargetPathW(hInstall, szFolder, szBuffer, &dwSize); + sValue.ReleaseBuffer(uiResult == NO_ERROR ? dwSize : 0); + return uiResult; + } else if (uiResult == NO_ERROR) { + // The result is empty. + sValue.Empty(); + return NO_ERROR; + } else { + // Return error code. + return uiResult; + } +} diff --git a/atlsec.h b/atlsec.h new file mode 100644 index 0000000..78a1e9d --- /dev/null +++ b/atlsec.h @@ -0,0 +1,84 @@ +/* + Copyright 1991-2015 Amebis + + This file is part of libatl. + + Setup is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Setup is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Setup. If not, see . +*/ + +#include + + +BOOLEAN GetUserNameExA(__in EXTENDED_NAME_FORMAT NameFormat, __out ATL::CAtlStringA &sName) +{ + ULONG ulSize = 0; + + // Query the final string length first. + if (!::GetUserNameExA(NameFormat, NULL, &ulSize)) { + if (::GetLastError() == ERROR_MORE_DATA) { + // Prepare the buffer and retry. + LPSTR szBuffer = sName.GetBuffer(ulSize - 1); + if (!szBuffer) { + SetLastError(ERROR_OUTOFMEMORY); + return FALSE; + } + if (::GetUserNameExA(NameFormat, szBuffer, &ulSize)) { + sName.ReleaseBuffer(ulSize); + return TRUE; + } else { + sName.ReleaseBuffer(0); + return FALSE; + } + } else { + // Return error. + return FALSE; + } + } else { + // The result is empty. + sName.Empty(); + return NO_ERROR; + } +} + + +BOOLEAN GetUserNameExW(__in EXTENDED_NAME_FORMAT NameFormat, __out ATL::CAtlStringW &sName) +{ + ULONG ulSize = 0; + + // Query the final string length first. + if (!::GetUserNameExW(NameFormat, NULL, &ulSize)) { + if (::GetLastError() == ERROR_MORE_DATA) { + // Prepare the buffer and retry. + LPWSTR szBuffer = sName.GetBuffer(ulSize - 1); + if (!szBuffer) { + SetLastError(ERROR_OUTOFMEMORY); + return FALSE; + } + if (::GetUserNameExW(NameFormat, szBuffer, &ulSize)) { + sName.ReleaseBuffer(ulSize); + return TRUE; + } else { + sName.ReleaseBuffer(0); + return FALSE; + } + } else { + // Return error. + return FALSE; + } + } else { + // The result is empty. + sName.Empty(); + return NO_ERROR; + } +} diff --git a/atlshlwapi.h b/atlshlwapi.h new file mode 100644 index 0000000..4b4dcfa --- /dev/null +++ b/atlshlwapi.h @@ -0,0 +1,53 @@ +/* + Copyright 1991-2015 Amebis + + This file is part of libatl. + + Setup is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Setup is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Setup. If not, see . +*/ + +#pragma once + +#include +#include + + +inline BOOL PathCanonicalizeA(__out ATL::CAtlStringA &sValue, __in LPCSTR pszPath) +{ + // Prepare the buffer data and read into it. + LPSTR szBuffer = sValue.GetBuffer(MAX_PATH); + if (!szBuffer) { + ::SetLastError(ERROR_OUTOFMEMORY); + return FALSE; + } + BOOL bResult = ::PathCanonicalizeA(szBuffer, pszPath); + sValue.ReleaseBuffer(bResult ? (int)strnlen(szBuffer, MAX_PATH) : 0); + sValue.FreeExtra(); + return bResult; +} + + +inline BOOL PathCanonicalizeW(__out ATL::CAtlStringW &sValue, __in LPCWSTR pszPath) +{ + // Prepare the buffer data and read into it. + LPWSTR szBuffer = sValue.GetBuffer(MAX_PATH); + if (!szBuffer) { + ::SetLastError(ERROR_OUTOFMEMORY); + return FALSE; + } + BOOL bResult = ::PathCanonicalizeW(szBuffer, pszPath); + sValue.ReleaseBuffer(bResult ? (int)wcsnlen(szBuffer, MAX_PATH) : 0); + sValue.FreeExtra(); + return bResult; +} diff --git a/atlwin.h b/atlwin.h new file mode 100644 index 0000000..f4056de --- /dev/null +++ b/atlwin.h @@ -0,0 +1,423 @@ +/* + Copyright 1991-2015 Amebis + + This file is part of libatl. + + Setup is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Setup is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Setup. If not, see . +*/ + +#pragma once + +#include "atlex.h" +#include +#include +#include + + +inline DWORD GetModuleFileNameA(__in_opt HMODULE hModule, __out ATL::CAtlStringA &sValue) +{ + DWORD dwSize = 0; + + for (;;) { + // Increment size and allocate buffer. + LPSTR szBuffer = sValue.GetBuffer(dwSize += 1024); + if (!szBuffer) { + ::SetLastError(ERROR_OUTOFMEMORY); + return 0; + } + + // Try! + DWORD dwResult = ::GetModuleFileNameA(hModule, szBuffer, dwSize); + if (dwResult == 0) { + // Error. + sValue.ReleaseBuffer(0); + return 0; + } else if (dwResult < dwSize) { + DWORD dwLength = (DWORD)strnlen(szBuffer, dwSize); + sValue.ReleaseBuffer(dwLength++); + if (dwLength == dwSize) { + // Buffer was long exactly enough. + return dwResult; + } if (dwLength < dwSize) { + // Buffer was long enough to get entire string, and has some extra space left. + sValue.FreeExtra(); + return dwResult; + } + } + } +} + + +inline DWORD GetModuleFileNameW(__in_opt HMODULE hModule, __out ATL::CAtlStringW &sValue) +{ + DWORD dwSize = 0; + + for (;;) { + // Increment size and allocate buffer. + LPWSTR szBuffer = sValue.GetBuffer(dwSize += 1024); + if (!szBuffer) { + ::SetLastError(ERROR_OUTOFMEMORY); + return 0; + } + + // Try! + DWORD dwResult = ::GetModuleFileNameW(hModule, szBuffer, dwSize); + if (dwResult == 0) { + // Error. + sValue.ReleaseBuffer(0); + return 0; + } else if (dwResult < dwSize) { + DWORD dwLength = (DWORD)wcsnlen(szBuffer, dwSize); + sValue.ReleaseBuffer(dwLength++); + if (dwLength == dwSize) { + // Buffer was long exactly enough. + return dwResult; + } if (dwLength < dwSize) { + // Buffer was long enough to get entire string, and has some extra space left. + sValue.FreeExtra(); + return dwResult; + } + } + } +} + + +inline int GetWindowTextA(__in HWND hWnd, __out ATL::CAtlStringA &sValue) +{ + int iResult; + + // Query the final string length first. + iResult = ::GetWindowTextLengthA(hWnd); + if (iResult > 0) { + // Prepare the buffer and read the string data into it. + LPSTR szBuffer = sValue.GetBuffer(iResult++); + if (!szBuffer) { + SetLastError(ERROR_OUTOFMEMORY); + return 0; + } + iResult = ::GetWindowTextA(hWnd, szBuffer, iResult); + sValue.ReleaseBuffer(iResult); + return iResult; + } else { + // The result is empty. + sValue.Empty(); + return 0; + } +} + + +inline int GetWindowTextW(__in HWND hWnd, __out ATL::CAtlStringW &sValue) +{ + int iResult; + + // Query the final string length first. + iResult = ::GetWindowTextLengthW(hWnd); + if (iResult > 0) { + // Prepare the buffer and read the string data into it. + LPWSTR szBuffer = sValue.GetBuffer(iResult++); + if (!szBuffer) { + SetLastError(ERROR_OUTOFMEMORY); + return 0; + } + iResult = ::GetWindowTextW(hWnd, szBuffer, iResult); + sValue.ReleaseBuffer(iResult); + return iResult; + } else { + // The result is empty. + sValue.Empty(); + return 0; + } +} + + +inline BOOL GetFileVersionInfoA(__in LPCSTR lptstrFilename, __reserved DWORD dwHandle, __out ATL::CAtlArray &aValue) +{ + // Get version info size. + DWORD dwVerInfoSize = ::GetFileVersionInfoSizeA(lptstrFilename, &dwHandle); + if (dwVerInfoSize != 0) { + if (aValue.SetCount(dwVerInfoSize)) { + // Read version info. + return ::GetFileVersionInfoA(lptstrFilename, dwHandle, dwVerInfoSize, aValue.GetData()); + } else { + ::SetLastError(ERROR_OUTOFMEMORY); + return FALSE; + } + } else + return FALSE; +} + + +inline BOOL GetFileVersionInfoW(__in LPCWSTR lptstrFilename, __reserved DWORD dwHandle, __out ATL::CAtlArray &aValue) +{ + // Get version info size. + DWORD dwVerInfoSize = ::GetFileVersionInfoSizeW(lptstrFilename, &dwHandle); + if (dwVerInfoSize != 0) { + if (aValue.SetCount(dwVerInfoSize)) { + // Read version info. + return ::GetFileVersionInfoW(lptstrFilename, dwHandle, dwVerInfoSize, aValue.GetData()); + } else { + ::SetLastError(ERROR_OUTOFMEMORY); + return FALSE; + } + } else + return FALSE; +} + + +inline DWORD ExpandEnvironmentStringsA(__in LPCSTR lpSrc, ATL::CAtlStringA &sValue) +{ + DWORD dwBufferSizeEst = (DWORD)strlen(lpSrc) + 0x100; // Initial estimate + + for (;;) { + DWORD dwBufferSize = dwBufferSizeEst; + LPSTR szBuffer = sValue.GetBuffer(dwBufferSize); + if (!szBuffer) { + ::SetLastError(ERROR_OUTOFMEMORY); + return FALSE; + } + dwBufferSizeEst = ::ExpandEnvironmentStringsA(lpSrc, szBuffer, dwBufferSize); + if (dwBufferSizeEst > dwBufferSize) { + // The buffer was to small. Repeat with a bigger one. + sValue.ReleaseBuffer(0); + } else if (dwBufferSizeEst == 0) { + // Error. + sValue.ReleaseBuffer(0); + return 0; + } else { + // The buffer was sufficient. Break. + sValue.ReleaseBuffer(); + sValue.FreeExtra(); + return dwBufferSizeEst; + } + } +} + + +inline DWORD ExpandEnvironmentStringsW(__in LPCWSTR lpSrc, ATL::CAtlStringW &sValue) +{ + DWORD dwBufferSizeEst = (DWORD)wcslen(lpSrc) + 0x100; // Initial estimate + + for (;;) { + DWORD dwBufferSize = dwBufferSizeEst; + LPWSTR szBuffer = sValue.GetBuffer(dwBufferSize); + if (!szBuffer) { + ::SetLastError(ERROR_OUTOFMEMORY); + return FALSE; + } + dwBufferSizeEst = ::ExpandEnvironmentStringsW(lpSrc, szBuffer, dwBufferSize); + if (dwBufferSizeEst > dwBufferSize) { + // The buffer was to small. Repeat with a bigger one. + sValue.ReleaseBuffer(0); + } else if (dwBufferSizeEst == 0) { + // Error. + sValue.ReleaseBuffer(0); + return 0; + } else { + // The buffer was sufficient. Break. + sValue.ReleaseBuffer(); + sValue.FreeExtra(); + return dwBufferSizeEst; + } + } +} + + +inline VOID GuidToString(_In_ LPCGUID lpGuid, ATL::CAtlStringA &str) +{ + str.Format("{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}", + lpGuid->Data1, + lpGuid->Data2, + lpGuid->Data3, + lpGuid->Data4[0], lpGuid->Data4[1], + lpGuid->Data4[2], lpGuid->Data4[3], lpGuid->Data4[4], lpGuid->Data4[5], lpGuid->Data4[6], lpGuid->Data4[7]); +} + + +inline VOID GuidToString(_In_ LPCGUID lpGuid, ATL::CAtlStringW &str) +{ + str.Format(L"{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}", + lpGuid->Data1, + lpGuid->Data2, + lpGuid->Data3, + lpGuid->Data4[0], lpGuid->Data4[1], + lpGuid->Data4[2], lpGuid->Data4[3], lpGuid->Data4[4], lpGuid->Data4[5], lpGuid->Data4[6], lpGuid->Data4[7]); +} + + +inline LSTATUS RegQueryStringValue(_In_ HKEY hReg, _In_z_ LPCSTR pszName, _Out_ ATL::CAtlStringA &sValue) +{ + LSTATUS lResult; + DWORD dwSize = 0, dwType; + + // Determine the type and size first. + if ((lResult = ::RegQueryValueExA(hReg, pszName, NULL, &dwType, NULL, &dwSize)) == ERROR_SUCCESS) { + if (dwType == REG_SZ || dwType == REG_MULTI_SZ) { + // The value is REG_SZ or REG_MULTI_SZ. Read it now. + LPSTR szTemp = sValue.GetBuffer(dwSize / sizeof(TCHAR)); + if (!szTemp) return ERROR_OUTOFMEMORY; + if ((lResult = ::RegQueryValueExA(hReg, pszName, NULL, NULL, (LPBYTE)szTemp, &dwSize)) == ERROR_SUCCESS) { + sValue.ReleaseBuffer(); + } else { + // Reading of the value failed. + sValue.ReleaseBuffer(0); + } + } else if (dwType == REG_EXPAND_SZ) { + // The value is REG_EXPAND_SZ. Read it and expand environment variables. + ATL::CTempBuffer sTemp(dwSize / sizeof(CHAR)); + if ((lResult = ::RegQueryValueExA(hReg, pszName, NULL, NULL, (LPBYTE)(CHAR*)sTemp, &dwSize)) == ERROR_SUCCESS) + if (::ExpandEnvironmentStringsA((const CHAR*)sTemp, sValue) == 0) + lResult = ::GetLastError(); + } else { + // The value is not a string type. + lResult = ERROR_INVALID_DATA; + } + } + + return lResult; +} + + +inline LSTATUS RegQueryStringValue(_In_ HKEY hReg, _In_z_ LPCWSTR pszName, _Out_ ATL::CAtlStringW &sValue) +{ + LSTATUS lResult; + DWORD dwSize = 0, dwType; + + // Determine the type and size first. + if ((lResult = ::RegQueryValueExW(hReg, pszName, NULL, &dwType, NULL, &dwSize)) == ERROR_SUCCESS) { + if (dwType == REG_SZ || dwType == REG_MULTI_SZ) { + // The value is REG_SZ or REG_MULTI_SZ. Read it now. + LPWSTR szTemp = sValue.GetBuffer(dwSize / sizeof(TCHAR)); + if (!szTemp) return ERROR_OUTOFMEMORY; + if ((lResult = ::RegQueryValueExW(hReg, pszName, NULL, NULL, (LPBYTE)szTemp, &dwSize)) == ERROR_SUCCESS) { + sValue.ReleaseBuffer(); + } else { + // Reading of the value failed. + sValue.ReleaseBuffer(0); + } + } else if (dwType == REG_EXPAND_SZ) { + // The value is REG_EXPAND_SZ. Read it and expand environment variables. + ATL::CTempBuffer sTemp(dwSize / sizeof(WCHAR)); + if ((lResult = ::RegQueryValueExW(hReg, pszName, NULL, NULL, (LPBYTE)(WCHAR*)sTemp, &dwSize)) == ERROR_SUCCESS) + if (::ExpandEnvironmentStringsW((const WCHAR*)sTemp, sValue) == 0) + lResult = ::GetLastError(); + } else { + // The value is not a string type. + lResult = ERROR_INVALID_DATA; + } + } + + return lResult; +} + + +inline LSTATUS RegQueryValueExA(__in HKEY hKey, __in_opt LPCSTR lpValueName, __reserved LPDWORD lpReserved, __out_opt LPDWORD lpType, __out ATL::CAtlArray &aData) +{ + LSTATUS lResult; + DWORD dwDataSize; + + if ((lResult = RegQueryValueExA(hKey, lpValueName, lpReserved, NULL, NULL, &dwDataSize)) == ERROR_SUCCESS) { + if (!aData.SetCount(dwDataSize)) return ERROR_OUTOFMEMORY; + if ((lResult = RegQueryValueExA(hKey, lpValueName, lpReserved, lpType, aData.GetData(), &dwDataSize)) != ERROR_SUCCESS) + aData.SetCount(0); + } + + return lResult; +} + + +inline LSTATUS RegQueryValueExW(__in HKEY hKey, __in_opt LPCWSTR lpValueName, __reserved LPDWORD lpReserved, __out_opt LPDWORD lpType, __out ATL::CAtlArray &aData) +{ + LSTATUS lResult; + DWORD dwDataSize; + + if ((lResult = RegQueryValueExW(hKey, lpValueName, lpReserved, NULL, NULL, &dwDataSize)) == ERROR_SUCCESS) { + if (!aData.SetCount(dwDataSize)) return ERROR_OUTOFMEMORY; + if ((lResult = RegQueryValueExW(hKey, lpValueName, lpReserved, lpType, aData.GetData(), &dwDataSize)) != ERROR_SUCCESS) + aData.SetCount(0); + } + + return lResult; +} + + +#if _WIN32_WINNT >= _WIN32_WINNT_VISTA + +inline LSTATUS RegLoadMUIStringA(__in HKEY hKey, __in_opt LPCSTR pszValue, __out ATL::CAtlStringA &sOut, __in DWORD Flags, __in_opt LPCSTR pszDirectory) +{ + LSTATUS lResult; + DWORD dwSize; + + Flags &= ~REG_MUI_STRING_TRUNCATE; + + lResult = RegLoadMUIStringA(hKey, pszValue, NULL, 0, &dwSize, Flags, pszDirectory); + if (lResult == ERROR_MORE_DATA) { + LPSTR szBuffer = sOut.GetBuffer(dwSize - 1); + if (!szBuffer) return ERROR_OUTOFMEMORY; + sOut.ReleaseBuffer((lResult = RegLoadMUIStringA(hKey, pszValue, szBuffer, dwSize, &dwSize, Flags, pszDirectory)) == ERROR_SUCCESS ? dwSize - 1 : 0); + } else if (lResult == ERROR_SUCCESS) + sOut.Empty(); + + return lResult; +} + + +inline LSTATUS RegLoadMUIStringW(__in HKEY hKey, __in_opt LPCWSTR pszValue, __out ATL::CAtlStringW &sOut, __in DWORD Flags, __in_opt LPCWSTR pszDirectory) +{ + LSTATUS lResult; + DWORD dwSize; + + Flags &= ~REG_MUI_STRING_TRUNCATE; + + lResult = RegLoadMUIStringW(hKey, pszValue, NULL, 0, &dwSize, Flags, pszDirectory); + if (lResult == ERROR_MORE_DATA) { + LPWSTR szBuffer = sOut.GetBuffer(dwSize - 1); + if (!szBuffer) return ERROR_OUTOFMEMORY; + sOut.ReleaseBuffer((lResult = RegLoadMUIStringW(hKey, pszValue, szBuffer, dwSize, &dwSize, Flags, pszDirectory)) == ERROR_SUCCESS ? dwSize - 1 : 0); + } else if (lResult == ERROR_SUCCESS) + sOut.Empty(); + + return lResult; +} + +#endif + + +namespace ATL +{ + class CAtlLibrary : public CObjectWithHandleT + { + public: + virtual ~CAtlLibrary() throw() + { + if (m_h) + FreeLibrary(m_h); + } + + inline BOOL Load(__in LPCTSTR lpFileName, __reserved HANDLE hFile, __in DWORD dwFlags) throw() + { + HANDLE h = LoadLibraryEx(lpFileName, hFile, dwFlags); + if (h) { + Attach(h); + return TRUE; + } else + return FALSE; + } + + protected: + virtual void InternalFree() + { + FreeLibrary(m_h); + } + }; +} diff --git a/atlwlan.h b/atlwlan.h new file mode 100644 index 0000000..3d5be95 --- /dev/null +++ b/atlwlan.h @@ -0,0 +1,54 @@ +/* + Copyright 1991-2015 Amebis + + This file is part of libatl. + + Setup is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Setup is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Setup. If not, see . +*/ + +#pragma once + +#include +#include + + +inline DWORD WlanReasonCodeToString(__in DWORD dwReasonCode, __out ATL::CAtlStringW &sValue, __reserved PVOID pReserved) +{ + DWORD dwSize = 0; + + for (;;) { + // Increment size and allocate buffer. + LPWSTR szBuffer = sValue.GetBuffer(dwSize += 1024); + if (!szBuffer) return ERROR_OUTOFMEMORY; + + // Try! + DWORD dwResult = ::WlanReasonCodeToString(dwReasonCode, dwSize, szBuffer, pReserved); + if (dwResult == NO_ERROR) { + DWORD dwLength = (DWORD)wcsnlen(szBuffer, dwSize); + sValue.ReleaseBuffer(dwLength++); + if (dwLength == dwSize) { + // Buffer was long exactly enough. + return NO_ERROR; + } else if (dwLength < dwSize) { + // Buffer was long enough to get entire string, and has some extra space left. + sValue.FreeExtra(); + return NO_ERROR; + } + } else { + // Return error code. + sValue.ReleaseBuffer(0); + return dwResult; + } + } +} diff --git a/stdafx.cpp b/stdafx.cpp new file mode 100644 index 0000000..81111ac --- /dev/null +++ b/stdafx.cpp @@ -0,0 +1,20 @@ +/* + Copyright 1991-2015 Amebis + + This file is part of libatl. + + Setup is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Setup is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Setup. If not, see . +*/ + +#include "stdafx.h" diff --git a/stdafx.h b/stdafx.h new file mode 100644 index 0000000..99c70cc --- /dev/null +++ b/stdafx.h @@ -0,0 +1,33 @@ +/* + Copyright 1991-2015 Amebis + + This file is part of libatl. + + Setup is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Setup is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Setup. If not, see . +*/ + +#pragma once + +#include "atlwin.h" + +#include "atlcrypt.h" +#include "atleap.h" +#include "atlex.h" +#include "atlmsi.h" +#if defined(SECURITY_WIN32) || defined(SECURITY_KERNEL) || defined(SECURITY_MAC) +#include "atlsec.h" +#endif +#include "atlshlwapi.h" +#include "atlwin.h" +#include "atlwlan.h"