📄 atldb.h
字号:
}
void CLEARBIT( DWORD rgdwFlags[], const DWORD dwBit )
{
rgdwFlags[DivDword(dwBit)] &= ~( 1 << ModDword(dwBit) );
}
DWORD TESTBIT( const DWORD rgdwFlags[], const DWORD dwBit )
{
//old//Note: Not {0,1}, but from {0...2^32-1}.
// Note: Now returns {0,1}.
return ( rgdwFlags[DivDword(dwBit)] & ( 1 << ModDword(dwBit) ) ) != 0;
}
};
// Implementation Class
class CDBIDOps
{
public:
HRESULT CompareDBIDs(const DBID* pdbid1, const DBID* pdbid2)
{
// Array of valid eKind matches, in addition to matching exactly.
static BYTE s_rgbKind[] =
{
DBKIND_PGUID_NAME, // DBKIND_GUID_NAME
DBKIND_PGUID_PROPID, // DBKIND_GUID_PROPID
DBKIND_NAME, // DBKIND_NAME
DBKIND_GUID_NAME, // DBKIND_PGUID_NAME
DBKIND_GUID_PROPID, // DBKIND_PGUID_PROPID
DBKIND_PROPID, // DBKIND_PROPID
DBKIND_GUID // DBKIND_GUID
};
if( !pdbid1 || !pdbid2 )
return S_FALSE;
// Assume a match, and discard early if we can.
if (!InRange(pdbid2->eKind, (DWORD)0, (DWORD)(sizeof(s_rgbKind)/sizeof(*s_rgbKind))))
{
ATLTRACE2(atlTraceDBProvider, 0, "Column ID out of Range\n");
return E_FAIL;
}
if (pdbid1->eKind != pdbid2->eKind
&& pdbid1->eKind != s_rgbKind[pdbid2->eKind])
return S_FALSE;
if (DBID_USE_GUID_OR_PGUID(pdbid1->eKind))
{
if (!DBID_USE_GUID_OR_PGUID(pdbid2->eKind))
return S_FALSE;
// Compare GUIDs.
// Note that _GUID_ is equivalent to _PGUID_.
if (!InlineIsEqualGUID(
DBID_USE_PGUID(pdbid1->eKind) ? *(pdbid1->uGuid.pguid) : pdbid1->uGuid.guid,
DBID_USE_PGUID(pdbid2->eKind) ? *(pdbid2->uGuid.pguid) : pdbid2->uGuid.guid ))
return S_FALSE;
}
if (DBID_USE_NAME(pdbid1->eKind))
{
if (!DBID_USE_NAME(pdbid2->eKind))
return S_FALSE;
// Compare names.
// Need to check if 1 is null and the other is not.
if ( ((pdbid1->uName.pwszName == NULL) &&
(pdbid2->uName.pwszName != NULL)) ||
((pdbid1->uName.pwszName != NULL) &&
(pdbid2->uName.pwszName == NULL)) )
return S_FALSE;
// Since the above check does not rule out both being null, which is
// a valid comparison, and wcscmp will GPF if they were, we need
// to check for valid pointers
if( pdbid1->uName.pwszName && pdbid2->uName.pwszName )
{
// Assume null-terminated.
// Assume LCID match is OK (note diff with lstrcmp(), CompareString().)
if (wcscmp(pdbid1->uName.pwszName, pdbid2->uName.pwszName) != 0)
return S_FALSE;
}
}
if (DBID_USE_PROPID(pdbid1->eKind))
{
if (!DBID_USE_PROPID(pdbid2->eKind))
return S_FALSE;
// Compare PROPID.
if (pdbid1->uName.ulPropid != pdbid2->uName.ulPropid)
return S_FALSE;
}
// No reason to discard, so must have matched each field successfully.
return S_OK;
}
static HRESULT IsValidDBID(const DBID* pdbid1)
{
ATLASSERT( pdbid1 );
if( pdbid1 &&
((pdbid1->eKind == DBKIND_GUID_NAME) ||
(pdbid1->eKind == DBKIND_GUID_PROPID) ||
(pdbid1->eKind == DBKIND_NAME) ||
(pdbid1->eKind == DBKIND_PGUID_NAME) ||
(pdbid1->eKind == DBKIND_PGUID_PROPID) ||
(pdbid1->eKind == DBKIND_PROPID) ||
(pdbid1->eKind == DBKIND_GUID)) )
return S_OK;
else
return S_FALSE;
}
HRESULT CopyDBIDs(DBID* pdbidDest, const DBID* pdbidSrc)
{
size_t cwchBuffer;
ATLASSERT( pdbidDest || pdbidSrc );
if( !pdbidDest || !pdbidSrc )
return S_FALSE;
// Save eKind
pdbidDest->eKind = pdbidSrc->eKind;
switch( pdbidSrc->eKind )
{
case DBKIND_GUID_NAME:
pdbidDest->uGuid.guid = pdbidSrc->uGuid.guid;
cwchBuffer = ocslen(pdbidSrc->uName.pwszName);
cwchBuffer++;
pdbidDest->uName.pwszName = (PWSTR)CoTaskMemAlloc(cwchBuffer * sizeof(WCHAR));
if( pdbidDest->uName.pwszName )
memcpy(pdbidDest->uName.pwszName, pdbidSrc->uName.pwszName, cwchBuffer*sizeof(WCHAR));
else
return E_OUTOFMEMORY;
break;
case DBKIND_GUID_PROPID:
pdbidDest->uGuid.guid = pdbidSrc->uGuid.guid;
pdbidDest->uName.ulPropid = pdbidSrc->uName.ulPropid;
break;
case DBKIND_NAME:
cwchBuffer = ocslen(pdbidSrc->uName.pwszName);
cwchBuffer++;
pdbidDest->uName.pwszName = (PWSTR)CoTaskMemAlloc(cwchBuffer * sizeof(WCHAR));
if( pdbidDest->uName.pwszName )
memcpy(pdbidDest->uName.pwszName, pdbidSrc->uName.pwszName, cwchBuffer*sizeof(WCHAR));
else
return E_OUTOFMEMORY;
break;
case DBKIND_PGUID_NAME:
pdbidDest->uGuid.pguid = (GUID*)CoTaskMemAlloc(sizeof(GUID));
if( pdbidDest->uGuid.pguid )
{
*(pdbidDest->uGuid.pguid) = *(pdbidSrc->uGuid.pguid);
cwchBuffer = ocslen(pdbidSrc->uName.pwszName);
cwchBuffer++;
pdbidDest->uName.pwszName = (PWSTR)CoTaskMemAlloc(cwchBuffer * sizeof(WCHAR));
if( pdbidDest->uName.pwszName )
{
memcpy(pdbidDest->uName.pwszName, pdbidSrc->uName.pwszName, cwchBuffer*sizeof(WCHAR));
break;
}
else
{
CoTaskMemFree(pdbidDest->uGuid.pguid);
pdbidDest->uGuid.pguid = NULL;
}
}
return E_OUTOFMEMORY;
case DBKIND_PGUID_PROPID:
pdbidDest->uGuid.pguid = (GUID*)CoTaskMemAlloc(sizeof(GUID));
if( pdbidDest->uGuid.pguid )
*(pdbidDest->uGuid.pguid) = *(pdbidSrc->uGuid.pguid);
else
return E_OUTOFMEMORY;
pdbidDest->uName.ulPropid = pdbidSrc->uName.ulPropid;
break;
case DBKIND_PROPID:
pdbidDest->uName.ulPropid = pdbidSrc->uName.ulPropid;
break;
case DBKIND_GUID:
pdbidDest->uGuid.guid = pdbidSrc->uGuid.guid;
break;
default:
ATLASSERT(L"Unhandled dbid1.ekind");
return S_FALSE;
}
return S_OK;
}
static GUID* GetDBIDpGuid(DBID& dbid)
{
GUID* pGuid;
switch (dbid.eKind)
{
case DBKIND_PGUID_NAME:
case DBKIND_PGUID_PROPID:
pGuid = dbid.uGuid.pguid;
break;
case DBKIND_GUID_NAME:
case DBKIND_GUID_PROPID:
case DBKIND_GUID:
pGuid = &(dbid.uGuid.guid);
break;
default:
pGuid = NULL;
}
return pGuid;
}
static ULONG GetPropIDFromDBID(DBID& dbid)
{
switch (dbid.eKind)
{
case DBKIND_GUID_PROPID:
case DBKIND_PGUID_PROPID:
case DBKIND_PROPID:
return dbid.uName.ulPropid;
default:
return 0;
}
}
void FreeDBIDs(DBID* pdbidSrc)
{
switch( pdbidSrc->eKind )
{
case DBKIND_GUID_NAME:
CoTaskMemFree(pdbidSrc->uName.pwszName);
break;
case DBKIND_NAME:
CoTaskMemFree(pdbidSrc->uName.pwszName);
break;
case DBKIND_PGUID_NAME:
CoTaskMemFree(pdbidSrc->uGuid.pguid);
CoTaskMemFree(pdbidSrc->uName.pwszName);
break;
case DBKIND_PGUID_PROPID:
CoTaskMemFree(pdbidSrc->uGuid.pguid);
break;
case DBKIND_GUID_PROPID:
case DBKIND_PROPID:
case DBKIND_GUID:
break;
default:
ATLASSERT(L"Unhandled dbid1.ekind");
break;
}
}
};
extern "C" const CLSID CLSID_DataConvert;
class CConvertHelper
{
public:
CConvertHelper() {}
HRESULT FinalConstruct()
{
HRESULT hr = ::CoCreateInstance(CLSID_DataConvert, NULL, CLSCTX_INPROC_SERVER, IID_IDataConvert, (void**)&m_spConvert);
if (FAILED(hr))
return hr;
// Check to see if the data conversion routine is 2.0 capable, if so. Initialize
// the conversion routine to be 2.0.
DCINFO rgInfo[] = {{DCINFOTYPE_VERSION, {VT_UI4, 0, 0, 0, 0x0}}};
CComPtr<IDCInfo> spIDCInfo;
hr = m_spConvert->QueryInterface(&spIDCInfo);
if (hr == S_OK)
{
V_UI4(&rgInfo->vData) = 0x200; // OLEDB Version 02.00
spIDCInfo->SetInfo(1, rgInfo);
}
return hr;
}
CComPtr<IDataConvert> m_spConvert;
};
// IDBCreateSessionImpl
template <class T, class SessionClass>
class ATL_NO_VTABLE IDBCreateSessionImpl : public IDBCreateSession
{
public:
STDMETHOD(CreateSession)(IUnknown *pUnkOuter,
REFIID riid,
IUnknown **ppDBSession)
{
ATLTRACE2(atlTraceDBProvider, 0, "IDBCreateSessionImpl::CreateSession\n");
if (ppDBSession == NULL)
return E_INVALIDARG;
T* pT = (T*)this;
if (!(pT->m_dwStatus & DSF_INITIALIZED))
{
ATLTRACE2(atlTraceDBProvider, 0, "IDBCreateSessionImpl::CreateSession : Error not initialized\n");
*ppDBSession = NULL;
return E_UNEXPECTED;
}
CComPolyObject<SessionClass> *pSession;
// You can't QI for an interface other than IUnknown when aggregating
// and creating the object. You might ask for your own interface,
// which would be bad. Note, we return DB_E_NOAGGREGATION instead of
// CLASS_E_NOAGGREGATION due to OLE DB constraints.
if (pUnkOuter != NULL && !InlineIsEqualUnknown(riid))
return DB_E_NOAGGREGATION;
HRESULT hr = CComPolyObject<SessionClass>::CreateInstance(pUnkOuter, &pSession);
if (SUCCEEDED(hr))
{
CComPtr<IObjectWithSite> spCreator;
hr = pSession->QueryInterface(IID_IObjectWithSite, (void**)&spCreator);
if (SUCCEEDED(hr))
{
spCreator->SetSite(this);
hr = pSession->QueryInterface(riid, (void**)ppDBSession);
}
else
delete pSession;
}
return hr;
}
};
// IDBInitializeImpl
template <class T>
class ATL_NO_VTABLE IDBInitializeImpl : public IDBInitialize
{
public:
IDBInitializeImpl()
{
m_dwStatus = 0;
m_pCUtlPropInfo = NULL;
m_cSessionsOpen = 0;
}
~IDBInitializeImpl()
{
delete m_pCUtlPropInfo;
}
STDMETHOD(Uninitialize)(void)
{
ATLTRACE2(atlTraceDBProvider, 0, "IDBInitializeImpl::Uninitialize\n");
T* pT = (T*)this;
pT->Lock();
if (pT->m_cSessionsOpen != 0)
{
ATLTRACE2(atlTraceDBProvider, 0, "Uninitialized called with Open Sessions\n");
return DB_E_OBJECTOPEN;
}
delete m_pCUtlPropInfo;
m_pCUtlPropInfo = NULL;
pT->m_dwStatus |= DSF_PERSIST_DIRTY;
pT->m_dwStatus &= DSF_MASK_INIT; // Clear all non-init flags.
pT->Unlock();
return S_OK;
}
LONG m_cSessionsOpen;
DWORD m_dwStatus;
CUtlPropInfo<T>* m_pCUtlPropInfo;
STDMETHOD(Initialize)(void)
{
ATLTRACE2(atlTraceDBProvider, 0, "IDBInitializeImpl::Initialize\n");
T *pT = (T*)(this);
T::ObjectLock lock(pT);
HRESULT hr;
if (pT->m_dwStatus & DSF_INITIALIZED)
{
ATLTRACE2(atlTraceDBProvider, 0, "IDBInitializeImpl::Initialize Error : Already Initialized\n");
return DB_E_ALREADYINITIALIZED;
}
delete m_pCUtlPropInfo;
m_pCUtlPropInfo = NULL;
ATLTRY(m_pCUtlPropInfo = new CUtlPropInfo<T>())
if (m_pCUtlPropInfo == NULL)
{
ATLTRACE2(atlTraceDBProvider, 0, "IDBInitializeImpl::Initialize Error : OOM\n");
return E_OUTOFMEMORY;
}
hr = m_pCUtlPropInfo->FInit();
if (hr == S_OK)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -