windows-nt/Source/XPSP1/NT/net/ias/services/dictionary/datasource.cpp

256 lines
6.3 KiB
C++
Raw Permalink Normal View History

2020-09-26 03:20:57 -05:00
///////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 1997, Microsoft Corp. All rights reserved.
//
// FILE
//
// DataSource.cpp
//
// SYNOPSIS
//
// This file implements the class CIasDataSource.
//
// MODIFICATION HISTORY
//
// 11/05/1997 Original version.
// 12/19/1997 Added ExecuteCommand method.
// 01/15/1998 Implemented IIasComponent method.
// 02/09/1998 Added AllowUpdate property.
// 03/17/1999 Create TMP dir before calling IDBInitialize::Initialize.
// 04/22/1999 Clean-up session and connection in destructor.
//
///////////////////////////////////////////////////////////////////////////////
#include <iascore.h>
#include <iasutil.h>
#include <guard.h>
#include <DataSource.h>
#include <PropSet.h>
CIasDataSource::CIasDataSource() throw ()
: initStatus(E_FAIL),
provider(NULL),
name(NULL),
userID(NULL),
password(NULL),
allowUpdate(false),
connection(NULL),
session(NULL)
{
}
CIasDataSource::~CIasDataSource() throw ()
{
if (session) { session->Release(); }
if (connection) { connection->Release(); }
delete[] password;
delete[] userID;
delete[] name;
delete[] provider;
}
//////////
// Macros to handle getting and putting a string property.
//////////
#define WSTRING_PROPERTY(class, prop, member) \
STDMETHODIMP class ## ::put_ ## prop (LPCWSTR newVal) \
{ \
_com_serialize \
delete[] member; \
member = ias_wcsdup(newVal); \
return S_OK; \
} \
\
STDMETHODIMP class ## ::get_ ## prop (LPWSTR* pVal) \
{ \
if (pVal == NULL) return E_POINTER; \
_com_serialize \
*pVal = com_wcsdup(member); \
return S_OK; \
}
WSTRING_PROPERTY(CIasDataSource, Provider, provider)
WSTRING_PROPERTY(CIasDataSource, Name, name)
WSTRING_PROPERTY(CIasDataSource, UserID, userID)
WSTRING_PROPERTY(CIasDataSource, Password, password)
STDMETHODIMP CIasDataSource::put_AllowUpdate(boolean newVal)
{
allowUpdate = (newVal != 0);
return S_OK;
}
STDMETHODIMP CIasDataSource::get_AllowUpdate(boolean* pVal)
{
return pVal ? (*pVal = (boolean)allowUpdate), S_OK : E_POINTER;
}
//////////
// Macro to set the InitStatus and bail on an error.
//////////
#define CHECK_INIT(expr) \
if (FAILED(initStatus = expr)) return initStatus;
STDMETHODIMP CIasDataSource::Initialize()
{
_com_serialize
// Clean up an existing connection.
Shutdown();
// Convert the ProgID to a ClsID.
CLSID clsid;
CHECK_INIT(CLSIDFromProgID(provider, &clsid));
// Create the OLE DB provider.
CHECK_INIT(CoCreateInstance(clsid,
NULL,
CLSCTX_INPROC_SERVER,
IID_IDBInitialize,
(PVOID*)&connection));
//////////
// Set the properties for the data source.
//////////
CComPtr<IDBProperties> properties;
CHECK_INIT(connection->QueryInterface(IID_IDBProperties,
(PVOID*)&properties));
DBPropertySet<4> propSet(DBPROPSET_DBINIT);
propSet.AddProperty(DBPROP_INIT_MODE, allowUpdate ? DB_MODE_READWRITE
: DB_MODE_READ);
if (name) propSet.AddProperty(DBPROP_INIT_DATASOURCE, name);
if (userID) propSet.AddProperty(DBPROP_AUTH_USERID, userID);
if (password) propSet.AddProperty(DBPROP_AUTH_PASSWORD, password);
CHECK_INIT(properties->SetProperties(1, &propSet));
//////////
// JetInit fails if the TMP directory doesn't exist, so we'll try to
// create it just in case.
//////////
DWORD needed = GetEnvironmentVariableW(L"TMP", NULL, 0);
if (needed)
{
PWCHAR buf = (PWCHAR)_alloca(needed * sizeof(WCHAR));
DWORD actual = GetEnvironmentVariableW(L"TMP", buf, needed);
if (actual > 0 && actual < needed)
{
CreateDirectoryW(buf, NULL);
}
}
//////////
// Initialize the connection.
//////////
CHECK_INIT(connection->Initialize());
//////////
// Create a session.
//////////
CComPtr<IDBCreateSession> creator;
CHECK_INIT(connection->QueryInterface(IID_IDBCreateSession,
(PVOID*)&creator));
CHECK_INIT(creator->CreateSession(NULL,
IID_IOpenRowset,
(IUnknown**)&session));
return S_OK;
}
STDMETHODIMP CIasDataSource::Shutdown()
{
_com_serialize
IAS_DEREF(session);
IAS_DEREF(connection);
initStatus = E_FAIL;
return S_OK;
}
STDMETHODIMP CIasDataSource::OpenTable(LPCWSTR szTableName, IUnknown** ppTable)
{
if (!ppTable)
{
return E_POINTER;
}
// Make sure the data source has been successfully initialized.
_com_serialize
if (FAILED(initStatus))
{
return initStatus;
}
*ppTable = NULL;
DBID idTable;
idTable.eKind = DBKIND_NAME;
idTable.uName.pwszName = const_cast<LPWSTR>(szTableName);
return session->OpenRowset(NULL,
&idTable,
NULL,
IID_IUnknown,
0,
NULL,
ppTable);
}
STDMETHODIMP CIasDataSource::ExecuteCommand(REFGUID rguidDialect,
LPCWSTR szCommandText,
IUnknown** ppRowset)
{
if (!ppRowset)
{
return E_POINTER;
}
_com_serialize
// Make sure the data source has been successfully initialized.
if (FAILED(initStatus))
{
return initStatus;
}
*ppRowset = NULL;
CComPtr<IDBCreateCommand> creator;
RETURN_ERROR(session->QueryInterface(IID_IDBCreateCommand,
(PVOID*)&creator));
CComPtr<ICommandText> command;
RETURN_ERROR(creator->CreateCommand(NULL,
IID_ICommandText,
(IUnknown**)&command));
RETURN_ERROR(command->SetCommandText(rguidDialect,
szCommandText));
return command->Execute(NULL,
IID_IUnknown,
NULL,
NULL,
ppRowset);
}